Carga de confianza de Schrödinger. Intel Boot Guard

Carga de confianza de Schrödinger. Intel Boot Guard
Proponemos descender nuevamente a un nivel bajo y hablar sobre la seguridad de los firmware de plataformas informáticas compatibles con x86. Esta vez, el ingrediente principal de la investigación es Intel Boot Guard (no confundir con Intel BIOS Guard) – una tecnología de arranque seguro del BIOS, respaldada por hardware, que el proveedor del sistema informático puede activar o desactivar permanentemente en la etapa de producción. Y la receta de la investigación ya nos es familiar: desmenuzar con ingeniería inversa la implementación de esta tecnología, describir su arquitectura, llenándola con detalles no documentados, condimentar al gusto con vectores de ataque y mezclar. Añadiremos un poco de fuego contando cómo un error de producción que ha sido clonado durante años en varios proveedores permite a un potencial atacante aprovechar esta tecnología para crear un rootkit oculto en el sistema que no puede ser eliminado (ni siquiera por un programador).

Por cierto, la base del artículo son las presentaciones "A la defensiva contra los rootkits: Intel BootGuard" en la conferencia ZeroNights 2016 y el 29º encuentro DefCon Russia (ambas presentaciones aquí).

Firmware de plataformas informáticas con arquitectura Intel 64

Para comenzar, respondamos a la pregunta: ¿qué es el firmware de una plataforma informática moderna con arquitectura Intel 64? Por supuesto, es el UEFI BIOS. Pero esa respuesta no sería precisa. Echemos un vistazo a la imagen que muestra la variante de escritorio (o portátil) de esta arquitectura.

Carga de confianza de Schrödinger. Intel Boot Guard
La base es la combinación:

  • Del procesador (CPU, Unidad Central de Procesamiento), que además de los núcleos principales, incluye una unidad gráfica (no en todos los modelos) y un controlador de memoria integrado (IMC, Integrated Memory Controller);
  • Del chipset (PCH, Hub de Controlador de Plataforma), que contiene diversos controladores para interactuar con dispositivos periféricos y gestionar subsistemas. Entre ellos se encuentra la conocida Intel Management Engine (ME), que también posee su propio firmware (firmware de Intel ME).

Los portátiles, además de lo mencionado, suponen la presencia de un controlador integrado (ACPI EC, Controlador Embebido de Interfaz de Control y Alimentación Avanzada), que se encarga del funcionamiento del subsistema de alimentación, del touchpad, del teclado, de las teclas Fn (brillo de pantalla, volumen, retroiluminación del teclado, etc.) y de otros elementos. Y también tiene su propio firmware.

Así que la combinación de los firmware mencionados constituye el firmware de la plataforma informática (system firmware), que se almacena en la memoria flash SPI compartida. Para que los usuarios de esta memoria no se confundan sobre la ubicación de los datos, el contenido de esta memoria se divide en las siguientes regiones (como se muestra en la figura):

  • UEFI BIOS;
  • firmware ACPI EC (una región separada apareció con la microarquitectura del procesador Skylake en 2015, pero hasta ahora no hemos visto ejemplos de su uso en la práctica, así que el firmware del controlador integrado sigue formando parte del UEFI BIOS);
  • firmware Intel ME;
  • configuración (dirección MAC, etc.) del adaptador de red integrado GbE (Gigabit Ethernet);
  • descriptores flash (Flash Descriptors) – la región principal de la memoria flash que contiene punteros a las demás regiones, así como permisos para acceder a ellas.

Carga de confianza de Schrödinger. Intel Boot Guard
La delimitación de acceso a las regiones (de acuerdo con los permisos establecidos) es gestionada por el maestro del bus SPI – un controlador SPI integrado en el chipset, a través del cual se accede a esta memoria. Si los permisos están establecidos en los valores recomendados (por razones de seguridad) por Intel, entonces cada usuario de la memoria flash SPI tiene acceso completo (lectura/escritura) solo a su región. Las demás regiones son accesibles solo para lectura o no son accesibles en absoluto. Un hecho conocido es que en muchos sistemas, la CPU tiene acceso completo al UEFI BIOS y al GbE, acceso de lectura únicamente a los descriptores flash, y no tiene acceso a la región de Intel ME en absoluto. ¿Por qué en muchos y no en todos? Lo que se recomienda no es necesariamente obligatorio. Más detalles serán discutidos más adelante en el artículo.

Mecanismos de protección del firmware de la plataforma informática contra modificaciones

Es evidente que el firmware de la plataforma informática debe protegerse contra posibles compromisos que permitan a un atacante potencial asentarse en él (sobrevivir a actualizaciones/reinstalaciones del sistema operativo), ejecutar su código en los modos más privilegiados, etc. Y la delimitación del acceso a las regiones de la memoria flash SPI, por supuesto, no es suficiente. Por lo tanto, se aplican varios mecanismos para proteger el firmware contra modificaciones, específicos para cada entorno de ejecución.

Así, el firmware Intel ME está firmado para controlar la integridad y autenticidad, y es verificado por el controlador ME en cada carga en la memoria ME UMA. Este proceso de verificación ya lo hemos discutido en uno de los artículos, dedicada al subsistema Intel ME.

El firmware de ACPI EC, por lo general, solo se verifica por su integridad. Sin embargo, dado que este binario está incluido en el UEFI BIOS, casi siempre está sujeto a los mismos mecanismos de protección que utiliza el UEFI BIOS. De eso hablaremos.

Estos mecanismos se pueden clasificar en dos categorías.

Protección contra escritura en la región del UEFI BIOS

  1. Protección física del contenido de la memoria flash SPI mediante el jumper de protección contra escritura;
  2. Protección de la proyección de la región del UEFI BIOS en el espacio de direcciones de la CPU usando los registros PRx del chipset;
  3. Bloqueo de intentos de escritura en la región del UEFI BIOS mediante la generación y manejo de la interrupción SMI correspondiente al establecer los bits BIOS_WE/BLE y SMM_BWP en los registros del chipset;
  4. Una variante más avanzada de tal protección es Intel BIOS Guard (PFAT).

Además de estos mecanismos, los proveedores pueden desarrollar y aplicar sus propias medidas de seguridad (por ejemplo, la firma de cápsulas con actualizaciones del UEFI BIOS).

Es importante señalar que en un sistema específico (dependiendo del proveedor) pueden no aplicarse todos los mecanismos de protección mencionados anteriormente, pueden no ser aplicados del todo, o pueden implementarse de manera vulnerable. Para obtener más información sobre estos mecanismos y la situación de su implementación, se puede leer en este artículo. Recomendamos a los interesados que se familiaricen con todo el ciclo de artículos sobre la seguridad del UEFI BIOS de CodeRush.

Verificación de la autenticidad del UEFI BIOS

Cuando hablamos de tecnologías de arranque confiable, lo primero que viene a la mente es Secure Boot. Sin embargo, arquitectónicamente está diseñado para verificar la autenticidad de los componentes externos, en relación con el UEFI BIOS (controladores, cargadores, etc.), y no del propio firmware.

Por lo tanto, Intel implementó Secure Boot (Verified Boot) no apagado en los SoC con arquitectura Bay Trail (2012), que no tiene nada que ver con la tecnología Secure Boot mencionada anteriormente. Posteriormente (2013), este mecanismo fue mejorado y lanzado como Intel Boot Guard para escritorios con arquitectura Haswell.

Antes de describir Intel Boot Guard, aclaremos los entornos de ejecución en la arquitectura Intel 64, que, a su vez, son las raíces de confianza para esta tecnología de arranque confiable.

Intel CPU

Cap señala que el procesador es el principal entorno de ejecución en la arquitectura Intel 64. ¿Por qué es también la raíz de confianza? Resulta que su propiedad de poseer los siguientes elementos lo convierte en tal:

  • El ROM de microcódigo es una memoria no volátil y no regrabable que almacena microcódigo. Se considera que el microcódigo es la implementación del conjunto de instrucciones del procesador en instrucciones básicas. También pueden ocurrir errores en el microcódigo. errores. Por lo tanto, en la BIOS se pueden encontrar binarios con actualizaciones de microcódigo (se superponen durante el arranque, ya que el ROM no puede ser regrabado). El contenido de estos binarios está cifrado, lo que dificulta significativamente su análisis (por lo tanto, el contenido específico del microcódigo solo lo conocen aquellos que lo desarrollan) y está firmado para el control de integridad y autenticidad;
  • clave AES para descifrar el contenido de las actualizaciones de microcódigo;
  • hash de la clave pública RSA, que verifica la firma de las actualizaciones de microcódigo;
  • hash de la clave pública RSA, que verifica la firma de los módulos de código autenticados ACM (Authenticated Code Module) desarrollados por Intel, que la CPU puede ejecutar antes del inicio de la ejecución de la BIOS (hola microcódigo) o durante su funcionamiento, en ciertos eventos.

Intel ME

Esta subsistema ha sido objeto de atención en nuestro blog. dos artículoRecordemos que este entorno ejecutable se basa en un microcontrolador integrado en el chipset y es el más oculto y privilegiado del sistema.

A pesar de su ocultamiento, Intel ME también es la raíz de la confianza, ya que posee:

  • ROM de ME: una memoria no volátil y no regrabable (no hay forma de actualizarla), que contiene el código de arranque, así como el hash SHA256 de la clave pública RSA, que verifica la firma del firmware de Intel ME;
  • clave AES para almacenar información secreta;
  • acceso al conjunto de fusibles programables en fábrica (FPFs, Field Programmable Fuses) integrado en el chipset para el almacenamiento permanente de cierta información, incluida la proporcionada por el vendedor del sistema informático.

Intel Boot Guard 1.x

Un pequeño descargo de responsabilidad. Los números de versión de la tecnología Intel Boot Guard que manejamos en este artículo son condicionales y pueden no tener relación con la numeración utilizada en la documentación interna de Intel. Además, la información presentada aquí sobre la implementación de esta tecnología se obtuvo mediante ingeniería inversa y puede contener inexactitudes en comparación con la especificación de Intel Boot Guard, que probablemente nunca será publicada.

