
Implementación en shellcode de la inyección Reflective DLL. Convierte DLLs a shellcode independiente de posición.
sRDI permite la conversión de archivos DLL a shellcode independiente de la posición. Intenta ser un cargador PE completamente funcional que admite permisos de sección adecuados, callbacks TLS y comprobaciones de integridad. Puede considerarse como un cargador PE de shellcode acoplado a una DLL empaquetada.
La funcionalidad se logra mediante dos componentes:
Este proyecto consta de los siguientes elementos:
La DLL no necesita compilarse con RDI, sin embargo la técnica es compatible entre plataformas.
Antes de usarlo, recomiendo familiarizarse con Reflective DLL Injection y su propósito.
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)
El código del cargador PE usa el argumento flags para controlar las diversas opciones de la lógica de carga:
SRDI_CLEARHEADER [0x1]: La cabecera DOS y el stub DOS de la DLL de destino se borran completamente con bytes nulos al cargar (excepto e_lfanew). Esto podría causar problemas con las API estándar de Windows al proporcionar la dirección base como un pseudo HMODULE.SRDI_CLEARMEMORY [0x2]: Después de llamar a las funciones en el módulo cargado (DllMain y cualquier exportación), los datos de la DLL se borrarán de la memoria. Esto es peligroso si espera continuar ejecutando código del módulo (Hilos / GetProcAddressR).SRDI_OBFUSCATEIMPORTS [0x4]: El orden de las importaciones en el módulo se aleatorizará antes de comenzar el parcheo de IAT. Además, los 16 bits superiores del flag se pueden usar para almacenar el número de segundos de pausa antes de procesar la siguiente importación. Por ejemplo, flags | (3 << 16) pausará 3 segundos entre cada importación.SRDI_PASS_SHELLCODE_BASE [0x8]: A diferencia de pasar los datos de usuario proporcionados a la función exportada, sRDI pasará la dirección base del bloque de shellcode que se está ejecutando actualmente. Esto puede ser útil para la autolimpieza dentro de módulos más avanzados.Este proyecto se compila con Visual Studio 2019 (v142) y Windows SDK 10. El script python está escrito en Python 3.
Los scripts de Python y Powershell se encuentran en:
Python\ConvertToShellcode.pyPowerShell\ConvertTo-Shellcode.ps1Después de compilar el proyecto, los otros binarios se ubicarán en:
bin\NativeLoader.exebin\DotNetLoader.exebin\TestDLL_<arch>.dllbin\ShellcodeRDI_<arch>.binSi desea actualizar los blobs estáticos dentro de cualquiera de las herramientas:
> 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
Si encuentra mi código desagradable, o simplemente busca un proyecto alternativo de cargador PE en memoria, eche un vistazo a algunos de estos:
La base de este proyecto se deriva de "Improved Reflective DLL Injection" de Dan Staples que a su vez se deriva del proyecto original de Stephen Fewer.
El marco del proyecto para compilar código C como shellcode está tomado de la investigación de Mathew Graeber "PIC_BindShell"