На аппаратном пентесте серверной платформы я снял дамп SPI-flash и обнаружил в DXE-томе модуль, которого не было в исходной прошивке с сайта вендора. Два дня реверса через Ghidra - выяснилось: кастомный драйвер интегратора, не закладка. Но путь от подозрения до вердикта потребовал полного цикла анализа UEFI-прошивки - binwalk, UEFITool и Ghidra в связке. Цикл, от извлечения UEFI-образа до идентификации подозрительных модулей, и разберём - с конкретными командами и паттернами, которые экономят время.
Место UEFI-анализа в цепочке атаки
Реверс-инжиниринг UEFI-прошивки - не так сложен, как может показаться. Firmware-level persistence входит в арсенал APT-групп, и пентестеру нужно понимать этот вектор с обеих сторон. В MITRE ATT&CK анализ прошивки затрагивает несколько техник:- System Firmware (T1542.001, Persistence / Defense Evasion) - модификация прошивки для закрепления. Имплант переживает переустановку ОС и замену диска, так как перезаписывает код BIOS или UEFI.
- Bootkit (T1542.003, Persistence / Defense Evasion) - внедрение в цепочку загрузки. Перехват управления до старта ОС.
- Component Firmware (T1542.002, Persistence / Defense Evasion) - изменение прошивок отдельных компонентов: сетевых карт, BMC-контроллеров, дисковых контроллеров.
- Firmware Corruption (T1495, Impact) - деструктивное воздействие: «окирпичивание» платформы через порчу прошивки.
- Firmware (T1592.003, Reconnaissance) - сбор данных о версиях прошивок цели перед атакой.
Модель доступа: white box (вендор дал эталонный образ и спецификацию платформы) или grey box (дамп снят с устройства, эталон скачан с сайта вендора). Целевые платформы - x86/x64 системы с UEFI: серверы, рабочие станции, ноутбуки. Прошивки на базе открытых проектов (EDK II/Tianocore) и проприетарные реализации (AMI Aptio, Insyde H2O, Phoenix SecureCore).
Требования к окружению
Прежде чем лезть в статический анализ прошивки BIOS - подготовьте рабочее место.| Компонент | Минимум | Рекомендуется |
|---|---|---|
| ОС | Linux (Ubuntu 22.04+) или Windows 10 | Linux - удобнее для CLI-инструментов |
| RAM | 8 ГБ | 16 ГБ (Ghidra жрёт память при анализе крупных модулей) |
| Ghidra | 10.x | 11.x, активно поддерживается NSA, регулярные релизы |
| UEFITool | NE (New Engine) | Обе версии: NE для навигации, старая для модификации |
| binwalk | 2.3+ | 3.x (Rust-перепись от оригинального автора, активная разработка) |
| Python | 3.8+ | 3.10+ для скриптов Ghidra и efiXplorer |
| Средство дампа | flashrom или CHIPSEC | SPI-программатор (CH341A ~500 руб., Dediprog ~15 000 руб.) |
Дополнительно: плагин efiXplorer для Ghidra (разработка Binarly, открытый исходный код, последний коммит - 2024, проект активный). Установка - через менеджер расширений Ghidra или ручное копирование в директорию
Extensions.Извлечение UEFI-образа: программный и аппаратный подход
Прошивка хранится в SPI NOR flash - микросхеме на материнской плате. Без дампа этой микросхемы анализ невозможен.Программный дамп
На работающей GNU/Linux-системе SPI flash дамп снимается одной командой:flashrom -p internal -r firmware_dump.bin. Альтернатива - Intel CHIPSEC: chipsec_util spi dump firmware_dump.bin делает то же самое, но дополнительно позволяет проверить статус защитных регистров SPI - BIOS Write Enable, BIOS Lock Enable, PRx-регионы (Protected Range Registers).Ограничение программного метода: на современных платформах с Intel Boot Guard или активными SPI Protected Ranges дамп будет неполным. ME-регион и часть BIOS-региона окажутся заполнены нулями (0x00) или пустыми (0xFF). Для полного дампа нужен аппаратный подход.
Аппаратный дамп
SPI-программатор подключается напрямую к микросхеме flash-памяти - через SOIC-8 клипсу (внутрисхемное чтение) или после выпаивания чипа. Командаflashrom -p ch341a_spi -r firmware_dump.bin снимает дамп через CH341A. Для надёжности - два дампа подряд с проверкой хешей: sha256sum dump1.bin dump2.bin. Хеши разъехались - проблема с контактом клипсы, нужно пережать или зачистить площадки.Аппаратный метод обходит любые программные блокировки, но требует физического доступа к плате. На практике - открутить крышку, найти SPI flash (обычно SOIC-8 корпус рядом с южным мостом), подключить клипсу. Весь процесс - 10-15 минут, если знаешь расположение микросхемы на конкретной плате. (На незнакомой плате первый раз можно и полчаса провозиться, пока найдёшь нужный чип среди десятка похожих.)
Первичная разведка с binwalk: что покажет и что пропустит
binwalk - первое, что запускаю на свежем дампе. Он сканирует файл на сигнатуры известных форматов, ищет сжатые потоки, определяет границы вложенных структур.
Код:
$ binwalk firmware_dump.bin
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------
0 0x0 Intel Flash descriptor
4096 0x1000 Intel ME firmware region
2097152 0x200000 UEFI PI Firmware Volume, GUID: ...
3145728 0x300000 LZMA compressed data, properties: 0x5D
3276800 0x320000 UEFI PI Firmware Volume, GUID: ...
7340032 0x700000 UEFI PI Firmware Volume, GUID: ...
binwalk -E firmware_dump.bin) выделяет участки с аномально высокой аномальностью - потенциально зашифрованные данные. Для UEFI высокая энтропия в LZMA-сжатых секциях - норма. А вот участок с энтропией ~1.0, не распознанный как известный формат сжатия, - повод копнуть глубже.Извлечение компонентов:
binwalk -e firmware_dump.bin вытаскивает распознанные файлы в отдельную директорию. Для UEFI результат потребует ручной сортировки - binwalk создаст набор firmware volumes и сжатых блоков без понимания их иерархии.Чего binwalk UEFI-прошивке не даст:
- Не парсит иерархию вложенных firmware volumes
- Не понимает EFI_FFS_FILE_HEADER - не идентифицирует модули по GUID и типу (PEI/DXE/SMM)
- Не показывает зависимости между модулями (протоколы, PPI, события)
- Не отличает PEI-модуль формата TE от DXE-драйвера формата PE32+
UEFITool: навигация по томам и извлечение модулей
UEFITool - специализированный инструмент для работы со структурой UEFI-прошивок, созданный CodeRush (LongSoft). Без него реверс-инжиниринг UEFI прошивки превращается в бессмысленное блуждание по hex-дампу.При открытии дампа UEFITool строит дерево:
- Flash Image → Regions (BIOS, ME, GbE, PDR)
- BIOS Region → Firmware Volumes (FV)
- Firmware Volume → Files (каждый файл - отдельный модуль)
- File → Sections (PE32 Image, TE Image, Compressed, UI Name, DependencyExpression)
EFI_FV_FILETYPE_PEIM (PEI-модуль), EFI_FV_FILETYPE_DRIVER (DXE-драйвер), EFI_FV_FILETYPE_SMM (SMM-модуль), EFI_FV_FILETYPE_FREEFORM (произвольные данные, часто картинки) и другие. По данным из анализа типовой прошивки (RU-3), распределение модулей примерно такое: 50-60 PEIM, 190-200 DXE-драйверов, 50-60 SMM-модулей и до сотни Freeform-файлов с ресурсами. Зоопарк приличный.Ключевые операции с UEFITool
Поиск по GUID. Каждый UEFI-модуль идентифицируется 128-битным GUID. В UEFITool NE - Action → Search → GUID. Принцип такой, если знаю GUID подозрительного модуля (из публичных исследований или списка известных имплантов) - ищу напрямую. Если нет - ищу по тексту в секциях UI Name.Извлечение модулей для Ghidra. Правый клик на секции PE32 → Extract body. Результат - чистый PE32+ файл, который Ghidra распознаёт при импорте. Для PEI-модулей в формате TE - аналогично, у Ghidra есть встроенный TE-загрузчик.
Обнаружение аномалий. UEFITool сигнализирует о нарушениях спецификации UEFI PI. Пример из практики (описан CodeRush в разборе HP SecureUpdating): данные в свободном пространстве DXE-тома оказались контрольной суммой, спрятанной производителем вне рамок спецификации. Модуль SecureUpdating обращался к этим данным по фиксированному смещению для проверки целостности тома. Такие аномалии - точки входа в глубокий анализ.
Сравнение с референсом. Скачиваю эталонную прошивку с сайта вендора, открываю оба образа в двух экземплярах UEFITool. Побайтово сравниваю состав модулей: любое расхождение в количестве файлов, изменение GUID-ов, модифицированные секции PE32 - потенциальный индикатор компрометации. Добавленные DXE-драйверы, отсутствующие в референсе, - приоритет номер один.
На что обращать внимание при первичном осмотре: модули без секции UI Name (или с generic именем), DXE-драйверы вне основного DXE-тома, файлы типа RAW с нетипичным содержимым, секции DependencyExpression со ссылками на нестандартные протоколы.
Ghidra для анализа UEFI-прошивки: загрузка, плагины, идентификация сервисов
После извлечения интересующих модулей из UEFITool переходим к глубокому анализу в Ghidra. Ghidra - основной инструмент для статического анализа прошивки BIOS на уровне кода.
Загрузка PE/TE-модулей
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Ручная идентификация сервисных вызовов
Точка входа DXE-драйвера получает два параметра:ImageHandle и указатель на EFI_SYSTEM_TABLE. Из SystemTable по смещению 0x60 (для 64-бит) достаётся указатель на EFI_BOOT_SERVICES, а дальше - конкретные сервисы по смещениям в этой таблице (смещения по UEFI Specification 2.x для 64-битной платформы).
Код:
MOV RAX, [RDX+60h] ; SystemTable->BootServices
MOV RAX, [RAX+140h] ; BootServices->LocateProtocol (UEFI 2.x, 64-bit)
LEA R8, [RSP+28h] ; Interface (выходной указатель)
LEA RDX, [rip+GUID_addr] ; указатель на GUID протокола
XOR ECX, ECX ; Registration = NULL
CALL RAX
AllocatePool/FreePool (аналоги malloc/free), AllocatePages/FreePages (аналоги VirtualAlloc/VirtualFree), LocateProtocol (поиск протокола по GUID), InstallProtocolInterface (публикация нового протокола), CreateEvent/SignalEvent (событийная модель).Для PEI-модулей схема аналогична, но вместо EFI_SYSTEM_TABLE используется двойной указатель на EFI_PEI_SERVICES. Как отмечено в разборе HP SecureUpdating: «разыменование двойного указателя - не слишком популярная процедура в обычном коде, поэтому большую часть вызовов PEI-сервисов можно отследить глазами прямо в листинге». Характерный паттерн:
MOV EAX, [EBP+PeiServices] → MOV EAX, [EAX] → CALL [EAX+offset] - двойное разыменование с последующим вызовом по смещению. Когда привыкнешь к этому паттерну - он буквально бросается в глаза в листинге.Протоколы и зависимости между модулями
Каждый протокол UEFI идентифицируется уникальным GUID. Когда модуль вызываетLocateProtocol с определённым GUID, он зависит от модуля, установившего этот протокол через InstallProtocolInterface. Восстановление этих зависимостей (Static Dependency Graph) для всех модулей прошивки - задача, описанная в RU-3 как «алгоритмически не разрешимая в общем случае», но на практике для конкретной прошивки - вполне подъёмная.Для firmware security research приоритетны модули, устанавливающие или использующие протоколы, связанные с SMM (
EFI_SMM_* GUID-ы), SPI-контроллером (SPI Flash Protocol), Secure Boot (Image Verification Protocol, переменные PK/KEK/db/dbx).Паттерны UEFI-уязвимостей и имплантов: что искать в прошивке
SMM Callout
SMM (System Management Mode) - самый привилегированный режим x86-процессора. Код в SMRAM недоступен даже ядру ОС. SMM callout - класс уязвимостей, при которых SMI-обработчик использует данные или вызывает код из памяти, контролируемой непривилегированным кодом.При анализе SMM-драйверов (тип
EFI_FV_FILETYPE_SMM в UEFITool) ищу: обращения к CommBuffer (область обмена данных между ОС и SMM) без проверки, что указатели ведут внутрь SMRAM; вызовы функций по указателям из CommBuffer; использование SmmGetVariable для чтения UEFI-переменных без валидации размера буфера. Каждый из этих паттернов - потенциальный вектор эскалации из ring-0 в SMM.Контекст применимости: внутренний пентест или аудит с физическим доступом. Эксплуатация SMM callout требует привилегий ядра ОС (ring-0) - это техника повышения привилегий, а не начального доступа.
UEFI Secure Boot обход
Secure Boot верифицирует подписи загружаемых модулей через цепочку доверия: PK → KEK → db/dbx. Обход возможен через уязвимости в парсере PE-заголовков (integer overflow при обработке размеров секций), манипуляции с NVRAM-переменными (если запись в PK/KEK/db не заблокирована), или загрузку подписанного, но уязвимого загрузчика (shim, GRUB), через который передаётся управление неподписанному коду.
В Ghidra ищу модули, обращающиеся к Secure Boot-переменным: строки
SecureBootEnable, PK, KEK, db, dbx в секции данных. Модули, способные менять эти переменные или обходить проверку подписей в DXE-фазе, - приоритетные цели, если они не заблокированы.В файле:
efivar -a -n PK -d pk.cerЗагружаем подписанный, но уязвимый загрузчик (shim, GRUB), через который передаётся управление неподписанному коду.
grub2-install --target=x86_64-efi --efi-directory=/boot/efi --boot-loader-id=GRUBИспользуем уязвимость в парсере PE-заголовков для обхода проверки подписей.
Обнаружение UEFI rootkit и firmware-имплантов
Имплант уровня UEFI - DXE-драйвер, внедрённый в прошивку для закрепления (T1542.001, Persistence). Публично известные примеры (LoJax, MosaicRegressor) работали по одной схеме: добавленный DXE-модуль при каждой загрузке сбрасывал на диск агент, переживающий переустановку ОС и замену жёсткого диска.Признаки импланта:
- DXE-модуль, отсутствующий в эталонной прошивке вендора
- Модуль без UI Name секции или с нехарактерным именем
- Обращения к файловой системе через EFI_SIMPLE_FILE_SYSTEM_PROTOCOL из DXE-фазы (нетипично для легитимных драйверов платформы)
- Сетевые обращения через EFI_SIMPLE_NETWORK_PROTOCOL до загрузки ОС
- Запись данных на диск через DiskIo/BlockIo протоколы в DXE-фазе
- Обфускация кода (T1027, Defense Evasion) или деобфускация данных в runtime (T1140, Defense Evasion)
Сравнение инструментов анализа firmware
| Инструмент | Этап workflow | Преимущества | Ограничения | Когда не подходит |
|---|---|---|---|---|
| binwalk | Первичная разведка | Быстрый, универсальный, энтропийный анализ | Не понимает иерархию UEFI FV | Детальный анализ модулей |
| UEFITool | Навигация, извлечение | Полный парсинг UEFI-структуры, поиск по GUID | Нет дизассемблера | Анализ логики кода |
| Ghidra + efiXplorer | Глубокий анализ кода | Бесплатный, расширяемый, автоматизация UEFI-типов | Требует ручной доработки для нестандартных прошивок | Быстрый обзор структуры |
| CHIPSEC | Аудит конфигурации | Проверка SPI lock, SMM lock, Secure Boot | Не анализирует код, только конфигурацию | Реверс конкретных модулей |
| Qiling | Динамический анализ | Эмуляция DXE-модулей, трассировка вызовов | Неполная эмуляция HW, не все протоколы реализованы | PEI-фаза и HW-зависимый код |
На практике workflow линейный:
flashrom/CHIPSEC (дамп) → binwalk (разведка, SPI flash дамп анализ) → UEFITool (навигация, извлечение) → Ghidra (глубокий анализ). Инструменты не конкурируют - они покрывают разные этапы конвейера. Пытаться анализировать UEFI-прошивку только в Ghidra без UEFITool - всё равно что реверсить PE-файл без понимания структуры PE-заголовка: технически возможно, но вы просто утонете.Firmware-уровень нередко выпадает из скоупа пентестерских команд. Стандартный аргумент: «у нас нет физического доступа» или «это слишком нишевая тема». Но реальность меняется - всё больше заказчиков включают firmware assessment в скоуп аппаратного пентеста, особенно в критической инфраструктуре и финтехе. И тут выясняется, что команда, уверенно работающая с AD и web, оказывается беспомощной перед дампом SPI-flash.
Барьер при этом не в инструментарии. Ghidra с efiXplorer опустил порог входа до уровня «умеешь реверсить PE на Windows - разберёшься с DXE-драйвером за день». Барьер - в понимании архитектуры: фазы загрузки (SEC → PEI → DXE → BDS), модель протоколов, граница SMM, специфика TE-формата. Эту базу реально освоить за неделю целенаправленной работы с дампом реальной прошивки, а не с документацией UEFI PI в вакууме. По моей оценке, BIOS reverse engineering будет всё активнее востребован в командах, работающих с аппаратной безопасностью, а firmware assessment войдёт в стандартные чеклисты пентеста критической инфраструктуры. Навык чтения дизассемблерного листинга, наработанный на UEFI-модулях, прямо переносится на reverse-задачи на HackerLab.pro - подход тот же, формат компактнее.
Последнее редактирование модератором: