RustCobaltStrike4.4Beacon重写与强规避改造

admin 2026-09-04 04:38:36 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文介绍用Rust重写CobaltStrike4.4Beacon并保持协议兼容的项目,实现上线、命令执行、BOF加载、进程注入等功能,并通过PEB动态API获取、间接syscall、配置加密、AMSI/ETW补丁等手段降低静态与行为特征,提升规避能力。文章提供详细模块设计、实现方案与构建测试方法,对红队工具开发具有较高参考价值。 综合评分: 85 文章分类: 红队,免杀,渗透测试,安全开发


Rust Cobalt Strike 4.4 Beacon 重写与强规避改造

原创

cc cc

freedom安全

2026年9月2日 12:00 北京

在小说阅读器读本章

去阅读

在公众号小说中沉浸阅读

1. 项目定位

这个项目是把原 C 语言 Cobalt Strike Beacon 客户端重写为 Rust,并且保持与 Cobalt Strike 4.4 的 HTTP Beacon 协议兼容。

目标不是完全复刻 Cobalt Strike,而是:

  • 能正常上线 CS 4.4 teamserver
  • 能执行常用 Beacon 命令
  • 能在隔离环境中验证 BOF、进程注入、任务管理、截图、键盘记录、hashdump
  • 逐步把静态特征和行为特征改弱,降低杀软和 EDR 的直接命中率

2. 项目结构

beacon-rs/├── Cargo.toml├── build.rs├── config.plain.json├── asm/│   └── syscall.asm├── docs/│   └── rust-beacon-evasion.md└── src/    ├── main.rs    ├── api.rs    ├── syscall.rs    ├── inject.rs    ├── jobs.rs    ├── bof.rs    ├── packet.rs    ├── http.rs    ├── metadata.rs    ├── crypto.rs    ├── config.rs    ├── encoding.rs    ├── fsops.rs    ├── system.rs    ├── features.rs    ├── patch.rs    └── util.rs

核心模块职责:

| 模块 | 作用 | | — | — | | api.rs | PEB 动态获取 API | | syscall.rs | SSN 解析、syscall stub 调用 | | inject.rs | 进程创建、内存分配、注入、线程恢复 | | jobs.rs | 管道、job、execute-assembly | | bof.rs | BOF COFF 加载和 relocation | | packet.rs | CS 4.4 报文封装和命令解析 | | http.rs | HTTP 通信 | | metadata.rs | Beacon metadata 构造 | | crypto.rs | AES、HMAC、RSA、hash | | config.rs | 加密配置运行时解密 |

3. 已实现功能

3.1 基础 Beacon 功能

  • sleep
  • pwd
  • getuid
  • shell
  • cd
  • filebrowse
  • upload
  • download
  • mkdir
  • drives
  • rm
  • cp
  • mv
  • setenv
  • getprivs
  • ps

3.2 进阶功能

  • jobs / jobkill
  • execute-assembly
  • inject
  • spawn
  • dllinject
  • inline-execute,即 BOF
  • screenshot
  • keylogger
  • hashdump
  • AMSI patch
  • ETW patch

4. Cobalt Strike 4.4 协议兼容

为了继续兼容 CS 4.4,协议没有大改。

核心链路:

生成 metadata  -> RSA PKCS1 v1.5 加密  -> Base64  -> Cookie 头  -> HTTP GET 收到任务  -> 去掉 data= / %%  -> NetBIOS 解码  -> mask XOR 解码  -> AES-CBC 解密  -> 解析 commandType + commandLen + commandBuf 执行任务  -> 生成 callback packet  -> AES-CBC + HMAC  -> mask + Base64  -> HTTP POST

报文相关算法:

  • AES-128-CBC
  • HMAC-SHA256,前 16 字节
  • SHA256 生成会话 AES/HMAC 密钥
  • RSA PKCS1 v1.5 加密 metadata
  • NetBIOS 编码
  • mask XOR
  • Base64

5. PEB 动态 API 获取

为了减少静态导入,项目实现了一套 PEB 动态 API 解析。

5.1 获取 PEB

通过 x64 TEB 获取 PEB:

TEB -> gs:[0x60] -> PEB

Rust 使用 asm! 读取:

core::arch::asm!(    ”mov {0}, gs:[0x60]”,    out(reg) peb,    options(nostack, preserves_flags));

5.2 遍历模块

PEB + 0x18 -> PEB_LDR_DATAPEB_LDR_DATA + 0x20 -> InMemoryOrderModuleList

遍历链表时:

InMemoryOrderLinks 位于 entry + 0x10DllBase 位于 entry + 0x30BaseDllName 位于 entry + 0x58

5.3 解析导出表

找到模块后,解析 PE 导出表:

IMAGE_EXPORT_DIRECTORYAddressOfFunctionsAddressOfNamesAddressOfNameOrdinals

模块名和函数名使用 FNV hash,避免在代码中直接保存敏感 API 名。

6. Syscall 实现

6.1 已 syscall 化的函数

当前已实现:

NtOpenProcessNtAllocateVirtualMemoryNtWriteVirtualMemoryNtProtectVirtualMemoryNtCreateThreadExNtGetContextThreadNtSetContextThreadNtResumeThreadNtFreeVirtualMemoryNtReadFileNtWriteFileNtClose

6.2 SSN 解析

动态解析 ntdll 函数后,扫描函数 stub:

mov r10, rcxmov eax,

从而获得 SSN。

6.3 indirect syscall

多数 stub 采用 indirect syscall:

动态找到 ntdll 内 syscall 指令stub 跳转到 ntdll 的 syscall; ret

这样调用栈更接近正常 ntdll 调用。

部分稳定性敏感函数使用 direct syscall:

NtResumeThread

原因是 indirect 跳转在恢复线程场景下出现过异常。

6.4 汇编 stub

asm/syscall.asm 中定义:

beacon_NtOpenProcess PROC    mov r10, rcx    mov eax, DWORD PTR [g_ssn]    mov r11, QWORD PTR [g_addr]    jmp r11beacon_NtOpenProcess ENDP

7. 敏感 API 动态化

除了 syscall,很多非 syscall API 也改成 PEB 动态调用。

例如:

CreateProcessAGetThreadContextSetThreadContextResumeThreadIsWow64ProcessFlushInstructionCacheCreateToolhelp32SnapshotProcess32FirstWProcess32NextWProcessIdToSessionIdCreateFileWMiniDumpWriteDumpGetAsyncKeyStateGetLogicalDrivesFileTimeToLocalFileTimeFileTimeToSystemTimeGetUserNameAGetComputerNameAGetACPGetOEMCPGetCurrentProcessIdGetVersionExWGetModuleFileNameAMultiByteToWideCharWideCharToMultiByteCreatePipePeekNamedPipeWaitForSingleObject

这些 API 通过 api::resolve_fn 运行时获取。

8. 进程注入

8.1 spawn

CreateProcessA 动态调用CREATE_SUSPENDEDNtAllocateVirtualMemoryNtWriteVirtualMemoryNtProtectVirtualMemoryNtGetContextThreadNtSetContextThreadNtResumeThread

8.2 inject

NtOpenProcessNtAllocateVirtualMemoryNtWriteVirtualMemoryNtProtectVirtualMemoryNtCreateThreadEx

8.3 execute-assembly

CreatePipeCreateProcessA注入 invokeassembly DLL管道读取输出注册 job

9. Job 与管道

job 模块支持:

  • 匿名管道
  • 命名管道
  • SMB message 模式
  • 普通 byte 模式
  • jobs
  • jobkill

读取管道时:

PeekNamedPipe 检查数据ReadFile / NtReadFile 读取

10. BOF 加载器

inline-execute 支持基础 COFF BOF 加载:

解析 entryPoint读取 code / rdata / data / relocations / argsVirtualAlloc / NtAllocateVirtualMemory处理 COFF relocation加载动态模块调用 entry释放内存

Beacon API 表已经提供基础实现,包括:

BeaconDataParseBeaconDataPtrBeaconDataIntBeaconDataShortBeaconDataLengthBeaconDataExtractBeaconFormatAllocBeaconFormatResetBeaconFormatAppendBeaconFormatIntBeaconFormatFreeBeaconOutputBeaconPrintf

11. Screenshot / Keylogger / Hashdump

11.1 screenshot

  • CS 原生 screenshot 使用 Job + DLL 注入
  • 项目内 shell screenshot 使用 PowerShell System.Drawing

