セキュリティ
DRAMのスパゲッティ化
Spaghettifying DRAM (github.com)
要約
「skitter-creek-bath-salts」と名付けられたこの技術は、DRAMコントローラーの脆弱性を利用して、CPUの保護されたメモリ領域(PSP、C6、マイクロコード、SMMなど)へのアクセスを可能にします。物理アドレス変換を書き換えることで、カーネルからも見えない特殊なメモリ領域を解放し、プラットフォームの最も隠された秘密を明らかにします。この手法はAMD CPUで開発・テストされましたが、その基本原理は他のアーキテクチャにも応用可能であると示唆されています。
全文翻訳
skitter-creek-bath-salts CPU上のすべてをDRAMスクランブリングで解除 — PSP、C6、マイクロコード、SMM、および仕様で省略されたその他のすべて。 &x == &x。通常。DRAMコントローラーを操作すると、アドレスはメモリ内の任意の場所に配置できます。skitter-creek-bath-saltsは、メモリ階層の最も深いレベルに到達し、物理DRAMアドレス変換を再配線して、プラットフォームメモリをスクランブルし、カーネルからも見えない特殊な領域という最も守られた秘密を解放します。変換が壊れると、それらに基づく壁が崩壊し、すべてが解除されます。
TL;DR
プラットフォームセキュリティプロセッサを解除
システム管理モードを解除
C6 DRAMを解除
CPUマイクロコードを解除
ターゲット
DRAMコントローラーの変換レジスタのデータシートが文書化されており、ロックできないことを示している、最後の世代であるAMD Family 16h CPUで開発およびテストされました。17h以降では、この情報は単純に省略されています。*pの旅は、世代やアーキテクチャを超えて類似しており、基本的な変換はARM、RISC-V、およびそれ以降にまで拡張されます。skitter-creek-bath-saltsは、その始まり方を示しているにすぎません。
*pの旅
それは長い道のりです。メモリは、ほとんど不条理なほど深い抽象化の層の上に構築されています。コードが*pを逆参照すると、pにあるDRAMにアクセスするように見えます。それは違います — pは仮想アドレスであり、DRAMのビットが触れられる前に、以下のガントレットを生き残る必要があります:
── CPUコア / MMU ─────────────────────────────────────────────────
┌─ VA ← 64ビット仮想アドレス(ロード/ストアから)
│└> 正規化チェック ──────────────────────┐ ← ビット [63:48] ビット47からの符号拡張
┌─ セグメントベース追加 <─────────────────────────┘ ← FS.base / GS.base (MSR_FS_BASE, MSR_GS_BASE)
│└> TLBプローブ ─────────────────────────────────┐ ← PCID(ホスト)/ VPID(ゲスト)でタグ付け
ヒット → 物理アドレス k
ミス → ハードウェアページウォーカーを起動
┌─ ページウォーク(CR3から) <─────────────────────┘ ← TLBミス時のみウォーク
PML5[VA 56:48] ← CR4.LA57の場合のみ
PML4[VA 47:39]
PDPT[VA 38:30] ← 1 GiBリーフの可能性
PD [VA 29:21] ← 2 MiBリーフの可能性
PT [VA 20:12]
PTE ← R/W · U/S · NX · A/D · PAT · PCD · PWT · G
└> レベルごとのチェック ──────────────────────────┐ ← 各ウォークレベルで評価
権限(U/S)
← CPL vs PTE.U/S
書き込み(R/W)
← + CR0.WP
実行(NX)
← EFER.NXE SMEP / SMAP
← CR4.SMEP · CR4.SMAP · EFLAGS.AC
保護キー
← PKRU (ユーザー) · IA32_PKRS (スーパーバイザー)
┌─ A/Dビット更新 <───────────────────────────┘ ← PTEのロックされたRMW
└> ゲストの場合: EPT / NPT再ウォーク ───────────────┐ ← 上記の各ゲストPAが再ウォークされる
EPT-PML4 → EPT-PDPT → EPT-PD → EPT-PT
← + EPTメモリタイプオーバーライド ⇒ 単一ゲストウォークあたり約5回のウォーク
┌─ TLBシュートダウンIPIs <───────────────────────┘ ← invlpgをピアvCPUにブロードキャスト
│
── IOMMU(チップセット / I/Oファブリック) ──────────────────────────────────
│└> デバイス開始の場合、IOMMUページウォーク ──────┐ ← VT-d / AMD-Vi: デバイスID → ドメイン → テーブル
┌── **物理アドレス k** <─────────────────┘
│
── CPUコア / MMU — メモリタイプ解決 ────────────────────────
│└> MTRR範囲マッチ ──────────────────────────┐ ← IA32_MTRR_DEF_TYPE + 固定/可変MTRR
┌─ PATエントリ選択 <─────────────────────────┘ ← IA32_PAT[ PTE.PAT:PCD:PWT ]
└> 有効なメモリタイプ ─────────────────────┐ ← { WB, WT, WC, WP, UC-, UC }
── CPUアンコア — キャッシュ & コヒーレンス ────────────────────────────────
│┌─ L1-Dプローブ <───────────────────────────────┘ ← VIPT、コアごと
│└> L2プローブ ──────────────────────────────────┐ ← コアごと / CCXごと
┌─ LLCプローブ + ディレクトリコンサルテーション <────────────┘ ← 共有、スライス
│└> スヌープ / コヒーレンス ─────────────────────────┐ ← MESI / MOESI intra-socketにブロードキャスト
│ ← ソケット間ピアコアへのブロードキャスト
│ ← QPI · UPI · Infinity Fabric · CXL.cache ホームノードディレクトリ応答
│ ← データ | 介入 | 中止
── システムデータファブリック / インターコネクト ──────────────────────────────
│┌─ MMIO範囲または4 GiB未満のMMIOホールの場合 <─────┘ ← アンコア/データファブリックのポスト/非ポストトランザクション
│→ デバイスBAR; 完了
└> それ以外の場合、DRAMバウンド: データファブリック / メッシュ ───────┐ ← AMD DF · Intel メッシュまたはリングアンコア
┏━━ ── MCT / IMC(メモリコントローラー) ──────────────────────────────── W
┃┌─ DRAMホールリマップ ──────────────────────────┘ ← TOMより上のハイメモリリマップ
┃│
┃└> メモリ領域除外リマップ ─────────────┐ ← 予約済み/保護された範囲
┃┌─ チャンネルインターリーブハッシュ ──────────────────┘ ← 選択されたPAビットのXOR → チャンネルA
┃│
┃└> ランクインターリーブハッシュ ──────────────────────┐ ← 選択されたPAビットのXOR → ランク
┃┌─ バンクインターリーブハッシュ ─────────────────────┘ ← 選択されたPAビットのXOR → バンク
┃│
┃└> バンクスワップル/XORスクランブル ───────────────┐ ← ベンダーおよびBIOSで設定可能
┃┌─ チップセレクト正規化(DCT) <──────────────┘ ← 各ランクのCSライン
┃│ランク → CSマップ
┃ R
┃ E
┃└> サブチャンネル選択 ────────────────────────┐ ← DDR5 / LPDDR5のみ
┗━━
││ DRAM座標 ─────────────────────────┘ ← バンクグループ · バンク · 行(RAS) · 列(CAS)
このプロジェクトは、*pパイプラインの最も深いレベル、つまり物理アドレスがデータファブリック/インターコネクトからメモリコントローラーに入り、DIMMに発行される生のDRAM座標に最終的に書き換えられるMCT/DCTレイヤーで動作します。
DRAMのスパゲッティ化
物理アドレスは実際には提案にすぎません。
xor dword [0xf80c2094], 0x00400000
それがエクスプロイトです。すべてです。DRAMコントローラーの1ビット反転は、*pパイプラインの基盤全体を再配線し、&xにあったデータは飛行中のどこかに移動します。突然、&x != &xになります。CPU、ファームウェア、アンコア、チップセットが、メモリの最も保護されたすべての領域を壁で囲むために細心の注意を払って使用してきたすべての精巧なメカニズムは、メモリコントローラーの上にあり、その下で起こるすべてを完全に認識していません。既存のすべてのメモリフェンスは物理アドレスを保護しており、DRAM座標を保護していません。DRAM座標を並べ替えると、その上に構築されたCPUとデータファブリックのバリアはすべて認識しません。しかし、DRAMの再配線は簡単です。上記のビットは、DCTのバンクスワップルモードであり、最終レイヤーのアドレスリマップを制御する数十のモードのうちの1つにすぎません。それらを突き刺すだけで、その上に構築されたすべてを崩壊させることができます。次に難しいのは、システムメモリ全体がその下でスクランブルされている間、プラットフォームを維持することです。トリックは、高速で、DRAMに触れないことです。APを無効にし、TLBをプライムし、キャッシュをウォームアップし、割り込みを無効にし、ターゲットをフラッシュし、メモリアクセスをシリアライズし、CPUが次の命令をプリフェッチしたことを願います。次に、MCT/DCTを再配線してDRAMをスパゲッティ化し、保護された領域からデータを取得し、マッピングを元に戻し、再度シリアライズし、割り込みを有効にし、APを再開します。すべてが元に戻り、プラットフォームの残りは完全に無傷です。
mov eax, [0xf80c2094] ; MMIO TLBをプライム
mov eax, [0x6f800000] ; ターゲットTLBをプライム
pushf ; フラグを保存
cli ; 割り込みオフ
clflush [0x6f800000] ; ターゲットを追い出し、DRAM読み込みを強制
mfence ; バリア - コヒーレントなワールドDRAMアクセスなし
lfence ; スパゲッティ化されたビューに再編成
xor dword [0xf80c2094], 1<<22 ; DCTスワップルを反転 → DRAMをスパゲッティ化
mov ebx, [0x6f800000] ; スパゲッティ化されたビューでターゲットを取得
xor dword [0xf80c2094], 1<<22 ; DCTスワップルを復元 → スクランブル解除
mfence ; バリア - スパゲッティ化されたDRAMアクセスなし
lfence ; コヒーレントなワールドビューに再編成
popf ; 割り込みバックオン
ページング、キャッシュ状態、スレッディング、TLBの慎重なセットアップにより、アドレススクランブリングはCから機能させることができ、*pパイプラインの崩壊と、突然&x != &xになったときのプラットフォームの破損したビューを示すことができます。
したがって、痕跡を残さずにマップを再配線して復元できます。残っているのは、それを何に再配線したかを知ることだけです。
すべてを解除する
プラットフォーム上のすべての保護されたメモリ領域に、計算機で到達可能。
上記の戦略により、実行中のシステムでMCT/DCT変換を再プログラムできます。*pパイプラインの最下位ステージを再編成して、その上に構築されたすべての保護を回避するようにメモリをスクランブルします。しかし、課題があります。その間、