Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

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

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

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-50416-writeup-and-poc — CVE-2026-50416: Windows 11 KASLR 우회 | Kitploit
도구/GitHubGitHub/karollooool/cve-2026-50416-writeup-and-poc
Exploit FrameworksMemory ForensicsVulnerability AnalysisExploitationInformation GatheringCTFBinary AnalysisPapers & ResearchLearning & Education
Labs & Practice
GitHubkarollooool/cve-2026-50416-writeup-and-poc

CVE-2026-50416-writeup-and-poc

CVE-2026-50416: Windows 11 KASLR 우회

저장소 보기웹사이트
445249일 전Kitploit 검토 완료

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-50416: 데스크톱 힙에 존재하는 커널 주소

영향을 받는 시스템에서 Win32 데스크톱 힙의 사용자 매핑에서 이 읽기 작업은 커널 주소를 반환했습니다:

ULONG64 leaked = *(ULONG64 *)(desktop_heap + 0x100);

이것이 전체 공개 내용이다. 처음에는 그럴듯한 상위 비트를 가진 8바이트 값에 불과했다. 나는 그 값을 읽는 것보다 그 값이 무엇을 뒤따르는지 확인하는 데 더 많은 시간을 썼다.

Microsoft는 이 문제를 CVE-2026-50416으로 공개했으며, CWE-200으로 분류된 Win32k 정보 노출 취약점이다.

매핑에 도달하기까지

PoC는 x64 TEB에서 시작한다. GS:[0x30]은 현재 TEB를 가리키고, 내가 테스트한 빌드에서는 TEB + 0x800이 Win32 클라이언트 데이터에 도달하며, 슬롯 5에는 데스크톱 힙의 사용자 주소가 들어 있다:

PVOID teb = (PVOID)__readgsqword(0x30);
PVOID *client_info = (PVOID *)((BYTE *)teb + 0x800);
BYTE *desktop_heap = (BYTE *)client_info[5];

Slot 5는 해당 클라이언트 데이터에서 또 다른 0x28 바이트 지점입니다. Trellix는 Windows 10 1909에서 tagWND 매핑을 연구하면서 동일한 TEB + 0x800 + 0x28 경로를 문서화했습니다. 이 오프셋들은 ABI가 아닙니다. 저는 이 값들을 하드코딩했으며, 매핑된 영역을 사용하기 전에 그 결과에 대해 VirtualQuery를 호출합니다.

포인터 검사는 정규 x64 부호 확장, 8바이트 정렬, 그리고 알려진 센티널 패턴을 다룹니다. 그런 다음 해당 값은 아래의 동작 테스트를 통과해야 합니다.

그 주변에서 제가 변경한 것

메인 PoC는 오프셋 0x100을 읽고, STATIC 하나, BUTTON 하나, EDIT 창 하나를 생성한 뒤, 다시 읽고, 세 창을 파괴한 다음, 한 번 더 읽습니다.

ULONG64 before = *(ULONG64 *)(desktop_heap + 0x100);

/* Create STATIC, BUTTON and EDIT windows. */
ULONG64 after_create = *(ULONG64 *)(desktop_heap + 0x100);

/* Destroy all three. */
ULONG64 after_destroy = *(ULONG64 *)(desktop_heap + 0x100);

세 개의 QWORD가 일치했습니다. 해당 윈도우 할당은 생성되었다가 사라졌지만, 0x100에 위치한 값은 그대로였습니다.

kaslr_sandbox_proof.c는 프로세스 비교를 처리합니다. 부모 프로세스는 파이프를 통해 각 자식 프로세스의 stdout을 리다이렉트하고, 자식이 읽은 QWORD를 파싱하여 기준값과 비교합니다.

기본 데스크톱에 연결된 자식 프로세스들은 동일한 값을 반환했습니다. CreateDesktop으로 생성된 데스크톱에 할당된 자식 프로세스는 다른 값을 반환했습니다. 이 하네스는 또한 Low 무결성, AppContainer, 해당 LPAC 구성, 그리고 Low 무결성 AppContainer 자식 프로세스들도 실행합니다. 이들은 모두 부모의 값을 받는 대신 자신의 TEB와 매핑에서 읽기를 수행합니다.

supporting_proof_no_window.c는 CreateWindowEx를 호출하지 않고 읽기를 수행합니다. 새로운 USER 윈도우는 필요하지 않습니다.

주소 연산

메인 PoC는 유출된 값에서 0x40을 뺀 값을 데스크톱 힙에 대응하는 커널 측 베이스로 취급합니다:

ULONG64 candidate_kernel_heap_base = leaked - 0x40;

그런 다음 user32!gSharedInfo를 조회하고, HWND의 하위 16비트를 USER 핸들 테이블 인덱스로 사용하며, HeEntrySize만큼 aheList를 따라 이동합니다. 해당 엔트리의 첫 번째 QWORD가 0이 아니고 매핑된 힙보다 작으면, PoC는 이를 상대적 데스크톱 힙 오프셋으로 사용합니다:

ULONG index = (ULONG)(ULONG_PTR)hwnd & 0xffff;
BYTE *entry = (BYTE *)shared->aheList + index * shared->HeEntrySize;
ULONG64 heap_offset = *(ULONG64 *)entry;

if (heap_offset > 0 && heap_offset < heap_size) {
    BYTE *user_candidate = desktop_heap + heap_offset;
    ULONG64 kernel_candidate = candidate_kernel_heap_base + heap_offset;
}

이는 구형 데스크톱 힙 기법에서 사용되던 것과 동일한 일반적 관계입니다. 사용자 뷰와 커널 뷰가 각자의 힙 베이스로부터 동일한 오프셋에 객체를 배치합니다. Unit 42는 USER 핸들 테이블과 구형 gSharedInfo 및 HMValidateHandle 주소 유출에 관한 유용한 배경 정보를 제공합니다.

그 결과로 얻어진 주소들이 PoC의 커널 객체 후보입니다. 0x40 관계, 핸들 엔트리 레이아웃, TEB 오프셋은 테스트에 사용된 빌드에 속합니다.

객체 후보는 여기까지만 다루겠습니다. desktop_heap + 0x100에 위치한 QWORD는 이미 사용자가 읽을 수 있는 매핑 내의 안정적인 커널 공간 주소 정보입니다. 별도의 Win32k 메모리 손상 버그는 주소 추측 대신 이 값을 사용할 수 있습니다.

도구 다운로드