
CryptoPro署名のUEFI Shellを悪用したCVE-2022-34303 Secure Bootバイパスを実演し、mmコマンドでgSecurity2を無効化して未署名のUEFIアプリケーションをロードします。
CryptoPro Secure Disk UEFI Shell - Bring Your Own Vulnerable UEFI Application (BYOVUA) - 署名済み UEFI Shell と gSecurity2 の破壊による Secure Boot バイパス。
このリポジトリは、CVE-2022-34303 を悪用することで BYOVUA (Bring Your Own Vulnerable UEFI Application) テクニックを実演します。これは CryptoPro Secure Disk UEFI ブート環境における Secure Boot バイパス脆弱性です。
このケースでは、Secure Boot が信頼するコンポーネントは、Microsoft の UEFI Third Party Certificate Authority によって署名されたカスタム shim です。一度実行されると、この shim は第二段階として UEFI Shell をロードし、それによって mm (memory modify) コマンドが公開され、OS 起動前のフェーズにおいて 任意のメモリ読み書き 機能が提供されます。
このプリミティブは、DXE コア内の gSecurity2 グローバルポインタを特定して無効化するために使用できます。その結果、以降の UEFI イメージ検証が無効化され、Secure Boot が有効であっても未署名の UEFI アプリケーションやブートキットをロードできるようになります。
BYOVUA は、カーネルレベルで使用される BYOVD (Bring Your Own Vulnerable Driver) テクニックの UEFI 版です。脆弱性を持つ署名済みカーネルドライバを持ち込む代わりに、攻撃者は署名済み UEFI アプリケーション - この場合は完全な UEFI Shell - を持ち込み、Secure Boot を無効化できる機能を利用します。
このアプリケーション - この場合は UEFI Shell を第二段階としてロードするカスタム shim - は Microsoft が信頼する証明書で署名されているため、Secure Boot によって疑われることなく受け入れられ、この証明書を Secure Boot データベース (db) に含むあらゆるシステム - つまり過去 10 年間に出荷されたほぼすべての UEFI 対応 PC - で信頼されます。一度実行されると、その組み込みコマンドは攻撃者に直接的なハードウェアおよびメモリアクセスを提供し、オペレーティングシステムがロードされる前 に動作します。そこでは、最新のセキュリティ制御 (ASLR、DEP、カーネル保護) は単に存在しません。
Shell_Full.efi は、プリブート認証およびディスク暗号化製品である CryptoPro Secure Disk の一部として配布されている UEFI Shell です。
| プロパティ | 値 |
|---|---|
| ファイル | Shell_Full.efi = EFI/Boot/BootX64.efi (SHIM) -> EFI/CPSD/Bootxsa.efi (Shell) |
| ベンダー | CryptoPro Secure Disk |
| CVE | CVE-2022-34303 |
| 署名 | Microsoft Corporation UEFI CA 2011 (Third Party) |
| 発見 | Eclypsium (Mickey Shkatov, Jesse Michael) - 2022年8月 |
| プレゼンテーション | DEF CON 30 - "One Bootloader to Load Them All" |
| 失効 | Microsoft KB5012170 により DBX に追加 (2022年8月) |
この脆弱性はバグではなく、設計上の欠陥 です。UEFI Shell は正規の診断ツールであり、Secure Boot 環境で実行されることは想定されていませんでした。しかし、Microsoft が信頼する証明書で署名し、商用製品の一部として配布することで、ベンダーは意図せず Secure Boot の署名済みバイパスを作成してしまいました。
核心的な問題: Secure Boot によって信頼される署名済みバイナリが、その組み込みコマンドを通じて無制限のメモリ読み書き機能を提供します。この組み合わせが Secure Boot の信頼モデル全体を破壊します。
mm (memory modify) コマンドは、システムメモリへの直接的な読み書きアクセスを提供する標準の UEFI Shell 組み込みコマンドです。UEFI Shell Specification (セクション 5.3) に記載されています。```
MM Address [Value] [-w 1|2|4|8] [-MEM | -MMIO | -IO | -PCI | -PCIE] [-n]
| パラメータ | 説明 |
|-----------|-------------|
| `Address` | 対象メモリアドレス |
| `Value` | 書き込む値(読み取り専用の場合は省略) |
| `-w` | 幅: 1、2、4、または 8 バイト |
| `-MEM` | システムメモリアクセス |
| `-MMIO` | メモリマップド I/O |
| `-IO` | I/O ポートアクセス |
| `-n` | 非対話型(次のアドレスのプロンプトを表示しない) |
---
<div id='gsecurity2'/>
### ***gSecurity2 とセキュリティアーキテクチャプロトコル***
UEFI における Secure Boot イメージ検証は、UEFI Platform Initialization(PI)仕様で定義されている[セキュリティアーキテクチャプロトコル](https://uefi.org/specs/PI/1.8/V2_DXE_Architectural_Protocols.html#security-architectural-protocols)を通じて実施されます。
DXE コア(DxeMain)は [`gSecurity2`](https://github.com/tianocore/edk2/blob/edk2-stable202608/MdeModulePkg/Core/Dxe/DxeMain.h#L252) と呼ばれるグローバルポインタを保持しており、これは `EFI_SECURITY2_ARCH_PROTOCOL` 構造体を指します。このプロトコルには単一の関数ポインタ - `FileAuthenticationState` - が含まれており、UEFI イメージがロードされるたびに `LoadImage()` から呼び出されます:```c
// EFI_SECURITY2_ARCH_PROTOCOL structure (PI Specification)
typedef struct _EFI_SECURITY2_ARCH_PROTOCOL {
EFI_SECURITY_FILE_AUTHENTICATION_STATE FileAuthenticationState;
} EFI_SECURITY2_ARCH_PROTOCOL;
// GUID: 94AB2F58-1438-4EF1-9152-18941A3A0E68
LoadImage() が呼び出されると、DXE コアは次をチェックします:```c
if (gSecurity2 != NULL)
{
Status = gSecurity2->FileAuthenticationState(gSecurity2, DevicePath, FileBuffer, FileSize, BootPolicy
);
if (EFI_ERROR(Status))
{
// Image rejected - signature verification failed
}
}
`gSecurity2 = NULL` を設定することで、`if` チェックが失敗し、`FileAuthenticationState` は決して呼び出されません。イメージ検証は完全にスキップされます - **Secure Boot は「有効」のままですが、もはや強制されません**。署名されていない UEFI アプリケーションはその後自由にロードできます。
gSecurity2 を自動的に特定してパッチを適用する専用の UEFI アプリケーションを含む、この手法の深い技術的理解については、コンパニオンプロジェクトを参照してください: [Exploitation Technique - UEFI Secure Boot Bypass via gSecurity2 Corruption](https://github.com/TheMalwareGuardian/Exploitation-Technique-UEFI-SecureBoot-Bypass-gSecurity2-Corruption)。
---
<div id='BYOVD'/>
### ***カーネル BYOVD との並行性***
UEFI BYOVUA とカーネル BYOVD の構造的な並行性は正確です:```
┌──────────────────────────────────────────────────────────────┐
│ UEFI BYOVUA (Secure Boot Bypass) │
│ │
│ 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) │
└──────────────────────────────────────────────────────────────┘
どちらの攻撃も同じ根本的な欠陥を悪用しています。セキュリティ機構から信頼されている署名済みコンポーネントが、まさにその機構を無効化するために必要なプリミティブを提供してしまうのです。
署名済みの Shell_Full.efi は EFI システムパーティション (ESP) に配置され、ブートオプションとして設定されます。これは Secure Boot によって信頼された証明書チェーンで署名されているため、ファームウェアは問題なく検証してロードします。```
EFI System Partition (ESP)
└── EFI/
└── Boot/
| └── BootX64.efi (SHIM) ← Signed by Microsoft Windows UEFI Driver Publisher
|
└── CPSD/
└── Bootxsa.efi (Shell) ← Signed by Security Coding Factory Software CA
└── startup.nsh (Script) ← Auto-executed on shell launch
---
<div id='Phase2'/>
### ***Phase 2 - Security2 プロトコルハンドルの列挙***
UEFI Shell から、`EFI_SECURITY2_ARCH_PROTOCOL`(GUID: `94AB2F58-1438-4EF1-9152-18941A3A0E68`)を公開しているハンドルを見つけ、そのプロトコルインターフェースのメモリアドレスを取得することが目的です。
> **Note:** `dh -p <GUID>` コマンドは、ほとんどの EDK2 Shell ビルドでは生の GUID を解決できません。登録されたプロトコル名のみを認識します。以下のアプローチはどの EDK2 Shell バージョンでも動作します。
**Step 1 - SecurityStubDxe ハンドルの検索**
すべてのハンドルを一覧表示し、`SecurityStubDxe` を探します。これは両方の Security Architectural Protocols をインストールする DXE ドライバーです:```
Shell> dh
出力で、SecurityStubDxe としてロードされたハンドルを特定します:```
10: Image(SecurityStubDxe)
**ステップ2 - 隣接するハンドルを検査する**