Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Вопрос Расскажите плиз подробнее про eufi инжектор

а есть где то сурсы / примеры?
Есть. Можешь на гитхабе ознакомиться, например, с EfiGuard. Написан весьма качественно, с точки зрения подхода к архитектуре. Можешь также посмотреть условный xigmapper, он написан весьма просто и понятно для "новичков".

Но я бы рекомендовал ознакомиться с процессом загрузки не из исходников буткитов, а из собственных наблюдений, ревёрса (загрузчиков и ядра) и статей на тему буткитов, ну и со спецификацией EFI тоже. Так будет проще понимать, что вообще происходит.

Я распишу в кратком изложении ниже, что из себя эти штуки представляют и что используют.



Буткиты, по сути, это просто драйвера времени исполнения EFI, которые поддерживают спецификацией конверсию физической памяти в виртуальную, тем самым перенося сами себя в "виртуальную память" (ну, не сами себя конечно, но да ладно).

С моей "субъективной" точки зрения, подходов к написанию буткита есть два:
  1. Полностью "строить" буткит на "паттернах", то есть использовать только их, не вмешиваясь в сервисные таблицы;
  2. Использовать "систему паттернов" и при необходимости вмешиваться в сервисные таблицы. Эдак система 50/50.
Оба хороши, просто за первым необходимо более тщательно следить (в конце концов паттернов будет больше). Подход к атаке на цепочку загрузки, в принципе, одинаковый - ты атакуешь бутменеджер (bootmgfw.efi) и бутлоадер (winload.efi). Все прототипы функций, упоминающихся далее, я буду выносить под спойлер.



Если говорить о первом способе, то в первую очередь твоя цель - бутменеджер, это функция ImgArchStartBootApplication, она ответственна за передачу управления от бутменеджера к бутлоадеру. Через её хук ты сможешь узнать адрес бутлоадера (и его размер).

Func #1:
Expand Collapse Copy
EFI_STATUS
EFIAPI
ImgArchStartBootApplication(
    IN VOID        *AppEntry,
    IN VOID        *ImageBase,
    IN UINT32   ImageSize,
    IN UINT8    BootOptions,
    IN VOID        *RetArgs
)

После того, как мы обнаружили базовый адрес бутлоадера - мы можем найти две функции: BlImgAllocateImageBuffer и OslFwpSetupKernelPhase1

Начнём с первой - она необходима для аллокации памяти под ядро ОС и его модули. Единственное, в неё нужно передавать специфичные флаги: 0xE0000012 и 0x424000. Первый флаг указывает на то, что загружается модуль ядра, второй - флаг для выделения RWX-страниц. Адрес выделенного буфера желательно сохранить.
Если тебе интересно, то можешь поглазеть на функу OslpLoadAllModules в winload.efi, как минимум на OslLoadImage (в ней позже вызовется BlImgAllocateImageBuffer):

LoDumVH.png


Func #2:
Expand Collapse Copy
EFI_STATUS
EFIAPI
BlImgAllocateImageBuffer(
    IN VOID        **ImageBuffer,
    IN UINTN    ImageSize,
    IN UINTN    MemoryType,
    IN UINTN    Attributes,
    IN VOID        *Reserved,
    IN UINTN    Flags
)

OslFwpSetupKernelPhase1 глобально нужен нам для получения базового адреса ядра, так как в функцию передаётся "главная"
Пожалуйста, авторизуйтесь для просмотра ссылки.
- LOADER_PARAMETER_BLOCK, в ней содержится вся информация, нужная для первых фаз инициализации ядра. В структуре нам нужно поле LoadOrderListHead, с помощью списка можно найти нужный модуль и информацию о нём (эт ядро в нашем случае).
В этот же момент ты наконец-то можешь мапнуть свою полезную нагрузку.

Func #3:
Expand Collapse Copy
EFI_STATUS
EFIAPI
OslFwpSetupKernelPhase1(
    IN PLOADER_PARAMETER_BLOCK    LoaderParameterBlock
)

