
Предлагаме отново да се спуснем на ниско ниво и да говорим за безопасността на фърмуерa на компютърни платформи, съвместими с x86. Този път основната съставка на изследването е Intel Boot Guard (да не се бърка с Intel BIOS Guard!) – хардуерно поддържана технология за доверена зареждане на BIOS, която производителят на компютърната система може постоянно да включва или изключва в етапа на производство. Рецептата за изследването е вече позната: фино нарязване на реверс-инженеринг на имплементацията на тази технология, описание на архитектурата ѝ, запълнена с недокументирани детайли, подправяне на вкус с атаки и разбъркване. Ще добавим малко огън, като разкажем как дългогодишна производствена грешка на няколко производители позволява на потенциален злонамерен субект да използва тази технология за създаване на неелиминируем (даже с програматор) скрит руткит в системата.
Статията е основана на докладите "На страже на рутките: Intel BootGuard" от конференцията и 29-то издание на (двете презентации ).
Фърмуер на компютърна платформа с архитектура Intel 64
Първо, нека отговорим на въпроса: какво представлява фърмуерът на съвременната компютърна платформа с архитектура Intel 64? Разбира се, UEFI BIOS. Но такъв отговор би бил неточен. Нека да погледнем в изображението, където е показан десктоп (или лаптоп) вариант на тази архитектура.

Основата е комбинация от:
- Процесор (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) – основният регион на флаш-паметта, който съдържа указатели към останалите региони, а също и разрешения за достъп до тях.

Разграничението на достъпа до регионите (в съответствие с определените разрешения) се извършва от майстора на шина 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
- Физическа защита на съдържанието на SPI флаш паметта чрез джъмпер за защита от запис;
- Защита на проекцията на UEFI BIOS в адресното пространство на CPU чрез PRx регистрите на чипсета;
- Блокиране на опити за запис в региона на UEFI BIOS чрез генериране и обработка на съответното прекъсване SMI чрез настройване на битовете BIOS_WE/BLE и SMM_BWP в регистрите на чипсета;
- По-усъвършенстван вариант на такава защита е Intel BIOS Guard (PFAT).
В допълнение към тези механизми, доставчиците могат да разработват и прилагат свои собствени мерки за сигурност (например подписване на капсули с актуализации на UEFI BIOS).
Важно е да се отбележи, че на конкретна система (в зависимост от доставчика) могат да не бъдат приложени всички изброени механизми за защита, да не бъдат приложени изобщо или да бъдат реализирани уязвимо. Повече за тези механизми и ситуацията с тяхната реализация можете да прочетете в . На заинтересованите препоръчваме да се запознаят с целия цикъл от статии относно сигурността на UEFI BIOS от .
Верификация на легитимността на UEFI BIOS
Когато говорим за технологии за доверено зареждане, първото нещо, което идва наум, е Secure Boot. Но архитектурно той е предназначен за проверка на автентичността на външни компоненти, спрямо UEFI BIOS (драйвери, зареждачи и т.н.), а не самия фърмуер.
Затова компанията Intel е реализирала хардуерен, недеактивируем Secure Boot (Verified Boot) в SoC с микропроцесорна архитектура Bay Trail (2012 г.), който няма нищо общо с горепосочената технология Secure Boot. По-късно (2013 г.) този механизъм беше усъвършенстван и под името Intel Boot Guard беше пуснат за десктопи с микропроцесорна архитектура Haswell.
Преди да опишем Intel Boot Guard, нека разгледаме средите на изпълнение в архитектурата Intel 64, които съвпадат с корените на доверието за тази технология за доверено зареждане.
Intel CPU
Кэп подказва, че процесорът е основната среда на изпълнение в архитектурата 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 открива на SPI флаш паметта проектиран и подписан от Intel кодов модул (Intel BG startup ACM), зарежда го в кеша си, верифицира (както беше споменато по-горе, CPU има хеш на публичния ключ, с който се проверява подписът на ACM) и го стартира.

Този кодов модул отговаря за верификацията на малка стартова част от 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), в които се записва резултатът от операцията по хеширане по формулата:

Т.е. текущото значение на 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 и създава две структури от данни (изобразени на фигурата):
- Манифест на коренния ключ на производителя (KEYM, OEM Root Key Manifest), в който се съдържа SVN (Security Version Number) на този манифест, SHA256 хеш на публичния ключ на следващия манифест, публичен ключ RSA (т.е. публичната част на коренния ключ на производителя) за проверка на подписа на този манифест и самият подпис;
- Манифест IBB (IBBM, Initial Boot Block Manifest), в който се съдържа SVN на този манифест, SHA256 хеш на IBB, публичен ключ за проверка на подписа на този манифест и самият подпис.
SHA256 хешът на публичния ключ на OEM Root Key постоянно се записва във фюзите на чипсета (FPF-ите), както и конфигурацията Intel BG. Ако конфигурацията Intel BG предвижда активиране на тази технология, то от този момент нататък само собственикът на частния ключ на OEM Root Key, т.е. производителят, може да обновява BIOS на тази система (т.е. да има възможност да преизчислява тези манифести).

При поглед към картинката веднага възниква съмнение в необходимостта от такава дълга верига за проверка – можеше да се използва само един манифест. Защо да се усложнява?
Всъщност компанията Intel по този начин предоставя на производителя възможността да използва различни ключове IBB за различни линии на своите продукти и един – като коренен. Ако частният ключ на IBB (с който се подписва вторият манифест) изтече, инцидентът ще засегне само една линия продукти и само дотогава, докато производителят не генерира нова двойка и не включи преизчислените манифести в следващото обновление на BIOS.
Но ако кореновият ключ (с който се подписва първият манифест) бъде компрометиран, не може да бъде заменен, тъй като не съществуват процедури за отмяна, тъй като хешът на публичната част на този ключ е програмиран в FPF-ите веднъж завинаги.
Конфигурация на Intel Boot Guard
Сега ще разгледаме по-подробно конфигурацията на Intel BG и процеса на нейното създаване. Ако погледнете съответната вкладка в GUI на инструмента Flash Image Tool от комплекта Intel System Tool Kit (STK), можете да видите, че конфигурацията на Intel BG включва хеш на публичната част от кореновия ключ на доставчика, двойка непознати стойности и т.н. профил на Intel BG.

Структурата на този профил:
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 на конкретна система, производителят по време на производството предприема следното:
- С помощта на утилитата Flash Image Tool (от Intel STK) се създава образ на фърмуера с зададената конфигурация Intel BG под формата на променливи в региона Intel ME (т.н. временно огледало за FPF-ите);
- С помощта на утилитата 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.

В разглеждания пример, на този адрес се намира стойността FFD6 9500h. Объркайки се на този адрес, процесорът вижда таблицата FIT, съдържанието на която е разделено на записи. Първият запис е заглавие на следната структура:
typedef struct FIT_HEADER
{
char Tag[8]; // ‘_FIT_ ’
unsigned long NumEntries; // including FIT header entry
unsigned short Version; // 1.0
unsigned char EntryType; // 0
unsigned char Checksum;
}; 
По неизвестна причина чексума не всегда правильно считается в этих таблицах (поле остается нулевым).
Остальные записи указывают на различные бинарники, которые необходимо распарсить/исполнить до запуска 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;
}; 
Поле 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; // in dwords
unsigned long : 32;
unsigned long : 32;
unsigned long ModuleVendor; // 8086h
unsigned long Date; // in BCD format
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];
}; 
Процессор загружает этот бинарь в свой кэш, верифицирует и запускает.
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];
}; 
За верификация на публичния ключ OEM Root Key се използва SHA256 хеш от фюзовете, който е получен от Intel ME.
Преминаваме към втория манифест. Той се състои от три структури:
typedef struct IBB_MANIFEST
{
ACBP Acbp; // Boot policies
IBBS Ibbs; // IBB description
IBB_DESCRIPTORS[];
PMSG Pmsg; // IBBM signature
};В първата – определени константи:
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;
}; 
Така, още преди началото на изпълнението на UEFI BIOS, процесорът стартира ACM, който проверява автентичността на съдържанието на разделите с кодовете SEC и PEI. След това процесорът излиза от ACM, преминава по RESET-вектора и започва да изпълнява BIOS.
Провереният PEI раздел трябва да съдържа модул, който да провери останалата част от BIOS (DXE код). Този модул е разработен от IBV (Independent BIOS Vendor) или самия производител на системата. Тъй като в нашето разположение имаме само системи Lenovo и Gigabyte с поддръжка на Intel BG, ще разгледаме кода, извлечен от тези системи.
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), отговорно за функционалността на системата за захранване и мониторинг на производителността.

Съдържанието на новия регион 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) видяхме, че производственият режим на тези системи не е затворен, следователно, фюзите на чипсета (FPF-ите) остават в неопределено състояние. Да, Intel BG в такива случаи нито е включен, нито е изключен.
Става въпрос за следните системи (по отношение на Intel BG и това, което ще се изложи по-долу в статията, ще говорим за системи с процесорна микроархитектура Haswell и нагоре):
- всички продукти на Gigabyte;
- всички продукти на MSI;
- 21 модел лаптопи Lenovo и 4 модела сървъри Lenovo.
Разбира се, съобщихме за находката на тези доставчици, както и на компанията Intel.
Адекватна реакция последва само от Lenovo, които признат проблема и .
Gigabyte изглежда приемат информацията за уязвимостта, но никога не коментираха.
Комуникацията с MSI изобщо не се е задържало на нашето искане да изпратим своя публичен PGP-ключ (за да им изпратим security advisory в encrypted вид). Те заявиха, че „са производители на хардуер и PGP-ключове не произвеждат“.
Но нека да преминем към същността. Тъй като фюзите остават в неопределено състояние, потребителят (или злонамерен достъп) може да ги програмира самостоятелно (най-сложното е ). За целта е необходимо да се изпълнят следните стъпки.
1. Да се стартира в ОС Windows (въобще, описаните по-долу действия могат да се извършат и от Linux, ако се разработи аналог на Intel STK за нужната ОС). Използвайки инструмента MEinfo, да се уверите, че фюзите на съответната система не са програмирани.

2. Да се счете съдържанието на флаш паметта с помощта на Flash Programming Tool.

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


На картинката е отбелязан публичният ключ RSA, хешът на който ще бъде програмиран във фюзите на чипсета заедно с останалата конфигурация Intel BG.
4. С помощта на Flash Image Tool да се събере нов образ на фърмуера (заяви конфигурацията Intel BG).

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

6. С помощта на Flash Programming Tool да се затвори режимът manufacturing mode.

7. Системата ще се перезареди, след което с помощта на MEinfo можете да се уверите, че FPF-ите сега са програмирани.

Тези действия за винаги включат 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 ISH все още не са изучени, тя представлява интересен вектор за атака срещу Intel ME.
Изводи
- Изследването позволи да се получи техническо описание на работата на технологията Intel Boot Guard. Няма много тайни в Intel-овския модел за сигурност чрез неяснота.
- Представен е сценарий за атака, позволяващ да се създаде в системата неизтриваем руткит.
- Видяхме, че съвременните процесори Intel са способни да изпълняват много проприетарен код още преди да започне работата на BIOS.
- Платформите с архитектура 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
