
ThrottleStop.sys — произвольное чтение/запись физической памяти
Полноценный proof-of-concept для драйвера ThrottleStop.sys от TechPowerUp (CVE-2025-7771).
Подписанный, всё ещё загружаемый драйвер ядра предоставляет непроверяемое чтение и запись
физической памяти через два IOCTL. Этот репозиторий превращает этот примитив в работающее
локальное повышение привилегий с администратора до SYSTEM и документирует особенность
именования устройства, которая ломает большинство детектов, основанных на путях и именах
файлов.
PoC для тех же IOCTL уже существовал (см. раздел Credits). Это независимая полная цепочка эксплойта, а не демонстрация примитива.
| Поле | Значение |
|---|---|
| SHA256 | 16F83F056177C4EC24C7E99D01CA9D9D6713BD0497EEEDB777A3FFEFA99C97F0 |
| SHA1 | 82ED942A52CDCF120A8919730E00BA37619661A3 |
| MD5 | 6BC8E3505D9F51368DDF323ACB6ABC49 |
| Версия | 3.0.0.0 ("Low-Level Driver", 2004-2020) |
| Подписант | TechPowerUp LLC, DigiCert EV Code Signing |
| Отпечаток сертификата | 524EDA9C819321C66E22C7BABEB23DAEAFFB2182 |
| Срок действия сертификата | 2019-08-10 — 2022-06-15 |
Срок действия сертификата истёк в 2022 году, но подпись содержит доверенную метку времени встречной подписи, поэтому Windows всё ещё загружает его. Отзыв помогает только в том случае, если его дата предшествует времени подписания, что редко бывает для таких старых драйверов, как этот.
В ресурсе версии нет CompanyName, OriginalFilename или InternalName, поэтому файл
невозможно атрибутировать какому-либо вендору по его собственным метаданным.
Два IOCTL читают и записывают физическую память без проверки границ и валидации адресов:
| IOCTL | Операция |
|---|---|
0x80006498 | Чтение физической памяти |
0x8000649C | Запись физической памяти |
Оба используют METHOD_BUFFERED, поэтому разыменования пользовательского указателя не
происходит; дефект заключается в отсутствии валидации переданного вызывающим физического
адреса, а не в непроверяемом указателе.
Стоит отметить: обработчик записи 0x8000649C объявлен с FILE_READ_ACCESS. Дескриптор,
открытый только для чтения, всё равно может выполнять физическую запись, то есть заявленная
маска доступа не соответствует тому, что обработчик делает на самом деле.
Открытие устройства требует прав администратора, поэтому само по себе это не пересечение границы привилегий. Атакующему, уже являющемуся администратором, это даёт произвольное чтение/запись памяти ядра из пользовательского режима, что обходит защиты, которые должны действовать выше уровня администратора: целостность кода HVCI, PPL и самозащиту EDR/AV. Классический bring-your-own-vulnerable-driver.
В качестве конкретной демонстрации PoC использует примитив R/W для кражи токена SYSTEM и запускает оболочку SYSTEM.
CVSS 4.0: AV:L/AC:H/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H (8.7, Высокий).
Всё выполняется из пользовательского режима через физические R/W IOCTL драйвера. Никакого обхода таблиц страниц и участия CR3 нет; оба процесса находятся прямым сканированием физической памяти:
ImageFileName равен System, а UniqueProcessId — 4. Сканирование ограничено
диапазонами реально установленной ОЗУ, полученными из ключа реестра прошивки
HARDWARE\RESOURCEMAP\...\Physical Memory, а не угаданным окном, поэтому дыры MMIO
никогда не затрагиваются и ничего за пределами установленной ОЗУ не пропускается.Token (EPROC_TOKEN) из найденного
EPROCESS.Token.
Токен — это _EX_FAST_REF, поэтому младшие биты счётчика ссылок по умолчанию
маскируются (--mask выбирает поведение).cmd.exe; whoami возвращает NT AUTHORITY\SYSTEM.Смещения (EPROC_TOKEN, EPROC_PID, EPROC_IMG_NAME и т.д.) рассчитаны на конкретную
сборку и должны быть сверены с dt nt!_EPROCESS в целевой версии Windows.
Имя исполняемого файла имеет значение. На шаге 3 наш собственный процесс находится по
совпадению его ImageFileName в физической памяти, а это поле ограничено 15 символами,
при этом сканирование сопоставляет первые 8. Держите имя скомпилированного файла коротким
и отличительным; если переименуете бинарник, оставайтесь в этом лимите, иначе
самосканирование не найдёт процесс.
Драйвер не использует фиксированное имя устройства. Он выводит имя объекта устройства из
имени службы, под которой зарегистрирован; имя файла на диске не имеет значения.
Регистрация бинарника под службой TRIXX даёт \\.\TRIXX, независимо от того, как файл
называется на диске.
Таким образом, любой детект, завязанный на \Device\ThrottleStop или ThrottleStop.sys,
тривиально обходится. Детектирование должно основываться на хеше файла или сертификате
подписи:
SHA256: 16F83F056177C4EC24C7E99D01CA9D9D6713BD0497EEEDB777A3FFEFA99C97F0
Thumbprint: 524EDA9C819321C66E22C7BABEB23DAEAFFB2182
Subject: CN=TechPowerUp LLC, O=TechPowerUp LLC, L=Spokane, S=Washington, C=US
Список DEVICE_NAMES в исходном коде — это лишь зонд для обнаружения известных установок
продукта. Передайте имя устройства аргументом командной строки, чтобы нацелиться на службу,
которую вы зарегистрировали самостоятельно.
| CVE | Драйвер |
|---|---|
| CVE-2019-7245 | GPU-Z.sys |
| CVE-2025-5324 | GPU-Z.sys |
| CVE-2025-7771 | ThrottleStop.sys (этот репозиторий) |
Бинарник здесь не распространяется. Сверяйте любую копию с SHA256 выше. Образец внесён в каталог LOLDrivers.
cl /nologo /EHsc /W4 /O2 src\ThrottleStop.cpp /Fe:myLittleLpe.exe /link advapi32.lib
Только для лабораторного использования. Запускайте в изолированной ВМ со снапшотом, чтобы можно было откатиться.
sc.exe create <name> type= kernel binPath= C:\path\to\ThrottleStop.sys
sc.exe start <name>
myLittleLpe.exe
sc.exe stop <name>
sc.exe delete <name>
Бинарник не принимает аргументов. Он выводит карту физической памяти, ищет SYSTEM и
локальный EPROCESS, подменяет токен и запускает cmd.exe с правами
NT AUTHORITY\SYSTEM.

Другие публичные работы по этому же драйверу для сравнения:
Опубликовано в целях защитных исследований и разработки средств детектирования. Уязвимость уже публично раскрыта как CVE-2025-7771. Всё здесь протестировано на системах, принадлежащих автору. Не запускайте это против систем, которыми вы не владеете или на тестирование которых у вас нет разрешения.