Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-53360-POC — PoC para CVE-2026-53360: lectura/escritura fuera de los límites del montón desencadenada por el invitado en el manejo de Page State Change (PSC) de KVM SEV-SNP. | Kitploit
Herramientas/GitHubGitHub/0xcyberstan/cve-2026-53360-poc
Forensia de MemoriaAnálisis de VulnerabilidadesExplotaciónSeguridad de HardwareExplotación de Binarios
GitHub0xcyberstan/cve-2026-53360-poc

CVE-2026-53360-POC

PoC para CVE-2026-53360: lectura/escritura fuera de los límites del montón desencadenada por el invitado en el manejo de Page State Change (PSC) de KVM SEV-SNP.

Ver Repositorio

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir
13hace 2 mesesAún no revisado

CVE-2026-53360: Desbordamiento de montón en PSC de KVM SEV-SNP

Prueba de concepto de una lectura y escritura fuera de los límites del montón en el manejo del Cambio de Estado de Página (PSC) de SEV-SNP de KVM. Un invitado SEV-SNP malicioso hace que el kernel anfitrión recorra un array de entradas PSC más allá del final de su asignación de slab. Esto filtra el diseño de los objetos kmalloc-cg-32 vecinos y escribe un valor pequeño controlado en ellos, y el invitado puede repetirlo tantas veces como desee.

Artículo completo: https://cyberstan.co.uk/sev-snp-oob/

CVECVE-2026-53360
ComponentSoporte anfitrión SNP de KVM, arch/x86/kvm/svm/sev.c
Introducido9b54e248d264 (primer manejo de PSC SNP de KVM, mayo 2024, ~v6.10)
Corregidodb3f219 (mainline, mayo 2026, Cc: stable), etiquetado Fixes: 4af663c
Reportado[email protected], 8 de abril de 2026
AfectadoSolo ruta anfitrión SEV-SNP. KVM no habilita PSC para invitados SEV-ES simples.

Impacto

Cualquier invitado SEV-SNP puede corromper el montón del kernel anfitrión y leer información sobre su diseño enviando una solicitud PSC malformada. Esta es la dirección invitado a anfitrión: SEV-SNP está diseñado para proteger al invitado de un anfitrión no confiable, pero el anfitrión aún tiene que defenderse contra un invitado malicioso, y este manejador no lo hace.

Requisitos

Esto requiere hardware SEV-SNP real. No se puede reproducir en Intel, y la virtualización anidada no le dará un invitado SNP.

Hardware:

  • Un chip de servidor AMD EPYC con SEV-SNP: Milan (7003) o más nuevo, es decir, Genoa (9004), Bergamo, Siena o Turin. SEV-SNP es silicio solo para EPYC. No está en Ryzen o Threadripper, y no hay equivalente de Intel aquí (Intel usa TDX).
  • Metal desnudo. Una instancia en la nube de metal desnudo también funciona (Vultr, AWS *.metal, Hetzner AX y similares).
  • En la BIOS, habilite SEV, SEV-ES, SEV-SNP, SME, IOMMU y SVM. Las nubes de metal desnudo administradas generalmente ya los tienen activados.

Kernel anfitrión:

  • Constrúyalo con KASAN para que se reporten los accesos fuera de los límites. Sin KASAN, el error aún corrompe la memoria del anfitrión, simplemente no se imprime. Probado en 6.11.11.
    root@kitploit:~
    CONFIG_KASAN=y
    CONFIG_KASAN_GENERIC=y
    CONFIG_KVM=y
    CONFIG_KVM_AMD=y
    CONFIG_KVM_AMD_SEV=y
    CONFIG_CRYPTO_DEV_SP_PSP=y
    
  • Arranque con SNP habilitado y KASAN en modo multi-shot para que cada acierto sea registrado:
    root@kitploit:~
    kvm_amd.sev=1 kvm_amd.sev_es=1 kvm_amd.sev_snp=1 kasan_multi_shot
    
  • Confirme que el anfitrión está listo:
    root@kitploit:~
    cat /sys/module/kvm_amd/parameters/sev_snp     # Y
    ls /dev/sev                                     # /dev/sev
    

Espacio de usuario anfitrión:

  • Un QEMU compatible con SNP. El QEMU estándar no soporta SNP, así que construya el fork de AMD:
    root@kitploit:~
    git clone https://github.com/AMDESE/qemu.git
    cd qemu && git checkout snp-latest
    mkdir build && cd build
    ../configure --target-list=x86_64-softmmu && make -j$(nproc)
    
  • Firmware OVMF SNP desde https://github.com/AMDESE/AMDSEV/releases.

Invitado:

  • Cualquier invitado Linux que arranque bajo SNP, con build-essential y linux-headers-$(uname -r) instalados para poder construir el módulo en él.

El error

Los invitados SEV-SNP se comunican con el anfitrión a través del GHCB, una página compartida de 4 KB. Una solicitud PSC establece SW_EXITCODE en SVM_VMGEXIT_PSC (0x80000010), apunta SW_SCRATCH a un descriptor y coloca la longitud del descriptor en SW_EXITINFO2.

El descriptor es un struct psc_buffer: un encabezado de 8 bytes seguido de un array de entradas de 8 bytes. No hay un campo de conteo explícito. El anfitrión procesa las entradas desde hdr->cur_entry hasta hdr->end_entry, ambos controlados por el invitado.

root@kitploit:~
struct psc_hdr {
        u16 cur_entry;
        u16 end_entry;
        u32 reserved;
} __packed;                     /* 8 bytes */

struct psc_entry {
        u64 cur_page    : 12;
        u64 gfn         : 40;
        u64 operation   :  4;
        u64 pagesize    :  1;
        u64 reserved    :  7;
} __packed;                     /* 8 bytes */

Se supone que un invitado GHCB v2+ mantiene su área de scratch dentro del Búfer Compartido de 2032 bytes del GHCB, para que el anfitrión pueda reutilizar su mapeo existente. Allí caben (2032 - 8) / 8 = 253 entradas, de donde proviene el máximo de protocolo VMGEXIT_PSC_MAX_COUNT (253). Ese número solo tiene sentido cuando el búfer es realmente el Búfer Compartido.

Si el invitado apunta el área de scratch fuera del GHCB, el anfitrión no puede usar su mapeo, por lo que setup_vmgexit_scratch() asigna un búfer separado del tamaño que el invitado solicitó. SNP nunca debería tomar este camino, pero nada lo impide:

root@kitploit:~
scratch_va = kvzalloc(len, GFP_KERNEL_ACCOUNT);   /* len == exit_info_2, controlado por el invitado */

len proviene directamente del invitado, y GFP_KERNEL_ACCOUNT coloca la asignación en los cachés kmalloc-cg-N contabilizados por cgroup. Solicite exit_info_2 = 24 y obtendrá una asignación de 24 bytes en el slot de 32 bytes de kmalloc-cg-32: espacio para el encabezado más dos entradas. Todo más allá de entries[1] es memoria de otro objeto.

Luego snp_begin_psc() verifica el conteo de entradas contra la constante del protocolo, no contra el búfer que realmente asignó:

root@kitploit:~
idx_end = hdr->end_entry;

if (idx_end >= VMGEXIT_PSC_MAX_COUNT) {   /* verifica 253, NO el tamaño del búfer */
        snp_complete_psc(svm, ...);
        return 1;
}

for (idx = idx_start; idx <= idx_end; idx++) {
        entry_start = entries[idx];       /* OOB una vez idx >= 2 */
        ...
}

Con un búfer de 24 bytes solo existen dos entradas, pero la verificación permite end_entry hasta 252. Establézcalo en 252 y el bucle recorre unos 2 KB más allá de la asignación, a través de objetos slab vecinos.

Primitivas

Cada paso más allá del final reinterpreta los siguientes 8 bytes de memoria slab como un psc_entry y los procesa a través del código PSC. Esto proporciona tres cosas:

  1. Oráculo de lectura. El anfitrión lee la qword adyacente solo para decodificarla, extrayendo entry.gfn y entry.operation de memoria que el búfer nunca poseyó. Esta es la lectura fuera de los límites del slab que KASAN detecta.
  2. Escritura restringida. Si la entrada decodificada parece válida y se envía como un KVM_HC_MAP_GPA_RANGE, el código de finalización escribe de vuelta en el mismo slot OOB: entries[idx].cur_page = entry.pagesize ? 512 : 1. Uno de dos valores pequeños en los 12 bits bajos de una palabra que el invitado elige, repetible.
  3. Oráculo de fallo. Si la entrada no se valida, la respuesta en SW_EXITINFO2 informa el índice en el que se detuvo. Incrementar end_entry de a uno filtra, slot por slot, si la memoria adyacente se decodificó como un no-op o como algo que falló, lo cual es suficiente para encontrar límites de objetos y distinguir cero de no cero.

Cada VMGEXIT reasigna el búfer de scratch, por lo que las solicitudes repetidas caen en diferentes slots de la lista libre y permiten al invitado barrer los vecinos en lugar de quedarse atascado con uno. En conjunto, esto produce divulgación del diseño del montón, la escritura restringida anterior y use-after-free entre solicitudes.

Lo que hace la PoC

trigger.c es un módulo del kernel del invitado. Cárguelo dentro de un invitado SEV-SNP y ejecuta cuatro etapas contra el anfitrión desde un solo insmod:

  • Etapa 1 sondea 48 entradas fuera de los límites una por una y construye un mapa del montón del anfitrión (memoria vecina cero vs no cero).
  • Etapa 2 demuestra que la escritura OOB persiste a través de VMGEXITs escribiendo cur_page en un vecino cero y confirmando que una solicitud posterior lo omite.
  • Etapa 3 dispara una solicitud con end_entry=200 y mide hasta dónde llega la lectura OOB antes de encontrar datos no cero.
  • Etapa 4 dispara 200 solicitudes con entries[3..10] fuera de los límites, cada una de las cuales genera un informe KASAN en el anfitrión.

El módulo asigna una página, la marca como descifrada con set_memory_decrypted(), la usa como área de scratch y construye manualmente la solicitud GHCB PSC. Sale con -EAGAIN para no permanecer cargado.

Construcción y ejecución

1. Iniciar un invitado SNP

Ajuste las rutas de OVMF y disco a su configuración:

root@kitploit:~
qemu-system-x86_64 \
    -enable-kvm -cpu EPYC-v4 \
    -machine q35,confidential-guest-support=sev0,memory-backend=ram1 \
    -object memory-backend-memfd,id=ram1,size=4G \
    -object sev-snp-guest,id=sev0,cbitpos=51,reduced-phys-bits=1,policy=0x30000 \
    -smp 4 -m 4G \
    -bios OVMF_SNP.fd \
    -drive file=guest.qcow2,format=qcow2,if=virtio \
    -netdev user,id=net0,hostfwd=tcp::2222-:22 \
    -device virtio-net-pci,netdev=net0 \
    -nographic

2. Construir y cargar en el invitado

Copie trigger.c y Makefile dentro del invitado, luego:

root@kitploit:~
make
insmod trigger.ko

El módulo verifica SEV-SNP mediante CPUID primero y se niega a ejecutarse en cualquier otro lugar. Ejecuta sus cuatro etapas y se descarga a sí mismo (init devuelve -EAGAIN, por lo que nunca permanece residente).

3. Observar el anfitrión

En el anfitrión:

root@kitploit:~
dmesg | grep -E "KASAN|BUG|snp_begin_psc"

Salida esperada:

root@kitploit:~
BUG: KASAN: slab-out-of-bounds in snp_begin_psc+0x126/0x890
Read of size 8 at addr ffff888219ffb5e0 by task qemu-system-x86/2199

BUG: KASAN: slab-out-of-bounds in snp_begin_psc+0x468/0x890
Write of size 8 at addr ffff888351566648 by task qemu-system-x86/2199

The buggy address belongs to the object at ffff888XXXXXXXXX
 which belongs to the cache kmalloc-cg-32 of size 32

Un solo insmod produjo 73 informes KASAN en el anfitrión de prueba (62 slab-out-of-bounds, 7 slab-use-after-free, 4 use-after-free), todos contra kmalloc-cg-32. Anfitrión de prueba: AMD EPYC 7443P, Ubuntu 24.04.4, kernel 6.11.11 con KASAN, invitado bajo AMDESE QEMU (snp-latest).

La corrección

La corrección en el upstream rechaza cualquier área de scratch fuera del GHCB para GHCB v2 y posteriores en setup_vmgexit_scratch(), lo que fija el búfer a un tamaño fijo conocido para que el bucle nunca pueda ejecutarse más allá del final:

root@kitploit:~
  } else {
+         /* GHCB v2 requires the scratch area to be within the GHCB. */
+         if (to_kvm_sev_info(svm->vcpu.kvm)->ghcb_version >= 2)
+                 goto e_scratch;
+
          /*
           * The guest memory must be read into a kernel buffer, so
           * limit the size

Esas cuatro líneas son db3f219. Llegaron como parte de una serie más grande que también limita el conteo de entradas contra el tamaño real del búfer y relee el descriptor una vez mediante READ_ONCE(), lo que cierra una variante de desplazamiento dentro del búfer y una condición de carrera de tiempo de verificación/tiempo de uso en el mismo manejador.

Archivos

ArchivoDescripción
trigger.cMódulo del kernel del invitado que ejecuta las cuatro etapas de la PoC
MakefileConstruye contra el kernel del invitado en ejecución

Solución de problemas

  • not an SEV-SNP guest: QEMU no se inició con sev-snp-guest, o el SNP del anfitrión está desactivado.
  • QEMU SEV-SNP not supported: verifique /sys/module/kvm_amd/parameters/sev_snp, la configuración de la BIOS y los parámetros de arranque.
  • QEMU LAUNCH_START failed: el PSP no está inicializado. Verifique dmesg | grep psp y CONFIG_CRYPTO_DEV_SP_PSP=y.
  • No hay salida de KASAN: verifique CONFIG_KASAN=y y kasan_multi_shot en la línea de comandos del anfitrión.

Advertencia

Esto corrompe la memoria del montón del kernel del anfitrión, dispara KASAN y puede bloquear el anfitrión. Ejecútelo solo contra un anfitrión de prueba desechable que controle, dentro de una VM propia. No lo ejecute contra infraestructura compartida o de producción.

Referencias

  • Artículo: https://cyberstan.co.uk/sev-snp-oob/
  • CVE-2026-53360 (rastrear commit db3f219 en linux-cve-announce)
  • Corrección: db3f219, autor Mike Roth, revisado por Tom Lendacky, enviado por Paolo Bonzini
  • Introducido: 9b54e248d264; corrección etiquetada Fixes: 4af663c
  • Especificación GHCB, sección 2.1 (SW_SCRATCH debe estar dentro del búfer compartido del GHCB)

Licencia

trigger.c es GPL-2.0, coincidiendo con su MODULE_LICENSE. Ver LICENSE.

Descargar herramienta
trigger.ko
LICENSEGPL-2.0, coincidiendo con el MODULE_LICENSE del módulo