
反射式DLL注入的Shellcode实现。将DLL转换为位置无关的Shellcode。
sRDI 允许将 DLL 文件转换为位置无关的 shellcode。它试图成为一个功能完整的 PE 加载器,支持正确的节权限、TLS 回调和完整性检查。可以将其视为一个绑定了打包 DLL 的 shellcode PE 加载器。
功能通过两个组件实现:
本项目包含以下元素:
DLL 无需使用 RDI 编译,但该技术是跨兼容的。
使用前,建议先了解反射式 DLL 注入及其用途。
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]:目标 DLL 的 DOS 头和 DOS 存根在加载时完全用零字节擦除(e_lfanew 除外)。这可能会在使用基地址作为伪 HMODULE 时导致标准 Windows API 出现问题。SRDI_CLEARMEMORY [0x2]:在调用加载模块中的函数(DllMain 和任何导出)后,DLL 数据将从内存中清除。如果你期望继续执行模块外的代码(线程 / GetProcAddressR),这很危险。SRDI_OBFUSCATEIMPORTS [0x4]:在开始 IAT 修补之前,模块中导入的顺序将被随机化。此外,标志的高 16 位可用于存储在处理下一个导入之前暂停的秒数。例如,flags | (3 << 16) 将在每次导入之间暂停 3 秒。SRDI_PASS_SHELLCODE_BASE [0x8]:与将提供的用户数据传递给导出函数不同,sRDI 改为传递当前正在执行的 shellcode 块的基地址。这在更高级的模块中对于自我清理可能很有用。本项目使用 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如果你想更新任何工具中的静态 blob:
> python .\lib\Python\EncodeBlobs.py -h
usage: EncodeBlobs.py [-h] solution_dir
sRDI Blob 编码器
positional arguments:
solution_dir 解决方案目录
optional arguments:
-h, --help 显示此帮助信息并退出
> python lib\Python\EncodeBlobs.py C:\code\srdi
[+] 已更新 C:\code\srdi\Native/Loader.cpp
[+] 已更新 C:\code\srdi\DotNet/Program.cs
[+] 已更新 C:\code\srdi\Python/ShellcodeRDI.py
[+] 已更新 C:\code\srdi\PowerShell/ConvertTo-Shellcode.ps1
如果你觉得我的代码不堪入目,或者只是在寻找一个替代的内存 PE 加载器项目,请查看以下项目:
本项目的基础源自 Dan Staples 的“改进的反射式 DLL 注入” ,而后者又源自 Stephen Fewer 的原始项目。
将 C 代码编译为 shellcode 的项目框架取自 Mathew Graeber 的研究“PIC_BindShell”