如何利用RunDLL32调用.NET Assembly
字数 930 2025-08-19 12:42:36
利用RunDLL32调用.NET Assembly技术详解
0x00 技术背景
随着安全防护技术的进步,Powershell环境变得越来越严格(由于AMSI、CLM和ScriptBlock日志记录),工具开发人员开始转向使用C#作为恶意软件和后渗透工具的开发语言。本文将详细介绍如何通过RunDLL32来启动.NET程序集(assembly)。
0x01 技术原理
传统上,RunDLL32等工具需要DLL提供导出表信息来引用内部方法,而.NET类assembly通常不包含这些信息。通过特殊方法可以让.NET assembly也提供导出表,从而实现兼容。
0x02 基础实现方法
方法一:手动修改IL代码
- 编写基础C#代码示例:
namespace Test {
public class TestClass {
public static void TestMethod() {
MessageBox.Show(".NET Assembly Running");
}
}
}
- 使用ildasm反编译为IL:
ildasm.exe /out:TestUnmanaged.il TestUnmanaged.dll
- 修改IL代码添加导出标记:
在方法定义前添加.export [1]描述符:
.method public hidebysig static void TestMethod() cil managed {
.export [1]
// 方法实现
}
- 使用ilasm重新编译:
ilasm.exe TestUnmanaged.il /DLL /output=TestUnamanged.dll
验证方法
使用RunDLL32调用:
rundll32.exe TestUnmanaged.dll,TestMethod
0x03 高级实现方法
使用DllExport工具简化流程
-
安装DllExport:
通过NuGet安装DllExport包,安装完成后删除NuGet包并运行DllExport_Configure.bat进行配置。 -
代码修改:
直接在方法上添加[DllExport]属性:
namespace Test {
public class TestClass {
[DllExport]
public static void TestMethod() {
MessageBox.Show(".NET Assembly Running");
}
}
}
- 项目设置:
将输出类型改为"Class Library"。
0x04 实际应用案例
以SafetyCatz工具为例的改造过程:
- 修改入口点:
[DllExport]
static void RunSafetyCatz() {
string[] args;
if (!IsHighIntegrity()) {
Console.WriteLine("\n[X] Not in high integrity, unable to grab a handle to lsass!\n");
}
// 其余代码...
}
- 调用方式:
rundll32.exe SafetyCatz.dll,RunSafetyCatz
0x05 技术优势
- 绕过限制:可以在软件限制策略下隐蔽执行
- 进程注入:可将.NET assembly远程注入到未加载CLR的进程(如iexplore.exe)
- 兼容性:保留了.NET框架的全部功能
0x06 注意事项
- 如需控制台输出,需添加Win32的
AttachConsole(-1)调用 - 使用前需测试目标环境是否支持此技术
- 某些安全产品可能会检测此类行为
0x07 扩展应用
此技术还可用于:
- 红队工具开发
- 后渗透阶段的功能扩展
- 绕过某些应用程序白名单限制
通过这种方法,我们成功地将.NET assembly的执行能力扩展到了传统的非托管环境中,为安全研究和渗透测试提供了更多可能性。