Cobalt Strike内存加载.NET程序集功能原理分析并重构
字数 1593 2025-10-01 14:05:44

Cobalt Strike execute-assembly 功能原理分析与实现指南

概述

Cobalt Strike 的 execute-assembly 功能允许在非托管进程(如 Beacon)中直接内存加载并执行 .NET 程序集,无需将文件写入磁盘。本文深入分析其技术原理,并提供重构实现的关键步骤。


0x01 技术背景

托管代码与非托管环境

  • .NET 程序集属于托管代码,依赖公共语言运行时(CLR)环境执行。
  • Beacon 等传统 payload 是非托管程序,需主动加载 CLR 才能运行 .NET 代码。
  • 关键技术:通过 COM 接口动态初始化 CLR 并加载程序集。

0x02 内存加载 .NET 程序集的核心步骤

1. 初始化 CLR 环境

需按顺序调用以下 COM 接口:

// 1. 获取 CLR MetaHost
ICLRMetaHost* iMetaHost;
CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (VOID**)&iMetaHost);

// 2. 获取指定版本运行时信息(如 v4.0.30319)
ICLRRuntimeInfo* iRuntimeInfo;
iMetaHost->GetRuntime(L"v4.0.30319", IID_ICLRRuntimeInfo, (VOID**)&iRuntimeInfo);

// 3. 加载 CLR 到当前进程并启动
ICorRuntimeHost* iRuntimeHost;
iRuntimeInfo->GetInterface(CLSID_CorRuntimeHost, IID_ICorRuntimeHost, (VOID**)&iRuntimeHost);
iRuntimeHost->Start();

2. 加载应用程序域(AppDomain)

  • AppDomain 提供代码执行的隔离环境。
  • 默认使用当前进程的默认域,也可创建新域。

3. 装载程序集并执行

  • 将程序集(二进制数据)加载到 AppDomain。
  • 通过反射获取入口点(如 Main 方法)。
  • 使用 MethodInfo.Invoke() 调用并传递参数。

4. 示例代码结构

// 编译后的 .NET 程序集字节数据
byte[] assemblyData = { /* HEX 数据 */ };

// 加载并执行流程:
// 1. 初始化 CLR → 2. 获取默认域 → 3. 加载程序集 → 4. 调用入口点

0x03 Cobalt Strike 的实际实现机制

关键设计:反射式注入(RDI)

  • Beacon 不直接加载 CLR,而是将 CLR 初始化代码嵌入到目标 .NET 程序集中。
  • 修改程序集,添加 ReflectiveLoader 导出函数,支持反射加载。

进程注入流程

  1. 选择目标进程

    • 默认使用 rundll32.exe(可配置其他进程)。
    • CREATE_SUSPENDED 方式创建进程,挂起主线程。
  2. 注入与执行

    • 将修改后的程序集注入目标进程。
    • 使用 SetThreadContext + ResumeThread 触发执行(避免 CreateRemoteThread 被监控)。
  3. 输出捕获

    • 通过管道(Pipe)重定向目标进程的 stdout/stderr。
    • Beacon 轮询读取管道数据并回传至服务端。

复杂处理逻辑(完整版支持)

  • 进程选择:根据 profile 配置动态决定。
  • BlockDlls 防护:可选阻止非微软 DLL 加载。
  • Token 模拟:支持凭据窃取后的上下文执行。
  • 智能注入(SmartInject):规避内存扫描。

0x04 简化版 execute-assembly 实现

功能阉割说明

  • 仅支持 x64 环境。
  • 使用固定目标进程(rundll32.exe)。
  • 无 Token 模拟/BlockDlls 等高级功能。
  • 输出捕获仅等待 2 秒,适合短时任务。

关键代码步骤

1. 启动挂起进程

STARTUPINFOA si = { sizeof(si) };
PROCESS_INFORMATION pi;
CreateProcessA("C:\\Windows\\System32\\rundll32.exe", ..., CREATE_SUSPENDED, ...);

2. 注入程序集

  • 使用 VirtualAllocEx 在目标进程分配内存。
  • 写入嵌入 CLR 初始化代码的程序集数据。
  • 通过 SetThreadContext 修改线程上下文并执行。

3. 读取输出

// 等待管道数据(最多 2 秒)
PipeWaitForExec(hReadPipe, 2000);

// 读取数据并返回
ReadFile(hReadPipe, buffer, ...);

0x05 总结与注意事项

技术要点

  • 核心是通过 COM 接口动态加载 CLR,无需安装 .NET 环境。
  • Cobalt Strike 通过 RDI 将初始化代码融入程序集,增强隐蔽性。
  • 完整实现需处理进程创建、注入策略、输出捕获等复杂逻辑。

局限性

  • 简化版无法处理长时间运行的任务(如 keylogger)。
  • 需完整实现 Job 管理和异步管道读取才能支持持续输出。

扩展建议

  • 参考开源 CoffLoader 项目实现 Beacon API。
  • 集成进程保护(BlockDlls)、Token 模拟等企业级功能。

参考文献

  • 逆向分析 Cobalt Strike 4.4 Beacon。
  • Microsoft DOCS: CLR Hosting Interfaces。
Cobalt Strike execute-assembly 功能原理分析与实现指南 概述 Cobalt Strike 的 execute-assembly 功能允许在非托管进程(如 Beacon)中直接内存加载并执行 .NET 程序集,无需将文件写入磁盘。本文深入分析其技术原理,并提供重构实现的关键步骤。 0x01 技术背景 托管代码与非托管环境 .NET 程序集属于 托管代码 ,依赖公共语言运行时(CLR)环境执行。 Beacon 等传统 payload 是 非托管程序 ,需主动加载 CLR 才能运行 .NET 代码。 关键技术:通过 COM 接口动态初始化 CLR 并加载程序集。 0x02 内存加载 .NET 程序集的核心步骤 1. 初始化 CLR 环境 需按顺序调用以下 COM 接口: 2. 加载应用程序域(AppDomain) AppDomain 提供代码执行的隔离环境。 默认使用当前进程的默认域,也可创建新域。 3. 装载程序集并执行 将程序集(二进制数据)加载到 AppDomain。 通过反射获取入口点(如 Main 方法)。 使用 MethodInfo.Invoke() 调用并传递参数。 4. 示例代码结构 0x03 Cobalt Strike 的实际实现机制 关键设计:反射式注入(RDI) Beacon 不直接加载 CLR ,而是将 CLR 初始化代码嵌入到目标 .NET 程序集中。 修改程序集,添加 ReflectiveLoader 导出函数,支持反射加载。 进程注入流程 选择目标进程 默认使用 rundll32.exe (可配置其他进程)。 以 CREATE_SUSPENDED 方式创建进程,挂起主线程。 注入与执行 将修改后的程序集注入目标进程。 使用 SetThreadContext + ResumeThread 触发执行(避免 CreateRemoteThread 被监控)。 输出捕获 通过管道(Pipe)重定向目标进程的 stdout/stderr。 Beacon 轮询读取管道数据并回传至服务端。 复杂处理逻辑(完整版支持) 进程选择 :根据 profile 配置动态决定。 BlockDlls 防护 :可选阻止非微软 DLL 加载。 Token 模拟 :支持凭据窃取后的上下文执行。 智能注入(SmartInject) :规避内存扫描。 0x04 简化版 execute-assembly 实现 功能阉割说明 仅支持 x64 环境。 使用固定目标进程( rundll32.exe )。 无 Token 模拟/BlockDlls 等高级功能。 输出捕获仅等待 2 秒,适合短时任务。 关键代码步骤 1. 启动挂起进程 2. 注入程序集 使用 VirtualAllocEx 在目标进程分配内存。 写入嵌入 CLR 初始化代码的程序集数据。 通过 SetThreadContext 修改线程上下文并执行。 3. 读取输出 0x05 总结与注意事项 技术要点 核心是通过 COM 接口动态加载 CLR,无需安装 .NET 环境。 Cobalt Strike 通过 RDI 将初始化代码融入程序集,增强隐蔽性。 完整实现需处理进程创建、注入策略、输出捕获等复杂逻辑。 局限性 简化版无法处理长时间运行的任务(如 keylogger)。 需完整实现 Job 管理和异步管道读取才能支持持续输出。 扩展建议 参考开源 CoffLoader 项目实现 Beacon API。 集成进程保护(BlockDlls)、Token 模拟等企业级功能。 参考文献 逆向分析 Cobalt Strike 4.4 Beacon。 Microsoft DOCS: CLR Hosting Interfaces。