Довереното качване на Шрьодингер. Intel Boot Guard

Довереното качване на Шрьодингер. Intel Boot Guard
Нека отново да слезем на дъното и да говорим за сигурността на фърмуерите за компютърни платформи, съвместими с x86. Този път основната съставка на изследването е Intel Boot Guard (не бъркайте с Intel BIOS Guard!) – хардуерна технология за доверено стартиране на BIOS, която производителят на компютърната система може трайно да включи или изключи на етапа на производство. А рецептата за изследване ни е позната: деликатно нарязване на реверс-инжинеринга на имплементацията на тази технология, описание на нейната архитектура, напълване с недокументирани детайли, овкусяване на атакуващи вектори и разбъркване. Нека добавим малко огън, разказвайки как повтарящата се грешка в производството на няколко производители позволява на потенциален нападател да използва тази технология за създаване на неизтриваем (дори от програмиста) скрит руткит в системата.

Между другото, основата на статията – докладите "На страже на руткитите: Intel BootGuard" от конференцията ZeroNights 2016 и 29-та среща DefCon Russia (и двете презентации тук.).

Фърмуер на компютърна платформа с архитектура Intel 64

Преди всичко, нека отговорим на въпроса: какво представлява фърмуерът на съвременна компютърна платформа с архитектура Intel 64? Разбира се, UEFI BIOS. Но такъв отговор няма да е точен. Нека погледнем изображението, на което е представен десктопният (лаптопният) вариант на тази архитектура.

Довереното качване на Шрьодингер. Intel Boot Guard
Основата е комбинацията:

  • Процесор (CPU, Central Processing Unit), в който, освен основните ядра, е вградено графично ядро (не във всички модели) и внедрен контролер на паметта (IMC, Integrated Memory Controller);
  • Чипсет (PCH, Platform Controller Hub), съдържащ различни контролери за взаимодействие с периферни устройства и управление на подсистемите. Сред тях е известният Intel Management Engine (ME), който също има своя фърмуер (Intel ME firmware).

Лаптопите, освен горепосоченото, предвиждат наличието на вграден контролер (ACPI EC, Advanced Control and Power Interface Embedded Controller), който отговаря за функционирането на подсистемата за захранване, тъчпада, клавиатурата, клавишите Fn (яркост на екрана, звукова сила, подсветка на клавиатурата и т.н.) и др. И той също има своя фърмуер.

Така, съвкупността от изброените по-горе фърмуери представлява фърмуера на компютърната платформа (system firmware), който се съхранява в обща SPI флаш памет. За да не се объркат потребителите на тази памет, съдържанието й е разделено на следните региони (както е показано на фигурата):

  • UEFI BIOS;
  • фърмуер на ACPI EC (отделен регион се появи с микроархитектурата на процесора Skylake (2015 година), но в реални условия все още не сме видели примери за неговото използване, така че фърмуерът на встроения контролер все още е част от UEFI BIOS);
  • фърмуер на Intel ME;
  • конфигурация (MAC адрес и т.н.) на встроения мрежов адаптер GbE (Gigabit Ethernet);
  • флаш описания (Flash Descriptors) – главният регион на флаш паметта, който съдържа указатели за останалите региони, както и разрешения за достъп до тях.

Довереното качване на Шрьодингер. Intel Boot Guard
Разграничаването на достъпа до регионите (в съответствие с определените разрешения) се извършва от мастер на шина SPI – встроен в чипсета SPI контролер, през който се осъществява достъпът до тази памет. Ако разрешенията са зададени на препоръчителните (от съображения за сигурност) от Intel стойности, то всеки потребител на SPI флаш паметта има пълен достъп (четене/писане) само до своя регион. Останалите – или са само за четене, или не са достъпни. Известен факт: на много системи CPU има пълен достъп до UEFI BIOS и GbE, достъп до четене само до флаш описанията, а към регион Intel ME достъп няма изобщо. Защо на много, а не на всички? Това, което е препоръчително, не е задължително. Повече ще разкажем в статията.

Механизми за защита на фърмуера на компютърната платформа от модификации

Очевидно е, че фърмуера на компютърната платформа трябва да бъде защитен от възможна компрометация, която би позволила на потенциален злонамерен потребител да се установи в него (да оцелее през актуализации/преинсталации на ОС), да изпълнява свой код в най-привилегированите режими и т.н. И разграничението на достъпа до регионите на SPI флаш паметта, разбира се, не е достатъчно. Затова се прилагани различни механизми за защита на фърмуера от модификации, специфични за всяка среда на изпълнение.

Така, фърмуерът на Intel ME е подписан за контрол на целостта и автентичността и се проверява от ME контролера при всяко негово зареждане в паметта ME UMA. Този процес на верификация вече беше разгледан от нас в един от статии, посветена на подсистемата Intel ME.

А фирмата ACPI EC, като правило, се проверява само за цялостност. Въпреки това, тъй като този бинарен файл е включен в UEFI BIOS, почти винаги важат същите механизми за защита, каквито използва UEFI BIOS. За тях ще говорим.

Тези механизми могат да се разделят на две категории.

Защита от запис в региона на UEFI BIOS

  1. Физическа защита на съдържанието на SPI флаш паметта с помощта на write-protect джъмпер;
  2. Защита на проекцията на региона UEFI BIOS в адресното пространство на CPU чрез PRx регистрите на чипа;
  3. Блокиране на опити за запис в региона на UEFI BIOS чрез генериране и обработка на съответното прекъсване SMI чрез задаване на битовете BIOS_WE/BLE и SMM_BWP в регистрите на чипа;
  4. По-усъвършенстван вариант на такава защита е Intel BIOS Guard (PFAT).

В допълнение към тези механизми, производителите могат да разработват и прилагат собствени мерки за сигурност (например, подписване на капсули с актуализации на UEFI BIOS).

Важно е да отбележим, че на конкретна система (в зависимост от производителя) могат да бъдат приложени не всички изброени механизми за защита, да не бъдат приложени изобщо или да бъдат уязвимо реализирани. Повече информация за тези механизми и ситуацията с тяхната реализация може да се прочете в тази статия. За заинтересованите препоръчваме да се запознаят с целия цикъл статии за сигурността на UEFI BIOS от CodeRush.

Верификация на автентичността на UEFI BIOS

Когато говорим за технологии за доверено зареждане, първото, което идва наум, е Secure Boot. Въпреки това, архитектурно, той е предназначен за проверка на автентичността на външни, спрямо UEFI BIOS, компоненти (драйвери, загрузчици и т.н.), а не на самата фърмуер.

Следователно, компанията Intel в SoC-ите с микроархитектура Bay Trail (2012 година) внедри апаратен недизключаем Secure Boot (Verified Boot), който няма нищо общо с гореспоменатата технология Secure Boot. По-късно (2013 година) този механизъм беше усъвършенстван и под името Intel Boot Guard беше пуснат за десктопи с микроархитектура Haswell.

Преди да опишем Intel Boot Guard, нека се разберем със средите на изпълнение в архитектурата Intel 64, които, заедно, са корените на доверието за тази технология за доверено зареждане.

Процесор Intel

Кэп подсказва, че процесорът е основната среда на изпълнение в архитектурата Intel 64. Защо той е корен на доверието? Оказва се, че той притежава следните елементи:

  • Микрокод ROM — енергийно независима, неизтриваема памет за съхранение на микрокода. Смята се, че микрокодът е имплементация на системата за команди на процесора на основни инструкции. В микрокода също възникват грешки. Така че в BIOS могат да се намерят бинарни файлове с актуализации на микрокода (те се налагат по време на зареждане, тъй като ROM не може да бъде записан повторно). Съдържанието на тези бинарни файлове е криптирано, което значително усложнява анализа (поради това конкретното съдържание на микрокода е известно само на тези, които го разработват), и е подписано за контрол на целостта и автентичността;
  • AES ключ за декриптиране на съдържанието на актуализациите на микрокода;
  • хеш на публичния ключ RSA, с който се проверява подписа на актуализациите на микрокода;
  • хеш на публичния ключ RSA, с който се проверява подписа на кодовите модули ACM (Authenticated Code Module), разработени от Intel, които CPU може да изпълнява преди началото на изпълнението на BIOS (привет на микрокода) или по време на неговата работа, при възникване на определени събития.

Intel ME

На тази подсистема в нашия блог беше посветен дори две на статията. Напомняме, че тази изпълнима среда е основана на вградения в чипсета микроконтролер и е най-скритата и привилегирована в системата.

