
CVE-2024-51324(BYOVD)に関する修士論文研究。4つの動作モード(SCANNER, LOADER, KILLER, CLEANUP)を備えた高度なエクスプロイト、SHA-256ドライバ検証、完全な学術文書を含む。ポートフォリオ作品は、Windowsカーネルドライバセキュリティ、IOCTLリバースエンジニアリング、Bring Your Own Vulnerable Driverエクスプロイトをカバーする。
Bring Your Own Vulnerable Driver (BYOVD) — Baidu アンチウイルス
BdApiUtil64.sys
3つの未ドキュメントのカーネルプリミティブ: プロセス終了、任意ファイル削除、SectionObjectPointer バイパスによる使用中ファイル削除
影響: Baidu アンチウイルス v5.2.3.116083 (BdApiUtil64.sys)
脆弱ドライバをカーネルにロード中(LOADER モード)
このリポジトリには、Baidu アンチウイルスのカーネルドライバ BdApiUtil64.sys における Bring Your Own Vulnerable Driver (BYOVD) の脆弱性である CVE-2024-51324 に関する私の 修士論文研究 が含まれています。
NVD レコードは CVSS v3.1 ベーススコア 3.8 (低)、ベクタ AV:N/AC:L/PR:H/UI:N/S:U/C:L/I:L/A:N、CWE-269 (不適切な特権管理) を割り当てています。このスコアは本研究で文書化されたローカル攻撃の現実を反映していません。管理者がドライバをロードした後(ソーシャルエンジニアリングや任意のローカル特権昇格によって達成可能な1回限りのステップ)、サンドボックス化されたプロセスや標準ユーザープロセスを含む後続のプロセスは、追加の権限チェックなしで IOCTL を送信できます。研究者が評価した CVSS v3.1 スコア 7.8 (高)、ベクタ AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H は、ロード後の悪用の現実をより正確に捉えています。両方のスコアは技術文書で議論されています。
このドライバはデバイスオブジェクト \Device\BdApiUtil を SecurityDescriptor = NULL で作成するため、任意のプロセス(整合性レベルに関係なく)がハンドルを開いて IOCTL を送信できます。Ghidra 11.0.3 による静的解析の結果、内部メカニズムは以前文書化されたよりも重要であることが明らかになりました。ドライバは ZwOpenProcess ではなく PsLookupProcessByProcessId + ObOpenObjectByPointer(KernelMode) を使用しており、SeAccessCheck を完全にバイパスします。3つの IOCTL プリミティブが完全に特性評価され、そのうち2つは公開文書がありません。
| 側面 | 説明 |
|---|---|
| 技術的訂正 | ZwOpenProcess はインポートテーブルに存在せず、実際のメカニズムは PsLookupProcessByProcessId + ObOpenObjectByPointer(KernelMode) であり、無条件に SeAccessCheck をバイパスします |
| 3つの文書化されたプリミティブ | プロセス終了 (0x800024B4)、任意ファイル削除 (0x80002648)、SectionObjectPointer バイパスによる使用中ファイル削除 (0x8000264C) — 最後の2つは公開文書なし |
| 4つの動作モード | LOADER、KILLER、SCANNER、CLEANUP — 完全なライフサイクル管理 |
| SHA-256 検証 | ロード試行前にドライバハッシュを検証 |
| PPL 実証テスト | プロセスカテゴリごとに10回試行し、PPL が唯一のランタイム緩和策であることを確認 |
| フォレンジック分析 | クリーンアップ後の永続的な Event ID 7045、自己告訴的なログクリア成果物としての Event ID 1102 |
| 検出ルール | Sigma ルールと Sysmon 設定(ハッシュによる Event ID 6 + レジストリキーによる Event ID 13) |
| CVSS 再評価 | 公式 NVD スコア (3.8 低) と研究者評価によるローカル悪用の深刻度 (7.8 高) との差異を文書化 |
CVE-2024-51324/
├── README.md
├── LICENSE
│
├── drivers/
│ └── BdApiUtil64.sys # ドライバ(配布なし)
│
├── exploit/
│ ├── exploit-explanation.md
│ └── byovd_killer.py # メインエクスプロイト — 4つの動作モード
│
└── docs/
├── screenshots/
│ ├── 01-byovd-scan.png
│ ├── 02-byovd-scan-target.png
│ ├── 03-byovd-load.png
│ ├── 04-byovd-load-custom.png
│ ├── 05-kill-name.gif
│ ├── 06-kill-pid.gif
│ ├── 07-kill-limit.gif
│ ├── 08-dry-run.gif
│ └── 09-byovd-cleanup.png
│
└── analysis/
├── 01-root-cause.md
├── 02-driver-analysis.md # Ghidra RE 完全版、3つのプリミティブ、PPL テスト
└── 03-timeline.md
BdApiUtil64.sys (SHA-256: 47EC51B5F0EDE1E70BD66F3F0152F9EB536D534565DBB7FCC3A05F542DBE4428)python exploit/byovd_killer.py --scan
python exploit/byovd_killer.py --scan --target lsass.exe
python exploit/byovd_killer.py --load
python exploit/byovd_killer.py --load --driver C:\path\to\BdApiUtil64.sys
python exploit/byovd_killer.py --load --service-name MyService
python exploit/byovd_killer.py --kill notepad.exe
python exploit/byovd_killer.py --pid 1234
python exploit/byovd_killer.py --kill notepad.exe --max-instances 2
python exploit/byovd_killer.py --kill notepad.exe --dry-run
python exploit/byovd_killer.py --cleanup
python exploit/byovd_killer.py --cleanup --service-name MyService
| モード | コマンド | 権限 | 説明 |
|---|---|---|---|
| SCANNER | --scan | 任意のユーザー | システムおよびドライバのステータス情報 |
| LOADER | --load | 管理者 | カーネルサービス作成によるドライバのロード |
| KILLER | --kill / --pid | 任意のユーザー | IOCTL によるプロセス終了 |
| CLEANUP | --cleanup | 管理者 | ドライバサービスの停止と削除 |









Ghidra 11.0.3 による BdApiUtil64.sys のリバースエンジニアリングにより、従来の公開情報よりも広い攻撃面が特定されました。
| IOCTL | ハンドラ | プリミティブ | 事前の文書 |
|---|---|---|---|
0x800024B4 | FUN_000152b0 | プロセス終了 | 部分あり(メカニズムが不正確) |
0x80002648 | FUN_00013bb0 | 任意ファイル削除 | なし |
0x8000264C | FUN_00013850 | 使用中ファイル削除(SectionObjectPointer バイパス) | なし |
0x800024B4)ディスパッチチェーンは3つのレベルで構成されます。
IOCTL 0x800024B4
└─ FUN_00028630 (IRP_MJ_DEVICE_CONTROL ディスパッチャ)
└─ FUN_00015230 (ラッパー: IOCTL コードとバッファサイズ = 4 バイトを検証)
└─ FUN_000152b0 (強制終了ハンドラ — 脆弱性の所在)
再構築されたハンドラ (Ghidra):
if ((param_1 != 0) && (param_1 != 4)) {
PsLookupProcessByProcessId(param_1, &local_res10);
ObOpenObjectByPointer(
local_res10,
0x200, // OBJ_KERNEL_HANDLE
0, // PassedAccessState: NULL
0x1fffff, // PROCESS_ALL_ACCESS
0, // ObjectType: NULL
0, // AccessMode: KernelMode ← SeAccessCheck をバイパス
local_res18
);
ZwTerminateProcess(local_res18[0], 0);
}
なぜ KernelMode が SeAccessCheck をバイパスするのか:
ZwOpenProcess のパス:
NtOpenProcess → ObOpenObjectByName → SeAccessCheck
(DACL、呼び出し元トークン、整合性レベルをチェック)
STATUS_ACCESS_DENIED を返す可能性あり
ObOpenObjectByPointer(KernelMode) のパス:
SeAccessCheck ← 呼び出されない
→ PROCESS_ALL_ACCESS ハンドルが無条件に付与される
ZwOpenProcess は ドライバのインポートテーブルに存在しません。以前の情報源に基づく ZwOpenProcess を使用した説明は技術的に誤りです。
0x80002648)