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-2024-21978-poc | Kitploit
Herramientas/GitHubGitHub/freax13/cve-2024-21978-poc
Herramientas de Cifrado/DescifradoForensia de MemoriaAnálisis de VulnerabilidadesExplotaciónPruebas de PenetraciónSeguridad de HardwareExplotación de Binarios
GitHubfreax13/cve-2024-21978-poc

cve-2024-21978-poc

Ver Repositorio
9hace 1 añoAún no revisado

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

Vulnerabilidad en el firmware SEV

Este repositorio contiene un exploit para una vulnerabilidad en el firmware SEV. El exploit permite descifrar memoria arbitraria de un invitado SEV-SNP en ejecución.

Probado en la versión 1.55.16 (la más reciente en el momento de escribir esto).

Causa raíz

El campo nv_paddr del comando SEV_INIT_EX se puede usar para donar un fragmento de memoria al firmware, de modo que pueda usarse en lugar de la memoria flash persistente. Si SEV-SNP está habilitado, esta memoria tiene que estar en el estado FIRMWARE. El firmware comprueba esto una sola vez mientras ejecuta el comando SEV_INIT_EX. A partir de ese momento, el firmware asume que esta memoria está en el estado FIRMWARE y escribe en ella sin comprobaciones adicionales. La suposición de que la memoria sigue en el estado FIRMWARE no siempre es correcta; nada impide que el host cambie el estado de nuevo al estado HYPERVISOR mediante el comando SNP_PAGE_RECLAIM. Una vez que las páginas están en el estado HYPERVISOR, se pueden transicionar a otros estados, por ejemplo, CONTEXT. Aunque las páginas ya no están en el estado FIRMWARE, el firmware escribirá en ellas, rompiendo así la integridad requerida por ciertos estados de página.

Exploit

Podemos explotar esta corrupción de memoria apuntando a páginas CONTEXT. Las páginas CONTEXT son un objetivo potente, pero hay algunos problemas:

  1. Las páginas CONTEXT están cifradas con una clave distinta a la del resto de la memoria. Como resultado, no es fácil controlar el texto plano incluso si pudiéramos controlar el texto cifrado.
  2. No tenemos mucho control sobre la memoria escrita por el firmware.

La corrupción de memoria efectivamente llena la página CONTEXT con datos aleatorios, por lo que no es fácil corromper las páginas CONTEXT de una manera que sea útil para el atacante. Para solucionar eso, podemos disparar el bug repetidamente para causar corrupción y usar el comando SNP_GUEST_STATUS para leer los campos relevantes de la página CONTEXT corrupta hasta que observemos valores que sean útiles.

El comando SNP_DBG_DECRYPT se puede usar para descifrar la memoria de un invitado SEV-SNP con la política DEBUG habilitada. Si podemos manipular un CONTEXT de modo que tenga el flag DEBUG activado y contenga el ASID de otro invitado, podemos usarlo para descifrar la memoria del otro invitado aunque este no tenga la política DEBUG configurada.

Resulta que SNP_DBG_DECRYPT ignora la mayoría de los campos en la página CONTEXT; solo comprueba gctx->guest.asid, gctx->guest.policy_snp y gctx->guest.guest_flags. La probabilidad de que estos campos sean correctos después de la corrupción de memoria no es alta, pero tampoco es imposible. La buena noticia es que también podemos leer todos esos campos usando el comando GUEST_STATUS.

En conclusión, podemos explotar el bug con los siguientes pasos:

  1. Transicionar nv_paddr al estado FIRMWARE usando la instrucción rmpupdate.
  2. Ejecutar el comando SEV_INIT_EX.
  3. Transicionar nv_paddr de nuevo al estado HYPERVISOR usando el comando SNP_RECLAIM_PAGE.
  4. Crear una o más páginas CONTEXT en nv_paddr.
  5. Engañar al firmware para que escriba en nv_paddr usando el comando SEV_PDH_GEN. Esto corrompe las páginas CONTEXT.
  6. Usar el comando GUEST_STATUS para comprobar si SNP_DBG_DECRYPT tendría éxito; si no es así, volver al paso 5. El principal cuello de botella aquí es que los ASID se almacenan en un int de 32 bits, pero hay muchos menos ASID válidos (509 o 1006 dependiendo de la CPU), por lo que se necesitarán bastantes intentos para que esto salga bien.

El exploit pasa la mayor parte del tiempo en los pasos 5 y 6. Las probabilidades de acertar todas las condiciones son de aproximadamente 1/20.000.000 en un EPYC Milan y podemos hacer alrededor de 100 intentos por segundo, por lo que esperamos acertar las condiciones aproximadamente una vez cada dos días (Advertencia: los cálculos son solo aproximaciones y puede que haya metido la pata en algo, pero anecdóticamente, una vez cada dos días parece correcto). Podemos acelerar esto no atacando una sola página CONTEXT a la vez, sino tres páginas CONTEXT en nv_paddr, nv_paddr+4096 y nv_paddr+8192 (SEV_PDG_GEN corromperá tres páginas). Convenientemente, esos pasos se pueden hacer antes de lanzar al invitado víctima y solo tienen que tener éxito una vez para atacar a un número arbitrario de invitados (aunque hay que tener en cuenta que el PoC actualmente ataca solo a un invitado).

Impacto

Aunque todavía no he podido probar esto, creo que una vez que un atacante haya usado esta vulnerabilidad para filtrar las claves de comunicación de la plataforma de la máquina virtual del invitado, debería poder enviar mensajes de invitado al firmware en nombre del invitado y usar esto para solicitar informes de atestación. Esto viola un principio clave de SEV-SNP en el que solo el invitado debería poder solicitar informes de atestación.

Mitigación

Algunos comandos (por ejemplo, SNP_RECLAIM_PAGE, SNP_GCTX_CREATE, RING_BUFFER, ¿quizás más?, ¿quizás todos para estar seguros?) que aceptan una página FIRMWARE deberían comprobar si se solapa con nv_paddr y fallar si es así.

Mitigaciones de actualización

Tengo una preocupación más, que no estoy seguro de que sea válida y me encantaría escuchar su opinión: Si entiendo correctamente, el firmware SEV se puede actualizar sin interrumpir a los invitados en ejecución. Esto me sugiere que sería posible transferir la página CONTEXT corrupta de una versión antigua vulnerable del firmware a una versión nueva corregida. ¿Sería posible comenzar con una versión antigua vulnerable, hacer el exploit descrito anteriormente, actualizar y confirmar el nuevo firmware corregido, lanzar el invitado con el nuevo firmware (para que la versión antigua del firmware no aparezca en el informe de atestación) y luego usar la página CONTEXT corrupta creada con el firmware antiguo para atacar al invitado creado con la nueva versión? ¿Podría un consumidor de los informes de atestación generados por el nuevo invitado saber que la versión antigua del firmware se estaba ejecutando en algún momento antes de que se lanzara el nuevo invitado? Si no es así, ¿se requieren más mitigaciones para evitar que esto suceda?

Uso del PoC

  1. Aplicar los parches de la carpeta linux-patches al último commit de https://github.com/AMDESE/linux/commits/snp-host-v10. Compilar, instalar e iniciar el kernel.
  2. Ejecutar el PoC.
    root@kitploit:~
    root@server:~/sev-exploit# cargo run --release
        Finished release [optimized] target(s) in 0.12s
        Running `target/release/sev-exploit`
    Corrupt guest context page so that ASID is in range 1..510
    Smallest ASID: 0x0000001f iterations: 14052175 zeros: 10539628 unique asids: 31500727 elapsed time: 1d 19h 20m 31s
    Creating VM with same ASID
    [03, 00, 00, 00, 00, 00, 00, 00, 11, 0f, a0, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, f0, 51, a5, 03, 3f, 69, 6b, 93, e8, d8, 61, 0d, 2e, 5a, 45, f1, ea, 6d, bf, 49, fe, e4, a9, 2d, 8d, af, 76, 5e, 2e, 56, e0, fa, a9, b3, a7, e0, bc, 09, d9, 4f, 28, 5c, 9f, 84, d2, 7e, 34, eb, ea, 3f, 29, 88, 30, 01, 28, 65, 8b, 73, 3c, 84, 00, ae, 4a, 74, a2, 7a, d1, c7, 4f, 63, 7f, 72, 7b, 3b, 2f, 08, b3, 1a, 8c, 99, 1b, ad, b5, 1d, 42, 0b, 4d, 98, d4, 7d, c1, 0b, d6, 2f, b4, 6c, 6b, 51, a2, 92, 17, 3b, 01, e8, 82, 11, 1e, cb, cb, a2, 8f, c9, b0, 52, 1d, 1d, b7, d2, 25, 8d, 32, a9, 7a, 6f, 86, e4, 40, 44, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 80, 00, 88, 00, 00, 00, 00, ee, ff, 00, 00, f0, ff, ff, ff, ff, ff, ff, ff, ff, 3f, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, <cut off zeros>]
    thread 'main' panicked at src/main.rs:170:13:
    not yet implemented: use the leaked secrets to send guest messages
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    

Ten en cuenta que es normal que el exploit se ejecute durante un tiempo significativo (del orden de horas si tienes suerte, días si no la tienes). Ejecutarlo en un EPYC Genoa probablemente será más rápido porque hay casi el doble de ASID válidos.

Durante los pasos 5 y 6 el PoC muestra algunas métricas:

  • "Smallest ASID": El ASID más pequeño encontrado hasta ahora. Es solo una métrica de verificación para asegurarse de que con el tiempo se encuentren ASID cada vez más pequeños.
  • "iterations": Esta métrica se incrementa cada vez que se dispara el bug.
  • "zeroes": En aproximadamente 1/4 de los casos, la página CONTEXT está en un estado en el que el firmware considera que aún no se le ha asignado un ASID. En esos casos, SNP_GUEST_STATUS devolverá 0 en el campo ASID.
  • "unique asids": Otra métrica de verificación para asegurarse de que los ASID son aleatorios y no se repiten después de un tiempo.
  • "elapsed time": Duración desde que se inició el PoC.

En la mayoría de los casos, retirar las páginas CONTEXT corruptas causa un fallo del firmware (muy probablemente aquí). Hasta donde sé, los fallos del firmware provocan un reinicio de todo el sistema. Para evitar tales fallos, los parches del kernel evitan que las páginas CONTEXT puedan ser retiradas. Un inconveniente de esto es que el módulo del kernel ccp no se puede descargar. Una vez que el PoC se ha iniciado, todo el sistema debe reiniciarse antes de poder iniciarlo de nuevo (independientemente de si el PoC tuvo éxito o fue abortado).

Descargar herramienta
  • Lanzar (y opcionalmente ejecutar) un invitado víctima usando el ASID corrupto en la página CONTEXT corrupta. Llevar un registro de la página de secretos. Esto es posible porque el firmware SEV rastrea los ASID activos internamente y no consulta las páginas CONTEXT activas para comprobar duplicados.
  • Usar la página CONTEXT corrupta para ejecutar SNP_DBG_DECRYPT sobre la página de secretos del invitado víctima.