Въпреки скритостта, Intel ME също е коренът на доверието, тъй като има:

  • ME ROM — енергийно независима, неизтриваема памет (начин за актуализиране не е предвиден), съдържаща стартиращ код, както и SHA256 хеш на публичния ключ RSA, с който се проверява подписа на фърмуера на Intel ME;
  • AES ключ за съхранение на секретна информация;
  • достъп до вградения в чипсета комплект фюзи (FPFs, Field Programmable Fuses) за перманентно съхранение на някои данни, включително и на тези, зададени от доставчика на компютърната система.

Intel Boot Guard 1.x

Небольшой дисклеймер. Номера версий технологии Intel Boot Guard, которыми мы оперируем в этой статье, являются условными, и могут не иметь ничего общего с нумерацией, которая применяется во внутренней документации компании Intel. К тому же, приведённые здесь сведения об имплементации этой технологии были получены в ходе реверс-инжиниринга, и могут содержать неточности по сравнению со спецификацией на Intel Boot Guard, которая вряд ли когда-нибудь будет опубликована.

И така, Intel Boot Guard (BG) е хардуерно поддържана технология за удостоверяване на автентичността на UEFI BIOS. Съдя по краткото си описание в книгата [Platform Embedded Security Technology Revealed, глава Boot with Integrity, or Not Boot], тя работи като верига на доверена зареждане. Първият елемент в нея е зареждащият код (микрокод) в CPU, който се активира при събитие RESET (не бъркайте с RESET-вектора в BIOS!). CPU намира проектиран и подписан от Intel кодов модул (Intel BG startup ACM) в SPI флаш паметта, зарежда го в кеша си, удостоверява (както бе споменато по-горе, CPU разполага с хеш на публичния ключ, с който се проверява подписа на ACM) и стартира.

Довереното качване на Шрьодингер. Intel Boot Guard

Този кодов модул отговаря за удостоверяване на малка стартова част от UEFI BIOS — Initial Boot Block (IBB), който от своя страна съдържа функционалността за удостоверяване на основната част на UEFI BIOS. По този начин Intel BG позволява да се уверите в автентичността на BIOS преди зареждането на операционната система (която може да се изпълнява под наблюдение на технологията Secure Boot).

Технологията Intel BG предвижда два режима на работа (като единият не пречи на другия, т.е. и двата режима могат да бъдат включени в системата, или и двата да бъдат изключени).

Measured Boot

В режима Measured Boot (MB) всеки компонент на зареждане (започвайки от CPU boot ROM) "измерва" следващия, използвайки възможностите на TPM (Trusted Platform Module). За тези, които не са запознати, да поясним.

TPM има PCR-ите (Platform Configuration Registers), в които се записва резултатът от хеширането по формулата:

Довереното качване на Шрьодингер. Intel Boot Guard

Т.е. текущата стойност на PCR зависи от предишната, като данните в регистрите се нулират само при RESET на системата.

По този начин, в режима MB в определен момент PCR-ите отразяват уникален (в границите на възможностите на хеширането) идентификатор на кода или данните, които "измервани". Стойностите на PCR могат да бъдат използвани при операцията по шифроване на определени данни (TPM_Seal). След това, тяхното декриптиране (TPM_Unseal) ще бъде възможно само в случай, че стойностите на PCR в резултат от зареждането не са се променили (т.е. нито един "измерен" компонент не е бил модифициран).

Verified Boot

Най-страшното за любителите на модификация на UEFI BIOS е режимът Verified Boot (VB), при който всеки компонент на зареждане криптографски проверява целостта и автентичността на следващия. А в случай на грешка в удостоверяването, настъпва (едно от):

  • изключване по таймаут от 1 мин до 30 мин (за да може потребителят да разбере причината, поради която компютърът му не се зарежда, и, по възможност, да опита да възстанови BIOS);
  • незабавно изключване (за да не може потребителят да разбере нищо и, особено, да направи нещо);
  • продължаване на работа с невъзмутим вид (този случай, когато безопасността не е приоритет, защото има по-важни дела).

Изборът на действие зависи от зададената конфигурация Intel BG (а именно, от т.н. enforcement policy), която вендорът на компютърната платформа постоянно записва в специално предназначено хранилище – фюзите на чипсета (FPF-ите). По-точно ще се спрем на този момент по-късно.

Освен конфигурацията, вендорът генерира два ключа RSA 2048 и създава две структури от данни (изобразени на изображението):

  1. Манифест на коренния ключ на вендора (KEYM, OEM Root Key Manifest), в който поставя SVN (Security Version Number) на този манифест, SHA256 хеш на публичния ключ на следващия манифест, публичен ключ RSA (т.е. публичната част на коренния ключ на вендора) за проверка на подписа на този манифест и самия подпис;
  2. Манифест IBB (IBBM, Initial Boot Block Manifest), в който поставя SVN на този манифест, SHA256 хеш на IBB, публичен ключ за проверка на подписа на този манифест и самия подпис.

SHA256 хешът на публичния ключ на OEM Root Key постоянно се записва във фюзите на чипсета (FPF-ите), както и конфигурацията Intel BG. Ако конфигурацията Intel BG предвижда активиране на тази технология, то от този момент на съответната система обновяването на BIOS (т.е. възможността за преизчисляване на тези манифести) може да се извършва само от притежателя на частния ключ на OEM Root Key, т.е. вендора.

Довереното качване на Шрьодингер. Intel Boot Guard

При поглед върху картината веднага възникват съмнения относно необходимостта от така дълга верификационна верига – можеше да се използва един манифест. Защо да усложняваме?

Всъщност, компанията Intel по този начин предоставя на вендора възможността да използва различни ключове IBB за различни линии на своите продукти и един – като коренен. Ако частният ключ на IBB (с който се подписва вторият манифест) изтече, инцидентът ще засегне само една линия продукти и само дотогава, докато вендорът не генерира нова двойка и не включи преизчислените манифести в следващото обновление на BIOS.

Но ако основният ключ (с който се подписва първият манифест) бъде компрометиран, няма да може да бъде заменен. Процедура за отмяна не е предвидена, тъй като хешът на публичната част на този ключ е програмиран в FPF-ите веднъж завинаги.

Конфигурация на Intel Boot Guard

Сега да се спрем по-подробно на конфигурацията на Intel BG и процеса на нейното създаване. Ако погледнем съответната раздела в графичния интерфейс на утилитата Flash Image Tool от комплекта Intel System Tool Kit (STK), можем да забележим, че конфигурацията на Intel BG включва хеш на публичната част на коренния ключ на доставчика, двойка неясни стойности и т.н. профил Intel BG.

Довереното качване на Шрьодингер. Intel Boot Guard

Структурата на този профил:

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 – не прави нищо
                                              // 01b – изключване с таймаут
                                              // 11b – незабавно изключване
	unsigned long : 26;
};

По принцип, конфигурацията на Intel BG е много гъвкава. Нека разгледаме, например, флага Force_Boot_Guard_ACM. Когато той е деактивиран, в случай че модулът BG startup ACM на SPI флаш паметта не бъде намерен, доверена зареждане няма да се извърши. Ще бъде незабелязано.

Вече писахме, че политиката за налагане за режим VB може да бъде настроена така, че при грешка верификацията да доведе до незабелязано зареждане.

Да оставим такива неща на преценката на доставчиците...

GUI утилитата предвижда следните "вградени" профили:

Номер
Режим
Описание

0
No_FVME
технологията Intel BG е изключена

1
VE
включен режим VB, изключване по таймаут

2
VME
включени са и двата режима (VB и MB), изключване по таймаут

3
VM
включени са и двата режима, без изключване на системата

4
FVE
включен режим VB, незабавно изключване

5
FVME
включени са и двата режима, незабавно изключване

Както вече беше споменато, конфигурацията на Intel BG трябва да бъде записана веднъж завинаги от доставчика на системата във фюзите на чипсета (FPF-ите) – малко (по непотвърдена информация, само 256 байта) хардуерно хранилище на информация в чипсета, което може да бъде програмирано извън производствените мощности на компания Intel (защото именно Field Programmable Fuses).

То е отлично за съхранение на конфигурацията, тъй като:

  • разполага с еднократна програмируема област за съхраняване на данни (точно там, където се записва конфигурацията на Intel BG);
  • чита и програмира само Intel ME.

За да зададете конфигурацията за технологията Intel BG на конкретна система, производителят извършва следните стъпки по време на производството:

  1. С помощта на утилитата Flash Image Tool (от Intel STK) се създава образ на фърмуера с определената конфигурация Intel BG, представена като променливи в региона Intel ME (т.н. временно огледало за FPF-ове);
  2. С помощта на утилитата Flash Programming Tool (от Intel STK) този образ се записва в SPI флаш паметта на системата и се затваря т.н. manufacturing mode (при което се изпраща съответната команда в Intel ME).

