среда, 13 апреля 2022 г.

I was visited by death again: UEFI руткиты в схемах и мемах, поговорим о заражении

 

Спустя, наверное, продолжительное время, я потихоньку собираюсь с силами (мне просто надоело залипать в Krita), что не может меня не радовать. Я хочу запустить цикл статей, где мы будем говорить о достаточно непонятной вещи — о руткитах, находящихся между ОС и прошивкой (между 0 и -2 кольцами). Эта по сути вводная статья, где я допускаю много воды и щитпосчу, объясняю все на теории, в дальнейших статьях цикла я постараюсь подобного более не допускать (или допускать, но меньше). Что же, стоит ввести в курс дела, дать понятие, что такое UEFI/EFI.


Кто такой этот ваш UEFI/EFI

UEFI/EFI – это некий интерфейс, который связывает ОС и программы железяк, для успешного взаимодействия оных друг с другом. О таких микропрограммах (или микрокоде) мы когда-нибудь обязательно поговорим, сейчас вам стоит попытаться не путать наш UEFI с другой, не менее интересной штукой — HAL (Hardware Abstraction Layer), о нем мы тоже поговорим в одном из будущих райтапов, надеюсь. Так вот, задачей UEFI/EFI является корректное связывание микропрограмм и программ ОС, т.е правильная инициализация оборудования и последующая передача управления к загрузчику основной ОС (на самом деле это поле не паханное).

Не вижу смысла говорить, что UEFI/EFI был создан в качестве замены более устаревшего интерфейса — BIOS. Однако, я все же это вам напомню. Раньше интерфейс UEFI назывался EFI, но в последствие был переименован в UEFI (к сожалению я точно не вспомню, когда это произошло), поэтому мы обусловим, что для удобства в последующих статьях мы будем называть наш интерфейс UEFI.


UEFI руткиты, особенности и несколько забавных фактов

Мы плавно подбираемся к нашей основной теме цикла статей об подобных руткитах. Но стоит еще кое-что сказать, что нам пригодится в дальнейшем.

Первое, что стоит обусловить — существует среда драйверов, называемая EFI Byte Code (EBC), она предоставляет нам независимую среду от UEFI платформы для драйверов устройств. В таком случае у фирмварного ПО должен быть интерпретатор EBC (последняя ревизия спецификации вышла в марте 2021 года):


Также, введем понятие EFI Shell – оболочки, командной строки для управления и выполнения необходимых вещей пользователю (например, обновление UEFI). EFI Shell находится на ПЗУ материнской платы, собсна, где и все драйвера UEFI. Кстати, EFI Shell это тоже приложение, но я думаю, что это очевидно.


Благодаря всему описанному выше, мы можем вывести для себя понятие, что такое UEFI руткит:

UEFI руткит — драйвер интерфейса UEFI, выполняемый до этапа загрузки основной ОС и находящийся в специальном пространстве EBC, созданный с целью получения полного контроля над компьютером пользователя.


Кстати, хочу еще кое-что приметить у UEFI:

- Полная поддержка TCP/IP стека. Да, даже HTTP. UEFI предоставляет нам все необходимые протоколы. Славно, не правда ли? (Можете почитать об UNDI на досуге)

- Одна из интересных особенностей — драйвера носят MZ и PE сигнатуры.

В дальнейшем мы будем основываться на тианкоровской реализации API UEFI, я об edk2.

Конечно, все не так просто.


Как мы можем добраться до поражения UEFI

И мы немного уплываем из UEFI и переносимся в трансцендентность (ыыы).


Из обычного пользователя мы добраться до UEFI никак не сможем. Для того, чтоб добраться для UEFI нам необходимо повысить привилегии каким-либо способом, что нам позволит стать админом. Не думаю, что это удивительно, да и я считаю это тоже очевидным, существуют тысячи реализаций эксплойтов для повышения локальных привилегий, на том же github. Но это не та самая загвоздка.

Настоящей занозой в жопе будет добираться до интерфейса UEFI. Я когда-то выдвигал у себя предположение, что нам необходимо неким образом «заэкслойтиться» так, чтоб мы могли писать в SPI Flash, обходя, допустим, BIOSWE (механизм защиты SPI от записи, если я не ошибаюсь). К сожалению, такие штуки очень платформозависимы. Таким примером может послужить CVE-2017-3197, который затрагивает GB-BSi7H-6500 и GB-BXi7-5775.


Также, теоретически мы можем изменять уже занятые UEFI-переменные, по типу SecureBoot. Для этого, кстати, есть "высокоуровневое" API у Windows: GetEnvironmentVariable и SetEnvironmentVariable. Их также можно дергать из NTAPI.

 


А, ну и никто никогда не отменял атаки на SMRAM.

Однако, мы еще можем поговорить о кое чем еще.


Runtime Services и процесс загрузки интерфейса

Интересной концепцией может послужить атака на SPI Flash во время выгрузки рантайм сервисов интерфейса. Как это происходит? DXE IPL (Driver Execution Environment Initial Program Loader) распаковывает FV_MAIN (содержит в себе сжатые UEFI драйвера), затем DXE Dispatcher диспатчит рантайм драйвера из FV_MAIN в память. Параллельно с этим также работает SMM, который инициализируется в SMRAM, он в принципе занимается тем же самым, что и DXE IPL. Так вот, DXE драйвера отваливаются после загрузки ОС, тем самым остаются только рантайм драйвера (это на самом деле любые драйвера оборудования) и драйвера SMM Core в адрессном пространстве системы. Тем самым, мы технически можем атаковать подобные драйвера из kernel mode (нулевое кольцо). Однако, я не уверен, что это может дать нам запись в SPI, но теоретически может нам дать внесение правок в рантайм драйвера (мое любимое ROP), ну или я тупой немного.


Так что в идеале мы должны искать путь чистой записи в SPI, но это немного не в моих силах уже.


Юмореськи


 

Самое время для моего любимого щитпоста (весь мой контент это по сути щитпост, только тсс).


Однажды я пытался сдампить UEFI, чтоб у меня была хоть какая-то база для сплойтинга. В итоге я убил свой компостер к хуям. Ну, зато батя (мы с ним потели над KSE) поржал, да. Компостер живой, не беспокойтесь, могу даже сфоткать потом.

Вторая юмореська — RWEverything (программа для взаимодействия с подобными низкоуровневыми штуками, как UEFI, SPI и т.д) все еще не видит нормально SPI, а если и видит — начинает выкидывать Access Violation. Я не знаю, что там намудрили инженеры AMD, но у меня сгорела жопа, да и это мемная хуйня получается.


Вывод

Сегодня мы получили представление об UEFI, а также немножечко поговорили, как мы можем добраться до UEFI. Не знаю, дельно это или нет, но я все же решил вынести это в отдельный топик/статью, т.к в следующих частях мы уже окончательно уедем в UEFI и edk.

Да, как я говорил — мы постараемся разобраться с edk2 и что-то на нем сделать, желательно что-то рабочее.

На самом деле я не знаю, когда будет продолжение цикла, в планах у меня разобрать еще кое-какие вещи, более простые для понимания. Тот же HAL я хотел разобрать, но мне нужны силы, которых у меня не осталось, ех.


BTW, спасибо за потраченное время, увидимся, солнышки!

Комментариев нет:

Отправить комментарий

I was visited by death again: UEFI руткиты в схемах и мемах, поговорим о заражении

  Спустя, наверное, продолжительное время, я потихоньку собираюсь с силами (мне просто надоело залипать в Krita), что не может меня не радов...