
CVE-2022-34302を実演します。これはNew Horizon Datasys署名済みブートローダーを介したSecure Bootバイパスであり、その組み込みカスタムPE/COFFローダーが未署名のUEFIアプリケーションを実行します。
New Horizon Datasys Reboot Restore ブートローダー - Bring Your Own Vulnerable UEFI Application (BYOVUA) - 署名済みブートローダーに組み込まれたカスタム PE/COFF ローダーが未署名の UEFI アプリケーションをロードすることによる Secure Boot バイパス。
本リポジトリは、New Horizon Datasys ブートローダーにおける Secure Boot バイパス脆弱性である CVE-2022-34302 を悪用することで、BYOVUA (Bring Your Own Vulnerable UEFI Application) テクニックを実証するものです。
UEFI Shell ベースの脆弱性 (CVE-2022-34301 および CVE-2022-34303) とは異なり、このブートローダーは UEFI Shell を公開していません。代わりに、shdloader.efi は独自のカスタム PE/COFF ローダーを実装しており、ファームウェアの LoadImage() 関数を使用せず、かつ署名検証を一切行わずに、セカンドステージバイナリ (shdmgr.ef_) をロードします。攻撃者は shdmgr.ef_ を互換性のある任意の UEFI アプリケーションに置き換えるだけで、Secure Boot が有効な状態で任意のコード実行を達成できます。
これは「One Bootloader to Load Them All」の研究で公表された 3 つの脆弱性の中で最も危険なものです。Eclypsium が指摘したように、このバイパスは組み込み済みで、完全にサイレントであり、画面上に視覚的な兆候を一切残しません。そのため、モニターを備えたシステムでも目視できず、サーバーや産業機器などのヘッドレスシステムでは検出不可能です。
BYOVUA は、カーネルレベルで使用される BYOVD (Bring Your Own Vulnerable Driver) テクニックの UEFI 版です。脆弱性を持つ署名済みカーネルドライバーを持ち込む代わりに、攻撃者は Secure Boot を無効化する機能を含む署名済み UEFI アプリケーションを持ち込みます。
shdloader.efi は Microsoft が信頼する証明書で署名されているため、Secure Boot に無条件で受け入れられ、この証明書を Secure Boot データベース (db) に含むあらゆるシステムで信頼されます。これは過去 10 年間に出荷されたほぼすべての UEFI 対応 PC に該当します。一度実行されると、その組み込みのカスタム PE ローダーにより、攻撃者はオペレーティングシステムがロードされる前に任意の未署名コードをロードおよび実行できるようになります。これは、最新のセキュリティ制御 (ASLR、DEP、カーネル保護) が単純に存在しない環境です。
shdloader.efi は、New Horizon Datasys のシステム復元およびリカバリ製品 (Reboot Restore Rx、RollBack Rx) の一部として配布される UEFI ブートローダーです。正規のブートチェーンにおける役割は、オペレーティングシステムが起動する前にスナップショットおよび復元操作を処理するプリ OS 管理コンポーネント (shdmgr.ef_) をロードすることです。
| プロパティ | 値 |
|---|---|
| ファイル | shdloader.efi = EFI/Boot/bootx64.efi |
| ベンダー | New Horizon Datasys Inc |
| 製品 | Reboot Restore Rx / RollBack Rx |
| CVE | CVE-2022-34302 |
| 署名 | Microsoft Windows UEFI Driver Publisher → Microsoft Corporation UEFI CA 2011 |
| 発見 | Eclypsium (Mickey Shkatov、Jesse Michael) - 2022 年 8 月 |
| プレゼンテーション | DEF CON 30 - 「One Bootloader to Load Them All」 |
| 失効 | Microsoft KB5012170 により DBX に追加 (2022 年 8 月) |
この脆弱性は、ブートローダーのアーキテクチャにおける設計上の欠陥です。Secure Boot の署名検証を強制するファームウェアの LoadImage() および StartImage() ブートサービスを使用する代わりに、shdloader.efi は独自のカスタム PE/COFF ローダーを実装しており、生のディスクバイトから shdmgr.ef_ を直接読み取り、再配置し、実行することで、ファームウェアのセキュリティチェックを完全にバイパスします。
核心的な問題は、Secure Boot に信頼されている署名済みバイナリが、署名を検証しない独自のイメージローダーを含んでいることです。ファームウェアは shdloader.efi を署名済みとして検証しますが、一度実行されると、shdmgr.ef_ を一切の検証なしにロードします。shdmgr.ef_ を任意の UEFI アプリケーションに置き換えると、Secure Boot が有効と報告されたまま、そのアプリケーションが完全なハードウェアアクセスで実行されます。
これは CVE-2022-34301 および CVE-2022-34303 とは根本的に異なります。これらの脆弱性では、攻撃者は UEFI Shell と対話し、gSecurity2 を手動で破壊して検証を無効化する必要があります。ここでは、バイパスは自動的かつサイレントです - ユーザー操作も、目に見える出力も、シェルプロンプトもありません。
署名済みの shdloader.efi は、PE/COFF イメージローダーの独自実装を含んでいます。ファームウェアの LoadImage() ブートサービスを呼び出すと、Security Architectural Protocols が呼び出され、イメージの署名が Secure Boot データベースに対して検証されますが、このブートローダーは代わりに以下の処理を行います:
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL を使用して \EFI\Boot\shdmgr.ef_ を開く.reloc セクションを処理し、ベース再配置を適用するこのプロセスのどの時点でも、ローダーはイメージの Authenticode 署名を検証したり、Secure Boot データベース (db/dbx) をチェックしたり、EFI_SECURITY2_ARCH_PROTOCOL を呼び出したりしません。イメージは純粋にその PE/COFF 構造の妥当性に基づいてロードされます。```c
// Pseudocode of what shdloader.efi does internally
//
// NOTE: This is a simplified representation. The actual
// implementation was derived from reverse engineering.
EFI_STATUS LoadShdmgr(VOID) { // Step 1: Open the file File = OpenFile(L"\EFI\Boot\shdmgr.ef_");
// Step 2: Read raw bytes (no signature check)
ReadFile(File, &Buffer, &Size);
// Step 3: Parse PE/COFF headers
DosHeader = (EFI_IMAGE_DOS_HEADER *)Buffer;
PeHeader = (EFI_IMAGE_NT_HEADERS *)(Buffer + DosHeader->e_lfanew);
// Step 4: Allocate memory and copy sections
ImageBase = AllocatePages(...);
CopySections(ImageBase, Buffer, PeHeader);
// Step 5: Apply base relocations from .reloc
Delta = ImageBase - PeHeader->OptionalHeader.ImageBase;
ApplyRelocations(ImageBase, PeHeader, Delta);
// Step 6: Jump to entry point
// NO SIGNATURE VERIFICATION ANYWHERE
EntryPoint = ImageBase + PeHeader->OptionalHeader.AddressOfEntryPoint;
((EFI_IMAGE_ENTRY_POINT)EntryPoint)(ImageHandle, SystemTable);
}
---
<div id='LoadImageVsCustomLoader'/>
### ***LoadImage とカスタムローダー***
ファームウェアの `LoadImage()` とカスタムローダーの違いは、決定的なセキュリティギャップです:```
┌─────────────────────────────────────────────────────────────────────────┐
│ Firmware LoadImage() - How legitimate boot chains work │
│ │
│ bootx64.efi ──> LoadImage("shdmgr.ef_") │
│ │ │
│ ├── Parse PE/COFF headers │
│ ├── Verify Authenticode signature │
│ ├── Check signature against db (allowed) │
│ ├── Check hash against dbx (revoked) │
│ ├── Call gSecurity2->FileAuthenticationState() │
│ │ │ │
│ │ ├── Signature valid? ── YES ──> Load image │
│ │ └── Signature invalid? ── NO ──> REJECT │
│ └── StartImage() │
│ │
├─────────────────────────────────────────────────────────────────────────┤
│ Custom PE Loader - What shdloader.efi does │
│ │
│ shdloader.efi ──> OpenFile("shdmgr.ef_") │
│ │ │
│ ├── ReadFile() into buffer │
│ ├── Parse PE/COFF headers │
│ ├── Allocate memory │
│ ├── Copy sections │
│ ├── Apply .reloc relocations │
│ ├── *** NO SIGNATURE CHECK *** │
│ └── Jump to EntryPoint │
│ │
│ Result: ANY valid PE/COFF EFI application runs, signed or not │
└─────────────────────────────────────────────────────────────────────────┘
カスタム PE ローダーは簡易実装であり、特定の PE/COFF レイアウトを前提としています。準拠しないバイナリはエラーで拒否されます:``` Reloc table overflows binary Relocation failed Invalid entry point
これらのいずれかが欠けているバイナリは、カスタムローダーによって拒否されます。
| フィールド | 必須値 | 理由 |
|-------|---------------|--------|
| *Machine* | `0x8664` (x64) | ローダーは x86-64 イメージのみをサポートします |
| *Subsystem* | `10` (EFI Application) | EFI Application である必要があります |
| *.reloc セクション* | `.reloc` が有効なベースリロケーションエントリとともに存在する必要があります | ローダーは独自のイメージリロケーションを実行します。.reloc がない場合、「Reloc table overflows binary」で失敗します |
| *Relocation Directory* | `VirtualAddress` != 0、Size != 0 (DATA_DIRECTORY[5]) | ディレクトリエントリは有効なリロケーションデータを指している必要があります |
デプロイ前に互換性を確認するための検証スクリプト (Scripts/VerifyPE.py) が提供されています。
---
<div id='BYOVD'/>
### ***カーネル BYOVD との並行性***
UEFI BYOVUA とカーネル BYOVD の構造的な並行性は正確であり、CVE-2022-34302 は最も直接的な形態を表しています。つまり、署名されたコンポーネント**自体**が未署名のコードをロードするのであり、検証を無効にするプリミティブを提供するのではありません。```
┌──────────────────────────────────────────────────────────────┐
│ UEFI BYOVUA - CVE-2022-34302 (Custom PE Loader) │
│ │
│ Signed Bootloader ──> Custom PE Loader ──> Load unsigned │
│ (trusted by (no sig check) UEFI apps │
│ Secure Boot) │
├──────────────────────────────────────────────────────────────┤
│ UEFI BYOVUA - CVE-2022-34301/34303 (Shell + gSecurity2) │
│ │
│ Signed Shell ─ mm ─> gSecurity2 = NULL ─> Load unsigned │
│ (trusted by (Security2 Protocol) UEFI apps │
│ Secure Boot) │
├──────────────────────────────────────────────────────────────┤
│ Kernel BYOVD (DSE Bypass) │
│ │
│ Signed Driver ─ IOCTL ─> g_CiOptions = 0 ─> Load unsigned │
│ (trusted by (CI.dll) kernel drivers │
│ DSE / CI) │
└──────────────────────────────────────────────────────────────┘
CVE-2022-34302は最も危険な亜種です。なぜなら、このバイパスはブートローダーの設計に固有のものであり、攻撃者がセキュリティ機構を破壊する必要がある中間ステップが存在しないからです。署名されたコンポーネントは、その通常の動作として、未署名のコードを直接ロードします。
署名済みのshdloader.efiは、デフォルトのブートローダーとしてEFIシステムパーティション(ESP)に配置されます。これはMicrosoftのUEFI Driver Publisher証明書によって署名されているため、Secure Bootは問題なく検証してロードします。```
EFI System Partition (ESP)
└── EFI/
└── Boot/
└── bootx64.efi (shdloader.efi) ← Signed by Microsoft Windows UEFI Driver Publisher
└── shdmgr.ef_ (PAYLOAD) ← Unsigned, loaded by shdloader's custom PE loader
システム起動時、ファームウェアは次の処理を行います:
1. ESP から `bootx64.efi` を読み取る
2. `LoadImage()` を呼び出し、Secure Boot データベースに対して Authenticode 署名を検証する
3. 署名が `db` 内の Microsoft UEFI CA 2011 証明書と一致する → イメージが受け入れられる
4. `StartImage()` を呼び出し、実行を `shdloader.efi` に移す
---
<div id='Phase2'/>
### ***フェーズ 2 - カスタム PE ローダーの起動***
`shdloader.efi` が制御を取得すると、診断メッセージを出力し、直ちに独自の PE/COFF ローダーを起動します:```
Booting in insecure mode
ブートローダーは次に:
\EFI\Boot\shdmgr.ef_ を開く.text、、 など)を割り当てられたメモリにコピーする.data.relocLoadAddress - ImageBase)を計算し、.reloc セクションからすべてのベースリロケーションを適用するLoadAddress + AddressOfEntryPoint を実行ターゲットとして解決するこのプロセスのどの時点でも署名検証は行われません。 ローダーは LoadImage() を呼び出さず、gSecurity2->FileAuthenticationState() を呼び出さず、db または dbx データベースをチェックしません。ファイルは純粋に構造的な妥当性に基づいてロードされます。
ファイルが見つからない場合、ブートローダーは次を報告します:``` Failed to open \EFI\Boot\shdmgr.ef_ - 800000000000000E Failed to load image
---
<div id='Phase3'/>
### ***Phase 3 - 署名なしコードの実行***
カスタムローダーは `shdmgr.ef_` のエントリポイントにジャンプします。署名なしの UEFI アプリケーションは次の状態で実行されます:
- 完全なハードウェアアクセス(直接メモリ、I/O ポート、PCI、MMIO)
- オペレーティングシステムはまだロードされていない
- ASLR、DEP、カーネル保護なし
- EDR やエンドポイントセキュリティ監視なし
- 後続の OS クエリに対して Secure Boot は **有効** と報告
攻撃は完全にサイレントです。目に見える UEFI Shell プロンプトを表示する CVE-2022-34301 や CVE-2022-34303 とは異なり、このエクスプロイトは「Booting in insecure mode」メッセージ以外の視覚的出力を生成しません(正規のシステムでは、このメッセージは一瞬表示され、すぐに OS の起動画面に置き換わります)。ヘッドレスシステム(サーバー、IoT、産業機器)では、兆候はまったくありません。
---
<div id='Phase4'/>
### ***Phase 4 - 永続化***
攻撃はデフォルトで永続的です。`shdloader.efi` が `\EFI\Boot\bootx64.efi` に存在し、攻撃者のペイロードが ESP 上の `\EFI\Boot\shdmgr.ef_` に存在する限り、署名なしのペイロードは起動のたびに実行されます。
`startup.nsh` スクリプトは不要です。ファームウェア更新をまたいで gSecurity2 アドレスを再計算する必要もありません。カスタム PE ローダーは、見つけた `shdmgr.ef_` を無条件にロードします。
システムは引き続き Secure Boot を「有効」と報告します - 信頼チェーンがブートローダーレベルで破壊されているだけです。これにより、攻撃は OS レベルの Secure Boot ステータスクエリや、Secure Boot の証明に依存するあらゆるセキュリティソフトウェアから見えなくなります。
> **重要:** 永続化が破られるのは、DBX が `shdloader.efi` の失効エントリ(KB5012170)で更新された場合のみです。これにより、カスタムローダーが起動する前にファームウェアが `shdloader.efi` 自体を拒否します。
---
---
---
<div id='Exploit'/>
## ***エクスプロイト***
`Exploit/` ディレクトリには、互換性のある `shdmgr.ef_` をビルドするために必要なすべてが含まれています:```
Exploit/
|
├── README.md ← Build guide and PE/COFF requirements
|
├── PayloadShdmgr/
| |
│ ├── ForceReloc.nasm ← Force .reloc section generation
│ ├── shdmgr.ef_.c ← UEFI application source (EDK2)
│ ├── shdmgr.ef_.inf ← EDK2 module definition
│ ├── shdmgr.ef_.dsc ← EDK2 platform build configuration
│ └── shdmgr.ef_.dec ← EDK2 package declaration
|
└── Scripts/
└── VerifyPE.py ← PE/COFF compatibility verifier
署名済みブートローダーは、KB5012170(2022年8月)を通じてMicrosoftのDBX失効リストに追加されました。更新されたシステムでは、カスタムPEローダーが起動する前に、Secure Bootによってブートローダーが拒否されます。
ラボ環境には、以下のいずれかの条件を満たすシステムが必要です:
QEMU UEFI Research Environmentは、このための自動セットアップを提供します。
CVE-2022-34302は、CVE-2022-34301およびCVE-2022-34303よりも悪用が簡単です:
| 観点 | CVE-2022-34302(カスタムローダー) | CVE-2022-34301/34303(シェル) |
|---|---|---|
| 手法 | shdmgr.ef_をペイロードに置き換える | mmコマンドでgSecurity2を破壊する |
| 操作 | なし(完全自動) | 手動シェルコマンドまたはstartup.nsh |
| 可視性 | サイレント(「Booting in insecure mode」) | 可視的なUEFI Shellプロンプト |
| ファームウェア依存性 | なし(ペイロードは自己完結型) | gSecurity2アドレスはファームウェアビルドごとに変化 |
| 複雑さ | 低(ファイル置き換え) | 中(メモリスキャンとパッチ適用) |
| ステルス性 | 高(ヘッドレスで視覚出力なし) | 低(画面上でシェルが可視) |