Приветствую всех!
Сегодня я вам представлю свои наработки по способу инжекта 64-битных DLL библиотек в процессы WOW64, сам который считал невозможным. Любителей потрогать внутренности Windows приглашаю под кат.
Windows обеспечивает совместимость со старыми x86-приложениями с помощью прослойки WOW64. Эта технология создает 32-битное пространство, совместимые структуры 
Выход из эмуляции можно выполнить и произвольно, для выполнения 64-битного кода прямо посреди 32-битного. Этот метод называется Heaven’s Gate и доступен в любом WOW64 процессе, но подобный код не получится выполнить в Windows x86, так как там этот механизм отсутствует. Переключение всегда выполняется для всех потоков в WOW64 процессе, если указатель на начальную функцию находится в памяти корректно загруженного 32-битного модуля (exe или dll). Однако, если адрес указывает на код в 64-битном модуле, переключение не произойдет и режим потока останется прежним, что открывает определенные возможности.
Благодаря тому, что любом WOW64 процессе всегда есть несколько 64-битных библиотек, можно использовать свободное место в конце секции .text для выполнения шеллкода, чтобы загрузить нашу библиотеку. Также важно понимать, что DLL-библиотеки можно загружать стандартным способом (например, с помощью LoadLibrary) или вручную, выполняя все действия PE-загрузчика самостоятельно — этот метод называется Manual Map. В этой части мы рассмотрим первый способ.
Hidden text
Предупреждая вопросы — система позволяет записать данные в с помощью QueryWorkingSetEx (пример кода)
Загрузка DLL с помощью LoadLibrary (но не совсем)
LoadLibrary — функция Win32 API для загрузки динамических библиотек, определенная в kernel32.dll, и часто используемая как явно, так и неявно. Однако в нашем случае мы не можем её использовать, так как kernel32.dll в процессе принадлежит подсистеме WOW64 и может загружать только 32-битные библиотеки. LoadLibrary сама по себе не выполняет загрузку, а вызывает недокументированную функцию LdrLoadDll из ntdll, которая и выполняет всю работу. К счастью, LdrLoadDll, хоть и не упоминается на MSDN, доступна в отладочных символах и публично экспортируется из ntdll. Прототип вызова этой функции следующий:
NTSTATUS __stdcall LdrLoadDll(PWSTR SearchPath, PULONG LoadFlags, PUNICODE_STRING Name, PVOID *BaseAddress)
Так как 64-битная версия ntdll всегда загружается по одному и тому же адресу в памяти, мы можем найти адрес LdrLoadDll и вызвать её в пространстве процесса-цели следующим образом:
-
Получаем адрес LdrLoadDll с помощью GetProcAddress.
-
Находим свободное пространство в сегменте .text в ntdll для шеллкода.
-
Открываем хендл процесса-цели с помощью OpenProcess.
-
Выделяем страницу памяти под контекст шеллкода с помощью VirtualAllocEx (или находим свободную RW страницу памяти, убедившись, что это не нарушит работу программы).
-
С помощью WriteProcessMemory записываем в контекст адрес LdrLoadDll и данные о пути к загружаемой библиотеке
-
Записываем сам шеллкод в найденное место в ntdll.
-
Создаем новый поток в ntdll с помощью CreateRemoteThread.
-
В шеллкод вызываем LdrLoadDll, остальная работа будет выполнена без нашего участия.
Пример кода можно увидеть на github.
Плюсы такого инжекта заключаются в том, что LdrLoadDll выполнит полную загрузку библиотеки, подгрузив все необходимые зависимости, включая 64-битную kernel32.dll и другие. Во-первых, это удобно, так как не требует самостоятельной подгрузки зависимостей. Во-вторых, инжектируемая библиотека не нуждается в серьезных переработках под спартанские условия.
Минусы заключаются в том, что библиотека будет явным образом видна в списке загруженных библиотек и её можно загрузить только из файла на диске, что может стать ограничением для некоторых задач. Тем не менее, для большинства 32-битных приложений такая библиотека будет незаметна. Например, это можно использовать для перехвата NT-функций в 64-битной ntdll, тогда как все проверки на предмет изменений будут направлены на 32-битную версию.
В следующей части я опишу, как выполнить тот же инжект 64-to-32, но уже загружая библиотеку вручную — иначе говоря manual map. Это освободит от упомянутых минусов LdrLoadDll-инжекта, а также даст гибкость при загрузке.
Всех благодарю за внимание.
ссылка на оригинал статьи https://habr.com/ru/articles/826836/
Добавить комментарий