Intel Boot Guard (BG) es una tecnología de verificación de autenticidad del BIOS UEFI respaldada por hardware. Según su breve descripción en el libro [Platform Embedded Security Technology Revealed, capítulo Boot with Integrity, or Not Boot], funciona como una cadena de arranque de confianza. El primer eslabón en esta cadena es el código de arranque (microcódigo) dentro del CPU, que se activa con el evento RESET (no confundir con el vector RESET en el BIOS). El CPU encuentra en la memoria flash SPI un módulo de código diseñado y firmado por Intel (Intel BG startup ACM), lo carga en su caché, lo verifica (como se mencionó anteriormente, el CPU tiene un hash de la clave pública que se usa para verificar la firma del ACM) y lo ejecuta.

Carga de confianza de Schrödinger. Intel Boot Guard

Este módulo de código es responsable de verificar una pequeña parte inicial del BIOS UEFI — Initial Boot Block (IBB), que a su vez contiene la funcionalidad para verificar la parte principal del BIOS UEFI. Así, Intel BG permite asegurarse de la autenticidad del BIOS antes de cargar el sistema operativo (que puede ejecutarse bajo la vigilancia de la tecnología Secure Boot).

La tecnología Intel BG contempla dos modos de operación (y uno no interfiere con el otro, es decir, ambos modos pueden estar habilitados en el sistema, o ambos pueden estar deshabilitados).

Arranque Medido

En el modo Arranque Medido (MB), cada componente de arranque (comenzando desde el ROM de arranque del CPU) "mide" al siguiente, utilizando las capacidades del TPM (Módulo de Plataforma de Confianza). Para aquellos que no están familiarizados, vamos a aclararlo.

El TPM tiene PCR (Registros de Configuración de Plataforma), donde se almacena el resultado de la operación de hash según la fórmula:

Carga de confianza de Schrödinger. Intel Boot Guard

Es decir, el valor actual de los PCR depende del anterior, mientras que estos registros se restablecen solo en el RESET del sistema.

Por lo tanto, en el modo MB, en un momento dado, los PCR reflejan un identificador único (dentro de las capacidades de la operación de hash) del código o datos que han sido "medidos". Los valores de PCR pueden ser utilizados durante la operación de cifrado de algunos datos (TPM_Seal). Después, su descifrado (TPM_Unseal) solo será posible si los valores de PCR no han cambiado durante el arranque (es decir, ningún componente "medido" ha sido modificado).

Arranque Verificado

Lo más aterrador para los entusiastas de modificar el BIOS UEFI es el modo Arranque Verificado (VB), en el cual cada componente de arranque verifica criptográficamente la integridad y autenticidad del siguiente. Y en caso de error de verificación, ocurre (una de):

  • apagado por tiempo de espera de 1 minuto a 30 minutos (para que el usuario pueda entender por qué su computadora no arranca y, si es posible, intente restaurar el BIOS);
  • apagado inmediato (para que el usuario no tenga tiempo para entender nada y, mucho menos, hacer algo);
  • continuar trabajando con una expresión serena (ese caso en el que la seguridad no es prioritaria, ya que hay asuntos más importantes).

La elección de la acción depende de la configuración de Intel BG (específicamente, de la llamada enforcement policy), que el vendedor de la plataforma informática registra permanentemente en un almacenamiento especialmente designado: los fusibles del chipset (FPF). Hablaremos de este punto más adelante.

Además de la configuración, el vendedor genera dos claves RSA de 2048 y crea dos estructuras de datos (como se muestra en la imagen):

  1. El manifiesto de la clave raíz del vendedor (KEYM, OEM Root Key Manifest), en el que se incluye el SVN (Security Version Number) de este manifiesto, el hash SHA256 de la clave pública del siguiente manifiesto, la clave pública RSA (es decir, la parte pública de la clave raíz del vendedor) para verificar la firma de este manifiesto y la propia firma;
  2. El manifiesto IBB (IBBM, Initial Boot Block Manifest), en el que se incluye el SVN de este manifiesto, el hash SHA256 IBB, la clave pública para verificar la firma de este manifiesto y la propia firma.

El hash SHA256 de la clave pública OEM Root Key se graba permanentemente en los fusibles del chipset (FPF), al igual que la configuración de Intel BG. Si la configuración de Intel BG permite activar esta tecnología, a partir de ese momento solo el poseedor de la parte privada de la OEM Root Key, es decir, el vendedor, podrá actualizar el BIOS (es decir, tener la capacidad de recalcular estos manifiestos) en este sistema.

Carga de confianza de Schrödinger. Intel Boot Guard

Al observar la imagen, surgen dudas sobre la necesidad de una cadena de verificación tan larga: se podría haber utilizado un solo manifiesto. ¿Por qué complicar las cosas?

En realidad, Intel permite al vendedor utilizar diferentes claves IBB para distintas líneas de productos y una como raíz. Si se filtra la parte privada de la clave IBB (que firma el segundo manifiesto), el incidente solo afectará a una línea de productos y solo hasta que el vendedor genere un nuevo par y reintegre los manifiestos recalculados en la siguiente actualización del BIOS.

