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

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

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

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

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

Категории

Все категории
Loading categories
CallbackHell — Эксплойт для CVE-2021-40449 — уязвимость повышения привилегий Win32k (LPE) | Kitploit
Инструменты/GitHubGitHub/ly4k/callbackhell
Повышение привилегийАнализ уязвимостейЭксплуатацияШелл-кодПост-эксплуатацияРазработка Полезной НагрузкиЭксплуатация Бинарных Файлов
GitHubly4k/callbackhell

CallbackHell

Эксплойт для CVE-2021-40449 — уязвимость повышения привилегий Win32k (LPE)

Репозиторий
481954 лет назадПроверено Kitploit

Популярное

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

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

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

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

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

CallbackHell

Exploit for CVE-2021-40449 (Win32k - LPE)

  • CallbackHell
    • Описание
    • Техническое описание
    • PoC
    • Ссылки

Описание

CVE-2021-40449 — это use-after-free в Win32k, который позволяет повышать привилегии локально.

Уязвимость была обнаружена в реальных атаках компанией Kaspersky.

Обнаруженный эксплойт был написан для поддержки следующих продуктов Windows:

  • Microsoft Windows Vista
  • Microsoft Windows 7
  • Microsoft Windows 8
  • Microsoft Windows 8.1
  • Microsoft Windows Server 2008
  • Microsoft Windows Server 2008 R2
  • Microsoft Windows Server 2012
  • Microsoft Windows Server 2012 R2
  • Microsoft Windows 10 (build 14393)
  • Microsoft Windows Server 2016 (build 14393)
  • Microsoft Windows 10 (build 17763)
  • Microsoft Windows Server 2019 (build 17763)

Однако в настоящее время эксплойт протестирован только на следующих версиях:

  • Microsoft Windows 10 (build 14393)
  • Microsoft Windows 10 (build 17763)

Техническое описание

Я настоятельно рекомендую прочитать технический разбор от Kaspersky перед продолжением.

Как упоминалось в техническом разборе Kaspersky, уязвимость существует в GreResetDCInternal. Если атакующий перехватывает пользовательский колбэк DrvEnablePDEV, который вызывается во время hdcOpenDCW, можно уничтожить исходный контекст устройства, вызвав ResetDC, что приводит к use-after-free в ядре, когда пользовательский колбэк возвращается.

Следующий псевдокод частично составлен из утёкшего исходного кода Windows XP и частично путём реверс-инжиниринга последней (до патча) версии GreResetDCInternal из Win32kfull.sys. Не относящиеся к делу части удалены с помощью [...]. Ищите комментарии VULN: .

root@kitploit:~
BOOL GreResetDCInternal(
    HDC hdc,
    DEVMODEW *pdmw,
    BOOL *pbBanding,
    DRIVER_INFO_2W *pDriverInfo2,
    PVOID ppUMdhpdev)
{
    // [...]
    HDC hdcNew;

    {
        // Create DCOBJ from HDC
        DCOBJ dco(hdc);

        if (!dco.bValid())
        {
            SAVE_ERROR_CODE(ERROR_INVALID_HANDLE);
        }
        else
        {
            // Create DEVOBJ from `dco`
            PDEVOBJ po(dco.hdev());

            // [...]

            // Create the new DC
            // VULN: Can result in a usermode callback that destroys old DC, which
            // invalidates `dco` and `po`
            hdcNew = hdcOpenDCW(L"",
                                pdmw,
                                DCTYPE_DIRECT,
                                po.hSpooler,
                                prton,
                                pDriverInfo2,
                                ppUMdhpdev);

            if (hdcNew)
            {
                po->hSpooler = NULL;

                DCOBJ dcoNew(hdcNew);

                if (!dcoNew.bValid())
                {
                    SAVE_ERROR_CODE(ERROR_INVALID_HANDLE);
                }
                else
                {
                    // Transfer any remote fonts

                    dcoNew->pPFFList = dco->pPFFList;
                    dco->pPFFList = NULL;

                    // Transfer any color transform

                    dcoNew->pCXFList = dco->pCXFList;
                    dco->pCXFList = NULL;

                    PDEVOBJ poNew((HDEV)dcoNew.pdc->ppdev());

                    // Let the driver know
                    // VULN: Method is taken from old (possibly destroyed) `po`
                    PFN_DrvResetPDEV rfn = po->ppfn[INDEX_DrvResetPDEV];

                    if (rfn != NULL)
                    {
                        (*rfn)(po->dhpdev, poNew->dhpdev);
                    }

                    // [...]
                }
            }
        }
    }

    // Destroy old DC
    // [...]
}

Как видно из псевдокода, старый контекст устройства может быть освобождён в пользовательском колбэке из вызова hdcOpenDCW, и позже метод DrvResetPDEV извлекается из старого контекста устройства и вызывается с (po->dhpdev, poNew->dhpdev).

Чтобы создать и перехватить контекст устройства, можно сделать следующее:

  • Найти доступный принтер с помощью EnumPrinters
  • Загрузить драйвер принтера в память с помощью OpenPrinter, GetPrinterDriver и LoadLibraryExA
  • Получить таблицу пользовательских колбэков драйвера принтера с помощью GetProcAddress и DrvEnableDriver
  • Снять защиту с таблицы пользовательских колбэков драйвера принтера с помощью VirtualProtect
  • Перезаписать нужные записи в таблице пользовательских колбэков драйвера принтера
  • Создать контекст устройства для принтера с помощью CreateDC(NULL, printerName, NULL, NULL)

Теперь у нас должен быть контекст устройства для принтера с перехваченными пользовательскими колбэками.

Нас интересует только один перехват, а именно DrvEnablePDEV. Этот перехват интересен в двух аспектах: запуск UAF и контроль над аргументами, как описано ранее. Чтобы запустить уязвимость UAF, мы вызовем ResetDC внутри колбэка, что уничтожит старый контекст устройства. Когда мы вернёмся из колбэка, мы всё ещё будем внутри первого GreResetDCInternal, который вскоре после этого получит и вызовет указатель на функцию DrvResetPDEV из нашего старого и уничтоженного контекста устройства с двумя аргументами, возвращёнными из DrvEnablePDEV; старым и новым DHPDEV.

Если ваш процесс работает со средним уровнем целостности, KASLR не должен быть проблемой с помощью EnumDeviceDrivers и NtQuerySystemInformation.

Kaspersky упоминает, что оригинальный эксплойт использовал объекты палитры GDI и один вызов функции ядра для достижения произвольного чтения/записи памяти. Этот эксплойт использует технику выделения BitMapHeader в больших пулах и RtlSetAllBits для включения всех привилегий в токене нашего текущего процесса. BitMapHeader будет указывать на _SEP_TOKEN_PRIVILEGES токена нашего текущего процесса. Вызвав RtlSetAllBits(BitMapHeader), можно включить все привилегии для токена нашего текущего процесса одним вызовом функции ядра. После этого можно злоупотребить новыми привилегиями для получения SYSTEM. Этот эксплойт использует SeDebugPrivilege для внедрения шеллкода в процесс winlogon.exe.

PoC

./poc.png

Ссылки

  • https://securelist.com/mysterysnail-attacks-with-windows-zero-day/104509/
  • https://github.com/siberas/CVE-2016-3309_Reloaded/
  • https://www.ired.team/miscellaneous-reversing-forensics/windows-kernel-internals/how-kernel-exploits-abuse-tokens-for-privilege-escalation
  • https://github.com/KaLendsi/CVE-2021-40449-Exploit
  • https://mp.weixin.qq.com/s/AcFS0Yn9SDuYxFnzbBqhkQ
Скачать инструмент