
Реализация Reflective DLL Injection в виде шелл-кода. Преобразование DLL в позиционно-независимый шелл-код.
sRDI позволяет преобразовывать DLL-файлы в позиционно-независимый шеллкод. Он стремится быть полностью функциональным загрузчиком PE, поддерживающим правильные разрешения секций, обратные вызовы TLS и проверки целостности. Его можно рассматривать как загрузчик PE в виде шеллкода, прикреплённый к упакованной DLL.
Функционал реализуется двумя компонентами:
Этот проект состоит из следующих элементов:
DLL не обязательно компилировать с RDI, однако техника является кроссплатформенно совместимой.
Перед использованием рекомендую ознакомиться с Reflective DLL Injection и её назначением.
from ShellcodeRDI import *
dll = open("TestDLL_x86.dll", 'rb').read()
shellcode = ConvertToShellcode(dll)
DotNetLoader.exe TestDLL_x64.dll
python ConvertToShellcode.py TestDLL_x64.dll
NativeLoader.exe TestDLL_x64.bin
Import-Module .\Invoke-Shellcode.ps1
Import-Module .\ConvertTo-Shellcode.ps1
Invoke-Shellcode -Shellcode (ConvertTo-Shellcode -File TestDLL_x64.dll)
Код загрузчика PE использует аргумент flags для управления различными опциями логики загрузки:
SRDI_CLEARHEADER [0x1]: DOS-заголовок и DOS-заглушка целевой DLL полностью затираются нулевыми байтами при загрузке (кроме e_lfanew). Это может вызвать проблемы со стандартными Windows API при передаче базового адреса в качестве псевдо HMODULE.SRDI_CLEARMEMORY [0x2]: После вызова функций в загруженном модуле (DllMain и любых экспортов) данные DLL будут очищены из памяти. Это опасно, если вы планируете продолжать выполнение кода из модуля (потоки / GetProcAddressR).SRDI_OBFUSCATEIMPORTS [0x4]: Порядок импортов в модуле будет рандомизирован перед началом патчинга IAT. Кроме того, старшие 16 бит флага можно использовать для хранения количества секунд паузы перед обработкой следующего импорта. Например, flags | (3 << 16) приостановит выполнение на 3 секунды между каждым импортом.SRDI_PASS_SHELLCODE_BASE [0x8]: Вместо передачи предоставленных пользовательских данных в экспортируемую функцию, sRDI передаёт базовый адрес текущего выполняемого блока шеллкода. Это может быть полезно для самоочистки внутри более продвинутых модулей.Этот проект собирается с помощью Visual Studio 2019 (v142) и Windows SDK 10. Python-скрипт написан на Python 3.
Скрипты Python и PowerShell находятся по адресу:
Python\ConvertToShellcode.pyPowerShell\ConvertTo-Shellcode.ps1После сборки проекта остальные бинарные файлы будут находиться по адресу:
bin\NativeLoader.exebin\DotNetLoader.exebin\TestDLL_<arch>.dllbin\ShellcodeRDI_<arch>.binЕсли вы хотите обновить статические блобы внутри любого из инструментов:
> python .\lib\Python\EncodeBlobs.py -h
usage: EncodeBlobs.py [-h] solution_dir
sRDI Blob Encoder
positional arguments:
solution_dir Solution Directory
optional arguments:
-h, --help show this help message and exit
> python lib\Python\EncodeBlobs.py C:\code\srdi
[+] Updated C:\code\srdi\Native/Loader.cpp
[+] Updated C:\code\srdi\DotNet/Program.cs
[+] Updated C:\code\srdi\Python/ShellcodeRDI.py
[+] Updated C:\code\srdi\PowerShell/ConvertTo-Shellcode.ps1
Если мой код вас не устраивает, или вы просто ищете альтернативный проект загрузчика PE в памяти, ознакомьтесь с некоторыми из них:
Основа этого проекта взята из "Improved Reflective DLL Injection" от Дэна Стейплса, которая, в свою очередь, основана на оригинальном проекте Стивена Фьюера.
Проектный фреймворк для компиляции C-кода как шеллкода взят из исследования Мэтью Грэбера "PIC_BindShell"