Carregamento confiável de Schrödinger. Intel Boot Guard

Carregamento confiável de Schrödinger. Intel Boot Guard
Estamos prontos para descer a um nível mais baixo e discutir a segurança dos firmwares de plataformas de computador compatíveis com x86. Desta vez, o ingrediente principal da pesquisa é o Intel Boot Guard (não confundir com o Intel BIOS Guard!) – uma tecnologia de boot confiável suportada por hardware que o fornecedor do sistema pode ativar ou desativar permanentemente na fase de produção. E a receita da pesquisa já nos é familiar: fatiar finamente a implementação dessa tecnologia com engenharia reversa, descrever sua arquitetura, recheando com detalhes não documentados, temperar com vetores de ataque e misturar. Vamos adicionar um pouco mais de calor com a história de como um erro de produção, clonado por vários fornecedores ao longo dos anos, permite que um potencial invasor utilize essa tecnologia para criar um rootkit oculto que não pode ser removido (nem mesmo por um programador).

A propósito, a base do artigo são as apresentações "Na defesa contra rootkits: Intel BootGuard" da conferência ZeroNights 2016 e a 29ª reunião DefCon Russia (ambas as apresentações aqui).

Firmware da plataforma de computador com arquitetura Intel 64

Para começar, vamos responder à pergunta: o que é o firmware de uma plataforma de computador moderna com arquitetura Intel 64? Claro, é o UEFI BIOS. Mas essa resposta não está totalmente correta. Vamos olhar para a figura, que mostra a versão desktop (ou laptop) dessa arquitetura.

Carregamento confiável de Schrödinger. Intel Boot Guard
A base é uma combinação:

  • Do processador (CPU, Unidade Central de Processamento), que, além dos núcleos principais, possui um núcleo gráfico embutido (não em todos os modelos) e um controlador de memória incorporado (IMC, Integrated Memory Controller);
  • Do chipset (PCH, Platform Controller Hub), que contém vários controladores para interação com dispositivos periféricos e gerenciamento de subsistemas. Entre eles está a famosa Intel Management Engine (ME), que também possui seu próprio firmware (Intel ME firmware).

Os notebooks, além do exposto, devem conter um controlador integrado (ACPI EC, Advanced Control and Power Interface Embedded Controller), que é responsável pela operação do subsistema de alimentação, touchpad, teclado, teclas Fn (brilho da tela, volume, iluminação do teclado, etc.) e muito mais. Ele também possui seu próprio firmware.

Portanto, a combinação dos firmwares mencionados acima é o firmware da plataforma de computador (system firmware), que é armazenado na memória flash SPI compartilhada. Para que os usuários dessa memória não se confundam sobre a localização dos conteúdos, o conteúdo dessa memória é dividido nas seguintes regiões (conforme mostrado na figura):

  • UEFI BIOS;
  • firmware ACPI EC (uma região separada surgiu com a microarquitetura do processador Skylake (2015), mas até agora não vimos exemplos de seu uso na prática, portanto, o firmware do controlador embutido ainda faz parte do UEFI BIOS);
  • firmware Intel ME;
  • configuração (endereço MAC, etc.) do adaptador de rede embutido GbE (Gigabit Ethernet);
  • descritores de flash (Flash Descriptors) – a principal região da memória flash, que contém ponteiros para as outras regiões, além de permissões de acesso a elas.

Carregamento confiável de Schrödinger. Intel Boot Guard
O controle de acesso às regiões (de acordo com as permissões atribuídas) é feito pelo mestre do barramento SPI – um controlador SPI embutido no chipset, através do qual o acesso a essa memória é realizado. Se as permissões estiverem configuradas nos valores recomendados (por motivos de segurança) pela Intel, cada usuário da memória flash SPI terá acesso total (leitura/escrita) apenas à sua região. As demais regiões terão apenas acesso de leitura ou estarão completamente indisponíveis. É um fato conhecido: em muitos sistemas, a CPU tem acesso total ao UEFI BIOS e ao GbE, acesso de leitura apenas aos descritores de flash e nenhum acesso à região Intel ME. Por que em muitos e não em todos? O que é recomendado não é necessariamente obrigatório. Discutiremos mais sobre isso adiante no artigo.

Mecanismos de proteção do firmware da plataforma de computador contra modificação

É evidente que o firmware da plataforma de computador deve ser protegido contra possíveis compromissos que poderiam permitir que um potencial invasor se instalasse nele (sobrevivendo a atualizações/reinstalações do SO), executando seu código nos modos mais privilegiados, etc. E o controle de acesso às regiões da memória flash SPI, claro, não é suficiente. Portanto, diversas mecanismos de proteção contra modificações de firmware são aplicados, específicos para cada ambiente de execução.

Assim, o firmware Intel ME é assinado para controle de integridade e autenticidade, e é verificado pelo controlador ME em cada carregamento na memória ME UMA. Este processo de verificação já foi abordado por nós em um de nossos de artigos, dedicado ao subsistema Intel ME.

E a firmware ACPI EC geralmente é verificada apenas quanto à integridade. No entanto, uma vez que esse binário está incluído no UEFI BIOS, ele quase sempre é sujeito aos mesmos mecanismos de proteção utilizados pelo UEFI BIOS. Sobre isso, vamos falar.

Esses mecanismos podem ser divididos em duas categorias.

Proteção contra gravação na região do UEFI BIOS

  1. Proteção física do conteúdo da memória flash SPI com jumper de write-protect;
  2. Proteção da projeção da região do UEFI BIOS no espaço de endereçamento da CPU com os registros PRx do chipset;
  3. Bloqueio de tentativas de gravação na região do UEFI BIOS através da geração e tratamento da interrupção SMI correspondente, definindo os bits BIOS_WE/BLE e SMM_BWP nos registros do chipset;
  4. Uma versão mais avançada dessa proteção é o Intel BIOS Guard (PFAT).

Além desses mecanismos, os fornecedores podem desenvolver e aplicar suas próprias medidas de segurança (por exemplo, a assinatura de pacotes com atualizações do UEFI BIOS).

É importante notar que em um sistema específico (dependendo do fornecedor) nem todos os mecanismos de proteção mencionados acima podem ser aplicados, podem nem ser aplicados ou podem ser implementados de forma vulnerável. Para mais detalhes sobre esses mecanismos e sobre a situação de sua implementação, você pode ler em este artigo. Recomendamos que os interessados consultem todo o ciclo de artigos sobre segurança do UEFI BIOS de CodeRush.

Verificação da autenticidade do UEFI BIOS

Quando falamos sobre tecnologias de boot confiável, a primeira coisa que vem à mente é o Secure Boot. No entanto, arquitetonicamente, ele foi projetado para verificar a autenticidade de componentes externos ao UEFI BIOS (drivers, carregadores, etc.), e não da própria firmware.

Portanto, a Intel implementou um Secure Boot (Verified Boot) de hardware não desativável nos SoCs com a microarquitetura Bay Trail (2012), que não tem relação com a tecnologia Secure Boot mencionada anteriormente. Posteriormente (2013), esse mecanismo foi aprimorado e lançado para desktops com a microarquitetura Haswell sob o nome Intel Boot Guard.

Antes de descrever o Intel Boot Guard, vamos entender os ambientes de execução na arquitetura Intel 64, que, por sua vez, são as raízes de confiança para essa tecnologia de boot confiável.

CPU Intel

O Capitão sugere que o processador é o principal ambiente de execução na arquitetura Intel 64. Por que ele também é a raiz de confiança? Acontece que essa posição se deve a ele possuir os seguintes elementos:

  • Microcode ROM — memória não volátil, não regravável para armazenar microcódigo. Considera-se que o microcódigo é a implementação do conjunto de instruções do processador em instruções de nível mais baixo. Também podem ocorrer erros. Assim, no BIOS é possível encontrar binários com atualizações de microcódigo (aplicados durante a inicialização, uma vez que a ROM não pode ser regravada). O conteúdo desses binários é criptografado, o que dificulta significativamente a análise (por isso, o conteúdo específico do microcódigo é conhecido apenas por quem o desenvolve), e é assinado para controle de integridade e autenticidade;
  • chave AES para descriptografar o conteúdo das atualizações de microcódigo;
  • hash da chave pública RSA, que verifica a assinatura das atualizações de microcódigo;
  • hash da chave pública RSA, que verifica a assinatura dos módulos de código autenticados da Intel (ACM, Authenticated Code Module), que o CPU pode executar antes do início da execução do BIOS (olá, microcódigo) ou durante sua operação, ao ocorrer certos eventos.

Intel ME

Este subsistema foi dedicado em nosso blog a duas artigo. Lembramos que este ambiente executável é baseado em um microcontrolador incorporado ao chipset e é o mais oculto e privilegiado do sistema.

Apesar da sua ocultação, o Intel ME também é a raiz de confiança, pois possui:

  • ME ROM — memória não volátil, não regravável (sem método de atualização disponível), contendo código de inicialização, bem como o hash SHA256 da chave pública RSA, que verifica a assinatura do firmware do Intel ME;
  • chave AES para armazenar informações secretas;
  • acesso ao conjunto de fusíveis programáveis do campo (FPFs, Field Programmable Fuses) integrado ao chipset para armazenamento permanente de algumas informações, incluindo as definidas pelo fornecedor do sistema computacional.

Intel Boot Guard 1.x

Um pequeno aviso. Os números de versão da tecnologia Intel Boot Guard que utilizamos neste artigo são arbitrários e podem não ter qualquer relação com a numeração que é aplicada na documentação interna da Intel. Além disso, as informações apresentadas aqui sobre a implementação dessa tecnologia foram obtidas por meio de engenharia reversa e podem conter imprecisões em relação à especificação do Intel Boot Guard, que provavelmente nunca será publicada.

Assim, o Intel Boot Guard (BG) é uma tecnologia de verificação de autenticidade do UEFI BIOS suportada por hardware. De acordo com a sua breve descrição no livro [Platform Embedded Security Technology Revealed, capítulo Boot with Integrity, or Not Boot], funciona como uma cadeia de inicialização confiável. E o primeiro elo nesta cadeia é o código de inicialização (microcódigo) dentro da CPU, que é ativado pelo evento RESET (não confundir com o vetor RESET no BIOS!). A CPU localiza um módulo de código projetado e assinado pela Intel na memória flash SPI, carrega-o em seu cache, verifica (como mencionado, a CPU possui um hash da chave pública usada para verificar a assinatura do ACM) e o inicia.

Carregamento confiável de Schrödinger. Intel Boot Guard

Este módulo de código é responsável pela verificação de uma pequena parte inicial do UEFI BIOS — Initial Boot Block (IBB), que, por sua vez, contém funcionalidades para verificar a parte principal do UEFI BIOS. Assim, o Intel BG permite confirmar a autenticidade do BIOS antes do carregamento do sistema operacional (que pode ser executado sob a supervisão da tecnologia Secure Boot).

A tecnologia Intel BG prevê dois modos de operação (sendo que um não interfere no outro, ou seja, ambos os modos podem estar ativados no sistema, ou ambos podem estar desativados).

Measured Boot

No modo Measured Boot (MB), cada componente de inicialização (começando com o CPU boot ROM) "mede" o seguinte, utilizando os recursos do TPM (Trusted Platform Module). Para aqueles que não estão familiarizados, vamos esclarecer.

O TPM possui PCRs (Platform Configuration Registers), nos quais é armazenado o resultado da operação de hash de acordo com a fórmula:

Carregamento confiável de Schrödinger. Intel Boot Guard

Ou seja, o valor atual do PCR depende do anterior, com os dados dos registradores sendo zerados apenas durante o RESET do sistema.

Assim, no modo MB, em algum momento, os PCRs refletem um identificador único (dentro das capacidades da operação de hash) do código ou dos dados que foram "medidos". Os valores dos PCR podem ser utilizados na operação de criptografia de alguns dados (TPM_Seal). Em seguida, sua descriptografia (TPM_Unseal) só será possível se os valores dos PCR resultantes da inicialização não mudaram (ou seja, nenhum componente "medido" foi modificado).

Verified Boot

O que mais assusta os fãs de modificações no UEFI BIOS é o modo Verified Boot (VB), onde cada componente de inicialização verifica criptograficamente a integridade e autenticidade do próximo. E, em caso de erro na verificação, ocorre (uma das):

  • desligamento por timeout de 1 a 30 minutos (para que o usuário consiga entender o motivo pelo qual seu computador não está inicializando e, se possível, tente restaurar o BIOS);
  • desligamento imediato (para que o usuário não tenha tempo para entender nada e, muito menos, fazer algo);
  • continuação do trabalho com uma aparência impassível (aquela situação em que não se tem tempo para a segurança, pois há questões mais importantes).

A escolha da ação depende da configuração do Intel BG (ou seja, da chamada enforcement policy), que é permanentemente gravada pelo fornecedor da plataforma em um armazenamento específico – os fusíveis do chipset (FPF). Vamos abordar esse ponto com mais detalhes posteriormente.

Além da configuração, o fornecedor gera duas chaves RSA 2048 e cria duas estruturas de dados (como mostrado na figura):

  1. Manifesto da chave raiz do fornecedor (KEYM, OEM Root Key Manifest), que contém o SVN (Security Version Number) deste manifesto, o hash SHA256 da chave pública do próximo manifesto, a chave pública RSA (ou seja, a parte pública da chave raiz do fornecedor) para verificação da assinatura deste manifesto e a própria assinatura;
  2. Manifesto do IBB (IBBM, Initial Boot Block Manifest), que contém o SVN deste manifesto, o hash SHA256 do IBB, a chave pública para verificação da assinatura deste manifesto e a própria assinatura.

O hash SHA256 da chave pública do OEM Root Key é permanentemente gravado nos fusíveis do chipset (FPF), assim como a configuração do Intel BG. Se a configuração do Intel BG prevê a inclusão desta tecnologia, então, a partir desse momento, na referida sistema, a atualização do BIOS (ou seja, a possibilidade de recalcular esses manifestos) pode ser feita apenas pelo detentor da parte privada da chave OEM Root, ou seja, pelo fornecedor.

Carregamento confiável de Schrödinger. Intel Boot Guard

Ao olhar para a imagem, surgem imediatamente dúvidas sobre a necessidade de uma cadeia de verificação tão longa – poderia ter sido usado um único manifesto. Por que complicar?

Na verdade, a Intel fornece ao fornecedor a possibilidade de usar diferentes chaves IBB para diferentes linhas de produtos e uma – como raiz. Se a parte privada da chave IBB (com a qual o segundo manifesto é assinado) vazar, o incidente afetará apenas uma linha de produtos e apenas até que o fornecedor gere um novo par e inclua os manifestos recalculados na próxima atualização do BIOS.

Mas se a chave raiz (com a qual o primeiro manifesto é assinado) for comprometida, não será possível substituí-la, já que não há procedimentos de revogação previstos, pois o hash da parte pública dessa chave é programado nos FPFs uma vez e para sempre.

Configuração do Intel Boot Guard

Agora vamos nos concentrar em detalhes sobre a configuração do Intel BG e no processo de sua criação. Se olharmos a guia correspondente na interface gráfica da ferramenta Flash Image Tool do kit de ferramentas Intel System Tool Kit (STK), podemos perceber que a configuração do Intel BG inclui o hash da parte pública da chave raiz do fornecedor, um par de valores desconhecidos e o chamado perfil Intel BG.

Carregamento confiável de Schrödinger. Intel Boot Guard

A estrutura desse 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 – não fazer nada
                                              // 01b – desligamento com tempo limite
                                              // 11b – desligamento imediato
	unsigned long : 26;
};

De maneira geral, a configuração do Intel BG é uma entidade muito flexível. Vamos considerar, por exemplo, o sinalizador Force_Boot_Guard_ACM. Quando ele está desativado, caso o módulo BG startup ACM na memória flash SPI não seja encontrado, não haverá nenhum boot confiável. Haverá um boot não confiável.

Como já mencionamos acima, a política de aplicação para o modo VB pode ser configurada de tal forma que, em caso de erro de verificação, ocorrerá, novamente, um boot não confiável.

Deixar tais coisas a critério dos fornecedores...

A interface gráfica da ferramenta prevê os seguintes perfis "prontos":

Número
Modo
Descrição

0
No_FVME
tecnologia Intel BG desativada

1
VE
modo VB ativado, desligamento por tempo limite

2
VME
ambos os modos ativados (VB e MB), desligamento por tempo limite

3
VM
ambos os modos ativados, sem desligamento do sistema

4
FVE
modo VB ativado, desligamento imediato

5
FVME
ambos os modos ativados, desligamento imediato

Como já foi mencionado, a configuração do Intel BG deve ser gravada uma vez por todas pelo fornecedor do sistema nos fusíveis do chip (FPFs) – um pequeno armazenamento de informações (segundo informações não confirmadas, apenas 256 bytes) dentro do chip, que pode ser programado fora das instalações de produção da Intel (portanto, exatamente Field Programmable Fuses).

É excelente para armazenar a configuração, pois:

  • possui uma área de programação única para armazenar dados (é exatamente onde a configuração do Intel BG é gravada);
  • só pode ser lido e programado pelo Intel ME.

Portanto, para configurar a tecnologia Intel BG em um sistema específico, o fornecedor faz o seguinte durante a produção:

  1. Utilizando a ferramenta Flash Image Tool (do Intel STK), cria uma imagem de firmware com a configuração desejada do Intel BG na forma de variáveis dentro da região Intel ME (o chamado espelho temporário para os FPFs);
  2. Com a ferramenta Flash Programming Tool (do Intel STK), grava essa imagem na memória flash SPI do sistema e fecha o chamado modo de fabricação (neste processo, o comando correspondente é enviado para o Intel ME).

Como resultado dessas operações, o Intel ME irá comprometer os valores especificados no espelho para os FPFs na região ME, ajustará as permissões nos descritores de memória flash SPI aos valores recomendados pela Intel (descrito no início do artigo) e realizará um RESET do sistema.

Análise da implementação do Intel Boot Guard

Com o objetivo de analisar a implementação dessa tecnologia em um exemplo específico, verificamos os seguintes sistemas em busca de vestígios da tecnologia Intel BG:

Sistema
Nota

Gigabyte GA-H170-D3H
Skylake, há suporte

Gigabyte GA-Q170-D3H
Skylake, há suporte

Gigabyte GA-B150-HD3
Skylake, há suporte

MSI H170A Gaming Pro
Skylake, não há suporte

Lenovo ThinkPad 460
Skylake, há suporte, tecnologia ativada

Lenovo Yoga 2 Pro
Haswell, não há suporte

Lenovo U330p
Haswell, não há suporte

Por 'suporte' entendemos a presença do módulo ACM de inicialização do Intel BG, dos manifestos mencionados acima e do código correspondente no BIOS, ou seja, a implementação para análise.

Como exemplo, tomaremos a imagem da memória flash SPI baixada do site oficial do fornecedor para Gigabyte GA-H170-D3H (versão F4).

Intel CPU boot ROM

Primeiro, vamos falar sobre as ações do processador caso a tecnologia Intel BG esteja ativada.

Não foi possível encontrar amostras do microcódigo decifrado, portanto, como as ações descritas a seguir são implementadas (no microcódigo ou em hardware) é uma questão em aberto. Entretanto, o fato de que os processadores Intel modernos 'sabem' realizar essas ações é um fato.

Após sair do estado de RESET, o processador (cujas informações da memória flash já estão mapeadas no espaço de endereçamento) encontra a tabela FIT (Firmware Interface Table). Encontrá-la é simples, o ponteiro para ela está gravado no endereço FFFF FFC0h.

Carregamento confiável de Schrödinger. Intel Boot Guard
No exemplo em questão, neste endereço está o valor FFD6 9500h. Ao acessar este endereço, o processador vê a tabela FIT, cujo conteúdo é dividido em entradas. A primeira entrada é o cabeçalho da seguinte estrutura:

typedef struct FIT_HEADER
{
	char           Tag[8];     // ‘_FIT_’
	unsigned long  NumEntries; // incluindo a entrada do cabeçalho FIT
	unsigned short Version;    // 1.0
	unsigned char  EntryType;  // 0
	unsigned char  Checksum;
};

Carregamento confiável de Schrödinger. Intel Boot Guard
Por razões desconhecidas, a checksum nem sempre é calculada nessas tabelas (o campo é deixado como zero).

Os outros registros apontam para diferentes binários que precisam ser analisados/executados antes da execução do BIOS, ou seja, antes de voltar ao vetor de RESET legado (FFFF FFF0h). A estrutura de cada um desses registros é a seguinte:

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

Carregamento confiável de Schrödinger. Intel Boot Guard
O campo EntryType indica o tipo de bloco ao qual este registro se refere. Conhecemos vários 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
};

Agora está claro que um dos registros aponta para a localização do binário Intel BG startup ACM. A estrutura do cabeçalho desse binário é típica para módulos de código desenvolvidos pela Intel (ACMs, atualizações de microcódigo, seções de código Intel ME, ...).

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

Carregamento confiável de Schrödinger. Intel Boot Guard
O processador carrega esse binário em seu cache, verifica e inicia.

Intel BG startup ACM

A análise do funcionamento deste ACM revelou que ele faz o seguinte:

  • recebe do Intel ME a configuração Intel BG, armazenada nos fuses do chipset (FPFs);
  • localiza os manifestos KEYM e IBBM, verifica-os.

Para encontrar esses manifestos, o ACM também utiliza a tabela FIT, na qual foram reservados dois tipos de registros para indicar as estruturas de dados (veja FIT_ENTRY_TYPES acima).

Vamos nos deter um pouco mais nos manifestos. Na estrutura do primeiro manifesto, vemos várias constantes obscuras, o hash da chave pública do segundo manifesto e a chave pública OEM Root Key com uma assinatura em forma de estrutura aninhada:

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 == tamanho do hash?
	unsigned char  IbbmKeyHash[32]; // SHA256 de uma chave pública 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];
};

Carregamento confiável de Schrödinger. Intel Boot Guard
Para a verificação da chave pública OEM Root Key, lembramos que é utilizado o hash SHA256 proveniente dos fusíveis, que já foi obtido a partir do Intel ME.

Vamos passar para o segundo manifesto. Ele consiste em três estruturas:

typedef struct IBB_MANIFEST
{
	ACBP Acbp;         // Políticas de inicialização
	IBBS Ibbs;         // Descrição do IBB
	IBB_DESCRIPTORS[];
	PMSG Pmsg;         // Assinatura do IBBM
};

Na primeira – algumas 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
};

Na segunda, está o hash SHA256 do IBB e o número de descritores que descrevem o conteúdo do IBB (ou seja, a partir do qual o hash é calculado):

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 == tamanho do hash ?
	unsigned char  IbbHash[32];       // SHA256 de um IBB
	unsigned char  NumIbbDescriptors;
};

Os descritores do IBB seguem esta estrutura, um após o outro. O conteúdo deles tem o seguinte formato:

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

É simples: cada descritor contém o endereço/tamanho de um bloco do IBB. Assim, a concatenação dos blocos para os quais esses descritores apontam (na ordem em que os próprios descritores são colocados) é o IBB. E, como regra geral, o IBB é a soma de todos os módulos das fases SEC e PEI.

O segundo manifesto termina com uma estrutura que contém a chave pública do IBB (verificada pelo hash SHA256 do primeiro manifesto) e a assinatura deste manifesto:

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

Carregamento confiável de Schrödinger. Intel Boot Guard
Assim, antes mesmo do início da execução do UEFI BIOS, o processador iniciará o ACM, que verificará a autenticidade do conteúdo das seções de código das fases SEC e PEI. Em seguida, o processador sai do ACM, vai para o vetor de RESET e começa a executar o BIOS.

A seção PEI verificada deve conter um módulo que verificará o restante do BIOS (código DXE). Este módulo é desenvolvido pelo IBV (Independent BIOS Vendor) ou pelo próprio fornecedor do sistema. Como os sistemas disponíveis para nós que têm suporte ao Intel BG são apenas os da Lenovo e da Gigabyte, vamos considerar o código extraído desses sistemas.

Módulo do UEFI BIOS LenovoVerifiedBootPei

No caso da Lenovo, este foi o módulo LenovoVerifiedBootPei {B9F2AC77-54C7-4075-B42E-C36325A9468D}, desenvolvido pela Lenovo.

Seu trabalho consiste em buscar (por GUID) a tabela de hashes para DXE e verificar o DXE.

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

A tabela de hashes {389CC6F2-1EA8-467B-AB8A-78E769AE2A15} tem o seguinte 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 do UEFI BIOS BootGuardPei

No caso da Gigabyte, este foi o módulo BootGuardPei {B41956E1-7CA2-42DB-9562-168389F0F066}, desenvolvido pela AMI, portanto, presente em qualquer BIOS AMI com suporte ao Intel BG.

Seu algoritmo de trabalho é um pouco diferente, mas a essência é a mesma:

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;
}

A tabela de hashes {389CC6F2-1EA8-467B-AB8A-78E769AE2A15}, que ele procura, tem o seguinte 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

Vamos falar brevemente sobre outra implementação do Intel Boot Guard, que foi encontrada em um sistema mais novo baseado em Intel SoC com microarquitetura Apollo Lake — ASRock J4205-IT.

Embora essa versão seja aplicada apenas em SoCs (os novos sistemas com microarquitetura de processador Kaby Lake continuam a usar o Intel Boot Guard 1.x), ela é de grande interesse para o estudo de uma nova variante de arquitetura para plataformas em Intel SoC, onde ocorreram mudanças significativas, como:

  • as regiões do BIOS e do Intel ME (ou melhor, Intel TXE, de acordo com a terminologia para Intel SoC) agora são uma única região IFWI;
  • Embora a plataforma tivesse o Intel BG ativado, estruturas como FIT, KEYM e IBBM não foram encontradas na memória flash;
  • Além dos núcleos TXE e ISH (x86), o chipset adicionou um terceiro núcleo (novamente ARC, aliás) – PMC (Power Management Controller), relacionado à operação do subsistema de alimentação e monitoramento de desempenho.

Carregamento confiável de Schrödinger. Intel Boot Guard
O conteúdo da nova região IFWI consiste em um conjunto dos seguintes módulos:

Deslocamento
Nome
Descrição

0000 2000h
SMIP
uma configuração de plataforma, assinada pelo vendedor

0000 6000h
RBEP
seção de código do firmware Intel TXE, x86, assinado pela Intel

0001 0000h
PMCP
seção de código do firmware Intel PMC, ARC, assinado pela Intel

0002 0000h
FTPR
seção de código do firmware Intel TXE, x86, assinado pela Intel

0007 B000h
UCOD
atualizações de microcódigo para CPU, assinadas pela Intel

0008 0000h
IBBP
UEFI BIOS, fases SEC/PEI, x86, assinado pelo vendedor

0021 8000h
ISHC
seção de código do firmware Intel ISH, x86, assinado pelo vendedor

0025 8000h
NFTP
seção de código do firmware Intel TXE, x86, assinado pela Intel

0036 1000h
IUNP
desconhecido

0038 1000h
OBBP
UEFI BIOS, fase DXE, x86, não assinado

Durante a análise do firmware TXE, ficou claro que após o RESET, o TXE mantém o processador nesse estado até que o conteúdo básico do espaço de endereços para a CPU (FIT, ACM, vetor de RESET ...) esteja preparado. E o TXE armazena esses dados em sua SRAM, após o que temporariamente concede acesso ao processador e "libera-o" do RESET.

Defendendo-se contra rootkits

Agora vamos ao "quente". Uma vez descobrimos que em muitos sistemas, os descritores SPI de memória flash gravaram permissões de acesso a regiões da memória flash SPI, de forma que todos os usuários dessa memória podem escrever e ler qualquer região. Ou seja, nada.

Após verificar com a ferramenta MEinfo (do Intel STK), vimos que o modo de fabricação nesses sistemas não estava fechado, portanto, os fusíveis do chipset (FPF) foram deixados em um estado indefinido. Sim, o Intel BG em tais casos está nem ligado nem desligado.

Trata-se dos seguintes sistemas (em relação ao Intel BG e ao que será exposto a seguir no artigo, falaremos de sistemas com microarquitetura de processador Haswell ou superior):

  • toda a linha de produtos Gigabyte;
  • toda a linha de produtos MSI;
  • 21 modelos de laptops Lenovo e 4 modelos de servidores Lenovo.

Claro, informamos esses vendedores, assim como a Intel.

A resposta adequada veio apenas de Lenovo, que reconheceram o problema e lançaram um patch.

Gigabyte parece que aceitaram a informação sobre a vulnerabilidade, mas não comentaram.

Comunicação com MSI parou completamente em nosso pedido para enviar sua chave PGP pública (para enviar a eles um aviso de segurança de forma criptografada). Eles disseram que "são fabricantes de hardware e não produzem chaves PGP".

Mas indo direto ao ponto. Como os fusíveis estão deixados em um estado indefinido, o usuário (ou invasor) pode programá-los por conta própria (o mais difícil é encontrar o Intel STK). Para isso, é necessário realizar os seguintes passos.

1. Iniciar no sistema operacional Windows (na verdade, as ações descritas a seguir também podem ser feitas a partir do Linux, se um equivalente do Intel STK for desenvolvido para o sistema operacional necessário). Usando a ferramenta MEinfo, verificar se os fusíveis neste sistema não estão programados.

Carregamento confiável de Schrödinger. Intel Boot Guard
2. Ler o conteúdo da memória flash usando a Flash Programming Tool.

Carregamento confiável de Schrödinger. Intel Boot Guard
3. Abrir a imagem lida usando qualquer ferramenta para editar o UEFI BIOS, fazer as alterações necessárias (implementar um rootkit, por exemplo), criar/editar as estruturas KEYM e IBBM existentes na região ME.

Carregamento confiável de Schrödinger. Intel Boot Guard
Carregamento confiável de Schrödinger. Intel Boot Guard
Na imagem, a parte pública da chave RSA é destacada, o hash da qual será programado nos fusíveis do chipset junto com a restante configuração do Intel BG.

4. Usando a Flash Image Tool, compilar uma nova imagem de firmware (definindo a configuração Intel BG).

Carregamento confiável de Schrödinger. Intel Boot Guard
5. Gravar a nova imagem na memória flash usando a Flash Programming Tool, certificando-se, através do MEinfo, que a região ME agora contém a configuração Intel BG.

Carregamento confiável de Schrödinger. Intel Boot Guard
6. Usar a Flash Programming Tool para fechar o modo de fabricação.

Carregamento confiável de Schrödinger. Intel Boot Guard
7. O sistema reiniciará, após o que, usando o MEinfo, pode-se verificar que os FPFs agora estão programados.

Carregamento confiável de Schrödinger. Intel Boot Guard
Essas ações ativarão permanentemente o Intel BG neste sistema. Cancelar a ação não será possível, o que significa que:

  • apenas o possuidor da parte privada da chave raiz (ou seja, quem ativou o Intel BG) poderá atualizar o UEFI BIOS neste sistema;
  • se o firmware original deste sistema for restaurado, por exemplo, usando um programador, ele nem ligarão (devido à política de enforcement em caso de erro de verificação);
  • para se livrar de tal UEFI BIOS, é necessário substituir o chipset com os FPFs programados por um "limpo" (ou seja, re-soldar o chipset, se você tiver acesso a uma estação de soldagem a infravermelhos custando o preço de um carro, ou simplesmente substituir a placa-mãe).

Para entender o que um rootkit desse tipo pode causar, é preciso avaliar o que possibilita a execução do seu código no ambiente UEFI BIOS. Vamos dizer, no modo mais privilegiado do processador - SMM. Um rootkit desse tipo pode ter as seguintes características:

  • executar paralelamente ao SO (pode ser configurado para ativar a geração de interrupção SMI, que será disparada por um temporizador);
  • ter todas as vantagens de estar no modo SMM (acesso total ao conteúdo da memória RAM e aos recursos de hardware, ocultação do SO);
  • o código do rootkit pode estar em forma criptografada e ser descriptografado ao ser iniciado no modo SMM. Qualquer dado acessível apenas em modo SMM pode ser usado como chave de criptografia. Por exemplo, um hash de um conjunto de endereços em SMRAM. Para obter essa chave, é necessário acessar o SMM. Isso pode ser feito de duas formas. Encontrar RCE no código SMM e explorá-lo, ou adicionar seu próprio módulo SMM ao BIOS, o que é impossível, pois ativamos o Boot Guard.

Assim, essa vulnerabilidade permite que um invasor:

  • crie um rootkit oculto e indelével de finalidade desconhecida no sistema;
  • execute seu código em um dos núcleos do chip dentro do Intel SoC, especificamente, no Intel ISH (vamos olhar atentamente a imagem).

Carregamento confiável de Schrödinger. Intel Boot Guard
Carregamento confiável de Schrödinger. Intel Boot Guard
Embora as capacidades do subsistema Intel ISH ainda não tenham sido totalmente estudadas, ele se apresenta como um vetor interessante de ataque ao Intel ME.

Como resultado, obtemos um serviço de "monitoramento como serviço", automatizado na linha de produção de integração contínua. O desenvolvedor ou testador precisa apenas definir a lista de métricas em um arquivo JSON, e tudo o mais acontece automaticamente. Obtemos um controle de qualidade transparente dos lançamentos: todas as notificações sobre desempenho, consumo de recursos ou regressões arquitetônicas.

  1. A pesquisa permitiu obter uma descrição técnica do funcionamento da tecnologia Intel Boot Guard. Um a menos em vários mistérios na modelo da Intel de segurança através da obscuridade.
  2. Um cenário de ataque foi apresentado, permitindo a criação de um rootkit indelével no sistema.
  3. Vimos que os modernos processadores Intel são capazes de executar muito código proprietário antes do início do funcionamento do BIOS.
  4. Plataformas com arquitetura Intel 64 estão se tornando cada vez menos adequadas para executar software livre: verificação de hardware, o número crescente de tecnologias e subsistemas proprietários (três núcleos no chipset SoC: x86 ME, x86 ISH e ARC PMC).

Mitigações

Os fornecedores que deliberadamente mantêm o modo de fabricação aberto devem fechá-lo imediatamente. Até agora, apenas os olhos foram fechados e os novos sistemas Kaby Lake mostram isso.

Os usuários podem desativar o Intel BG em seus sistemas (que estão sujeitos à vulnerabilidade descrita) executando a ferramenta Flash Programming Tool com o parâmetro -closemnf. Antes disso, deve-se verificar (usando o MEinfo) se a configuração do Intel BG na região ME permite a desativação dessa tecnologia após a programação nos FPFs.

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster