Skip to content
KitploitKITPLOIT
ИнструментыЭксплойтыБлог
Log in
Отправить
ИнструментыЭксплойтыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

ЛентыКонтактыКонфиденциальность© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2026-50416-writeup-and-poc — CVE-2026-50416: обход KASLR в Windows 11 | Kitploit
Инструменты/GitHubGitHub/karollooool/cve-2026-50416-writeup-and-poc
Фреймворки для эксплойтовКриминалистика памятиАнализ уязвимостейЭксплуатацияСбор информацииCTFАнализ Бинарных ФайловСтатьи и ИсследованияОбучение и Образование
Лаборатории и Практика
GitHubkarollooool/cve-2026-50416-writeup-and-poc

CVE-2026-50416-writeup-and-poc

CVE-2026-50416: обход KASLR в Windows 11

РепозиторийСайт
445249 дней назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2026-50416: адрес ядра в куче рабочего стола

В затронутой системе это чтение из пользовательского отображения кучи рабочего стола Win32 вернуло адрес ядра:

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

Вот и всё раскрытие. Поначалу это было всего лишь восьмибайтовое значение с убедительными старшими битами. Я потратил больше времени на проверку того, за чем следовало это значение, чем на его чтение.

Microsoft опубликовала эту проблему как CVE-2026-50416 — раскрытие информации в Win32k, классифицированное как CWE-200.

Путь к отображению

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];

Слот 5 — это ещё 0x28 байт внутри этих клиентских данных. Trellix задокументировал тот же маршрут TEB + 0x800 + 0x28, изучая отображения tagWND в Windows 10 1909. Эти смещения не являются ABI. Я жёстко закодировал их и вызываю VirtualQuery для результата перед использованием отображённой области.

Проверка указателя охватывает каноническое знаковое расширение x64, восьмибайтовое выравнивание и известные шаблоны-маркеры. Затем значение должно пройти поведенческие тесты, описанные ниже.

Что я изменил вокруг этого

Основной 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 и AppContainer с уровнем целостности Low. Все они выполняют чтение из собственного TEB и собственного отображения, а не получают значение от родительского процесса.

supporting_proof_no_window.c выполняет чтение без вызова CreateWindowEx. Новое окно USER не требуется.

Арифметика адресов

Основной PoC рассматривает утёкшее значение минус 0x40 как базу на стороне ядра, соответствующую куче рабочего стола:

ULONG64 candidate_kernel_heap_base = leaked - 0x40;

Затем он ищет user32!gSharedInfo, использует младшие 16 бит HWND как индекс в таблице USER-хэндлов и продвигается по aheList на HeEntrySize. Если первый QWORD в этой записи ненулевой и меньше отображённой кучи, 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 относятся к сборке, использованной для теста.

Я оставляю кандидатов в объекты на этом. QWORD по адресу desktop_heap + 0x100 уже представляет собой стабильную информацию об адресе в пространстве ядра в доступном для пользователя отображении. Отдельная уязвимость повреждения памяти в Win32k может использовать её вместо угадывания адреса.

Скачать инструмент