11.2 keylogger

  • CS 原生 keylogger 使用 Job + DLL 注入
  • 项目内 shell keylogger 使用 GetAsyncKeyState 轮询

11.3 hashdump

  • CS 原生 hashdump 使用 Job + DLL 注入
  • 项目内 hashdump 使用 MiniDumpWriteDump 生成 LSASS minidump

12. 字符串与配置加密

因为beacon本身自带配置文件的字符串 所以对配置文件做了加密处理 防止被静态分析或者通过strings定位到关键位置

12.1 设计

配置文件:

beacon-rs/config.plain.json

构建时由 build.rs:

读取 config.plain.json生成随机 XOR key对配置字段加密生成 generated_config.rs

运行时由 config.rs:

读取 encrypted bytesblack_box 防止优化XOR 解密OnceLock 只解密一次

12.2 已加密内容

C2 IP端口GET URIPOST URIHost 头User-AgentServer 头Content-TypeCookie 前缀SESSIONIDdata=%%User:user=IVRSA 公钥

12.3 验证

构建后可以搜索二进制:

Select-String -Path target-new\release\beacon-rs.exe `    -Pattern ”172.20.10.3” -SimpleMatch

正常情况下不会找到明文。

13. AMSI / ETW Patch

AMSIScanBuffer patchEtwEventWrite patch

实现方式:

PEB 动态获取 LoadLibraryAPEB 动态获取 GetProcAddressVirtualProtect 动态调用内存补丁恢复保护属性

14. 构建与测试

14.1 环境

Windows 10 / 11Rust MSVC toolchainVisual Studio Build Tools

14.2 构建

cd beacon-rscargo testcargo build --release --target-dir target-new

14.3 测试

cargo test

当前测试覆盖:

mask / netbiosAES-CBCHMACSHA256metadata 构造PEB 导出解析NtAllocateVirtualMemoryNtOpenProcess

15. 配置方法

15.1 修改 C2

编辑:

beacon-rs/config.plain.json

例如:

{  ”server”: ”10.10.10.10”,  ”port”: 443,  ”get_path”: ”/checkin”,  ”post_path”: ”/result”}

然后:

cargo build --release

15.2 修改 RSA 公钥

替换:

”pub_key_pem”: ”-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----\n”

注意换行使用 \n。

16. 使用方式

16.1 启动 teamserver

使用原 Cobalt Strike 4.4 和对应 profile 启动服务端。

16.2 启动 Beacon

运行:

beacon-rs\target-new\release\beacon-rs.exe

16.3 常用命令

shell whoamipwdgetuidpsfilebrowse C:\upload local.txt C:\Windows\Temp\local.txtdownload C:\Windows\Temp\local.txt spawn x64inject  x64execute-assembly C:\Tools\test.exeinline-execute C:\Tools\whoami.o jobsjobkill 0 screenshotkeyloggerhashdump shell amsishell etw

17. 当前规避能力

| 分类 | 当前状态 | | — | — | | PEB 动态 API | 已实现 | | indirect syscall | 主要路径已实现 | | NtCreateThreadEx | 已实现 | | NtReadFile | 已实现 | | NtWriteFile | 已实现 | | NtClose | 已实现 | | 配置加密 | 已实现 | | RSA 公钥加密 | 已实现 | | sleep mask | 未实现 | | ntdll unhook | 未实现 | | threadless injection | 未实现 | | PPID spoofing | 未实现 | | C2 流量伪装 | 未实现 | | 完全 no_std | 未实现 |

18. 实战环境

原生马 编译直接可以绕过卡巴 无需loader或者sleepmask

天擎 不过对于这种EDR还需要流量二开 这里只是演示动静

火绒新版增加了内存查杀 这里我主动扫描依然扫不到 图里扫的不是我的beacon 是其他软件 注意我的进程名

onesec


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:freedom安全 cc cc《Rust Cobalt Strike 4.4 Beacon 重写与强规避改造》

FTP流量分析 网络安全文章

FTP流量分析

文章总结: 本文详细记录了FTP流量分析全过程,从识别攻击者IP192.168.39.88开始,逐步还原了存活主机探测、端口扫描、FTP服务识别、暴力破解分析、
评论:0   参与:  0