Încărcare de încredere a lui Schrödinger. Intel Boot Guard

Încărcare de încredere a lui Schrödinger. Intel Boot Guard
Vă propunem să coborâm din nou la un nivel de bază și să discutăm despre securitatea firmware-ului platformelor de calcul compatibile x86. De data aceasta, ingredientul principal al cercetării este Intel Boot Guard (nu trebuie confundat cu Intel BIOS Guard!) – o tehnologie de bootare de încredere, susținută hardware, pe care furnizorul sistemului de calcul o poate activa sau dezactiva permanent în etapa de fabricație. Iar rețeta cercetării ne este deja familiară: a tăia fin prin inginerie inversă implementarea acestei tehnologii, a-i descrie arhitectura, umplând-o cu detalii nedocumentate, a o condimenta după plac cu vectori de atac și a amesteca. Vom adăuga puțin foc cu povestea despre cum o eroare de fabricație clonată ani de zile de către mai mulți furnizori permite unui potențial atacator să folosească această tehnologie pentru a crea un rootkit ascuns (chiar și pentru programator) care nu poate fi eliminat din sistem.

Apropo, baza articolului este reprezentată de prezentările „La straja rootkit-urilor: Intel BootGuard” de la conferința ZeroNights 2016 și cea de-a 29-a întâlnire DefCon Russia (ambele prezentări aici).

Firmware-ul platformei de calcul cu arhitectură Intel 64

Pentru început, să răspundem la întrebarea: ce este firmware-ul unei platforme de calcul moderne cu arhitectură Intel 64? Evident, UEFI BIOS. Dar acest răspuns nu ar fi precis. Să ne uităm la imagine, unde este reprezentată o variantă desktop (sau laptop) a acestei arhitecturi.

Încărcare de încredere a lui Schrödinger. Intel Boot Guard
Baza este o combinație:

  • Procesorului (CPU, Unitatea Centrală de Procesare), în care, pe lângă nucleele principale, este integrat un nucleu grafic (nu în toate modelele) și un controler de memorie (IMC, Controler de Memorie Integrat);
  • Chipset-ului (PCH, Hub-ul de Control al Platformei), care conține diferite controlere pentru interacțiunea cu dispozitivele periferice și gestionarea subsistemelor. Printre acestea se numără binecunoscuta Intel Management Engine (ME), care are de asemenea firmware (Intel ME firmware).

Laptopurile, pe lângă cele menționate mai sus, presupun existența unui controler integrat (ACPI EC, Controler Înglobat avansat de Control și Putere), care este responsabil pentru funcționarea subsistemului de alimentare, a touchpad-ului, a tastaturii, a tastelor Fn (luminozitatea ecranului, volumul sonor, iluminarea tastaturii etc.) și a altor elemente. Și acesta are propriul său firmware.

Astfel, combinația firmware-ului menționat mai sus reprezintă firmware-ul platformei computerizate (system firmware), care este stocat în memoria flash SPI comună. Pentru a evita confuzia utilizatorilor acestei memorii, conținutul acesteia este împărțit în următoarele regiuni (așa cum este ilustrat în imagine):

  • UEFI BIOS;
  • firmware ACPI EC (o regiune separată a apărut cu microarhitectura procesorului Skylake (2015), însă în utilizarea curentă nu am întâlnit exemple de utilizare a acesteia, așa că firmware-ul controller-ului încorporat face încă parte din UEFI BIOS);
  • firmware Intel ME;
  • configurarea (adresa MAC etc.) a adaptorului de rețea încorporat GbE (Gigabit Ethernet);
  • descrierile flash (Flash Descriptors) – regiunea principală a memoriei flash, care conține indicii către celelalte regiuni, precum și permisiuni de acces la acestea.

Încărcare de încredere a lui Schrödinger. Intel Boot Guard
Gestionarea accesului la regiuni (în conformitate cu permisiunile stabilite) se desfășoară prin intermediul masterului magistralei SPI – un controller SPI încorporat în chipset, prin care se face accesul la această memorie. Dacă permisiunile sunt setate la valorile recomandate (din motive de securitate) de compania Intel, atunci fiecare utilizator al memoriei flash SPI are acces total (citire/scriere) doar la regiunea sa. Celelalte regiuni sunt fie accesibile doar pentru citire, fie nu sunt accesibile deloc. Un fapt bine cunoscut: în multe sisteme, CPU are acces complet la UEFI BIOS și GbE, acces în regim de citire doar la descrierile flash, iar la regiunea Intel ME nu are acces deloc. De ce în multe și nu în toate? Ceea ce este recomandat nu este întotdeauna obligatoriu. Vom discuta mai detaliat despre aceasta mai departe în articol.

Mecanisme de protecție a firmware-ului platformei computerizate împotriva modificărilor

Este evident că firmware-ul platformei computerizate trebuie protejat împotriva posibilelor compromiteri, care ar permite unui potențial atacator să se instaleze în acesta (să supraviețuieze actualizărilor/reinstalărilor de sistem de operare), să execute propriul cod în cele mai privilegiate moduri etc. Și gestionarea accesului la regiunile memoriei flash SPI, desigur, nu este suficientă. Prin urmare, pentru a proteja firmware-ul împotriva modificărilor, se aplică diverse mecanisme, specifice fiecărei medii de execuție.

Astfel, firmware-ul Intel ME este semnat pentru a controla integritatea și autenticitatea sa și este verificat de către controller-ul ME la fiecare încărcare în memoria ME UMA. Acest proces de verificare a fost deja discutat de noi într-una din articolele noastre, dedicată subsistemului Intel ME.

Firmware-ul ACPI EC, de obicei, este verificat doar pentru integritate. Totuși, având în vedere că acest binar este inclus în UEFI BIOS, aproape întotdeauna se aplică aceleași mecanisme de protecție utilizate de UEFI BIOS. Despre acestea vom discuta.

Aceste mecanisme pot fi împărțite în două categorii.

Protecția împotriva scrierii în regiunea UEFI BIOS

  1. Protecția fizică a conținutului memoriei flash SPI prin jumperul de protecție la scriere;
  2. Protecția proiecției regiunii UEFI BIOS în spațiul de adresare al CPU prin registrii PRx ai chipset-ului;
  3. Blocarea încercărilor de scriere în regiunea UEFI BIOS prin generarea și gestionarea întreruperii SMI corespunzătoare, prin setarea bitilor BIOS_WE/BLE și SMM_BWP în registrii chipset-ului;
  4. O variantă mai avansată a acestei protecții este Intel BIOS Guard (PFAT).

Pe lângă aceste mecanisme, furnizorii pot dezvolta și aplica măsuri proprii de securitate (de exemplu, semnarea capsulelor cu actualizări UEFI BIOS).

Este important de menționat că nu toate mecanismele de protecție enumerate mai sus pot fi aplicate pe un sistem specific (dependente de furnizor), pot să nu fie aplicate deloc sau pot fi implementate vulnerabil. Detalii despre aceste mecanisme și despre situația implementării lor pot fi găsite în această articole. Recomandăm interesatilor să consulte întregul ciclu de articole privind securitatea UEFI BIOS de la CodeRush.

Verificarea autenticității UEFI BIOS

Când vorbim despre tehnologiile de boot de încredere, primul lucru care ne vine în minte este Secure Boot. Totuși, arhitectural, acesta este destinat verificării autenticității componentelor externe, în raport cu UEFI BIOS (driver-e, bootloader-e etc.), nu a firmware-ului în sine.

De aceea, compania Intel a implementat în SoC-urile cu microarhitectură Bay Trail (2012) un Secure Boot hardware neactivabil (Verified Boot), care nu are nimic în comun cu tehnologia menționată anterior Secure Boot. Ulterior (2013), acest mecanism a fost îmbunătățit și sub numele de Intel Boot Guard a fost lansat pentru desktop-uri cu microarhitectură Haswell.

Înainte de a descrie Intel Boot Guard, să analizăm mediile de execuție în arhitectura Intel 64, care, de asemenea, reprezintă rădăcinile de încredere pentru această tehnologie de boot de încredere.

Intel CPU

Căpitanul sugerează că procesorul este mediul principal de execuție în arhitectura Intel 64. De ce este el considerat rădăcina de încredere? Se pare că acest lucru se datorează existenței următoarelor elemente:

  • Microcode ROM — memorie nevolatilă, nemodificabilă pentru stocarea microcodului. Se consideră că microcodul este implementarea setului de instrucțiuni al procesorului pe instrucțiuni de bază. În microcod există, de asemenea, erori. Așadar, în BIOS se pot găsi binare cu actualizări ale microcodului (care se suprapun în timpul încărcării, deoarece ROM-ul nu poate fi modificat). Conținutul acestor binare este criptat, ceea ce complică semnificativ analiza (de aceea, conținutul specific al microcodului este cunoscut doar celor care îl dezvoltă), și este semnat pentru a controla integritatea și autenticitatea;
  • cheia AES pentru decriptarea conținutului actualizărilor microcodului;
  • hash-ul cheii publice RSA, care verifică semnătura actualizărilor microcodului;
  • hash-ul cheii publice RSA, care verifică semnătura modulelor de cod autentificate ACM (Authenticated Code Module) dezvoltate de Intel, pe care CPU-ul le poate executa înainte de a începe execuția BIOS-ului (salut microcodului) sau în timpul funcționării acestuia, în anumite condiții.

Intel ME

Această subsistemă a fost dedicată în blogul nostru în două recomandările sunt aplicabile coronavirusurilor în general și COVID-19 în particular. Așadar, recomand să descărcați și să printați articolul (pentru cei interesați de acest subiect).. Reamintim că acest mediu executabil este bazat pe un microcontroler încorporat în chipset și este cel mai ascuns și privilegiate din sistem.

În ciuda ocultării, Intel ME este, de asemenea, rădăcina de încredere, deoarece are:

  • ME ROM — memorie nevolatilă, nemodificabilă (moduri de actualizare nu sunt prevăzute), care conține cod de pornire, precum și hash SHA256 al cheii publice RSA, care verifică semnătura firmware-ului Intel ME;
  • cheia AES pentru stocarea informațiilor secrete;
  • acces la setul de fuse-uri programabile în câmp (FPFs, Field Programmable Fuses) încorporat în chipset pentru stocarea permanentă a unor informații, inclusiv a celor specificate de furnizorul sistemului computerizat.

Intel Boot Guard 1.x

Un mic disclaimer. Numerele versiunilor tehnologiei Intel Boot Guard, despre care discutăm în acest articol, sunt convenționale și pot să nu aibă nimic de-a face cu numerotarea folosită în documentația internă a companiei Intel. De asemenea, informațiile prezentate aici despre implementarea acestei tehnologii au fost obținute prin inginerie inversă și pot conține inexactități în comparație cu specificația Intel Boot Guard, care este puțin probabil să fie publicată vreodată.

Astfel, Intel Boot Guard (BG) este o tehnologie hardware de verificare a autenticității UEFI BIOS. Judecând după descrierea sa scurtă în cartea [Platform Embedded Security Technology Revealed, capitolul Boot with Integrity, or Not Boot], funcționează ca o lanț de boot de încredere. Primul element din acest lanț este codul de boot (microcodul) din interiorul CPU-ului, care se activează în urma unui eveniment RESET (nu trebuie confundat cu vectorul RESET din BIOS!). CPU-ul găsește în memoria flash SPI un modul de cod dezvoltat și semnat de Intel (Intel BG startup ACM), îl încarcă în cache, îl verifică (precum s-a menționat anterior, CPU-ul are hash-ul cheii publice care verifică semnătura ACM) și apoi îl execuță.

Încărcare de încredere a lui Schrödinger. Intel Boot Guard

Acest modul de cod este responsabil pentru verificarea unei părți mici inițiale a UEFI BIOS - Initial Boot Block (IBB), care, la rândul său, conține funcționalități pentru verificarea părții principale a UEFI BIOS. Astfel, Intel BG permite asigurarea autenticității BIOS-ului înainte de a încărca sistemul de operare (care poate fi executat sub supravegherea tehnologiei Secure Boot).

Tehnologia Intel BG preconizează două moduri de operare (fiecare nu interferează cu celălalt, adică ambele moduri pot fi activate în sistem sau ambele pot fi dezactivate).

Measured Boot

În modul Measured Boot (MB), fiecare component de boot (începând cu CPU boot ROM) "măsoară" următoarea componentă, folosind capacitățile TPM (Trusted Platform Module). Pentru cei care nu sunt familiarizați, vom explica.

TPM-ul are PCR-uri (Platform Configuration Registers), în care se înregistrează rezultatul operațiunii de hashing conform formulei:

Încărcare de încredere a lui Schrödinger. Intel Boot Guard

Adică, valoarea curentă a PCR-ului depinde de cea anterioară, în timp ce aceste registre sunt resetate doar la RESET-ul sistemului.

Astfel, în modul MB, la un anumit moment, PCR-urile reflectă un identificator unic (în limita capabilităților operației de hashing) al codului sau datelor care au fost "măsurate". Valorile PCR pot fi utilizate în operația de criptare a unor date (TPM_Seal). După aceasta, decriptarea lor (TPM_Unseal) va fi posibilă doar dacă valorile PCR nu au fost modificate în urma boot-ului (adică, nici o componentă "măsurată" nu a fost modificată).

Verified Boot

Ceea ce este cel mai înfricoșător pentru cei care iubesc să modifice UEFI BIOS este modul Verified Boot (VB), în care fiecare component de boot verifică criptografic integritatea și autenticitatea următoarei componente. Iar în cazul unei erori de verificare, se produce (una dintre):

  • opțiunea de oprire temporizată de la 1 minut la 30 de minute (pentru ca utilizatorul să înțeleagă motivul pentru care computerul său nu se încarcă și, dacă este posibil, să încerce să recupereze BIOS);
  • oprirea imediată (pentru ca utilizatorul să nu reușească să înțeleagă nimic și, cu atât mai puțin, să facă ceva);
  • continuarea activității cu o față impasibilă (acela este momentul când securitatea nu este prioritară, deoarece există lucruri mai importante).

Alegerea acțiunii depinde de configurația setată Intel BG (mai precis, de așa-numita politică de aplicare), care este înregistrată permanent de către furnizorul platformei computerizate într-un depozit special destinat – fuzibilele chipset-ului (FPF-uri). Vom aborda acest aspect în detaliu mai târziu.

Pe lângă configurație, furnizorul generează două chei RSA 2048 și creează două structuri de date (ilustrate în imagine):

  1. Manifestul cheii rădăcină a furnizorului (KEYM, OEM Root Key Manifest), în care plasează SVN (Numărul de versiune de securitate) al acestui manifest, hash-ul SHA256 al cheii publice a următorului manifest, cheia publică RSA (adică partea publică a cheii rădăcină a furnizorului) pentru verificarea semnăturii acestui manifest și semnătura propriu-zisă;
  2. Manifestul IBB (IBBM, Initial Boot Block Manifest), în care plasează SVN al acestui manifest, hash-ul SHA256 IBB, cheia publică pentru verificarea semnăturii acestui manifest și semnătura propriu-zisă.

Hash-ul SHA256 al cheii publice OEM Root Key este înregistrat permanent în fuzibilele chipset-ului (FPF-uri), la fel ca și configurația Intel BG. Dacă configurația Intel BG preconizează activarea acestei tehnologii, atunci de la acel moment, în acest sistem, actualizarea BIOS-ului (adică capacitatea de a recalcula aceste manifesturi) poate fi efectuată doar de către deținătorul părții private a cheii OEM Root Key, adică furnizorul.

Încărcare de încredere a lui Schrödinger. Intel Boot Guard

Privind imaginea, se ridică imediat întrebări privind necesitatea unei astfel de lungi lanțuri de verificare – s-ar fi putut folosi un singur manifest. De ce să complicăm?

De fapt, compania Intel oferă în acest mod furnizorului oportunitatea de a folosi chei IBB diferite pentru diferite linii de produse și una ca fiind rădăcină. Dacă partea privată a cheii IBB (cu care se semnează al doilea manifest) este compromisă, incidentul va afecta doar o singură linie de produse și doar până când furnizorul nu generează o nouă pereche și nu include manifesturile recalibrate în următoarea actualizare BIOS.

Dar dacă cheia rădăcină (cu care se semnează primul manifest) este compromisă, aceasta nu poate fi înlocuită, deoarece nu există proceduri de revocare, deoarece hash-ul părții publice a acestei chei este programat în FPF-uri o dată pentru totdeauna.

Configurația Intel Boot Guard

Acum să ne concentrăm pe detaliile configurației Intel BG și pe procesul de creare a acesteia. Dacă ne uităm la fila corespunzătoare din GUI-ul utilitarului Flash Image Tool din kitul Intel System Tool Kit (STK), putem observa că configurația Intel BG include hash-ul părții publice a cheii rădăcină a vendorului, un set de valori obscură și așa-numitul profil Intel BG.

Încărcare de încredere a lui Schrödinger. Intel Boot Guard

Structura acestui profil:

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 – nu face nimic
                                              // 01b – oprire cu timeout
                                              // 11b – oprire imediată
	unsigned long : 26;
};

În general, configurația Intel BG este o entitate foarte flexibilă. Să luăm, de exemplu, flanul Force_Boot_Guard_ACM. Când acesta este dezactivat, dacă modulul BG startup ACM din memoria flash SPI nu este găsit, nu va exista nicio bootare de încredere. Va fi o bootare fără încredere.

Am menționat anterior că politica de aplicare pentru modul VB poate fi configurată astfel încât, în caz de eroare de verificare, să se întâmple, din nou, o bootare fără încredere.

A lăsa astfel de aspecte pe seama vendorilor...

GUI-ul utilitarului prevede următoarele profile "gata de utilizare":

Număr
Modul
Descriere

0
No_FVME
tehnologia Intel BG este dezactivată

1
VE
modul VB activat, oprire după timeout

2
VME
ambele moduri (VB și MB) activate, oprire după timeout

3
VM
ambele moduri activate, fără oprire a sistemului

4
FVE
modul VB activat, oprire imediată

5
FVME
ambele moduri activate, oprire imediată

Așa cum a fost menționat, configurația Intel BG trebuie să fie scrisă o dată pentru totdeauna de către vendorul sistemului în fuse-urile chipset-ului (FPF-uri) – un stocare hardware mică (după informații neconfirmate, doar 256 de biți) care poate fi programată în afara capacităților de producție ale companiei Intel (de aceea, anume Field Programmable Fuses).

Este ideală pentru stocarea configurației, deoarece:

  • are o zonă programabilă o singură dată pentru stocarea datelor (anume acolo unde este scrisă configurația Intel BG);
  • poate fi citită și programată doar de Intel ME.

Așadar, pentru a configura tehnologia Intel BG pe un sistem specific, producătorul efectuează următoarele acțiuni în timpul producției:

  1. Folosind utilitarul Flash Image Tool (din Intel STK), creează o imagine a firmware-ului cu configurația dorită Intel BG sub formă de variabile în regiunea Intel ME (așa-numitul mirror temporar pentru FPF-uri);
  2. Folosind utilitarul Flash Programming Tool (din Intel STK), scrie această imagine în memoria flash SPI a sistemului și închide așa-numitul manufacturing mode (în acest proces, se trimite comanda corespunzătoare în Intel ME).

Ca rezultat al acestor operațiuni, Intel ME va comite în FPF-uri valorile specificate din mirror-ul pentru FPF-uri în regiunea ME, va seta permisiunile în descriptorii flash SPI la valorile recomandate de compania Intel (așa cum a fost descris la începutul articolului) și va efectua RESET-ul sistemului.

Analiza implementării Intel Boot Guard

Cu scopul de a analiza implementarea acestei tehnologii printr-un exemplu concret, am verificat următoarele sisteme pentru urmele tehnologiei Intel BG:

Sistem
Notă

Gigabyte GA-H170-D3H
Skylake, suport disponibil

Gigabyte GA-Q170-D3H
Skylake, suport disponibil

Gigabyte GA-B150-HD3
Skylake, suport disponibil

MSI H170A Gaming Pro
Skylake, fără suport

Lenovo ThinkPad 460
Skylake, suport disponibil, tehnologia activată

Lenovo Yoga 2 Pro
Haswell, fără suport

Lenovo U330p
Haswell, fără suport

Prin „suport” se înțelege prezența modulului Intel BG startup ACM, manifestele menționate mai sus și codul corespunzător în BIOS, adică implementarea pentru analiză.

Ca exemplu, să luăm imaginea descărcată de pe site-ul oficial al producătorului pentru Gigabyte GA-H170-D3H (versiunea F4).

Intel CPU boot ROM

În primul rând, să discutăm despre acțiunile procesorului în cazul în care tehnologia Intel BG este activată.

Nu s-au găsit mostre de microcod decriptat, astfel încât modul în care acțiunile descrise mai jos sunt implementate (în microcod sau hardware) rămâne o întrebare deschisă. Totuși, este un fapt că procesoarele Intel moderne „pot” efectua aceste acțiuni.

După ce iese din starea RESET, procesorul (al cărui spațiu de adresare a fost deja mapat cu conținutul memoriei flash) găsește tabelul FIT (Firmware Interface Table). Găsirea acestuia este simplă, pointerul său fiind scris la adresa FFFF FFC0h.

Încărcare de încredere a lui Schrödinger. Intel Boot Guard
În exemplul discutat, la această adresă se află valoarea FFD6 9500h. Accesând această adresă, procesorul vede tabelul FIT, conținutul său fiind împărțit în înregistrări. Prima înregistrare este un antet cu următoarea structură:

typedef struct FIT_HEADER
{
	char           Tag[8];     // ‘_FIT_   ’
	unsigned long  NumEntries; // inclusiv înregistrarea antetului FIT
	unsigned short Version;    // 1.0
	unsigned char  EntryType;  // 0
	unsigned char  Checksum;
};

Încărcare de încredere a lui Schrödinger. Intel Boot Guard
Din motive necunoscute, suma de control nu este întotdeauna calculată în aceste tabele (câmpul este lăsat zero).

Celelalte înregistrări indică diverse binare, care trebuie analizate/executate înainte de a rula BIOS, adică înainte de a trece la vectorul de resetare legacy (FFFF FFF0h). Structura fiecărei astfel de înregistrări este următoarea:

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

Încărcare de încredere a lui Schrödinger. Intel Boot Guard
Câmpul EntryType indică tipul blocului la care face referire această înregistrare. Cunoaștem mai multe tipuri:

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

Acum este evident că una dintre înregistrări indică locația binarului Intel BG startup ACM. Structura antetului acestui binar este tipică pentru modulele de cod dezvoltate de compania Intel (ACM-uri, actualizări de microcod, secțiuni de cod Intel ME, …).

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

Încărcare de încredere a lui Schrödinger. Intel Boot Guard
Procesorul încarcă acest binar în cache, îl verifică și îl rulează.

Intel BG startup ACM

În urma analizei funcționării acestui ACM, a devenit clar că acesta face următoarele:

  • primește de la Intel ME configurația Intel BG, înregistrată în fusibilele chipsetului (FPF-uri);
  • găsește manifestele KEYM și IBBM, le verifică.

Pentru a găsi aceste manifeste, ACM folosește de asemenea tabelul FIT, în care sunt alocate două tipuri de înregistrări pentru a indica datele structurii (vezi FIT_ENTRY_TYPES mai sus).

Să ne oprim mai în detaliu asupra manifestelor. În structura primului manifest vedem câteva constante neclare, hash-ul cheii publice din al doilea manifest și cheia publică OEM Root Key cu semnătura sub formă de structură încorporată:

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 of an IBBM public key
	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];
};

Încărcare de încredere a lui Schrödinger. Intel Boot Guard
Pentru a verifica cheia publică OEM Root Key, reamintim că se folosește hash-ul SHA256 din fuze, care este deja obținut de la Intel ME.

Să trecem la al doilea manifest. Acesta este format din trei structuri:

typedef struct IBB_MANIFEST
{
	ACBP Acbp;         // Boot policies
	IBBS Ibbs;         // IBB description
	IBB_DESCRIPTORS[];
	PMSG Pmsg;         // IBBM signature
};

În prima – sunt anumite constante:

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

În a doua se află hash-ul SHA256 IBB și numărul descriptorilor, care descriu conținutul IBB (adică ceea ce este folosit pentru a calcula hash-ul):

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 of an IBB
	unsigned char  NumIbbDescriptors;
};

Descriptorii IBB urmează această structură, unul după altul. Conținutul lor are următorul format:

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

E simplu: fiecare descriptor conține adresa/ dimensiunea unei părți IBB. Astfel, concatenarea blocurilor către care indică acești descriptori (în ordinea în care se află descriptorii înșiși) reprezintă IBB. Și, în general, IBB este o acumulare a tuturor modulelor fazelor SEC și PEI.

Al doilea manifest se încheie cu o structură care conține cheia publică IBB (verificată prin hash-ul SHA256 din primul manifest) și semnătura acestui manifest:

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

Încărcare de încredere a lui Schrödinger. Intel Boot Guard
Astfel, înainte de a începe execuția UEFI BIOS, procesorul va lansa ACM, care va verifica autenticitatea conținutului secțiunilor cu codul fazelor SEC și PEI. Apoi, procesorul iese din ACM, trece la vectorul RESET și începe să execute BIOS-ul.

Secțiunea PEI verificată trebuie să conțină un modul care va verifica restul BIOS-ului (cod DXE). Acest modul este dezvoltat de IBV (Independent BIOS Vendor) sau de către furnizorul sistemului. Cum sistemele Lenovo și Gigabyte, care au suport Intel BG, au fost singurele disponibile, vom analiza codul preluat din aceste sisteme.

Modul UEFI BIOS LenovoVerifiedBootPei

În cazul Lenovo, acesta a fost modulul LenovoVerifiedBootPei {B9F2AC77-54C7-4075-B42E-C36325A9468D}, dezvoltat de compania Lenovo.

Funcția sa constă în găsirea (prin GUID) a tabelului de hash pentru DXE și în verificarea DXE.

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

Tabelul de hash {389CC6F2-1EA8-467B-AB8A-78E769AE2A15} are următorul format:

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

Modul UEFI BIOS BootGuardPei

În cazul Gigabyte, acesta a fost modulul BootGuardPei {B41956E1-7CA2-42DB-9562-168389F0F066}, dezvoltat de AMI, astfel că este prezent în orice BIOS AMI cu suport Intel BG.

Algoritmul său de funcționare este oarecum diferit, dar se concentrează pe aceleași principii:

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

Tabelul de hash {389CC6F2-1EA8-467B-AB8A-78E769AE2A15} pe care îl caută are următorul format:

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

Vom discuta pe scurt despre o altă implementare Intel Boot Guard, care a fost găsită într-un sistem mai recent bazat pe Intel SoC cu microarhitectura Apollo Lake — ASRock J4205-IT.

Deși această versiune va fi utilizată doar în SoC-uri (sistemele noi cu microarhitectura procesorului Kaby Lake continuând să folosească Intel Boot Guard 1.x), ea este de mare interes pentru studierea unei noi variante de arhitectură pentru platformele pe Intel SoC, în care s-au produs modificări notabile, cum ar fi:

  • regiunile BIOS și Intel ME (mai precis Intel TXE, conform terminologiei pentru Intel SoC) fiind acum o singură regiune IFWI;
  • Deși platforma avea Intel BG activat, structuri precum FIT, KEYM, IBBM nu au fost găsite în memoria flash;
  • Pe lângă nucleele TXE și ISH (x86), chipsetul a adăugat un al treilea nucleu (din nou ARC, de altfel) – PMC (Power Management Controller), legat de asigurarea funcționării subsistemului de alimentare și monitorizarea performanței.

Încărcare de încredere a lui Schrödinger. Intel Boot Guard
Conținutul noului domeniu IFWI este un set de următoarele module:

Offset
Nume
Descriere

0000 2000h
SMIP
o configurație a platformei, semnată de furnizor

0000 6000h
RBEP
secțiunea de cod a firmware-ului Intel TXE, x86, semnată de Intel

0001 0000h
PMCP
secțiunea de cod a firmware-ului Intel PMC, ARC, semnată de Intel

0002 0000h
FTPR
secțiunea de cod a firmware-ului Intel TXE, x86, semnată de Intel

0007 B000h
UCOD
actualizări de microcod pentru CPU, semnate de Intel

0008 0000h
IBBP
UEFI BIOS, fazele SEC/PEI, x86, semnată de furnizor

0021 8000h
ISHC
secțiunea de cod a firmware-ului Intel ISH, x86, semnată de furnizor

0025 8000h
NFTP
secțiunea de cod a firmware-ului Intel TXE, x86, semnată de Intel

0036 1000h
IUNP
necunoscut

0038 1000h
OBBP
UEFI BIOS, faza DXE, x86, nesemnat

Analizând firmware-ul TXE, a devenit evident că după RESET, TXE menține procesorul în această stare până când pregătește conținutul de bază al spațiului de adresare pentru CPU (FIT, ACM, vectorul RESET …). De altfel, TXE plasează aceste date în SRAM-ul său, după care oferă temporar acces procesorului și îl „deblochează” din RESET.

Pe calea rândurilor rău intenționate

Acum să trecem la „subiectul fierbinte”. Odată am descoperit că pe multe sisteme, descriptorii flash SPI au fost scriși cu permisiuni de acces la regiunile memoriei flash SPI astfel încât toți utilizatorii acestei memorii pot scrie și citi orice regiune. Asta înseamnă că deloc.

După verificarea cu ajutorul utilitarului MEinfo (din Intel STK), am observat că modul de fabricație pe aceste sisteme nu a fost închis, prin urmare, fuzionările chipset-ului (FPF-uri) au fost lăsate într-o stare nedeterminată. Da, Intel BG în aceste cazuri nu este nici activat, nici dezactivat.

Vorbind despre următoarele sisteme (referitor la Intel BG și ceea ce va fi expus în continuare în articol, ne vom referi la sisteme cu microarhitectura procesorului Haswell și mai recent):

  • toate produsele Gigabyte;
  • toate produsele MSI;
  • 21 model de laptopuri Lenovo și 4 modele de servere Lenovo.

Desigur, am raportat descoperirea acestor furnizori, precum și companiei Intel.

Răspunsul adecvat a venit doar de la Lenovo, care au recunoscut problema și au lansat un patch.

Gigabyte pare că au acceptat informația despre vulnerabilitate, dar nu au comentat deloc.

Comunicarea cu MSI s-a oprit complet la cererea noastră de a trimite cheia sa PGP deschisă (pentru a-i trimite un advisory de securitate într-o formă criptată). Ei au declarat că "sunt un producător de echipamente și nu produc chei PGP".

Dar, revenind la subiect. Deoarece fuzele sunt lăsate într-o stare neprogramată, utilizatorul (sau atacatorul) le poate programa singur (cel mai dificil este să găsească Intel STK). Pentru aceasta, este necesar să se efectueze următorii pași.

1. Încărcați în sistemul de operare Windows (de fapt, acțiunile descrise mai jos pot fi realizate și din Linux, dacă se dezvoltă un echivalent Intel STK pentru OS-ul dorit). Folosind utilitarul MEinfo, asigurați-vă că fuzele pe acest sistem nu sunt programate.

Încărcare de încredere a lui Schrödinger. Intel Boot Guard
2. Citiți conținutul memoriei flash folosind Flash Programming Tool.

Încărcare de încredere a lui Schrödinger. Intel Boot Guard
3. Deschideți imaginea citită cu orice instrument de editare a BIOS-ului UEFI, faceți modificările necesare (de exemplu, introduceți un rootkit), creați/schimbați structurile existente KEYM și IBBM în regiunea ME.

Încărcare de încredere a lui Schrödinger. Intel Boot Guard
Încărcare de încredere a lui Schrödinger. Intel Boot Guard
În imagine este evidențiată partea publică a cheii RSA, hash-ul căreia va fi programat în fuzele chipset-ului împreună cu restul configurației Intel BG.

4. Folosiți Flash Image Tool pentru a crea o nouă imagine a firmware-ului (stabilind configurația Intel BG).

Încărcare de încredere a lui Schrödinger. Intel Boot Guard
5. Scrieți noua imagine pe memoria flash folosind Flash Programming Tool, asigurați-vă prin MEinfo că regiunea ME conține acum configurația Intel BG.

Încărcare de încredere a lui Schrödinger. Intel Boot Guard
6. Folosiți Flash Programming Tool pentru a închide modul manufacturing mode.

Încărcare de încredere a lui Schrödinger. Intel Boot Guard
7. Sistemul se va reporni, după care, folosind MEinfo, se poate verifica că FPF-urile sunt acum programate.

Încărcare de încredere a lui Schrödinger. Intel Boot Guard
Aceste acțiuni vor activa Intel BG pe acest sistem. Anularea acțiunii nu va fi posibilă, ceea ce înseamnă:

  • actualizarea BIOS-ului UEFI pe acest sistem va putea fi realizată doar de deținătorul părții private a cheii de bază (adică cel care a activat Intel BG);
  • dacă se returnează acestui sistem firmware-ul original, de exemplu, folosind un programator, acesta nu se va porni (urmare a politicii de enforcement în cazul erorii de verificare);
  • pentru a scăpa de un astfel de BIOS UEFI, este necesară înlocuirea chipset-ului cu FPF-uri programate cu unul "curat" (adică să refolosiți chipset-ul, dacă aveți acces la o stație de lipit cu infraroșu cât costul unei mașini, sau pur și simplu să înlocuiți placa de bază).

Pentru a înțelege ce poate provoca un astfel de rootkit, trebuie să evaluăm ce posibilitate există de a executa codul său în mediul UEFI BIOS. Să spunem, în cel mai privilegiat mod al procesorului – SMM. Un astfel de rootkit poate avea următoarele caracteristici:

  • se poate executa paralel cu OS-ul (poate fi configurat să se activeze prin generarea unei întreruperi SMI, care va fi declanșată de un cronometru);
  • are toate avantajele de a se afla în modul SMM (acces complet la conținutul memoriei RAM și la resursele hardware, ascundere față de OS);
  • codul software al rootkit-ului poate fi în formă criptată și decriptat la pornire în modul SMM. Ca cheia pentru criptare pot fi folosite orice date disponibile doar în modul SMM. De exemplu, hash-ul unui set de adrese în SMRAM. Pentru a obține această cheie, va fi necesar să intri în SMM. Acest lucru se poate realiza în două moduri. Găsind RCE în codul SMM și exploatându-l, sau adăugând un modul SMM în BIOS-ul tău, ceea ce nu este posibil, deoarece am activat Boot Guard.

Astfel, această vulnerabilitate permite atacatorului:

  • să creeze un rootkit ascuns, imposibil de eliminat și de destinație necunoscută în sistem;
  • să execute codul său pe unul dintre nucleele chipset-ului din cadrul Intel SoC, și anume, pe Intel ISH (să ne uităm atent la imagine).

Încărcare de încredere a lui Schrödinger. Intel Boot Guard
Încărcare de încredere a lui Schrödinger. Intel Boot Guard
Deși capacitățile subsistemului Intel ISH nu sunt încă studiate, acesta pare a fi un vector interesant de atac asupra Intel ME.

Conclusions

  1. Cercetarea a permis obținerea unei descrieri tehnice a funcționării tehnologiei Intel Boot Guard. Minusurile unui model de securitate bazat pe obscuritate de la Intel.
  2. A fost prezentat un scenariu de atac care permite crearea unui rootkit imposibil de eliminat în sistem.
  3. Am văzut că procesoarele moderne Intel sunt capabile să execute mult cod proprietar chiar înainte de a începe funcționarea BIOS-ului.
  4. Platformele cu arhitectura Intel 64 devin din ce în ce mai puțin potrivite pentru a rula software liber: verificarea hardware-ului, numărul crescând de tehnologii și subsisteme proprietare (trei nuclee în chipset-ul SoC: x86 ME, x86 ISH și ARC PMC).

Mitigări

Furnizorii care lasă intenționat modul de fabricație deschis ar trebui să-l închidă neapărat. Deocamdată, doar își închid ochii, iar noile sisteme Kaby Lake arată acest lucru.

Utilizatorii pot dezactiva Intel BG pe sistemele lor (care sunt afectate de vulnerabilitatea descrisă), rulând utilitarul Flash Programming Tool cu parametrul -closemnf. În prealabil, ar trebui să se verifice (prin intermediul MEinfo) că configurația Intel BG în regiunea ME permite dezactivarea acestei tehnologii după programarea în FPF-uri.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster