Volver a actualizaciones
ActualizadaAug 31, 2026

skitter-creek-bath-salts — Actualizado!

Desbloqueando _todo_ en la CPU con DRAM scrambling

Compartir

skitter-creek-bath-salts

Desbloqueando todo en la CPU con el scrambling de DRAM — PSP, C6, microcódigo, SMM, y cualquier otra cosa que las especificaciones omitieron.

&x == &x.

Normalmente.

Desenredando la DRAM

Manipula el controlador de DRAM y una dirección puede terminar donde quieras en la memoria. skitter-creek-bath-salts modifica las capas inferiores de la jerarquía de memoria para recablear las traducciones de direcciones físicas de la DRAM. Esto altera la memoria de la plataforma, exponiendo regiones protegidas de la DRAM — reservas invisibles incluso para el kernel. Cuando las traducciones de direcciones se rompen, también lo hacen las primitivas de seguridad construidas sobre ellas, y desbloqueamos todo.


TL;DR


Objetivo

Desarrollado y probado en CPUs AMD Family 16h, la última generación cuyas hojas de datos documentan los registros de traducción del controlador de DRAM — y muestran que no pueden bloquearse. 17h y posteriores simplemente omiten esta información. La odisea de *p es similar entre generaciones y arquitecturas, y las transformaciones subyacentes se extienden incluso a ARM, RISC-V y más allá; skitter-creek-bath-salts nos muestra solo cómo empezar.


La odisea de *p

Es un largo camino hacia abajo.

La memoria está construida sobre capas de abstracción tan profundas que se vuelven casi absurdas. Cuando tu código desreferencia *p, parece acceder a la DRAM en p. No lo hace — p es una dirección virtual, y antes de que se toque un solo bit de DRAM, debe sobrevivir al calvario que se describe a continuación:``` ── 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)

Este proyecto trabaja en los niveles más profundos del pipeline `*p`, la capa MCT/DCT
— donde una dirección física proveniente del data fabric/interconnect entra en el controlador
de memoria y se reescribe una última vez en las coordenadas DRAM en bruto que se
emiten al DIMM.

---

## Espaguetizando la DRAM

> Las direcciones físicas son en realidad más una sugerencia.```nasm
xor dword [0xf80c2094], 0x00400000

Ese es el exploit. Todo él.

Categorías