Pero si se ve comprometida la clave raíz (con la que se firma el primer manifiesto), no podrá reemplazarse, ya que no hay procedimientos de revocación previstos, porque el hash de la parte pública de esta clave se programa en FPF una sola vez y para siempre.

Configuración de Intel Boot Guard

Ahora nos detendremos en la configuración de Intel BG y el proceso de su creación. Si miramos la pestaña correspondiente en la herramienta Flash Image Tool del conjunto Intel System Tool Kit (STK), podemos notar que la configuración de Intel BG incluye el hash de la parte pública de la clave raíz del proveedor, un par de valores poco claros y el llamado perfil de Intel BG.

Carga de confianza de Schrödinger. Intel Boot Guard

Estructura de este perfil:

typedef struct BG_PROFILE
{
	unsigned long Force_Boot_Guard_ACM : 1;
	unsigned long Verified_Boot : 1;
	unsigned long Measured_Boot : 1;
	unsigned long Protect_BIOS_Environment : 1;
	unsigned long Enforcement_Policy : 2; // 00b – no hacer nada
                                              // 01b – apagarse con tiempo de espera
                                              // 11b – apagado inmediato
	unsigned long : 26;
};

En general, la configuración de Intel BG es una entidad muy flexible. Consideremos, por ejemplo, el indicador Force_Boot_Guard_ACM. Cuando está desactivado, si no se encuentra el módulo BG startup ACM en la memoria flash SPI, no habrá ninguna carga confiable. Será no confiable.

Como mencionamos anteriormente, la política de aplicación para el modo VB se puede configurar de manera que en caso de error de verificación, nuevamente ocurra una carga no confiable.

Dejar tales decisiones a criterio de los proveedores...

La interfaz gráfica de la herramienta prevé los siguientes perfiles "listos":

Número
Modo
Descripción

0
No_FVME
tecnología Intel BG desactivada

1
VE
modo VB activado, apagado por tiempo de espera

2
VME
ambos modos (VB y MB) activados, apagado por tiempo de espera

3
VM
ambos modos activados, sin apagado del sistema

4
FVE
modo VB activado, apagado inmediato

5
FVME
ambos modos activados, apagado inmediato

Como se mencionó, la configuración de Intel BG debe ser programada de forma permanente por el proveedor del sistema en los fusibles del chipset (FPF) - un pequeño (según información no verificada, solo 256 bytes) almacenamiento físico de información dentro del chipset, que puede ser programado fuera de las instalaciones de producción de la compañía Intel (por lo que, precisamente Field Programmable Fuses).

Es ideal para almacenar configuración, ya que:

  • tiene un área programable una vez para almacenar datos (justo allí es donde se registra la configuración de Intel BG);
  • solo Intel ME puede leer y programarlo.

Entonces, para configurar la tecnología Intel BG en un sistema específico, el proveedor realiza lo siguiente durante la producción:

  1. Usando la herramienta Flash Image Tool (de Intel STK), crea una imagen de firmware con la configuración deseada de Intel BG en forma de variables dentro de la región Intel ME (el llamado espejo temporal para los FPF);
  2. Con la herramienta Flash Programming Tool (de Intel STK), graba esta imagen en la memoria flash SPI del sistema y cierra el denominado modo de fabricación (durante este proceso, se envía el comando correspondiente a Intel ME).

Como resultado de estas operaciones, Intel ME confirmará en los FPF los valores establecidos desde el espejo para los FPF en la región ME, asignará los permisos en los descriptores de memoria flash SPI a los valores recomendados por Intel (descrito al inicio del artículo) y realizará un RESET del sistema.

Análisis de la implementación de Intel Boot Guard

Con el fin de analizar la implementación de esta tecnología en un ejemplo específico, hemos verificado los siguientes sistemas en busca de rastros de la tecnología Intel BG:

Sistema
Nota

Gigabyte GA-H170-D3H
Skylake, hay soporte

Gigabyte GA-Q170-D3H
Skylake, hay soporte

Gigabyte GA-B150-HD3
Skylake, hay soporte

MSI H170A Gaming Pro
Skylake, no hay soporte

Lenovo ThinkPad 460
Skylake, hay soporte, tecnología habilitada

Lenovo Yoga 2 Pro
Haswell, no hay soporte

Lenovo U330p
Haswell, no hay soporte

Por 'soporte' entendemos la presencia de un módulo ACM de arranque de Intel BG, los manifiestos mencionados anteriormente y el código correspondiente en la BIOS, es decir, la implementación para el análisis.

Como ejemplo, tomemos la imagen de memoria flash SPI descargada del sitio oficial del proveedor para Gigabyte GA-H170-D3H (versión F4).

Intel CPU boot ROM

Primero, hablemos de las acciones del procesador en caso de que la tecnología Intel BG esté habilitada.

No se logró encontrar muestras del microcódigo descifrado, por lo que cómo se implementan las acciones descritas a continuación (en microcódigo o a nivel de hardware) sigue siendo una pregunta abierta. Sin embargo, el hecho de que los procesadores Intel modernos 'pueden' realizar estas acciones es un hecho.

Después de salir del estado de RESET, el procesador (cuyo espacio de direcciones ya ha asignado el contenido de la memoria flash) encuentra la tabla FIT (Firmware Interface Table). Es fácil encontrarla, el puntero a ella está grabado en la dirección FFFF FFC0h.

Carga de confianza de Schrödinger. Intel Boot Guard
En el ejemplo considerado, en esta dirección está el valor FFD6 9500h. Al acceder a esta dirección, el procesador ve la tabla FIT, cuyo contenido se divide en entradas. La primera entrada es el encabezado de la siguiente estructura:

typedef struct FIT_HEADER
{
	char           Tag[8];     // ‘_FIT_ ’
	unsigned long  NumEntries; // incluyendo la entrada del encabezado de FIT
	unsigned short Version;    // 1.0
	unsigned char  EntryType;  // 0
	unsigned char  Checksum;
};

Carga de confianza de Schrödinger. Intel Boot Guard
Por razones desconocidas, el checksum no siempre se calcula en estas tablas (el campo se deja en cero).

Las demás entradas indican diversos binarios que deben ser analizados/ejecutados antes de la ejecución de BIOS, es decir, antes de pasar al vector de reinicio de legado (FFFF FFF0h). La estructura de cada una de estas entradas es la siguiente:

typedef struct FIT_ENTRY
{
	unsigned long  BaseAddress;
	unsigned long  : 32;
	unsigned long  Size;
	unsigned short Version;     // 1.0
	unsigned char  EntryType;
	unsigned char  Checksum;
};

Carga de confianza de Schrödinger. Intel Boot Guard
El campo EntryType indica el tipo de bloque al que apunta esta entrada. Conocemos varios tipos:

enum FIT_ENTRY_TYPES
{
	FIT_HEADER = 0,
	MICROCODE_UPDATE,
	BG_ACM,
	BIOS_INIT = 7,
	TPM_POLICY,
	BIOS_POLICY,
	TXT_POLICY,
	BG_KEYM,
	BG_IBBM
};

Ahora es evidente que una de las entradas apunta a la ubicación del binario Intel BG startup ACM. La estructura del encabezado de este binario es típica de los módulos de código desarrollados por Intel (ACMs, actualizaciones de microcódigo, secciones de código de Intel ME, …).

typedef struct BG_ACM_HEADER
{
	unsigned short ModuleType;     // 2
	unsigned short ModuleSubType;  // 3
	unsigned long  HeaderLength;   // en DWORDs
	unsigned long  : 32;
	unsigned long  : 32;
	unsigned long  ModuleVendor;   // 8086h
	unsigned long  Date;           // en formato BCD
	unsigned long  TotalSize;      // en DWORDs
	unsigned long  unknown1[6];
	unsigned long  EntryPoint;
	unsigned long  unknown2[16];
	unsigned long  RsaKeySize;     // en DWORDs
	unsigned long  ScratchSize;    // en DWORDs
	unsigned char  RsaPubMod[256];
	unsigned long  RsaPubExp;
	unsigned char  RsaSig[256];
};

Carga de confianza de Schrödinger. Intel Boot Guard
El procesador carga este binario en su caché, lo verifica y lo ejecuta.

Intel BG startup ACM

Como resultado del análisis del funcionamiento de este ACM, se hizo evidente que hace lo siguiente:

  • recibe de Intel ME la configuración de Intel BG, escrita en los fusibles del chip (FPFs);
  • encuentra los manifiestos KEYM e IBBM y los verifica.

Para encontrar estos manifiestos, el ACM también utiliza la tabla FIT, en la que se han reservado dos tipos de entradas para señalar los datos de la estructura (ver FIT_ENTRY_TYPES arriba).

Detengámonos un momento en los manifiestos. En la estructura del primer manifiesto vemos varias constantes confusas, el hash de la clave pública del segundo manifiesto y la clave pública OEM Root Key con una firma en forma de estructura anidada:

typedef struct KEY_MANIFEST
{
	char           Tag[8];          // ‘__KEYM__’
	unsigned char  : 8;             // 10h
	unsigned char  : 8;             // 10h
	unsigned char  : 8;             // 0
	unsigned char  : 8;             // 1
	unsigned short : 16;            // 0Bh
	unsigned short : 16;            // 20h == ¿tamaño del hash?
	unsigned char  IbbmKeyHash[32]; // SHA256 de una clave pública de IBBM
	BG_RSA_ENTRY   OemRootKey;
};

typedef struct BG_RSA_ENTRY
{
	unsigned char  : 8;             // 10h
	unsigned short : 16;            // 1
	unsigned char  : 8;             // 10h
	unsigned short RsaPubKeySize;   // 800h
	unsigned long  RsaPubExp;
	unsigned char  RsaPubKey[256];
	unsigned short : 16;            // 14
	unsigned char  : 8;             // 10h
	unsigned short RsaSigSize;      // 800h
	unsigned short : 16;            // 0Bh
	unsigned char  RsaSig[256];
};

Carga de confianza de Schrödinger. Intel Boot Guard
Para la verificación de la clave pública de la OEM Root Key, recordemos que se utiliza un hash SHA256 de los fusibles, que ya ha sido obtenido de Intel ME.

Pasemos al segundo manifiesto. Está compuesto por tres estructuras:

typedef struct IBB_MANIFEST
{
	ACBP Acbp;         // Políticas de arranque
	IBBS Ibbs;         // Descripción de IBB
	IBB_DESCRIPTORS[];
	PMSG Pmsg;         // Firma de IBBM
};

En la primera – hay algunas constantes:

typedef struct ACBP
{
	char           Tag[8];          // ‘__ACBP__’
	unsigned char  : 8;             // 10h
	unsigned char  : 8;             // 1
	unsigned char  : 8;             // 10h
	unsigned char  : 8;             // 0
	unsigned short : 16;            // x & F0h = 0
	unsigned short : 16;            // 0 < x <= 400h
};

En la segunda se encuentra el hash SHA256 de IBB y el número de descriptore que describen el contenido de IBB (es decir, de lo que se calcula el hash):

typedef struct IBBS
{
	char           Tag[8];            // ‘__IBBS__’
	unsigned char  : 8;               // 10h
	unsigned char  : 8;               // 0
	unsigned char  : 8;               // 0
	unsigned char  : 8;               // x <= 0Fh
	unsigned long  : 32;              // x & FFFFFFF8h = 0
	unsigned long  Unknown[20];
	unsigned short : 16;              // 0Bh
	unsigned short : 16;              // 20h == ¿tamaño del hash?
	unsigned char  IbbHash[32];       // SHA256 de un IBB
	unsigned char  NumIbbDescriptors;
};

Los descriptores de IBB siguen a esta estructura, uno tras otro. Su contenido tiene el siguiente formato:

typedef struct IBB_DESCRIPTOR
{
	unsigned long  : 32;
	unsigned long  BaseAddress;
	unsigned long  Size;
};

Es sencillo: cada descriptor contiene la dirección/tamaño de un fragmento de IBB. Así, la concatenación de los bloques a los que apuntan estos descriptores (en el orden en que están los descriptores) es el IBB. Y, por lo general, el IBB es la colección de todos los módulos de las fases SEC y PEI.

El segundo manifiesto finaliza con una estructura que contiene la clave pública de IBB (que se verifica mediante el hash SHA256 del primer manifiesto) y la firma de este manifiesto:

typedef struct PMSG
{
	char           Tag[8];            // ‘__PMSG__’
	unsigned char  : 8;               // 10h
	BG_RSA_ENTRY   IbbKey;
};

Carga de confianza de Schrödinger. Intel Boot Guard
Así que, incluso antes de que se ejecute el UEFI BIOS, el procesador iniciará el ACM, que verificará la autenticidad de los contenidos de las secciones del código de fase SEC y PEI. Luego, el procesador sale del ACM, salta a la dirección RESET y comienza a ejecutar el BIOS.

La sección PEI verificada debe contener un módulo que comprobó el resto del BIOS (código DXE). Este módulo es desarrollado por el IBV (Independent BIOS Vendor) o por el propio proveedor del sistema. Dado que los sistemas que tenemos a nuestra disposición y que tienen soporte para Intel BG son solo sistemas Lenovo y Gigabyte, examinaremos el código extraído de estos sistemas.

Módulo UEFI BIOS LenovoVerifiedBootPei

En el caso de Lenovo, se trató del módulo LenovoVerifiedBootPei {B9F2AC77-54C7-4075-B42E-C36325A9468D}, desarrollado por la empresa Lenovo.

Su función es buscar (por GUID) la tabla de hashes para DXE y verificar DXE.

if (EFI_PEI_SERVICES->GetBootMode() != BOOT_ON_S3_RESUME)
{
	if (!FindHashTable())
		return EFI_NOT_FOUND;
	if (!VerifyDxe())
		return EFI_SECURITY_VIOLATION;
}

La tabla de hashes {389CC6F2-1EA8-467B-AB8A-78E769AE2A15} tiene el siguiente formato:

typedef struct HASH_TABLE
{
	char          Tag[8];            // ‘$HASHTBL’
	unsigned long NumDxeDescriptors;
	DXE_DESCRIPTORS[];
};

typedef struct DXE_DESCRIPTOR
{
	unsigned char BlockHash[32];     // SHA256
	unsigned long Offset;
	unsigned long Size;
};

Módulo UEFI BIOS BootGuardPei

En el caso de Gigabyte, se trató del módulo BootGuardPei {B41956E1-7CA2-42DB-9562-168389F0F066}, desarrollado por AMI, por lo tanto, está presente en cualquier BIOS AMI que soporte Intel BG.

Su algoritmo de funcionamiento es algo diferente, pero se reduce a lo mismo:

int bootMode = EFI_PEI_SERVICES->GetBootMode();

if (bootMode != BOOT_ON_S3_RESUME &&
    bootMode != BOOT_ON_FLASH_UPDATE &&
    bootMode != BOOT_IN_RECOVERY_MODE)
{
	HOB* h = CreateHob();
	if (!FindHashTable())
		return EFI_NOT_FOUND;
	WriteHob(&h, VerifyDxe());
	return h;
}

La tabla de hashes {389CC6F2-1EA8-467B-AB8A-78E769AE2A15} que busca tiene el siguiente formato:

typedef HASH_TABLE DXE_DESCRIPTORS[];

typedef struct DXE_DESCRIPTOR
{
	unsigned char BlockHash[32];     // SHA256
	unsigned long BaseAddress;
	unsigned long Size;
};

Intel Boot Guard 2.x

Hablemos brevemente de otra implementación de Intel Boot Guard que se encontró en un sistema más nuevo basado en Intel SoC con la microarquitectura Apollo Lake: ASRock J4205-IT.

Aunque esta versión solo se aplicará a los SoC (los nuevos sistemas con la microarquitectura de procesador Kaby Lake siguen usando Intel Boot Guard 1.x), es muy interesante al estudiar una nueva variante de la arquitectura para plataformas en Intel SoC, en la que se han producido cambios significativos, como:

  • las regiones de BIOS y Intel ME (más correctamente Intel TXE, según la terminología para Intel SoC) ahora son una sola región IFWI;
  • Aunque la plataforma tenía habilitado Intel BG, no se encontraron estructuras como FIT, KEYM, IBBM en la memoria flash;
  • Además de los núcleos TXE e ISH (x86), el chipset añadió un tercer núcleo (de nuevo ARC, por cierto) – PMC (Controlador de Gestión de Energía), relacionado con la operación del subsistema de energía y el monitoreo del rendimiento.

Carga de confianza de Schrödinger. Intel Boot Guard
El contenido de la nueva región IFWI consiste en un conjunto de los siguientes módulos:

Desplazamiento
Nombre
Descripción

0000 2000h
SMIP
una configuración de plataforma, firmada por el proveedor

0000 6000h
RBEP
sección de código del firmware Intel TXE, x86, firmada por Intel

0001 0000h
PMCP
sección de código del firmware Intel PMC, ARC, firmada por Intel

0002 0000h
FTPR
sección de código del firmware Intel TXE, x86, firmada por Intel

0007 B000h
UCOD
actualizaciones de microcódigo para CPU, firmadas por Intel

0008 0000h
IBBP
UEFI BIOS, fases SEC/PEI, x86, firmada por el proveedor

0021 8000h
ISHC
sección de código del firmware Intel ISH, x86, firmada por el proveedor

0025 8000h
NFTP
sección de código del firmware Intel TXE, x86, firmada por Intel

0036 1000h
IUNP
desconocido

0038 1000h
OBBP
UEFI BIOS, fase DXE, x86, no firmada

Durante el análisis del firmware TXE, quedó claro que después de un RESET, TXE mantiene el procesador en este estado hasta que prepara el contenido básico del espacio de direcciones para la CPU (FIT, ACM, vector de RESET...). Además, TXE almacena estos datos en su SRAM, después de lo cual permite temporalmente al procesador acceder a ellos y "libera" al procesador del RESET.

En guardia contra rootkits

Ahora pasemos a lo "caliente". Una vez descubrimos que en muchos sistemas, los descriptores de flash SPI tenían asignados permisos de acceso a las regiones de la memoria flash SPI, de forma que todos los usuarios de esta memoria podían escribir y leer cualquier región. Es decir, de ninguna manera.

Después de verificar con la utilidad MEinfo (de Intel STK), vimos que el modo de fabricación en estos sistemas no estaba cerrado, por lo tanto, los fusibles del chipset (FPF) quedaron en un estado indefinido. Sí, Intel BG en tales casos no estaba ni activado ni desactivado.

Se trata de los siguientes sistemas (en lo que respecta a Intel BG y lo que se expondrá a continuación en el artículo, hablaremos de sistemas con arquitectura de microprocesador Haswell y superiores):

  • todos los productos de Gigabyte;
  • todos los productos de MSI;
  • 21 modelos de laptops Lenovo y 4 modelos de servidores Lenovo.

Por supuesto, informamos a estos proveedores, así como a la compañía Intel.

Una respuesta adecuada solo siguió de Lenovo, que reconocieron el problema y lanzaron un parche.

Gigabyte aunque aceptaron la información sobre la vulnerabilidad, no hicieron ningún comentario al respecto.

La comunicación con MSI se detuvo por completo ante nuestra solicitud de enviar su clave PGP pública (para enviarles un aviso de seguridad encriptado). Ellos afirmaron que "son fabricantes de hardware y no producen claves PGP".

Pero yendo al grano. Dado que los fusibles se dejan en un estado no especificado, el usuario (o atacante) puede programarlos por sí mismo (lo más complicado es encontrar Intel STK). Para ello es necesario realizar las siguientes acciones.

1. Iniciar en el sistema operativo Windows (en realidad, las acciones descritas a continuación también se pueden realizar desde Linux, si se desarrolla un equivalente de Intel STK para el sistema operativo necesario). Usando la herramienta MEinfo, verificar que los fusibles en este sistema no estén programados.

Carga de confianza de Schrödinger. Intel Boot Guard
2. Leer el contenido de la memoria flash con la herramienta Flash Programming Tool.

Carga de confianza de Schrödinger. Intel Boot Guard
3. Abrir la imagen leída con cualquier herramienta para editar UEFI BIOS, realizar los cambios necesarios (por ejemplo, insertar un rootkit), crear/editar las estructuras KEYM e IBBM existentes en la región ME.

Carga de confianza de Schrödinger. Intel Boot Guard
Carga de confianza de Schrödinger. Intel Boot Guard
En la imagen se destaca la parte pública de la clave RSA, cuyo hash se programará en los fusibles del chipset junto con la configuración restante de Intel BG.

4. Usar la herramienta Flash Image Tool para compilar una nueva imagen de firmware (configurando la configuración de Intel BG).

Carga de confianza de Schrödinger. Intel Boot Guard
5. Grabar la nueva imagen en la memoria flash con la herramienta Flash Programming Tool, y verificar con MEinfo que la región ME ahora contiene la configuración de Intel BG.

Carga de confianza de Schrödinger. Intel Boot Guard
6. Cerrar el modo de fabricación utilizando la herramienta Flash Programming Tool.

Carga de confianza de Schrödinger. Intel Boot Guard
7. El sistema se reiniciará, después de lo cual se puede verificar con MEinfo que los FPF ahora están programados.

Carga de confianza de Schrödinger. Intel Boot Guard
Estas acciones activarán Intel BG en este sistema. No se podrá revertir esta acción, lo que significa:

  • que solo el poseedor de la parte privada de la clave raíz (es decir, quien activó Intel BG) podrá actualizar el UEFI BIOS en este sistema;
  • si se devuelve al sistema su firmware original, por ejemplo, con un programador, ni siquiera se encenderá (resultado de la política de enforcement en caso de error de verificación);
  • para deshacerse de este UEFI BIOS, es necesario reemplazar el chipset con FPF programados por uno "limpio" (es decir, desoldar el chipset, si tienes acceso a una estación de soldadura por infrarrojos que cuesta lo mismo que un coche, o simplemente reemplazar la placa madre).

Para entender lo que un rootkit de este tipo puede causar, es necesario evaluar qué permite ejecutar su propio código en el entorno UEFI BIOS. Por ejemplo, en el modo más privilegiado del procesador: SMM. Un rootkit así puede tener las siguientes propiedades:

  • ejecutarse paralelamente al sistema operativo (se puede configurar para que se active mediante la generación de una interrupción SMI, que se disparará por un temporizador);
  • disfrutar de todas las ventajas de estar en el modo SMM (acceso completo al contenido de la memoria RAM y a los recursos de hardware, invisibilidad para el sistema operativo);
  • el código del rootkit puede estar en forma cifrada y descifrarse al iniciarse en modo SMM. Se puede utilizar cualquier dato accesible solo en modo SMM como clave para el cifrado. Por ejemplo, el hash de un conjunto de direcciones en SMRAM. Para obtener esta clave, será necesario ingresar a SMM. Esto se puede hacer de dos maneras: encontrar una RCE en el código SMM y explotarla, o agregar su propio módulo SMM al BIOS, lo cual es imposible, ya que hemos activado Boot Guard.

Por lo tanto, esta vulnerabilidad permite al atacante:

  • crear un rootkit oculto e indeseado en el sistema con un propósito desconocido;
  • ejecutar su código en uno de los núcleos del chipset dentro de Intel SoC, a saber, en Intel ISH (echemos un vistazo a la imagen).

Carga de confianza de Schrödinger. Intel Boot Guard
Carga de confianza de Schrödinger. Intel Boot Guard
Aunque las capacidades del subsistema Intel ISH aún no han sido estudiadas, se presenta como un vector de ataque interesante sobre Intel ME.

Conclusiones

  1. La investigación permitió obtener una descripción técnica del funcionamiento de la tecnología Intel Boot Guard. Menos secretos en el modelo de seguridad a través de la oscuridad de Intel.
  2. Se presenta un escenario de ataque que permite crear un rootkit indeseado en el sistema.
  3. Hemos visto que los modernos procesadores Intel son capaces de ejecutar mucho código propietario incluso antes de que el BIOS comience a funcionar.
  4. Las plataformas con arquitectura Intel 64 se vuelven cada vez menos adecuadas para ejecutar software libre: verificación de hardware, un número creciente de tecnologías y subsistemas propietarios (tres núcleos en el chipset SoC: x86 ME, x86 ISH y ARC PMC).

Mitigaciones

A los proveedores que intencionalmente mantienen el modo de fabricación abierto, deben cerrarlo. Hasta ahora, solo cierran los ojos y los nuevos sistemas Kaby Lake lo demuestran.

Los usuarios pueden desactivar Intel BG en sus sistemas (que son vulnerables a la vulnerabilidad descrita) ejecutando la herramienta Flash Programming Tool con el parámetro -closemnf. Antes de eso, deben asegurarse (usando MEinfo) de que la configuración de Intel BG en la región ME permite desactivar esta tecnología después de la programación en los FPF.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster