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

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

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

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

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

Категории

Все категории
Loading categories
ThrottleStopPoC — CVE-2025-7771: Произвольное чтение/запись физической памяти и портов ввода-вывода через драйвер ThrottleStop | Kitploit
Инструменты/GitHubGitHub/fxrstor/throttlestoppoc
Повышение привилегийКриминалистика памятиАнализ уязвимостейЭксплуатацияАппаратный ХакингАппаратная БезопасностьЭксплуатация Бинарных Файлов
GitHubfxrstor/throttlestoppoc

ThrottleStopPoC

CVE-2025-7771: Произвольное чтение/запись физической памяти и портов ввода-вывода через драйвер ThrottleStop

Репозиторий
18711 месяцев назадЕщё не проверено

Популярное

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

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

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

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

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

ThrottleStopPoC

CVE-2025-7771: Произвольное чтение/запись физической памяти и портов ввода-вывода через драйвер ThrottleStop

ThrottleStop — это небольшое легитимное приложение, используемое для мониторинга и коррекции троттлинга ЦП. Оно имеет драйвер, который облегчает эти задачи, и в основном лишено какой-либо проверки входных данных.

Уязвимые IOCTL

IOCTLУязвимость
0x80006498Произвольное чтение памяти
0x8000649CПроизвольная запись памяти
0x80006430Произвольное чтение порта
0x80006434Произвольная запись порта

Также, похоже, есть произвольное чтение и запись MSR, но мне не удалось заставить их работать. Не стесняйтесь посмотреть самостоятельно. Чтение MSR по 0x80006448, запись по 0x8000644C.

Если вам удалось заставить это работать, пожалуйста, отправьте issue с описанием процедуры.


Все вызовы IOCTL, упомянутые ниже, реализованы в файле Exploit.c.


Произвольное чтение памяти

IOCTL 0x80006498 отображает любой предоставленный физический адрес в пространство ядра с помощью MmMapIoSpace и читает из него 1, 2, 4 или 8 байт. Затем данные копируются обратно в пользовательское пространство.

Для вызова этого IOCTL используется DeviceIoControl с физическим адресом на входе и размером выходного буфера, равным размеру чтения (1, 2, 4 или 8).

Упрощённый код этого IOCTL в драйвере:

root@kitploit:~
case 0x80006498: {
    size_t readSize = inputBuffer->Size;   // must be 1,2,4,8
    PHYSICAL_ADDRESS physAddr = inputBuffer->PhysAddr;
    void* mappedAddr = MmMapIoSpace(physAddr, readSize, MmNonCached);

    if (mappedAddr) {
        if (readSize == 1)
            *outputBuffer = *(uint8_t*)mappedAddr;
        else if (readSize == 2)
            *(uint16_t*)outputBuffer = *(uint16_t*)mappedAddr;
        else if (readSize == 4)
            *(uint32_t*)outputBuffer = *(uint32_t*)mappedAddr;
        else if (readSize == 8)
            *(uint64_t*)outputBuffer = *(uint64_t*)mappedAddr;

        MmUnmapIoSpace(mappedAddr, readSize);
    }
}

Произвольная запись памяти

Аналогично чтению, IOCTL 0x8000649C отображает предоставленный физический адрес в пространство ядра с помощью MmMapIoSpace и записывает в него 1, 2, 4 или 8 байт.

Для вызова этого IOCTL используется DeviceIoControl со следующей структурой входного буфера:

root@kitploit:~
struct {
    ULONGLONG PhysicalAddress;  // 8 bytes
    union {
        BYTE  Value8;
        WORD  Value16;
        DWORD Value32;
        QWORD Value64;
    };
};

Размер входного буфера будет равен 8 + (1, 2, 4 или 8) в зависимости от размера записи.

Выходной буфер и его размер не используются.

Упрощённый код этого IOCTL в драйвере:

root@kitploit:~
case 0x8000649C: {
    size_t writeSize = inputBuffer->Size;  // must be 1,2,4,8
    PHYSICAL_ADDRESS physAddr = inputBuffer->PhysAddr;
    void* mappedAddr = MmMapIoSpace(physAddr, writeSize, MmNonCached);

    if (mappedAddr) {
        if (writeSize == 1)
            *(uint8_t*)mappedAddr = inputBuffer->Value8;
        else if (writeSize == 2)
            *(uint16_t*)mappedAddr = inputBuffer->Value16;
        else if (writeSize == 4)
            *(uint32_t*)mappedAddr = inputBuffer->Value32;
        else if (writeSize == 8)
            *(uint64_t*)mappedAddr = inputBuffer->Value64;

        MmUnmapIoSpace(mappedAddr, writeSize);
    }
}

Произвольное чтение порта

IOCTL 0x80006430 позволяет пользователю указать порт ввода-вывода и читать из него напрямую с помощью __inbyte, __inword или __indword.

Входной буфер — это USHORT, размер входного буфера должен быть sizeof(USHORT).

Выходной буфер будет содержать результат (1, 2 или 4 байта в зависимости от запрошенного размера), а размер вывода может быть 1, 2 или 4.

Упрощённый код этого IOCTL в драйвере:

root@kitploit:~
case 0x80006430: {
    uint16_t port = inputBuffer->PortNumber;
    uint8_t size  = inputBuffer->AccessSize; // 1, 2, or 4

    if (size == 1)
        *outputBuffer = __inbyte(port);
    else if (size == 2)
        *(uint16_t*)outputBuffer = __inword(port);
    else if (size == 4)
        *(uint32_t*)outputBuffer = __indword(port);
}

Произвольная запись порта

Аналогично чтению порта, IOCTL 0x80006434 позволяет пользователю указать порт ввода-вывода и записать в него произвольные значения с помощью __outbyte, __outword или __outdword. Структура входного буфера:

root@kitploit:~
struct {
    USHORT PortNumber;
    BYTE   Padding[2];   // alignment
    union {
        BYTE  Value8;
        WORD  Value16;
        DWORD Value32;
    };
};

Размер входного буфера должен быть равен sizeof(USHORT) + sizeof(Value) (+ выравнивание). Выходной буфер и его размер не используются.

Упрощённый код этого IOCTL в драйвере:

root@kitploit:~
case 0x80006434: {
    uint16_t port = inputBuffer->PortNumber;
    uint8_t size  = inputBuffer->AccessSize; // 1, 2, or 4

    if (size == 1)
        __outbyte(port, inputBuffer->Value8);
    else if (size == 2)
        __outword(port, inputBuffer->Value16);
    else if (size == 4)
        __outdword(port, inputBuffer->Value32);
}

Преобразование виртуальных адресов в физические

Это преобразование возможно путём злоупотребления Superfetch — легитимным модулем ядра, который предоставляет преобразование виртуальных адресов в физические с помощью недокументированных API. Код для этого реализован в vtop.c

Сборка

Этот проект можно скомпилировать с помощью Meson. Он считывает поле UniqueProcessId, разрешая структуру EPROCESS системного процесса через PsInitialSystemProcess, и проверяет, равно ли оно 4 (реализовано в Main.c, а функции поиска EPROCESS для конкретного PID реализованы в EProcess.c). Кроме того, он спрашивает пользователя, хочет ли он принудительно перезагрузить систему. Это возможно путём записи значения 0x0E в порт 0xCF9.

Предупреждение: Всё было протестировано на Windows 11 сборка 24H2. Смещения в структуре EPROCESS могут отличаться на вашей системе.

Соберите проект с помощью

root@kitploit:~
meson setup build

Это создаст каталог build. Затем скомпилируйте проект с помощью

root@kitploit:~
meson compile -C build

Драйвер доступен в каталоге Drivers репозитория. Драйверы ThrottleStop можно напрямую извлечь из программы ThrottleStop.exe с помощью Resource Hacker. Вы найдёте 2 драйвера — x64 и x86. DriverObject->MajorFunction[14] содержит функцию диспетчеризации, в которой реализованы все IOCTL.

Создайте и запустите драйвер с помощью:

root@kitploit:~
sc create ThrottleStop binPath="<Path>" type=kernel
sc start ThrottleStop

Ссылки

https://github.com/jonomango/superfetch

Этот драйвер ещё не добавлен в список блокировки драйверов Microsoft ни в loldrivers.

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