Полезную нагрузку необходимо запустить, так что тебе нужно будет придумать, где и как её запустить. Можно, например, хукнуть что-то в ядре. Делать это надо в рантайме (то есть, когда управление передано в ядру). Нужно будет
Пожалуйста, авторизуйтесь для просмотра ссылки.
на конверсию памяти и там хукнуть, что нужно.

То есть получится такая картина:
sgOmQgm.png




Второй способ заключается в использовании таблицы сервисов, в частности
Пожалуйста, авторизуйтесь для просмотра ссылки.
EFI_BOOT_SERVICES. Все указатели внутри неё можно похукать, некоторые правда через отключение WP.

Условно говоря, похукав
Пожалуйста, авторизуйтесь для просмотра ссылки.
ExitBootServices, ты гарантировано пропустишь половину из того, что я описывал выше, ибо этот сервис вызывается единожды в OslFwpSetupKernelPhase1 (в бутлоадере). Останется только придумать, как выделить память и найти структуру LOADER_PARAMETER_BLOCK.
Касательно первого, ты можешь хукать другие сервисы, и в каждом вызове хука смотреть, был ли вызван он из бутлоадера - получать адрес вызывающего через _ReturnAddress, искать базовый адрес и смотреть на артефакты, присуще только бутлоадеру. Либо забить хуй (если тебе это не важно) и использовать аллокаторы из
Пожалуйста, авторизуйтесь для просмотра ссылки.
.
Касательно второго всё то же самое. Только ищешь по паттернам адрес структуры.

В остальном, всё также - мапаешь нагрузку в условном хуке ExitBootServices, регистрируешь ивент, делаешь что нужно.



Надеюсь, тебе это поможет и продвинет в твоих экспериментах, тема интересная, на самом деле.
Но настоятельно необходимо ознакомиться со
Пожалуйста, авторизуйтесь для просмотра ссылки.
!

P.S. Касательно второго способа и поиска LOADER_PARAMETER_BLOCK - его можно и не искать, если ориентироваться в том, что происходит в первых 16 мегабайтах физической памяти.
 
Есть. Можешь на гитхабе ознакомиться, например, с EfiGuard. Написан весьма качественно, с точки зрения подхода к архитектуре. Можешь также посмотреть условный xigmapper, он написан весьма просто и понятно для "новичков".

Но я бы рекомендовал ознакомиться с процессом загрузки не из исходников буткитов, а из собственных наблюдений, ревёрса (загрузчиков и ядра) и статей на тему буткитов, ну и со спецификацией EFI тоже. Так будет проще понимать, что вообще происходит.

Я распишу в кратком изложении ниже, что из себя эти штуки представляют и что используют.



Буткиты, по сути, это просто драйвера времени исполнения EFI, которые поддерживают спецификацией конверсию физической памяти в виртуальную, тем самым перенося сами себя в "виртуальную память" (ну, не сами себя конечно, но да ладно).

С моей "субъективной" точки зрения, подходов к написанию буткита есть два:
  1. Полностью "строить" буткит на "паттернах", то есть использовать только их, не вмешиваясь в сервисные таблицы;
  2. Использовать "систему паттернов" и при необходимости вмешиваться в сервисные таблицы. Эдак система 50/50.
Оба хороши, просто за первым необходимо более тщательно следить (в конце концов паттернов будет больше). Подход к атаке на цепочку загрузки, в принципе, одинаковый - ты атакуешь бутменеджер (bootmgfw.efi) и бутлоадер (winload.efi). Все прототипы функций, упоминающихся далее, я буду выносить под спойлер.



Если говорить о первом способе, то в первую очередь твоя цель - бутменеджер, это функция ImgArchStartBootApplication, она ответственна за передачу управления от бутменеджера к бутлоадеру. Через её хук ты сможешь узнать адрес бутлоадера (и его размер).

Func #1:
Expand Collapse Copy
EFI_STATUS
EFIAPI
ImgArchStartBootApplication(
    IN VOID        *AppEntry,
    IN VOID        *ImageBase,
    IN UINT32   ImageSize,
    IN UINT8    BootOptions,
    IN VOID        *RetArgs
)

После того, как мы обнаружили базовый адрес бутлоадера - мы можем найти две функции: BlImgAllocateImageBuffer и OslFwpSetupKernelPhase1

Начнём с первой - она необходима для аллокации памяти под ядро ОС и его модули. Единственное, в неё нужно передавать специфичные флаги: 0xE0000012 и 0x424000. Первый флаг указывает на то, что загружается модуль ядра, второй - флаг для выделения RWX-страниц. Адрес выделенного буфера желательно сохранить.
Если тебе интересно, то можешь поглазеть на функу OslpLoadAllModules в winload.efi, как минимум на OslLoadImage (в ней позже вызовется BlImgAllocateImageBuffer):

LoDumVH.png


Func #2:
Expand Collapse Copy
EFI_STATUS
EFIAPI
BlImgAllocateImageBuffer(
    IN VOID        **ImageBuffer,
    IN UINTN    ImageSize,
    IN UINTN    MemoryType,
    IN UINTN    Attributes,
    IN VOID        *Reserved,
    IN UINTN    Flags
)

OslFwpSetupKernelPhase1 глобально нужен нам для получения базового адреса ядра, так как в функцию передаётся "главная"
Пожалуйста, авторизуйтесь для просмотра ссылки.
- LOADER_PARAMETER_BLOCK, в ней содержится вся информация, нужная для первых фаз инициализации ядра. В структуре нам нужно поле LoadOrderListHead, с помощью списка можно найти нужный модуль и информацию о нём (эт ядро в нашем случае).
В этот же момент ты наконец-то можешь мапнуть свою полезную нагрузку.

Func #3:
Expand Collapse Copy
EFI_STATUS
EFIAPI
OslFwpSetupKernelPhase1(
    IN PLOADER_PARAMETER_BLOCK    LoaderParameterBlock
)

Полезную нагрузку необходимо запустить, так что тебе нужно будет придумать, где и как её запустить. Можно, например, хукнуть что-то в ядре. Делать это надо в рантайме (то есть, когда управление передано в ядру). Нужно будет
Пожалуйста, авторизуйтесь для просмотра ссылки.
на конверсию памяти и там хукнуть, что нужно.

То есть получится такая картина:
sgOmQgm.png




Второй способ заключается в использовании таблицы сервисов, в частности
Пожалуйста, авторизуйтесь для просмотра ссылки.
EFI_BOOT_SERVICES. Все указатели внутри неё можно похукать, некоторые правда через отключение WP.

Условно говоря, похукав
Пожалуйста, авторизуйтесь для просмотра ссылки.
ExitBootServices, ты гарантировано пропустишь половину из того, что я описывал выше, ибо этот сервис вызывается единожды в OslFwpSetupKernelPhase1 (в бутлоадере). Останется только придумать, как выделить память и найти структуру LOADER_PARAMETER_BLOCK.
Касательно первого, ты можешь хукать другие сервисы, и в каждом вызове хука смотреть, был ли вызван он из бутлоадера - получать адрес вызывающего через _ReturnAddress, искать базовый адрес и смотреть на артефакты, присуще только бутлоадеру. Либо забить хуй (если тебе это не важно) и использовать аллокаторы из
Пожалуйста, авторизуйтесь для просмотра ссылки.
.
Касательно второго всё то же самое. Только ищешь по паттернам адрес структуры.

В остальном, всё также - мапаешь нагрузку в условном хуке ExitBootServices, регистрируешь ивент, делаешь что нужно.



Надеюсь, тебе это поможет и продвинет в твоих экспериментах, тема интересная, на самом деле.
Но настоятельно необходимо ознакомиться со
Пожалуйста, авторизуйтесь для просмотра ссылки.
!

P.S. Касательно второго способа и поиска LOADER_PARAMETER_BLOCK - его можно и не искать, если ориентироваться в том, что происходит в первых 16 мегабайтах физической памяти.
+реп братан
 
Назад
Сверху Снизу