
Laten we opnieuw een laagje dieper duiken en het hebben over de beveiliging van x86-compatibele computerplatforms. Dit keer is de hoofdcomponent van het onderzoek Intel Boot Guard (niet te verwarren met Intel BIOS Guard!) – een hardware-ondersteunde technologie voor veilige BIOS-opstart, die de computerfabrikant permanent kan inschakelen of uitschakelen tijdens de productie. En ons recept voor het onderzoek is al bekend: we gaan de implementatie van deze technologie grondig analyseren, de architectuur beschrijven en aanvullen met undocumented details, gekruid met aanvalsvectoren en door elkaar gehusseld. We voegen wat vuur toe met een uitleg over hoe jarenlang gekopieerde productie-fouten bij verschillende fabrikanten een potentiële aanvaller in staat stellen deze technologie te gebruiken om een onoplosbaar (zelfs door de programmeur) verborgen rootkit in het systeem te creëren.
Overigens is de basis van dit artikel de presentatie "Op de wacht voor rootkits: Intel BootGuard" van de conferentie en de 29e bijeenkomst (beide presentaties ).
Firmware van een computerplatform met Intel 64-architectuur
Laten we beginnen met de vraag: wat is de firmware van een modern computerplatform met Intel 64-architectuur? Uiteraard is het UEFI BIOS. Maar dat antwoord is niet helemaal correct. Laten we kijken naar de afbeelding, waar het desktop- (of laptop-) versie van deze architectuur is afgebeeld.

De basis bestaat uit de combinatie:
- De Processor (CPU, Central Processing Unit), waarin, naast de basiscores, ook een grafische kern is ingebouwd (niet in alle modellen) en een geïntegreerde geheugencontroller (IMC, Integrated Memory Controller) is geïntegreerd;
- De Chipset (PCH, Platform Controller Hub), die verschillende controllers bevat voor de interactie met randapparatuur en het beheer van subsystemen. Onder deze controllers bevindt zich de beruchte Intel Management Engine (ME), die ook zijn eigen firmware heeft (Intel ME firmware).
Laptops vereisen, naast het bovenstaande, ook de aanwezigheid van een ingebouwde controller (ACPI EC, Advanced Control and Power Interface Embedded Controller), die verantwoordelijk is voor de werking van de stroomvoorzieningssystemen, touchpad, toetsenbord, Fn-toetsen (schermhelderheid, geluidsvolume, toetsenbordverlichting, enz.) en meer. Ook deze controller heeft zijn eigen firmware.
Dus, de verzameling van de hierboven genoemde firmware vormt de systeemfirmware die wordt opgeslagen in het gedeelde SPI-flashgeheugen. Om gebruikers van dit geheugen te helpen vermijden dat ze door elkaar gehaald worden over wat van wie is, is de inhoud van dit geheugen verdeeld in de volgende regio's (zoals weergegeven in de afbeelding):
- UEFI BIOS;
- firmware ACPI EC (een aparte regio die is verschenen met de processor microarchitectuur Skylake (2015), maar in de praktijk hebben we nog geen voorbeelden van het gebruik gezien, dus de firmware van de embedded controller maakt nog steeds deel uit van de UEFI BIOS);
- firmware Intel ME;
- configuratie (MAC-adres, enz.) van de ingebouwde netwerkadapter GbE (Gigabit Ethernet);
- flash-descriptoren (Flash Descriptors) - de belangrijkste regio van het flash-geheugen, die aanwijzingen bevat naar de andere regio's, alsook toegangsmachtigingen voor hen.

De toegang tot de regio's (volgens de opgegeven machtigingen) wordt beheerd door de SPI-bus master - de ingebouwde SPI-controller in de chipset, waarmee toegang tot dit geheugen wordt verkregen. Als de machtigingen zijn ingesteld op de aanbevolen waarden (om veiligheidsredenen) door Intel, dan heeft elke gebruiker van het SPI-flashgeheugen volledige toegang (lezen/schrijven) tot zijn eigen regio. De andere regio's zijn ofwel alleen-lezen of helemaal niet toegankelijk. Een bekend feit is dat in veel systemen de CPU volledige toegang heeft tot de UEFI BIOS en GbE, toegang tot flash-descriptoren alleen lezen heeft, en geen toegang heeft tot de Intel ME-regio. Waarom in veel systemen en niet in alle? Wat aanbevolen is, is niet noodzakelijk. Meer hierover later in het artikel.
Mechanismen ter bescherming van de firmware van de computerplatform tegen wijziging
Het is duidelijk dat de firmware van het computerplatform beschermd moet worden tegen mogelijke compromittering, die een potentiële aanvaller in staat zou stellen zich hierin te nestelen (updates/herinstallaties van het besturingssysteem te overleven), zijn code uit te voeren in de meest bevoegde modi, enz. En toegangsscheiding tot de SPI-flashregio's is natuurlijk niet voldoende. Daarom worden verschillende mechanismen toegepast om firmware tegen wijzigingen te beschermen, specifiek voor elke uitvoeringsomgeving.
Zo is de firmware van Intel ME ondertekend voor integriteits- en authenticiteitscontrole en wordt deze gecontroleerd door de ME-controller bij elke opname in het geheugen van ME UMA. Dit verificatieproces is reeds door ons behandeld in een van de , dat gewijd is aan het Intel ME-systeem.
De ACPI EC-firmware wordt doorgaans alleen op integriteit gecontroleerd. Aangezien deze binaire code echter deel uitmaakt van de UEFI BIOS, zijn dezelfde beschermingsmechanismen die worden gebruikt door de UEFI BIOS meestal van toepassing. Laten we het daarover hebben.
Deze mechanismen kunnen in twee categorieën worden onderverdeeld.
Schrijfbescherming in het UEFI BIOS-regio
- Fysieke bescherming van de inhoud van de SPI-flash-geheugen via een write-protect jumper;
- Beveiliging van de projectie van het UEFI BIOS-regio in de CPU-geheugenspace met behulp van de PRx-registers van de chipset;
- Het blokkeren van schrijfproberen naar de UEFI BIOS-regio door het genereren en verwerken van de bijbehorende SMI-interrupt door de BIOS_WE/BLE- en SMM_BWP-bits in de chipsetregisters in te stellen;
- Een geavanceerdere variant van deze bescherming is Intel BIOS Guard (PFAT).
Naast deze mechanismen kunnen leveranciers hun eigen veiligheidsmaatregelen ontwikkelen en toepassen (bijvoorbeeld het ondertekenen van capsules met UEFI BIOS-updates).
Het is belangrijk op te merken dat niet alle eerder genoemde beschermingsmechanismen op een specifiek systeem kunnen worden toegepast (afhankelijk van de leverancier), dat ze helemaal niet kunnen worden toegepast, of dat ze kwetsbaar kunnen zijn geïmplementeerd. U kunt meer over deze mechanismen en de implementatie ervan lezen in . Voor geïnteresseerden raden we aan om de gehele serie artikelen over de beveiliging van UEFI BIOS van .
Verificatie van de authenticiteit van UEFI BIOS
Wanneer we het hebben over technologieën voor vertrouwde opstart, is het eerste dat in me opkomt Secure Boot. Architectonisch is het echter bedoeld voor de verificatie van externe componenten (drivers, bootloaders, enz.) ten opzichte van de UEFI BIOS, en niet de firmware zelf.
Daarom heeft Intel in SoC's met de Bay Trail-microarchitectuur (2012) een niet-uitschakelbare hardwarematige Secure Boot (Verified Boot) geïmplementeerd, die niets te maken heeft met de hierboven genoemde Secure Boot-technologie. Later (2013) werd dit mechanisme verbeterd en onder de naam Intel Boot Guard uitgebracht voor desktops met de Haswell-microarchitectuur.
Voordat we Intel Boot Guard beschrijven, laten we de uitvoeringsomgevingen in de Intel 64-architectuur verkennen, die toevallig de wortels van vertrouwen vormen voor deze technologie voor vertrouwde opstart.
Intel CPU
Kép suggereert dat de processor de belangrijkste uitvoeringsomgeving is in de Intel 64-architectuur. Waarom is hij dan de wortel van vertrouwen? Blijkbaar is dat omdat hij beschikt over de volgende elementen:
- Microcode ROM — niet-vluchtig, niet-overschrijfbaar geheugen voor het opslaan van microcode. Het wordt beschouwd als de implementatie van de instructieset van de processor in de eenvoudigste instructies. Ook in microcode kunnen er . Daarom zijn er in de BIOS binaries te vinden met updates voor de microcode (deze worden tijdens het opstarten geladen, omdat ROM niet kan worden overschreven). De inhoud van deze binaries is versleuteld, wat de analyse aanzienlijk bemoeilijkt (daardoor is de specifieke inhoud van de microcode alleen bekend bij degenen die deze ontwikkelen), en het is ondertekend voor integriteits- en authenticiteitscontrole;
- AES-sleutel voor het decoderen van de inhoud van de microcode-updates;
- hash van de publieke RSA-sleutel, waarmee de handtekening van de microcode-updates wordt gecontroleerd;
- hash van de publieke RSA-sleutel, waarmee de handtekening van de door Intel ontwikkelde code-modules ACM (Authenticated Code Module) wordt gecontroleerd, die de CPU kan uitvoeren voordat de BIOS-executie begint (hallo microcode) of tijdens zijn werking, wanneer bepaalde gebeurtenissen zich voordoen.
Intel ME
Aan dit subsysteem is in onze blog artikelen gewijd. Ter herinnering: deze uitvoerbare omgeving is gebaseerd op een microcontroller die in de chipset is ingebouwd en is de meest verborgen en bevoorrechte in het systeem.
Ondanks de verborgenheid is Intel ME ook de root of trust, aangezien het heeft:
- ME ROM — niet-vluchtig, niet-overschrijfbaar geheugen (er is geen manier om het te upgraden), dat de opstartcode bevat, evenals de SHA256-hash van de publieke RSA-sleutel, waarmee de handtekening van de Intel ME-firmware wordt gecontroleerd;
- AES-sleutel voor het opslaan van vertrouwelijke informatie;
- toegang tot een in de chipset geïntegreerde set van fusies (FPFs, Field Programmable Fuses) voor permanente opslag van bepaalde informatie, inclusief die door de computerleverancier is opgegeven.
Intel Boot Guard 1.x
Een kleine disclaimer. De versienummers van de Intel Boot Guard-technologie die we in dit artikel gebruiken, zijn indicatief en kunnen niets te maken hebben met de nummering die in de interne documentatie van Intel wordt gebruikt. Bovendien zijn de hier gepresenteerde informatie over de implementatie van deze technologie verkregen via reverse engineering en kan deze onnauwkeurigheden bevatten in vergelijking met de specificatie van Intel Boot Guard, die waarschijnlijk nooit openbaar zal worden gemaakt.
Intel Boot Guard (BG) is eine hardwaregestützte UEFI BIOS-Authentifizierungsverifizierungstechnologie. Laut einer kurzen Beschreibung im Buch [Platform Embedded Security Technology Revealed, Kapitel Boot with Integrity, or Not Boot] funktioniert sie wie eine vertrauenswürdige Bootkette. Der erste Glied in dieser Kette ist der Boot-Code (Mikrocode) innerhalb der CPU, der beim RESET-Ereignis gestartet wird (nicht zu verwechseln mit dem RESET-Vektor im BIOS!). Die CPU findet im SPI-Flash-Speicher ein von Intel entwickeltes und signiertes Code-Modul (Intel BG startup ACM), lädt es in ihren Cache, verifiziert es (wie bereits erwähnt, hat die CPU einen Hash des öffentlichen Schlüssels, mit dem die Signatur des ACM überprüft wird) und startet es.

Dieses Code-Modul ist zuständig für die Verifizierung des kleinen Startteils des UEFI BIOS - des Initial Boot Block (IBB), der seinerseits die Funktionalität zur Verifizierung des Hauptteils des UEFI BIOS enthält. So ermöglicht Intel BG die Authentizität des BIOS vor dem Start des Betriebssystems zu überprüfen (das unter der Überwachung der Secure Boot-Technologie laufen kann).
Die Intel BG-Technologie sieht zwei Betriebsmodi vor (und einer stört den anderen nicht, d.h. beide Modi können im System aktiviert oder beide deaktiviert sein).
Measured Boot
Im Modus Measured Boot (MB) "misst" jede Boot-Komponente (begonnen mit CPU boot ROM) die nächste, indem sie die Fähigkeiten des TPM (Trusted Platform Module) nutzt. Für die Unbewanderten eine kurze Erklärung.
Das TPM hat PCRs (Platform Configuration Registers), in die das Ergebnis der Hash-Operation nach der Formel geschrieben wird:

Das aktuelle PCR-Wert hängt vom vorherigen ab, wobei diese Register nur bei einem RESET des Systems zurückgesetzt werden.
So spiegeln die PCRs im MB-Modus zu einem bestimmten Zeitpunkt einen einzigartigen (innerhalb der Möglichkeiten der Hash-Operation) Identifikator des Codes oder der Daten wider, die "gemessen" wurden. Die PCR-Werte können bei der Verschlüsselung bestimmter Daten (TPM_Seal) verwendet werden. Ihre Entschlüsselung (TPM_Unseal) ist danach nur möglich, wenn die PCR-Werte nach dem Booten unverändert geblieben sind (d.h. kein "gemessenes" Element wurde modifiziert).
Verified Boot
Der schlimmste Albtraum für alle, die UEFI BIOS modifizieren möchten, ist der Verified Boot-Modus (VB), bei dem jede Boot-Komponente die Integrität und Authentizität der nächsten kryptografisch überprüft. Bei einem Verifikationsfehler tritt (eines der folgenden) ein:
- tijdelijke uitschakeling van 1 minuut tot 30 minuten (zodat de gebruiker kan begrijpen waarom zijn computer niet opstart en indien mogelijk probeert de BIOS te herstellen);
- onmiddellijke uitschakeling (zodat de gebruiker niets kan begrijpen en dus ook niets kan doen);
- doorgaan met onverstoorbare houding (de situatie waarin veiligheid minder belangrijk is, want er zijn belangrijkere zaken).
De keuze van de actie hangt af van de ingestelde configuratie van Intel BG (met name van de zogenaamde enforcement policy), die permanent door de leverancier van het computerplatform in een speciaal daarvoor bestemd opslagmedium wordt opgeslagen – de fuses van de chipset (FPF’s). We zullen later meer over dit punt ingaan.
Naast de configuratie genereert de leverancier twee RSA 2048-sleutels en creëert twee datastructuren (zoals weergegeven in de afbeelding):
- Het manifest van de root-sleutel van de leverancier (KEYM, OEM Root Key Manifest), waarin het SVN (Security Version Number) van dit manifest wordt opgenomen, de SHA256-hash van de publieke sleutel van het volgende manifest, de publieke RSA-sleutel (dus het publieke deel van de root-sleutel van de leverancier) voor de verificatie van de handtekening van dit manifest, en de handtekening zelf;
- Het manifest van IBB (IBBM, Initial Boot Block Manifest), waarin het SVN van dit manifest, de SHA256-hash van IBB, de publieke sleutel voor de verificatie van de handtekening van dit manifest en de handtekening zelf worden opgenomen.
De SHA256-hash van de publieke sleutel van de OEM Root Key wordt permanent opgeslagen in de fuses van de chipset (FPF’s), evenals de configuratie van Intel BG. Als de configuratie van Intel BG het inschakelen van deze technologie toelaat, kan vanaf dat moment alleen de eigenaar van het private deel van de OEM Root Key de BIOS op dit systeem bijwerken (d.w.z. in staat zijn om deze manifesten opnieuw te berekenen), dat wil zeggen de leverancier.

Bij het bekijken van de afbeelding rijst onmiddellijk de vraag of zo'n lange verificatieketen echt nodig is – men had toch met één manifest kunnen volstaan. Waarom compliceren?
In werkelijkheid biedt Intel de leverancier op deze manier de mogelijkheid om verschillende IBB-sleutels voor verschillende productlijnen te gebruiken en één als root. Als het private deel van de IBB-sleutel (waarmee het tweede manifest wordt ondertekend) uitlekt, raakt het incident slechts één productlijn en alleen zolang de leverancier geen nieuw sleutelpaar genereert en de opnieuw berekende manifesten in de volgende BIOS-update opneemt.
Maar als de rootkey (waarmee het eerste manifest wordt ondertekend) gecompromitteerd raakt, kan deze niet worden vervangen; er is geen procedure voor intrekking, omdat de hash van de publieke sleutel van deze key eenmalig en voorgoed in de FPF's is geprogrammeerd.
Configuratie van Intel Boot Guard
Laten we nu dieper ingaan op de configuratie van Intel BG en het proces van het creëren ervan. Als we naar het bijbehorende tabblad in de GUI-tool Flash Image Tool uit het Intel System Tool Kit (STK) kijken, kunnen we zien dat de configuratie van Intel BG de hash van de publieke sleutel van de vendor bevat, een paar onduidelijke waarden en de zogenaamde Intel BG-profiel.

De structuur van dit profiel:
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 – niets doen
// 01b – afsluiten met timeout
// 11b – onmiddellijke afsluiting
unsigned long : 26;
};Over het algemeen is de configuratie van Intel BG een zeer flexibele entiteit. Laten we bijvoorbeeld de vlag Force_Boot_Guard_ACM bekijken. Wanneer deze is uitgeschakeld, zal, als de BG startup ACM-module op het SPI-flash-geheugen niet wordt gevonden, er geen vertrouwde opstart plaatsvinden. Het zal onbetrouwbaar zijn.
Eerder hebben we al opgemerkt dat het handhavingbeleid voor de VB-modus zodanig kan worden ingesteld dat er bij een verificatiefout opnieuw een onbetrouwbare opstart plaatsvindt.
Dit soort dingen aan de leveranciers overlaten…
De GUI-tool voorziet in de volgende 'kant-en-klare' profielen:
Nummer
Modus
Omschrijving
0
No_FVME
Intel BG-technologie is uitgeschakeld
1
VE
VB-modus is ingeschakeld, afsluiting met timeout
2
VME
Beide modi (VB en MB) zijn ingeschakeld, afsluiting met timeout
3
VM
Beide modi zijn ingeschakeld, zonder systeemafsluiting
4
FVE
VB-modus is ingeschakeld, onmiddellijke afsluiting
5
FVME
Beide modi zijn ingeschakeld, onmiddellijke afsluiting
Zoals eerder vermeld, moet de configuratie van Intel BG eenmalig door de systeemleverancier in de fuses van de chipset (FPF's) worden geschreven – een kleine (volgens onbevestigde gegevens, slechts 256 bytes) hardware-opslag voor informatie binnen de chipset, die kan worden geprogrammeerd buiten de productiecapaciteiten van Intel (daarom juist Field Programmable Fuses).
Het is uitstekend geschikt voor het opslaan van configuraties, omdat:
- het heeft een one-time-programmable gebied voor het opslaan van gegevens (precies daar waar de configuratie van Intel BG wordt geschreven);
- slechts Intel ME kan het lezen en programmeren.
Om de configuratie voor de Intel BG-technologie op een specifiek systeem in te stellen, voert de leverancier tijdens de productie de volgende stappen uit:
- Met behulp van de Flash Image Tool (uit de Intel STK) wordt een firmware-afbeelding met de opgegeven Intel BG-configuratie gemaakt in de vorm van variabelen binnen het Intel ME-regio (de zogenaamde tijdelijke spiegel voor FPF's);
- Met behulp van de Flash Programming Tool (uit de Intel STK) wordt deze afbeelding op het SPI-flashgeheugen van het systeem geschreven en wordt de zogenaamde manufacturing mode afgesloten (tijdens deze stap wordt een overeenkomstig commando naar Intel ME verzonden).
Als gevolg van deze handelingen commit Intel ME de opgegeven waarden uit de spiegel voor FPF's in de ME-regio naar de FPF's, stelt het de permissies in SPI-flashdescriptoren in op de door Intel aanbevolen waarden (beschreven aan het begin van het artikel) en voert het een RESET van het systeem uit.
Analyse van de implementatie van Intel Boot Guard
Ten behoeve van de analyse van de implementatie van deze technologie hebben we de volgende systemen gecontroleerd op sporen van de Intel BG-technologie:
Systeem
Opmerking
Gigabyte GA-H170-D3H
Skylake, ondersteuning aanwezig
Gigabyte GA-Q170-D3H
Skylake, ondersteuning aanwezig
Gigabyte GA-B150-HD3
Skylake, ondersteuning aanwezig
MSI H170A Gaming Pro
Skylake, geen ondersteuning
Lenovo ThinkPad 460
Skylake, ondersteuning aanwezig, technologie ingeschakeld
Lenovo Yoga 2 Pro
Haswell, geen ondersteuning
Lenovo U330p
Haswell, geen ondersteuning
Met 'ondersteuning' wordt bedoeld dat er een Intel BG startup ACM-module aanwezig is, de eerder genoemde manifes en de bijbehorende code in de BIOS, d.w.z. implementatie voor analyse.
Als voorbeeld nemen we de gedownloade SPI-flashbeeld van de officiële website van de leverancier voor de Gigabyte GA-H170-D3H (versie F4).
Intel CPU boot ROM
Allereerst bespreken we de acties van de processor als de Intel BG-technologie is ingeschakeld.
Er zijn geen ontcijferde microcodevoorbeelden gevonden, dus hoe de hierna beschreven acties zijn gerealiseerd (in microcode of hardware) is een open vraag. Desondanks is het een feit dat moderne Intel-processoren deze acties 'kunnen' uitvoeren.
Na het verlaten van de RESET-status vindt de processor (wiens adresruimte al is gekoppeld aan de inhoud van het flashgeheugen) de FIT (Firmware Interface Table). Deze is eenvoudig te vinden, omdat er een aanwijzer naar is opgeslagen op het adres FFFF FFC0h.

In het onderzochte voorbeeld bevindt zich op dit adres de waarde FFD6 9500h. Door dit adres aan te spreken, ziet de processor de FIT-tabel, waarvan de inhoud is opgedeeld in records. Het eerste record is een header van de volgende structuur:
typedef struct FIT_HEADER
{
char Tag[8]; // ‘_FIT_ ’
unsigned long NumEntries; // inclusief FIT-header entry
unsigned short Version; // 1.0
unsigned char EntryType; // 0
unsigned char Checksum;
}; 
Om onbekende redenen is de checksum niet altijd berekend in deze tabellen (het veld is op nul gelaten).
De overige records wijzen naar verschillende binaries die moeten worden geparsed/geëxecuteerd nog voor de BIOS wordt uitgevoerd, dat wil zeggen vóór de overgang naar de legacy RESET-vector (FFFF FFF0h). De structuur van elk van deze records is als volgt:
typedef struct FIT_ENTRY
{
unsigned long BaseAddress;
unsigned long : 32;
unsigned long Size;
unsigned short Version; // 1.0
unsigned char EntryType;
unsigned char Checksum;
}; 
Het veld EntryType geeft het type blok aan waarnaar deze record verwijst. We kennen verschillende types:
enum FIT_ENTRY_TYPES
{
FIT_HEADER = 0,
MICROCODE_UPDATE,
BG_ACM,
BIOS_INIT = 7,
TPM_POLICY,
BIOS_POLICY,
TXT_POLICY,
BG_KEYM,
BG_IBBM
};Het is nu duidelijk dat een van de records verwijst naar de locatie van de Intel BG startup ACM binary. De structuur van de header van deze binary is typisch voor de door Intel ontwikkelde code-modules (ACM’s, microcode-updates, Intel ME code-segmenten, …).
typedef struct BG_ACM_HEADER
{
unsigned short ModuleType; // 2
unsigned short ModuleSubType; // 3
unsigned long HeaderLength; // in dwords
unsigned long : 32;
unsigned long : 32;
unsigned long ModuleVendor; // 8086h
unsigned long Date; // in BCD-formaat
unsigned long TotalSize; // in dwords
unsigned long unknown1[6];
unsigned long EntryPoint;
unsigned long unknown2[16];
unsigned long RsaKeySize; // in dwords
unsigned long ScratchSize; // in dwords
unsigned char RsaPubMod[256];
unsigned long RsaPubExp;
unsigned char RsaSig[256];
}; 
De processor laadt deze binary in zijn cache, verifieert en voert deze uit.
Intel BG startup ACM
Uit de analyse van de werking van deze ACM is gebleken dat het het volgende doet:
- ontvangt de Intel BG-configuratie van Intel ME, opgeslagen in de fuses van de chipset (FPF’s);
- vindt de manifesten KEYM en IBBM, verifieert deze.
Voor het vinden van deze manifesten maakt de ACM ook gebruik van de FIT-tabel, waarin twee typen records zijn gereserveerd voor het verwijzen naar gegevensstructuren (zie FIT_ENTRY_TYPES hierboven).
Laten we iets meer in detail ingaan op de manifesten. In de structuur van het eerste manifest zien we verschillende onduidelijke constanten, de hash van de publieke sleutel uit het tweede manifest en de publieke sleutel van de OEM Root Key met een handtekening in de vorm van een geneste structuur:
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 == hash size?
unsigned char IbbmKeyHash[32]; // SHA256 van een IBBM publieke sleutel
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];
}; 
Voor de verificatie van de publieke sleutel OEM Root Key, herinneren we ons dat de SHA256-hash van de fuses wordt gebruikt, die op dat moment al is verkregen van Intel ME.
Laten we verder gaan met het tweede manifest. Dit bestaat uit drie structuren:
typedef struct IBB_MANIFEST
{
ACBP Acbp; // Opstartbeleid
IBBS Ibbs; // IBB beschrijving
IBB_DESCRIPTORS[];
PMSG Pmsg; // IBBM handtekening
};In de eerste - enkele constanten:
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
};In de tweede bevindt zich de SHA256-hash van de IBB en het aantal descriptors die de inhoud van de IBB beschrijven (d.w.z. waaruit de hash wordt berekend):
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 == hash size ?
unsigned char IbbHash[32]; // SHA256 van een IBB
unsigned char NumIbbDescriptors;
};De IBB-descriptors volgen deze structuur, één voor één. Hun inhoud heeft het volgende formaat:
typedef struct IBB_DESCRIPTOR
{
unsigned long : 32;
unsigned long BaseAddress;
unsigned long Size;
};Het is eenvoudig: elke descriptor bevat adres/grootte van een stuk IBB. Zo is de concatenatie van de blokken waarnaar deze descriptors wijzen (in de volgorde van de locaties van de descriptors zelf) de IBB. En, doorgaans is de IBB de verzameling van alle modules van de SEC- en PEI-fase.
Het tweede manifest wordt afgesloten door een structuur die de publieke sleutel van de IBB bevat (verifieerbaar door de SHA256-hash van het eerste manifest) en de handtekening van dit manifest:
typedef struct PMSG
{
char Tag[8]; // ‘__PMSG__’
unsigned char : 8; // 10h
BG_RSA_ENTRY IbbKey;
}; 
Voordat UEFI BIOS wordt uitgevoerd, zal de processor ACM opstarten, dat de authenticiteit van de inhoud van de secties met SEC- en PEI-code controleert. Vervolgens verlaat de processor ACM, gaat naar de RESET-vector en begint BIOS uit te voeren.
De geverifieerde PEI-sectie moet een module bevatten die de resterende BIOS (DXE-code) controleert. Deze module wordt ontwikkeld door de IBV (Independent BIOS Vendor) of de systeemleverancier zelf. Aangezien de systemen van Lenovo en Gigabyte die compatibel zijn met Intel BG beschikbaar zijn, bekijken we de code die specifiek uit deze systemen is geëxtraheerd.
UEFI BIOS-module LenovoVerifiedBootPei
In het geval van Lenovo is dit de module LenovoVerifiedBootPei {B9F2AC77-54C7-4075-B42E-C36325A9468D}, ontwikkeld door Lenovo.
De functie is gericht op het zoeken (op GUID) van de hash-tabel voor DXE en het verifiëren van DXE.
if (EFI_PEI_SERVICES->GetBootMode() != BOOT_ON_S3_RESUME)
{
if (!FindHashTable())
return EFI_NOT_FOUND;
if (!VerifyDxe())
return EFI_SECURITY_VIOLATION;
}De hash-tabel {389CC6F2-1EA8-467B-AB8A-78E769AE2A15} heeft het volgende formaat:
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;
};UEFI BIOS-module BootGuardPei
In het geval van Gigabyte is dit de module BootGuardPei {B41956E1-7CA2-42DB-9562-168389F0F066}, ontwikkeld door AMI, en dus aanwezig in elke AMI BIOS met ondersteuning voor Intel BG.
Het algoritme werkt iets anders, maar komt op hetzelfde neer:
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;
}De hash-tabel {389CC6F2-1EA8-467B-AB8A-78E769AE2A15} die hij zoekt, heeft het volgende formaat:
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
Laten we kort een andere implementatie van Intel Boot Guard bespreken, die is gevonden in een nieuwer systeem op basis van Intel SoC met de Apollo Lake-microarchitectuur - ASRock J4205-IT.
Hoewel deze versie alleen zal worden toegepast in SoC's (nieuwe systemen met de Kaby Lake-processor microarchitectuur blijven Intel Boot Guard 1.x gebruiken), is het van groot belang om deze nieuwe architectuur voor Intel SoC-platformen te bestuderen, waarin enkele significante wijzigingen hebben plaatsgevonden, zoals:
- de BIOS- en Intel ME-regio's (eerder Intel TXE, volgens de terminologie voor Intel SoC) zijn nu één regio IFWI geworden;
- Hoewel de Intel BG op het platform was ingeschakeld, zijn structuren zoals FIT, KEYM, IBBM niet in het flashgeheugen gevonden;
- Naast de TXE- en ISH-kernen (x86) heeft de chipset een derde kern toegevoegd (wederom ARC, trouwens) - de PMC (Power Management Controller), die verband houdt met de werking van de voedingssubsystemen en de prestaties monitort.

De inhoud van het nieuwe IFWI-regio bestaat uit de volgende modules:
Offset
Naam
Omschrijving
0000 2000h
SMIP
een bepaalde platformconfiguratie, ondertekend door de leverancier
0000 6000h
RBEP
gedeelte van de Intel TXE-firmwarecode, x86, ondertekend door Intel
0001 0000h
PMCP
gedeelte van de Intel PMC-firmwarecode, ARC, ondertekend door Intel
0002 0000h
FTPR
gedeelte van de Intel TXE-firmwarecode, x86, ondertekend door Intel
0007 B000h
UCOD
microcode-updates voor CPU, ondertekend door Intel
0008 0000h
IBBP
UEFI BIOS, SEC/PEI-fases, x86, ondertekend door de leverancier
0021 8000h
ISHC
gedeelte van de Intel ISH-firmwarecode, x86, ondertekend door de leverancier
0025 8000h
NFTP
gedeelte van de Intel TXE-firmwarecode, x86, ondertekend door Intel
0036 1000h
IUNP
onbekend
0038 1000h
OBBP
UEFI BIOS, DXE-fase, x86, niet ondertekend
Tijdens de analyse van de TXE-firmware werd het duidelijk dat na een RESET TXE de processor in deze toestand houdt totdat het basisinhoud van het adresruimte voor de CPU (FIT, ACM, RESET-vector ...) heeft voorbereid. TXE plaatst deze gegevens in zijn SRAM, waarna het tijdelijk toegang tot de CPU verleent en hem 'laat gaan' uit de RESET.
Bewaker van rootkits
Laten we nu naar het 'heftige' gaan. Ooit ontdekten we dat op veel systemen in de SPI-flashbeschrijvingen toegangsmachtigingen voor regio's van het SPI-flashgeheugen zijn vastgelegd, zodat alle gebruikers van dit geheugen zowel kunnen schrijven als lezen in elke regio. Dat wil zeggen, helemaal niet.
Na controle met behulp van de MEinfo-tool (uit het Intel STK) zagen we dat de manufacturing mode op deze systemen niet afgesloten was, wat betekent dat de chipsets (FPF's) in ongedefinieerde staat zijn achtergelaten. Inderdaad, Intel BG is in zulke gevallen noch ingeschakeld, noch uitgeschakeld.
Het gaat om de volgende systemen (met betrekking tot Intel BG en wat er verder in het artikel wordt uiteengezet, zullen we spreken over systemen met de microarchitectuur van de processor Haswell en hoger):
- alle producten van Gigabyte;
- alle producten van MSI;
- 21 modellen van Lenovo-laptops en 4 modellen van Lenovo-servers.
Natuurlijk hebben we deze bevindingen gerapporteerd aan de leveranciers, alsook aan het bedrijf Intel.
Een adequate reactie volgde alleen van Lenovo, die het probleem erkenden en .
Gigabyte heet dat ze de informatie over de kwetsbaarheid hebben ontvangen, maar hebben nergens op gereageerd.
Communicatie met MSI is volledig gestopt met onze verzoek om hun openbare PGP-sleutel op te sturen (zodat we hen een beveiligingsadvies versleuteld konden toesturen). Ze verklaarden dat ze "de fabrikant van de hardware zijn en geen PGP-sleutels produceren."
Maar laten we ter zake komen. Aangezien de fuses in een onbepaalde staat zijn gelaten, kan de gebruiker (of aanvaller) ze zelf programmeren (het moeilijkste is - ). Hiervoor zijn de volgende stappen vereist.
1. Opstarten in Windows (overigens kunnen de onderstaande acties ook onder Linux worden uitgevoerd, als er een analoog van Intel STK voor het benodigde besturingssysteem wordt ontwikkeld). Gebruikmakend van de MEinfo-tool, controleren of de fuses op dit systeem niet zijn geprogrammeerd.

2. De inhoud van het flash-geheugen uitlezen met behulp van de Flash Programming Tool.

3. De uitgelezen afbeelding openen met elk hulpmiddel voor het bewerken van UEFI BIOS, de noodzakelijke wijzigingen aanbrengen (bijvoorbeeld een rootkit inbrengen), de bestaande KEYM- en IBBM-structuren in de ME-regio creëren/bewerken.


In de afbeelding is het openbare deel van de RSA-sleutel gemarkeerd, waarvan de hash in de fuses van de chipset wordt geprogrammeerd samen met de rest van de Intel BG-configuratie.
4. Met de Flash Image Tool een nieuw firmwarebeeld samenstellen (de Intel BG-configuratie opgeven).

5. Het nieuwe beeld op het flash-geheugen schrijven met de Flash Programming Tool, en met behulp van MEinfo controleren of de ME-regio nu de Intel BG-configuratie bevat.

6. Met de Flash Programming Tool de manufacturing mode afsluiten.

7. Het systeem zal opnieuw opstarten, en daarna kan met MEinfo worden gecontroleerd of de FPF's nu zijn geprogrammeerd.

Deze acties zetten voor altijd de Intel BG op dit systeem aan. Het is niet mogelijk deze actie terug te draaien, wat betekent:
- de UEFI BIOS op dit systeem kan alleen worden bijgewerkt door de eigenaar van het privédeel van de root-sleutel (d.w.z. degene die Intel BG heeft ingeschakeld);
- als je de originele firmware van dit systeem terugzet, bijvoorbeeld met een programmeerapparaat, zal het zelfs niet opstarten (gevolg van enforcement policy bij een verificatiefout);
- om zo'n UEFI BIOS kwijt te raken, moet je de chipset met geprogrammeerde FPF's vervangen door een 'schone' (d.w.z. de chipset solderen als je toegang hebt tot een infrarood soldeerstation ter waarde van een auto, of gewoon het moederbord vervangen).
Om te begrijpen wat zo'n rootkit kan aanrichten, moet men beoordelen wat de mogelijkheid geeft om eigen code uit te voeren in de UEFI BIOS-omgeving. Laten we zeggen, in de meest bevoorrechte modus van de processor – SMM. Zo'n rootkit kan de volgende eigenschappen hebben:
- uitgevoerd worden parallel aan het besturingssysteem (het is mogelijk om de werking in te stellen door het genereren van een SMI-interrupt, die getriggerd wordt door een timer);
- alle voordelen hebben van operationele modus SMM (volledige toegang tot de inhoud van het RAM-geheugen en hardware bronnen, verborgenheid voor het OS);
- de code van de rootkit kan in versleutelde vorm zijn en gedecodeerd worden bij de uitvoering in de SMM-modus. Als sleutel voor de versleuteling kunnen gegevens worden gebruikt die alleen beschikbaar zijn in de SMM-modus. Bijvoorbeeld, een hash van een reeks adressen in SMRAM. Om deze sleutel te verkrijgen, moet men de SMM binnendringen. Dit kan op twee manieren. Zoek een RCE in de SMM-code en exploiteer die, of voeg een eigen SMM-module toe aan de BIOS, wat onmogelijk is omdat we Boot Guard hebben ingeschakeld.
Deze kwetsbaarheid stelt een aanvaller in staat om:
- een verborgen, onverwijderbare rootkit van onbekende oorsprong in het systeem te creëren;
- zijn eigen code uit te voeren op een van de kernen van de chipset binnen de Intel SoC, namelijk op Intel ISH (kijk goed naar de afbeelding).


Hoewel de mogelijkheden van de Intel ISH-subsysteem nog niet zijn onderzocht, lijkt het een interessante aanvalsvector op Intel ME.
Conclusies
- Het onderzoek heeft een technische beschrijving van hoe Intel Boot Guard werkt opgeleverd. Een paar geheimen ontbreken in het Intel-model van security through obscurity.
- Een aanvalsscenario is gepresenteerd dat het mogelijk maakt om een onverwijderbare rootkit in het systeem te creëren.
- We hebben gezien dat moderne Intel-processoren in staat zijn om veel propriëtaire code uit te voeren nog vóór de BIOS wordt opgestart.
- Platformen met de Intel 64-architectuur worden steeds minder geschikt voor het draaien van vrije software: hardware verificatie, het toenemende aantal propriety-technologieën en subsystemen (drie kernen in de SoC-chipset: x86 ME, x86 ISH en ARC PMC).
Mitigaties
Leveranciers die opzettelijk de manufacturing mode openlaten, moeten deze zeker sluiten. Tot nu toe sluiten ze alleen hun ogen, en de nieuwe Kaby Lake-systemen tonen dit aan.
Gebruikers kunnen Intel BG zelf uitschakelen op hun systemen (die onderhevig zijn aan de beschreven kwetsbaarheid) door het Flash Programming Tool uit te voeren met de parameter -closemnf. Voordat dit gebeurt, moet worden gecontroleerd (met behulp van MEinfo) of de Intel BG-configuratie in de ME-regio daadwerkelijk het uitschakelen van deze technologie na programmeren in FPF's voorziet.
Bron: habr.com
