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

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

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

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

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

Категории

Все категории
Loading categories
Инструменты/GitHubGitHub/wqsv/throttlestoppoc
Повышение привилегийАнализ уязвимостейЭксплуатацияОбратная инженерияАппаратная БезопасностьСтатьи и ИсследованияRed TeamingЭксплуатация Бинарных Файлов
GitHubwqsv/throttlestoppoc

ThrottleStopPoC

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

Репозиторий
1871 год назадЕщё не проверено

Популярное

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

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

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

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

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

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) (+ padding). Выходной буфер и его размер не используются.

Упрощённый код для этого 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 процесса System с помощью PsInitialSystemProcess, и проверяет, равно ли оно 4 (реализовано в Main.c, а функции для поиска EPROCESS конкретного PID реализованы в EProcess.c). Дополнительно он спрашивает пользователя, хочет ли тот принудительно перезагрузить систему. Это возможно путём записи значения 0x0E в порт 0xCF9.

Предупреждение: Всё тестировалось на Windows 11 build 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.

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