
Демонстрирует CVE-2022-34302 — обход Secure Boot через подписанный загрузчик New Horizon Datasys, встроенный пользовательский загрузчик PE/COFF которого выполняет неподписанные UEFI-приложения.
New Horizon Datasys Reboot Restore Boot Loader - Bring Your Own Vulnerable UEFI Application (BYOVUA) - обход Secure Boot через подписанный загрузчик со встроенным пользовательским загрузчиком PE/COFF, который загружает неподписанные UEFI-приложения.
Этот репозиторий демонстрирует технику BYOVUA (Bring Your Own Vulnerable UEFI Application) путём эксплуатации CVE-2022-34302 - уязвимости обхода Secure Boot в загрузчике New Horizon Datasys.
В отличие от уязвимостей на основе UEFI Shell (CVE-2022-34301 и CVE-2022-34303), этот загрузчик не предоставляет UEFI Shell. Вместо этого shdloader.efi реализует собственный пользовательский загрузчик PE/COFF, который загружает бинарный файл второй стадии (shdmgr.ef_) без использования функции LoadImage() прошивки и без выполнения какой-либо проверки подписи. Злоумышленнику достаточно заменить shdmgr.ef_ на любое совместимое UEFI-приложение, чтобы добиться выполнения произвольного кода при включённом Secure Boot.
Это наиболее опасная из трёх уязвимостей, раскрытых в исследовании "One Bootloader to Load Them All". Как отметили в Eclypsium: обход встроен, полностью незаметен и не оставляет визуальных признаков на экране - что делает его невидимым даже на системах с монитором и необнаружимым на безголовых системах, таких как серверы или промышленное оборудование.
BYOVUA - это UEFI-эквивалент техники BYOVD (Bring Your Own Vulnerable Driver), используемой на уровне ядра. Вместо того чтобы принести подписанный драйвер ядра с уязвимостью, злоумышленник приносит подписанное UEFI-приложение, содержащее функциональность, способную подорвать Secure Boot.
Поскольку shdloader.efi подписан сертификатом, которому доверяет Microsoft, он принимается Secure Boot без вопросов, что делает его доверенным на любой системе, включающей этот сертификат в свою базу данных Secure Boot (db) - а это практически каждый ПК с поддержкой UEFI, выпущенный за последнее десятилетие. После запуска его встроенный пользовательский загрузчик PE даёт злоумышленнику возможность загружать и выполнять произвольный неподписанный код до загрузки операционной системы, в среде, где современные средства защиты (ASLR, DEP, защиты ядра) попросту отсутствуют.
shdloader.efi - это UEFI-загрузчик, распространяемый в составе продуктов восстановления и отката системы New Horizon Datasys (Reboot Restore Rx, RollBack Rx). Его роль в легитимной цепочке загрузки заключается в загрузке компонента управления до запуска ОС (shdmgr.ef_), который обрабатывает операции создания снимков и восстановления до запуска операционной системы.
Уязвимость представляет собой дефект проектирования в архитектуре загрузчика. Вместо использования загрузочных сервисов прошивки LoadImage() и StartImage(), которые обеспечивают проверку подписи Secure Boot, shdloader.efi реализует собственный пользовательский загрузчик PE/COFF, который читает, перемещает и выполняет shdmgr.ef_ напрямую из необработанных байтов диска, полностью обходя проверки безопасности прошивки.
Основная проблема: подписанный бинарный файл, которому доверяет Secure Boot, содержит собственный загрузчик образов, который не проверяет подписи. Прошивка проверяет shdloader.efi как подписанный, но как только он запущен, он загружает shdmgr.ef_ без какой-либо проверки. Замена shdmgr.ef_ на произвольное UEFI-приложение приводит к тому, что это приложение выполняется с полным доступом к оборудованию, в то время как Secure Boot отображается как включённый.
Это принципиально отличается от CVE-2022-34301 и CVE-2022-34303, где злоумышленнику необходимо взаимодействовать с UEFI Shell и вручную повредить , чтобы отключить проверку. Здесь обход - без взаимодействия с пользователем, без видимого вывода, без приглашения оболочки.
| Свойство | Значение |
|---|
| Файл | shdloader.efi = EFI/Boot/bootx64.efi |
| Производитель | New Horizon Datasys Inc |
| Продукт | Reboot Restore Rx / RollBack Rx |
| CVE | CVE-2022-34302 |
| Подпись | Microsoft Windows UEFI Driver Publisher → Microsoft Corporation UEFI CA 2011 |
| Обнаружение | Eclypsium (Mickey Shkatov, Jesse Michael) - август 2022 |
| Презентация | DEF CON 30 - "One Bootloader to Load Them All" |
| Отзыв | Добавлен в DBX через Microsoft KB5012170 (август 2022) |
gSecurity2Подписанный shdloader.efi содержит собственную реализацию загрузчика образов PE/COFF. Вместо вызова загрузочного сервиса прошивки LoadImage(), который задействовал бы архитектурные протоколы безопасности и проверил подпись образа по базе данных Secure Boot, загрузчик:
\EFI\Boot\shdmgr.ef_ с помощью EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.reloc и применяет базовые перемещенияНи на одном из этих этапов загрузчик не проверяет подпись Authenticode образа, не обращается к базе данных Secure Boot (db/dbx) и не вызывает EFI_SECURITY2_ARCH_PROTOCOL. Образ загружается исключительно на основе структурной корректности его PE/COFF.```c
// Pseudocode of what shdloader.efi does internally
//
// NOTE: This is a simplified representation. The actual
// implementation was derived from reverse engineering.
EFI_STATUS LoadShdmgr(VOID) { // Step 1: Open the file File = OpenFile(L"\EFI\Boot\shdmgr.ef_");
// Step 2: Read raw bytes (no signature check)
ReadFile(File, &Buffer, &Size);
// Step 3: Parse PE/COFF headers
DosHeader = (EFI_IMAGE_DOS_HEADER *)Buffer;
PeHeader = (EFI_IMAGE_NT_HEADERS *)(Buffer + DosHeader->e_lfanew);
// Step 4: Allocate memory and copy sections
ImageBase = AllocatePages(...);
CopySections(ImageBase, Buffer, PeHeader);
// Step 5: Apply base relocations from .reloc
Delta = ImageBase - PeHeader->OptionalHeader.ImageBase;
ApplyRelocations(ImageBase, PeHeader, Delta);
// Step 6: Jump to entry point
// NO SIGNATURE VERIFICATION ANYWHERE
EntryPoint = ImageBase + PeHeader->OptionalHeader.AddressOfEntryPoint;
((EFI_IMAGE_ENTRY_POINT)EntryPoint)(ImageHandle, SystemTable);
}
---
<div id='LoadImageVsCustomLoader'/>
### ***LoadImage против пользовательского загрузчика***
Разница между функцией прошивки `LoadImage()` и пользовательским загрузчиком представляет собой критический разрыв в безопасности:```
┌─────────────────────────────────────────────────────────────────────────┐
│ Firmware LoadImage() - How legitimate boot chains work │
│ │
│ bootx64.efi ──> LoadImage("shdmgr.ef_") │
│ │ │
│ ├── Parse PE/COFF headers │
│ ├── Verify Authenticode signature │
│ ├── Check signature against db (allowed) │
│ ├── Check hash against dbx (revoked) │
│ ├── Call gSecurity2->FileAuthenticationState() │
│ │ │ │
│ │ ├── Signature valid? ── YES ──> Load image │
│ │ └── Signature invalid? ── NO ──> REJECT │
│ └── StartImage() │
│ │
├─────────────────────────────────────────────────────────────────────────┤
│ Custom PE Loader - What shdloader.efi does │
│ │
│ shdloader.efi ──> OpenFile("shdmgr.ef_") │
│ │ │
│ ├── ReadFile() into buffer │
│ ├── Parse PE/COFF headers │
│ ├── Allocate memory │
│ ├── Copy sections │
│ ├── Apply .reloc relocations │
│ ├── *** NO SIGNATURE CHECK *** │
│ └── Jump to EntryPoint │
│ │
│ Result: ANY valid PE/COFF EFI application runs, signed or not │
└─────────────────────────────────────────────────────────────────────────┘
Пользовательский загрузчик PE представляет собой упрощённую реализацию и ожидает определённую структуру PE/COFF. Двоичные файлы, не соответствующие этим требованиям, отклоняются с ошибками:``` Reloc table overflows binary Relocation failed Invalid entry point
Бинарный файл, в котором отсутствует любое из этих полей, будет отклонён пользовательским загрузчиком.
| Поле | Требуемое значение | Причина |
|-------|---------------|--------|
| *Machine* | `0x8664` (x64) | Загрузчик поддерживает только образы x86-64 |
| *Subsystem* | `10` (EFI Application) | Должно быть EFI Application |
| *Секция .reloc* | `.reloc` должна существовать с корректными записями базовой релокации | Загрузчик выполняет собственную релокацию образа. Без .reloc он завершается с ошибкой "Reloc table overflows binary" |
| *Relocation Directory* | `VirtualAddress` != 0, Size != 0 (DATA_DIRECTORY[5]) | Запись каталога должна указывать на корректные данные релокации |
Скрипт проверки (Scripts/VerifyPE.py) предоставляется для проверки совместимости перед развёртыванием.
---
<div id='BYOVD'/>
### ***Параллель с Kernel BYOVD***
Структурная параллель между UEFI BYOVUA и kernel BYOVD точна, хотя CVE-2022-34302 представляет наиболее прямую форму — подписанный компонент **сам** загружает неподписанный код, а не предоставляет примитив для отключения проверки:```
┌──────────────────────────────────────────────────────────────┐
│ UEFI BYOVUA - CVE-2022-34302 (Custom PE Loader) │
│ │
│ Signed Bootloader ──> Custom PE Loader ──> Load unsigned │
│ (trusted by (no sig check) UEFI apps │
│ Secure Boot) │
├──────────────────────────────────────────────────────────────┤
│ UEFI BYOVUA - CVE-2022-34301/34303 (Shell + gSecurity2) │
│ │
│ Signed Shell ─ mm ─> gSecurity2 = NULL ─> Load unsigned │
│ (trusted by (Security2 Protocol) UEFI apps │
│ Secure Boot) │
├──────────────────────────────────────────────────────────────┤
│ Kernel BYOVD (DSE Bypass) │
│ │
│ Signed Driver ─ IOCTL ─> g_CiOptions = 0 ─> Load unsigned │
│ (trusted by (CI.dll) kernel drivers │
│ DSE / CI) │
└──────────────────────────────────────────────────────────────┘
CVE-2022-34302 — самый опасный вариант, поскольку обход присущ самой архитектуре загрузчика — нет промежуточного шага, на котором атакующему нужно было бы повредить механизм безопасности. Подписанный компонент напрямую загружает неподписанный код в рамках своей обычной работы.
Подписанный shdloader.efi размещается на EFI System Partition (ESP) в качестве загрузчика по умолчанию. Поскольку он подписан сертификатом Microsoft UEFI Driver Publisher, Secure Boot проверяет и загружает его без проблем.```
EFI System Partition (ESP)
└── EFI/
└── Boot/
└── bootx64.efi (shdloader.efi) ← Signed by Microsoft Windows UEFI Driver Publisher
└── shdmgr.ef_ (PAYLOAD) ← Unsigned, loaded by shdloader's custom PE loader
При загрузке системы прошивка:
1. Считывает `bootx64.efi` из ESP
2. Вызывает `LoadImage()`, которая проверяет подпись Authenticode по базе данных Secure Boot
3. Подпись совпадает с сертификатом Microsoft UEFI CA 2011 в `db` → образ принимается
4. Вызывает `StartImage()` для передачи управления `shdloader.efi`
---
<div id='Phase2'/>
### ***Фаза 2 — Активация пользовательского PE-загрузчика***
Как только `shdloader.efi` получает управление, он выводит диагностическое сообщение и немедленно активирует свой пользовательский загрузчик PE/COFF:```
Booting in insecure mode
Загрузчик затем:
\EFI\Boot\shdmgr.ef_ с использованием протокола файловой системы.text, .data, .reloc и т. д.) в выделенную памятьLoadAddress - ImageBase) и применяет все базовые перемещения из секции .relocLoadAddress + AddressOfEntryPoint как цель для выполненияНа протяжении всего этого процесса проверка подписи не выполняется. Загрузчик не вызывает LoadImage(), не обращается к gSecurity2->FileAuthenticationState() и не проверяет базы данных db или dbx. Файл загружается исключительно на основе структурной корректности.
Если файл не найден, загрузчик сообщает:``` Failed to open \EFI\Boot\shdmgr.ef_ - 800000000000000E Failed to load image
---
<div id='Phase3'/>
### ***Фаза 3 — Выполнение неподписанного кода***
Пользовательский загрузчик передаёт управление на точку входа `shdmgr.ef_`. Неподписанное UEFI-приложение теперь выполняется с:
- Полным доступом к оборудованию (прямая память, порты ввода-вывода, PCI, MMIO)
- Отсутствием загруженной операционной системы
- Отсутствием ASLR, DEP или защиты ядра
- Отсутствием EDR или мониторинга конечных точек
- Secure Boot, сообщающим о состоянии **включено** для любого последующего запроса ОС
Атака полностью незаметна. В отличие от CVE-2022-34301 и CVE-2022-34303, которые отображают видимую командную строку UEFI Shell, этот эксплойт не создаёт никакого визуального вывода, кроме сообщения "Booting in insecure mode" (которое на легитимной системе появляется ненадолго и быстро сменяется экраном загрузки ОС). На headless-системах (серверы, IoT, промышленное оборудование) нет никаких признаков вообще.
---
<div id='Phase4'/>
### ***Фаза 4 — Закрепление***
Атака является постоянной по умолчанию. Пока `shdloader.efi` остаётся в `\EFI\Boot\bootx64.efi`, а полезная нагрузка атакующего остаётся в `\EFI\Boot\shdmgr.ef_` на ESP, неподписанная полезная нагрузка выполняется при каждой загрузке.
Скрипт `startup.nsh` не требуется. Адрес gSecurity2 не нужно пересчитывать при обновлениях прошивки. Пользовательский PE-загрузчик загружает любой найденный `shdmgr.ef_` безоговорочно.
Система продолжает сообщать о Secure Boot как "включённом" — нарушена лишь цепочка доверия на уровне загрузчика. Это делает атаку невидимой для запросов статуса Secure Boot на уровне ОС и для любого защитного ПО, полагающегося на аттестацию Secure Boot.
> **Важно:** Постоянство нарушается только при обновлении DBX записью отзыва для `shdloader.efi` (KB5012170), что заставляет прошивку отклонить сам `shdloader.efi` до того, как пользовательский загрузчик вообще активируется.
---
---
---
<div id='Exploit'/>
## ***Эксплойт***
Каталог `Exploit/` содержит всё необходимое для сборки совместимого `shdmgr.ef_`:```
Exploit/
|
├── README.md ← Build guide and PE/COFF requirements
|
├── PayloadShdmgr/
| |
│ ├── ForceReloc.nasm ← Force .reloc section generation
│ ├── shdmgr.ef_.c ← UEFI application source (EDK2)
│ ├── shdmgr.ef_.inf ← EDK2 module definition
│ ├── shdmgr.ef_.dsc ← EDK2 platform build configuration
│ └── shdmgr.ef_.dec ← EDK2 package declaration
|
└── Scripts/
└── VerifyPE.py ← PE/COFF compatibility verifier
Подписанный загрузчик был добавлен в список отзыва Microsoft DBX через KB5012170 (август 2022). На обновлённых системах загрузчик будет отклонён Secure Boot ещё до того, как активируется пользовательский PE-загрузчик.
Для лабораторной среды нужна система, в которой:
QEMU UEFI Research Environment предоставляет автоматизированную настройку для этого.
CVE-2022-34302 проще в эксплуатации, чем CVE-2022-34301 и CVE-2022-34303:
| Аспект | CVE-2022-34302 (пользовательский загрузчик) | CVE-2022-34301/34303 (Shell) |
|---|
| Техника | Замена shdmgr.ef_ на полезную нагрузку | Повреждение gSecurity2 через команду mm |
| Взаимодействие | Отсутствует (полностью автоматически) | Ручные команды shell или startup.nsh |
| Заметность | Тихая ("Booting in insecure mode") | Видимая подсказка UEFI Shell |
| Зависимость от прошивки | Отсутствует (полезная нагрузка самодостаточна) | Адрес gSecurity2 меняется в зависимости от сборки прошивки |
| Сложность | Низкая (замена файла) | Средняя (сканирование и патчинг памяти) |
| Скрытность | Высокая (нет визуального вывода на headless) | Низкая (shell виден на экране) |