Довірене завантаження Шредінгера. 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 рік), але in-the-wild ми поки не бачили прикладів його використання, тому прошивка вбудованого контролера як і раніше входить до складу UEFI BIOS);
  • прошивка Intel ME;
  • конфігурація (MAC-адреса тощо) вбудованого мережевого адаптера GbE (Gigabit Ethernet);
  • Flash-дескриптори (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 CPU

Кеп підказує, що процесор є основним середовищем виконання в архітектурі Intel 64. Чому він є коренем довіри? Виявляється, таким його робить володіння такими елементами:

  • Microcode ROM — енергонезалежна пам'ять, що не перезаписується, для зберігання мікрокоду. Вважається, що мікрокод є імплементація системи команд процесора на найпростіших інструкціях. У мікрокоді теж трапляються баги. Так що в BIOS можна знайти бінар з оновленнями мікрокоду (накладаються під час завантаження, тому що ROM не можна перезаписати). Вміст цих бінарів зашифровано, що значно ускладнює аналіз (тому, конкретний зміст мікрокоду відомий лише тим, хто його розробляє), і підписаний для контролю цілісності та справжності;
  • AES ключ для дешифрування вмісту оновлень мікрокоду;
  • хеш публічного ключа RSA, яким перевіряється підпис оновлень мікрокоду;
  • хеш публічного ключа RSA, яким перевіряється підпис розроблених компанією Intel кодових модулів ACM (Authenticated Code Module), які 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. Судячи з її невеликого опису в книзі, працює вона як ланцюжок довіреного завантаження. І перша ланка в ній – завантажувальний код (мікрокод) усередині CPU, який запускається за подією RESET (не плутати з RESET-вектором у BIOS!). CPU знаходить на SPI флеш-пам'яті розроблений та підписаний компанією Intel кодовий модуль (Intel BG startup ACM), завантажує до себе в кеш, верифікує (вище вже було зазначено, що CPU має хеш публічного ключа, яким перевіряється підпис ACM) та запускає.

Довірене завантаження Шредінгера. Intel Boot Guard

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

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

Виміряне завантаження

У режимі 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 в результаті завантаження не змінилися (тобто жоден «вимірюваний» компонент не був модифікований).

Перевірене завантаження

Найстрашнішим для любителів модифікувати 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 та її створення. Якщо подивитися на відповідну вкладку у GUI утиліти 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 – do nothing
                                              // 01b – shutdown with timeout
                                              // 11b – immediate shutdown
	unsigned long : 26;
};

Взагалі, конфігурація Intel BG – суть дуже гнучка. Розглянемо, наприклад, прапор Force_Boot_Guard_ACM. Коли його знято, у випадку, якщо модуль BG startup ACM на SPI флеш-пам'яті не буде знайдений, жодного довіреного завантаження не буде. Буде недовірена.

Ми вже писали, що enforcement policy для режиму 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 (тому, саме Програмований у полі Fuses).

Воно відмінно підходить для зберігання конфігурації, оскільки:

  • має one-time-programmable область для зберігання даних (якраз туди, куди записується конфігурація 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; // including 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;   // 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 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;         // 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 of an 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, розроблений компанією 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 2000год
SMIP
деяка конфігурація платформи, підписано вендором

0000 6000год
RBEP
кодовий розділ прошивки Intel TXE, x86, підписано Intel

0001 0000год
PMCP
кодовий розділ прошивки Intel PMC, ARC, підписано Intel

0002 0000год
FTPR
кодовий розділ прошивки Intel TXE, x86, підписано Intel

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

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

0021 8000год
ISHC
кодовий розділ прошивки Intel ISH, x86, підписано вендором

0025 8000год
NFTP
кодовий розділ прошивки Intel TXE, x86, підписано Intel

0036 1000год
IUNP
невідомо

0038 1000год
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, які визнали проблему та випустили патч.

гігабайт Начебто й прийняли інформацію про вразливість, але ніяк не прокоментували.

Спілкування з 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 і проексплуатувати або додати в BIOS свій SMM модуль, що неможливо, оскільки ми включили Boot Guard.

Таким чином, ця вразливість дозволяє зловмиснику:

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

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

Висновки

  1. Дослідження дозволило отримати технічний опис роботи технології Intel Boot Guard. Мінус пара таємниць в Intel-івській моделі security through obscurity.
  2. Представлений сценарій атаки, що дозволяє створити в системі руткит, що не видаляється.
  3. Ми побачили, що сучасні процесори Intel здатні виконати багато пропрієтарного коду до початку роботи BIOS.
  4. Платформи з архітектурою Intel 64 стають все менш придатними для запуску вільного ПЗ: апаратна верифікація, кількість пропрієтарних технологій і підсистем, що збільшується (три ядра в чіпсеті SoC: x86 ME, x86 ISH і ARC PMC).

Пом'якшення

Вендорам, які навмисно залишають manufacturing mode відкритим, слід його обов'язково закривати. Поки що закривають тільки очі та нові Kaby Lake системи це показують.

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

Джерело: habr.com

Додати коментар або відгук