В резултат на тези операции Intel ME записва в FPF-ове зададените стойности от огледалото за FPF-ове в ME региона, регулира разрешенията в SPI флаш дескрипторите на препоръчителните от компанията Intel стойности (описани в началото на статията) и изпълнява RESET на системата.

Анализ на имплементацията на Intel Boot Guard

С цел анализ на реализацията на тази технология на конкретен пример проверихме следните системи за наличие на следи от технологията Intel BG:

Система
Забележка

Gigabyte GA-H170-D3H
Skylake, поддържа се

Gigabyte GA-Q170-D3H
Skylake, поддържа се

Gigabyte GA-B150-HD3
Skylake, поддържа се

MSI H170A Gaming Pro
Skylake, не се поддържа

Lenovo ThinkPad 460
Skylake, поддържа се, технологията е активирана

Lenovo Yoga 2 Pro
Haswell, не се поддържа

Lenovo U330p
Haswell, не се поддържа

Под "поддръжка" се разбира наличието на Intel BG startup ACM модула, споменатите по-горе манифести и съответния код в BIOS, т.е. имплементация за анализ.

Като пример, ще вземем изтегления от официалния сайт на производителя образ на SPI флаш памет за Gigabyte GA-H170-D3H (версия F4).

Intel CPU boot ROM

На първо място, ще говорим за действията на процесора в случай, че технологията Intel BG е активирана.

Не успяхме да намерим образци на декодирания микрокод, затова как описаните по-долу действия са реализирани (в микрокод или хардуерно) остава открит въпрос. Въпреки това, факт е, че съвременните процесори Intel "умее" да извършват тези действия.

След като излезе от RESET, процесорът (в адресното пространство на който вече е показано съдържанието на флаш паметта) намира таблицата FIT (Firmware Interface Table). Намирането ѝ е просто, указателят към нея е записан на адрес FFFF FFC0h.

Довереното качване на Шрьодингер. Intel Boot Guard
В разглеждания пример на този адрес се намира стойността FFD6 9500h. Когато процесорът се обърне към този адрес, той вижда таблицата FIT, чийто съдържание е разбито на записи. Първият запис е заглавие на следната структура:

typedef struct FIT_HEADER
{
	char           Tag[8];     // ‘_FIT_   ’
	unsigned long  NumEntries; // включително FIT header entry
	unsigned short Version;    // 1.0
	unsigned char  EntryType;  // 0
	unsigned char  Checksum;
};

Довереното качване на Шрьодингер. Intel Boot Guard
По неизвестна причина контролна сума не винаги е изчислена в тези таблици (полето остава нулево).

Останалите записи сочат към различни бинарни файлове, които трябва да бъдат парснати/изпълнени още преди стартиране на BIOS, т.е. преди преминаване на legacy RESET-вектор (FFFF FFF0h). Структурата на всяка такава запись е следната:

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

Довереното качване на Шрьодингер. Intel Boot Guard
Полето EntryType указва типа блок, на който сочи тази запись. Известни са няколко типа:

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

Сега е очевидно, че една от записите указва местоположението на бинарния файл Intel BG startup ACM. Структурата на заглавието на този бинарен файл е типична за разработените от Intel кодови модули (ACM-ове, актуализации на микрокода, кодови раздели Intel ME, …).

typedef struct BG_ACM_HEADER
{
	unsigned short ModuleType;     \/\/ 2
	unsigned short ModuleSubType;  \/\/ 3
	unsigned long  HeaderLength;   \/\/ в dwords
	unsigned long  : 32;
	unsigned long  : 32;
	unsigned long  ModuleVendor;   \/\/ 8086h
	unsigned long  Date;           \/\/ в BCD формат
	unsigned long  TotalSize;      \/\/ в dwords
	unsigned long  unknown1[6];
	unsigned long  EntryPoint;
	unsigned long  unknown2[16];
	unsigned long  RsaKeySize;     \/\/ в dwords
	unsigned long  ScratchSize;    \/\/ в dwords
	unsigned char  RsaPubMod[256];
	unsigned long  RsaPubExp;
	unsigned char  RsaSig[256];
};

Довереното качване на Шрьодингер. Intel Boot Guard
Процесорът зарежда този бинарен файл в кеша си, проверява и стартира.

Intel BG startup ACM

В резултат на анализа на работата на този ACM стана ясно, че той извършва следното:

  • получава от Intel ME конфигурация на Intel BG, записана във фюзите на чипсета (FPF-ове);
  • намира манифестите KEYM и IBBM и ги проверява.

За да намери тези манифести, ACM също използва таблицата FIT, в която са отделени два типа записи за указване на данни от структурата (вижте FIT_ENTRY_TYPES по-горе).

Нека се спрем по-подробно на манифестите. В структурата на първия манифест виждаме няколко неясни константи, хеш на публичния ключ от втория манифест и публичния ключ OEM Root Key с подпис, представен под формата на вложена структура:

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

Довереното качване на Шрьодингер. Intel Boot Guard
За верификация на публичния ключ OEM Root Key, напомняме, че се използва SHA256 хеш от фюзовете, който на този етап вече е получен от Intel ME.

Преминаваме към втория манифест. Той се състои от три структури:

typedef struct IBB_MANIFEST
{
	ACBP Acbp;         // Политики за стартиране
	IBBS Ibbs;         // Описание на IBB
	IBB_DESCRIPTORS[];
	PMSG Pmsg;         // Подпис на IBBM
};

В първата – някакви константи:

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

Втората съдържа SHA256 хеш на IBB и броя на дескрипторите, които описват съдържанието на IBB (т.е. това, от което се изчислява хешът):

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 на IBB
	unsigned char  NumIbbDescriptors;
};

Дескрипторите на IBB следват след тази структура, един след друг. Съдържанието им има следния формат:

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

Всичко е просто: всеки дескриптор съдържа адрес/размер на част от IBB. Така че, конкатенацията на блоковете, на които сочат тези дескриптори (в реда на разположението на самите дескриптори) е самият IBB. И, обикновено, IBB е съвкупността от всички модули на фазите SEC и PEI.

Вторият манифест завършва със структура, съдържаща публичния ключ на IBB (верифицируем чрез SHA256 хеша от първия манифест) и подписа на този манифест:

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

Довереното качване на Шрьодингер. Intel Boot Guard
И така, още преди да започне изпълнението на UEFI BIOS, процесорът стартира ACM, който проверява автентичността на съдържанието на разделите с кодовете SEC и PEI. След това, процесорът излиза от ACM, преминава по RESET-вектора и започва да изпълнява BIOS.

Потвърденият раздел PEI трябва да съдържа модул, който да провери останалата част от BIOS (DXE код). Този модул се разработва от IBV (Independent BIOS Vendor) или самия производител на системата. Понеже в нашите наличности и с поддръжка от Intel BG бяха само системи Lenovo и Gigabyte, ще разгледаме кода, извлечен именно от тези системи.

UEFI BIOS модул LenovoVerifiedBootPei

В случай на Lenovo, това е модулът LenovoVerifiedBootPei {B9F2AC77-54C7-4075-B42E-C36325A9468D}, разработен от компанията Lenovo.

Неговата работа е да търси (по GUID) хеш-таблица за DXE и да извършва верификация на DXE.

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

Хеш таблица {389CC6F2-1EA8-467B-AB8A-78E769AE2A15} има следния формат:

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 модул BootGuardPei

В случай на Gigabyte, това е модулът BootGuardPei {B41956E1-7CA2-42DB-9562-168389F0F066}, разработен от AMI, следователно, присъстващ във всеки AMI BIOS с поддръжка на Intel BG.

Алгоритъмът на работа е малко по-различен, но в крайна сметка е аналогичен:

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

Хеш таблица {389CC6F2-1EA8-467B-AB8A-78E769AE2A15}, която той търси, има следния формат:

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

Накратко ще споменем още една реализация на Intel Boot Guard, която беше намерена в по-нова система на базата на Intel SoC с микроархитектура Apollo Lake — ASRock J4205-IT.

Въпреки че тази версия ще се прилага единствено за SoC устройства (новите системи с процесорна микроархитектура Kaby Lake продължават да използват Intel Boot Guard 1.x), тя представлява голям интерес за изучаването на нов вариант на архитектурата за платформи на Intel SoC, в която се случиха съществени промени, например:

  • регионите на BIOS и Intel ME (по-скоро Intel TXE, в съответствие с терминологията за Intel SoC) вече представляват един регион IFWI;
  • Въпреки че на платформата беше активиран Intel BG, влошени структури като FIT, KEYM, IBBM не бяха намерени във флаш паметта;
  • В допълнение към ядрата TXE и ISH (x86), в чипсета добавиха трето ядро (отново ARC, между другото) – PMC (Power Management Controller), свързано с осигуряване на работоспособността на захранващата подсистема и мониторинга на производителността.

Довереното качване на Шрьодингер. Intel Boot Guard
Съдържанието на новия регион IFWI представлява набор от следните модули:

Офсет
Име
Описание

0000 2000h
SMIP
някаква конфигурация на платформата, подписана от вендора

0000 6000h
RBEP
кодова секция на фърмуера Intel TXE, x86, подписана от Intel

0001 0000h
PMCP
кодова секция на фърмуера Intel PMC, ARC, подписана от Intel

0002 0000h
FTPR
кодова секция на фърмуера Intel TXE, x86, подписана от Intel

0007 B000h
UCOD
обновления на микрокода за CPU, подписан от Intel

0008 0000h
IBBP
UEFI BIOS, фази SEC/PEI, x86, подписан от вендора

0021 8000h
ISHC
кодова секция на фърмуера Intel ISH, x86, подписана от вендора

0025 8000h
NFTP
кодова секция на фърмуера Intel TXE, x86, подписана от Intel

0036 1000h
IUNP
неизвестно

0038 1000h
OBBP
UEFI BIOS, фаза DXE, x86, не подписан

При анализа на фърмуера TXE стана очевидно, че след RESET TXE задържа процесора в това състояние, докато не подготви базовото съдържание на адресното пространство за CPU (FIT, ACM, RESET-вектор…). При това TXE поставя тези данни в SRAM при себе си, след което временно предоставя достъп на процесора до тях и го 'освобождава' от RESET.

На страже руткитов

Сега нека преминем към 'горещата' част. Един ден открихме, че на много системи в SPI флаш-дескрипторите са записани разрешения за достъп до регионите на SPI флаш паметта така, че всички потребители на тази памет могат да четат и записват всеки регион. Тоест, никак.

След проверка с помощта на утилита MEinfo (от Intel STK) видяхме, че режимът manufacturing mode на тези системи не е затворен, следователно фюзовете на чипсета (FPF-ите) са оставени в неопределено състояние. Да, Intel BG в такива случаи не е нито включен, нито изключен.

Става въпрос за следните системи (по отношение на Intel BG и това, което ще бъде изложено по-долу в статията, ще говорим за системи с процесорна микроархитектура Haswell и по-висока):

  • всички продукти на Gigabyte;
  • всички продукти на MSI;
  • 21 модел лаптопи Lenovo и 4 модела сървъри Lenovo.

Разбира се, уведомихме тези вендори, както и компания Intel.

Адекватна реакция последва само от Lenovo, които признали проблема и издадоха пач.

Gigabyte въпреки че приеха информацията за уязвимостта, не коментираха по никакъв начин.

Комуникация с MSI пълно се е забавило на нашето искане да изпратят своя открит PGP ключ (за да им изпратим security advisory в криптиран вид). Те заявиха, че «са производители на оборудване и PGP ключове не произвеждат».

Но по същество. Тъй като фюзите остават в неопределено състояние, потребителят (или злоумышленикът) може да ги програмира самостоятелно (най-трудното е да намери Intel STK). За това е необходимо да се извършат следните действия.

1. Да се зареди в ОС Windows (всъщност, описаните по-долу действия могат да бъдат извършени и под Linux, ако се разработи аналог на Intel STK за нужната ОС). Използвайки утилитата MEinfo, да се уверите, че фюзите на тази система не са програмирани.

Довереното качване на Шрьодингер. Intel Boot Guard
2. Да се счете съдържанието на флаш паметта с помощта на Flash Programming Tool.

Довереното качване на Шрьодингер. Intel Boot Guard
3. Да се отвори считаният образ с помощта на всякакъв инструмент за редактиране на UEFI BIOS, да се внесат необходимите промени (например, внедряване на руткит), да се създадат/редактират съществуващите структури KEYM и IBBM в ME региона.

Довереното качване на Шрьодингер. Intel Boot Guard
Довереното качване на Шрьодингер. Intel Boot Guard
На картинката е подчертана публичната част на RSA ключа, хешът на който ще бъде програмиран във фюзите на чипсета заедно с останалата конфигурация на Intel BG.

4. С помощта на Flash Image Tool да се събере нов образ на фърмуера (като се зададе конфигурацията на Intel BG).

Довереното качване на Шрьодингер. Intel Boot Guard
5. Да се запише новият образ на флаш паметта с помощта на Flash Programming Tool, да се уверите с MEinfo, че ME регионът сега съдържа конфигурацията на Intel BG.

Довереното качване на Шрьодингер. Intel Boot Guard
6. С помощта на Flash Programming Tool да се затвори режимът manufacturing mode.

Довереното качване на Шрьодингер. Intel Boot Guard
7. Системата ще се рестартира, след което с помощта на MEinfo може да се уверите, че FPF-ите сега са програмирани.

Довереното качване на Шрьодингер. Intel Boot Guard
Тези действия завинаги включат Intel BG на тази система. Отмяна на действието няма да бъде възможна, което означава:

  • обновяването на UEFI BIOS на тази система ще може да извърши само притежателят на частния ключ на кореновия ключ (т.е. този, който е включил Intel BG);
  • ако се върне оригиналната фърмуер на тази система, например, с помощта на програмист, тя дори няма да се включи (последствие на enforcement policy в случай на грешка при верификация);
  • за да се отървем от такъв UEFI BIOS, е необходимо да се замени чипсет с програмирани FPF-си на „чист“ (т.е. да се препои чипсета, ако имате достъп до инфрачервена запояваща станция, цената на която е като на автомобил, или просто да се смени дънната платка).

За да разберем какво може да направи такъв руткит, е нужно да оценим какво предствлява изпълнението на код в средата на UEFI BIOS. Например, в най-привилегирования режим на процесора – SMM. Такъв руткит може да има следните свойства:

  • да се изпълнява паралелно с ОС (може да бъде настроен да реагира на генериране на SMI прекъсване, което ще бъде задействано по таймер);
  • да има всички предимства на находката в режим SMM (пълен достъп до съдържанието на оперативната памет и хардуерни ресурси, невидимост от ОС);
  • програмният код на руткита може да бъде в криптиран вид и да се декриптира при стартиране в режим SMM. Като ключ за криптиране могат да се използват всякакви данни, налични само в режим SMM. Например, хеш от набор адреси в SMRAM. За да получим този ключ, е нужно да навлезем в SMM. А това може да стане по два начина. Да намерим RCE в кода на SMM и да го експлоатираме, или да добавим свой SMM модул в BIOS, което е невъзможно, тъй като сме активирали Boot Guard.

Така че, тази уязвимост позволява на злонамерени участници:

  • да създадат в системата скрит, неудаляем руткит с неизвестна цел;
  • да изпълняват своя код на едно от ядрата на чипсета в Intel SoC, а именно, на Intel ISH (внимателно разгледайте изображението).

Довереното качване на Шрьодингер. Intel Boot Guard
Довереното качване на Шрьодингер. Intel Boot Guard
Въпреки че възможностите на подсистемата Intel ISH все още не са изследвани, тя представлява интересен вектор за атака на Intel ME.

Изводи

  1. Изследването позволи да се получи техническо описание на работата на технологията Intel Boot Guard. Минус някои тайни в модела на сигурност на Intel чрез непроницаемост.
  2. Представен е сценарий на атака, който позволява създаването на неудаляем руткит в системата.
  3. Ние видяхме, че съвременните процесори Intel могат да изпълняват много проприетарен код още преди стартиране на BIOS.
  4. Платформите с архитектура Intel 64 стават все по-малко подходящи за стартиране на свободен софтуер: хардуерна верификация, нарастващ брой проприетарни технологии и подсистеми (три ядра в SoC чипсета: x86 ME, x86 ISH и ARC PMC).

Mitigations

На доставчиците, които умишлено оставят производствения режим отворен, трябва да им се наложи да го затворят. Досега само затварят очи и новите системи Kaby Lake го доказват.

Потребителите могат сами да деактивират Intel BG на своите системи (които са податливи на описаната уязвимост), като стартират утилитата Flash Programming Tool с параметър -closemnf. Преди това, трябва да се уверите (чрез MEinfo), че конфигурацията на Intel BG в региона ME предвижда именно деактивация на тази технология след програмиране в FPF-ите.

Източник: habr.com

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster