Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2024-42642 — Crucial MX500 SSD의 SM2259 컨트롤러에서 발견된 세 가지 펌웨어 취약점에 대한 기술적 분석 및 개념 증명 익스플로잇입니다. 여기에는 ATA DOWNLOAD-MICROCODE 핸들러의 버퍼 오버플로우와 정수 언더플로우가 포함되며, 잠재적인 코드 실행으로 이어질 수 있습니다. | Kitploit
도구/GitHubGitHub/vl4dr/cve-2024-42642
Embedded Systems SecurityVulnerability AnalysisExploitationReverse EngineeringHardware HackingHardware SecurityBinary AnalysisFirmware Analysis
GitHubvl4dr/cve-2024-42642

CVE-2024-42642

Crucial MX500 SSD의 SM2259 컨트롤러에서 발견된 세 가지 펌웨어 취약점에 대한 기술적 분석 및 개념 증명 익스플로잇입니다. 여기에는 ATA DOWNLOAD-MICROCODE 핸들러의 버퍼 오버플로우와 정수 언더플로우가 포함되며, 잠재적인 코드 실행으로 이어질 수 있습니다.

저장소 보기
1411년 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2024-42642

소개

해당 디바이스는 모든 MX500 시리즈 SSD입니다. 이 SSD는 Sillicon-Motion SM2259 컨트롤러로 제어됩니다 (이전 배치에서는 이전 컨트롤러인 Sillicon-Motion SM2258을 사용했지만, 이 문서의 주요 초점은 새로운 컨트롤러입니다). SM2259는 ARC 아키텍처 기반의 32비트 리틀 엔디언 CPU를 탑재한 4채널 SATA 6Gb/s 마이크로컨트롤러입니다. 이 문서 작성 시점의 최신 펌웨어인 M3CR046을 관찰한 결과, 정적 및 동적으로 몇 가지 문제가 확인되고 입증되었습니다. 모든 문제는 컨트롤러의 펌웨어 업데이트 메커니즘에서 식별되었으며, 이는 ATA PIO DOWNLOAD-MICROCODE (0x92) 명령어의 마이크로컨트롤러 핸들러에 해당합니다. 특히 서브커맨드 0x03 및 0x0E에 해당하는 오프셋 방식을 사용하여 펌웨어를 다운로드하는 로직에서 발생합니다. 이 문서에서 다루는 모든 버그는 Crucial MX500 500GB SSD (CT500MX500SSD1), SM2259H-AC 컨트롤러, M3CR046 펌웨어, NY112 플래시 칩, x86_64 CPU를 사용하는 PC에서 검증되었습니다.

펌웨어 코드는 기본 주소 0x80020000에 매핑되어 있으며, 취약한 ATA 핸들러는 주소 0x80024A9C에 위치합니다. 해당 함수의 디컴파일된 버전은 resources/download_microcode_handler.c에서 참조할 수 있습니다.

기술적 세부 사항을 다루기보다 결론을 이해하고 싶은 분들은 아래 FAQ 섹션을 참조하시기 바랍니다.

M3CR046에는 여러 펌웨어 이미지가 포함되어 있으며, 펌웨어 업데이트 메커니즘에 의해 적절한 이미지가 선택됩니다 (실제 사용된 플래시 칩이나 기타 하드웨어 특성에 따라 다를 수 있음). 이 문서에서는 첫 번째 펌웨어 변형의 세부 사항을 다룹니다 (이 펌웨어는 특정 드라이브에서 지원되므로 해당 변형만 테스트할 수 있었습니다). 그러나 이 문서에 제시된 버그는 모든 펌웨어 변형에 적용되는 것처럼 보이지만, 실제 재현 시 약간의 차이가 있을 수 있습니다.

버그 #1

이 문제는 전송된 첫 번째 청크의 크기가 0x200 섹터보다 큰 경우를 다룹니다. ATA 명령 핸들러 내부, 특히 청크 크기가 섹터 크기보다 크고 해당 청크가 첫 번째로 전송된 경우 실행되는 로직을 살펴보면:

image info

다음 오프셋 (우리의 경우 단일 청크만 전송했으므로 청크의 섹터 길이)과 lower_bound_fw_offset이라는 변수(입력 다운로드 이미지 내에서 펌웨어 이미지가 위치할 것으로 예상되는 블록 오프셋, 즉 섹터 단위 오프셋)를 기반으로 일부 변수를 설정합니다. 이는 펌웨어 변형별 하드코딩된 값으로, 우리의 경우(첫 번째 변형) 0과 같습니다. 이 경우 some_index에 대한 빼기 결과를 계산할 때 언더플로우가 발생하여 some_index가 0xFFFF까지 높아집니다. 이는 예상치 못한 동작으로, 데이터를 다운로드 버퍼로 이동하는 로직을 살펴보면:

image info

데이터가 복사되는 소스 주소가 some_index에 대해 계산된 예상치 못한 값으로 인해 유효하지 않을 수 있음을 알 수 있습니다. 첫 번째 청크의 크기가 0x200 섹터보다 큰 펌웨어 업데이트 요청을 동적으로 전송하여 테스트했을 때, 컨트롤러가 멈추고 원래 요청에 대한 응답조차 보내지 않았습니다. 이는 일관되게 재현 가능합니다. 이는 계산된 소스 주소에 대한 유효하지 않은 참조로 인해 예외가 발생하여 컨트롤러가 중단되는 것으로 추정됩니다. 이는 입증되지 않았지만 중단을 설명할 수 있는 추측입니다.

버그 #2

입력 다운로드 이미지 (M3CR046의 경우)의 크기는 0x242400 바이트이며, 이 이미지 내에는 3개의 내부 펌웨어 이미지가 있습니다. 펌웨어 업데이트 프로세스 후 최종적으로 플래시에 기록되는 이미지는 하나뿐이며, 각 이미지의 크기는 0xC0C00 바이트 (또는 0x606 섹터)입니다. 즉, 펌웨어 업데이트 메커니즘이 입력 다운로드 이미지에서 올바른 펌웨어 사본을 추출할 때 크기가 0xC0C00 바이트를 초과하지 않는지 확인해야 합니다. 컨트롤러는 실제로 그렇게 시도하지만, 예기치 않은 동작을 초래할 수 있는 몇 가지 코너 케이스가 있습니다. 다음 스니펫을 살펴보겠습니다 (이전 버그와 코드 일부를 공유함):

image info

현재 청크의 크기가 0x200 섹터보다 크고 시퀀스에서 첫 번째 청크가 아닌 경우, 한 번에 0x200 섹터 (0x40000 바이트)가 복사됩니다. 그런 다음 펌웨어 이미지의 총 크기가 higher_bound_fw_offset을 초과하는 경우 (우리의 경우 0x606 섹터, 펌웨어 크기가 정확히 이 값이어야 함) 복사할 바이트 수에서 초과 바이트를 잘라내기 위한 검사가 있습니다. 이 로직은 전반적으로 타당하지만, 한 가지 결함이 있습니다. 마지막으로 전송된 청크로 인해 다음 오프셋이 너무 높아져 초과 바이트 수가 0x200 섹터(또는 0x40000 바이트)를 초과하면 curr_bytes_to_copy가 "음수" 값을 가지게 되어 약 ~4GB (~0xFFFFFFFF)로 언더플로우됩니다. 앞서 보았듯이 이 변수는 다운로드 버퍼로 전송할 바이트 수를 결정하는 데 사용됩니다. r_maybe_some_efficient_data_transfer 내부를 살펴보면 다음 코드 조각을 볼 수 있습니다:

image info

즉, 복사 크기는 32MB로 잘립니다 (원래 ~4GB 복사 크기에서). 그러나 여전히 큰 숫자이며, 0x40000000에서 시작하는 메모리 범위의 크기가 32MB보다 작은 경우 정의되지 않은 동작이 발생할 수 있습니다. 오프셋 0x600에 도달하도록 ATA 청크를 전송한 다음 크기가 0x207 섹터인 큰 청크를 전송하여 언더플로우를 유발하는 동적 테스트를 수행했을 때, 컨트롤러는 다시 한 번 중단되었습니다. 아마도 복사 중 유효하지 않은 메모리 액세스 때문일 것입니다. 이 버그는 이전 버그보다 더 흥미롭습니다. 통제된 덮어쓰기가 아니라 (오히려 예외를 발생시켜 컨트롤러를 중단시키는 큰 덮어쓰기) 데이터를 다운로드 버퍼로 이동하는 함수가 충돌하기 전에 많은 양의 데이터를 전송할 수 있다면 (다운로드 버퍼 바로 뒤에 있는 메모리 범위를 덮어씀) 예외 핸들러의 동작이 덮어쓰여진 데이터에 의해 변경될 수 있기 때문입니다. 예를 들어 예외 핸들러가 덮어쓰여진 영역에서 포인터를 읽고 해당 포인터로 점프하는 경우 이런 일이 발생할 수 있습니다 (이 특정 경우는 특히 가능성이 높지는 않지만, 더 많은 연구를 통해 비슷한 것이 발견될 수 있습니다).

버그 #3

앞서 언급했듯이 다운로드 이미지의 크기는 0x242400 (또는 0x1212 섹터)입니다. 펌웨어는 다음 오프셋이 0x1212 섹터를 초과하지 않는지 확인하여 전송된 이미지의 총 크기가 이 크기를 초과하지 않도록 검증합니다. 이 검사는 타당하지만, 다음 오프셋 계산에 결함이 있습니다:

image info

현재 오프셋이 0x600 섹터이고 처리할 다음 ATA 명령어의 크기가 충분히 크다면 (예: 0xFC00 섹터, ATA 표준에서 허용됨) 다음 오프셋이 래핑되어 앞서 언급한 검사가 제대로 작동하지 않습니다:

image info

즉, 일반적인 경우 펌웨어 업데이트 메커니즘은 상태 머신을 초기화하고 오류를 반환하지만, 매우 큰 청크를 보내면 계속 처리하게 됩니다. 다음 코드 스니펫은 전송이 어떻게 이루어지는지 보여줍니다:

image info

이 시점에서 전송할 섹터 수가 0x200 섹터보다 크고 현재 청크가 첫 번째가 아닌 경우, 0x200 섹터가 한 번에 다운로드 버퍼로 복사된다는 것을 기억합니다. 이는 매우 흥미로운데, 다운로드 버퍼 너머로 약 0x200 섹터 (또는 0x40000 바이트)를 복사하여 메인 메모리의 데이터를 덮어쓸 수 있음을 의미하기 때문입니다. 예를 들어 현재 오프셋이 0x605 섹터이고 0xF9FB 섹터 크기의 청크를 제공하면 __next_offset이 래핑되어 0이 됩니다. 복사가 시작되는 소스 인덱스는 0이고 curr_bytes_to_copy는 0x40000 값을 얻습니다. 현재 오프셋이 0x605 섹터이므로 g_blocks_copied는 0x605 값을 얻습니다. 현재 오프셋이 유효하므로 (다음 오프셋도 유효함) 다운로드 버퍼로의 복사 작업이 트리거되어 다운로드 버퍼 끝을 약간 넘어 0x40000 바이트 미만의 대규모 덮어쓰기가 발생합니다. 이것은 이전 경우처럼 즉시 컨트롤러를 충돌시키지 않는 훨씬 더 강력한 컨트롤러 버퍼 오버플로우를 허용하는 강력한 프리미티브이며, 이전 버그보다 훨씬 높은 확률로 코드 실행으로 이어질 수 있습니다 (그러나 여전히 메인 메모리에서 다운로드 버퍼 뒤에 정확히 무엇이 배치되는지에 대한 더 많은 연구가 필요하여 익스플로잇 특성을 결정해야 합니다).

버그 재현 및 참고 사항

이 모든 버그는 Ubuntu 22.04 64비트 머신에서 표준 Linux SCSI 드라이버를 SG_IO 인터페이스를 통해 사용하여 검증되었습니다. 이 특정 드라이버로 버그 #3을 재현하려면 huge page를 활성화하고 큰 요청을 위해 단일 1GB 페이지를 할당해야 한다는 점을 지적해야 합니다. 그 이유는 이 드라이버가 전체 ATA 요청이 물리적으로 연속된 메모리 블록에 있어야 하는 것으로 보이기 때문입니다. 요청 크기가 약 ~30MB에 가깝기 때문에 2MB 페이지로는 충분하지 않으며, 따라서 1GB 페이지가 테스트 시스템에서 다음 (그리고 마지막) 사용 가능한 크기입니다. 그러나 이 단계가 트리거에 필수적인 것은 아니라는 점도 주목해야 합니다. 아직 다루지 않은 큰 ATA 요청을 보낼 수 있는 다른 해결 방법이 있을 수 있기 때문입니다. Huge-page 활성화는 이 버그를 확인하는 가장 빠른 방법이었을 뿐입니다. 이 외에도 이러한 모든 버그를 트리거하는 데 필요한 유일한 전제 조건은 ATA 패킷을 보낼 수 있는 적절한 권한입니다 (일반적으로 컨트롤러와 통신하는 PC에 대한 루트 액세스).

위에서 언급한 모든 버그를 재현하는 소스 코드는 이 저장소의 일부로 제공됩니다. 버그 #1 및 버그 #2의 경우 예상되는 동작은 드라이브가 다음 전원 사이클까지 중단되는 것입니다. 버그 #3의 경우 제공된 소스 코드가 반드시 컨트롤러를 충돌시키는 것은 아니지만 다운로드 버퍼 너머로 큰 덮어쓰기를 수행합니다.

컴파일 및 실행

앞서 언급했듯이 버그는 Ubuntu 22.04 64비트 머신에서 검증되었으므로 컴파일 프로세스는 유사한 머신에서 수행되어야 합니다. 다른 배포판이나 운영 체제에 대한 보장은 없습니다.

빌드하려면 프로젝트 루트 디렉터리에서 다음을 실행합니다.

root@kitploit:~
cmake -B build && make

빌드 프로세스는 3개의 바이너리를 빌드하며, 모두 build 디렉터리에 CVE_MX500_BUG_1, CVE_MX500_BUG_2 및 CVE_MX500_BUG_3이라는 이름으로 제공됩니다. 이는 각각 버그 #1, 버그 #2 및 버그 #3을 트리거하는 소스 파일에 해당합니다.

각 바이너리는 MX500 SSD의 디바이스 경로를 인수로 받으며, 루트 권한으로 실행되어야 합니다. 예를 들어:

root@kitploit:~
sudo ./build/CVE_MX500_BUG1 /dev/sda

FAQ

관리자/루트 권한이 필요하다면, 여기에 언급된 취약점에 대해 논의하는 이유는 무엇입니까? 드라이브에 대한 완전한 제어 권한이 이미 있지 않습니까?

잠재적 공격자의 최종 목표에 따라 다릅니다. 목표가 단순히 드라이브 저장소에 대한 전체 읽기/쓰기 액세스 권한을 얻는 것이라면, PC 내부에 접근하는 것만으로 충분합니다. 그러나 공격자가 한 걸음 더 나아가고자 한다면 어떻게 될까요? 드라이브의 펌웨어가 디지털 서명되어 있는 경우 버그 #3을 통해 공격자는 펌웨어의 서명 검증을 우회하여 드라이브 펌웨어에 악성 페이로드를 주입할 수 있습니다. 일단 주입되면 이러한 페이로드는 매우 잘 숨겨지며, 드라이브 포맷에서도 살아남고 컨트롤러 펌웨어 업데이트에서도 생존할 수 있습니다. 이러한 페이로드가 실제로 무엇을 할 수 있는지는 이 문서의 범위를 벗어나므로 논의하지 않겠습니다.

심각하게 들리는데, 걱정해야 할까요?

대답은 아마도 "아니오"일 가능성이 높습니다. 실제로 이러한 공격을 수행하는 데 필요한 R&D 양은 매우 높으며, 매우 심각한 위협 행위자에 의해서만 가능할 것입니다. 정부의 표적이 아니라면 이런 일이 당신에게 영향을 미칠 가능성은 극히 낮습니다.

벤더가 이에 대한 패치를 릴리스하기 전에 왜 이 CVE의 세부 정보를 공개했습니까?

벤더는 수개월 동안 이 문제에 대한 여러 이메일에 응답하지 않았습니다. CVE가 실제로 게시되려면 할당된 CNA에 공개 링크를 제공해야 합니다. 안타깝게도 정보를 비공개로 보내는 것은 이 절차에 해당하지 않습니다.

공개 타임라인을 공유해 주시겠습니까?

이 문서에서 언급된 버그는 원래 2024년 5월에 발견되었습니다. 그 이후로 Micron에 여러 번 연락했지만 (공식 보안 이메일을 통해) 응답이 없었습니다. 2024년 7월 MITRE에 통보되었고, 2024년 8월에 CVE가 할당되었습니다. 2024년 8월 말, 이 저장소가 공개되었습니다 (CVE가 MITRE에 의해 승인된 지 며칠 후).

이전 버전도 영향받나요?

M3CR046보다 오래된 M3CR04X 펌웨어는 더 이상 다운로드할 수 없으므로 영향받는지 여부는 불분명하지만, 추측하자면 그럴 것 같습니다. 더 오래된 버전, 예를 들어 M3CR033의 경우 정적 분석에 따르면 매우 유사한 버그가 존재하는 것으로 보입니다.

다른 벤더는 어떤가요?

해당 컨트롤러인 SM2259는 다른 벤더의 SSD에도 내장되어 있습니다. 벤더가 펌웨어 코드의 일부를 수정할 가능성은 있지만, 이러한 버그 (또는 매우 유사한 버그)가 다른 벤더의 SSD에도 존재할 가능성은 분명히 있습니다.

공개

이 CVE는 MITRE에 의해 게시되었습니다. 또한 NVD에서 CVSS 3.0 점수 6.7 (중간)로 분석되었습니다.

마지막 참고 사항

설명에 부정확하거나 실수가 있거나 이러한 버그를 재현하는 데 어려움이 있는 경우 log1kxd at gmail.com으로 연락해 주시기 바랍니다.

도구 다운로드