Merlin Agent木马破绽:内存密钥暴露与加密流量破解全解
字数 1719 2025-08-30 06:50:27
Merlin Agent木马加密流量破解全解
概述
Merlin Agent是一种远控木马,支持构建多层跳板网络。本文详细解析如何从内存中提取Merlin Agent的通信密钥并解密其加密流量。研究发现,Merlin Agent在内存中存储的通信密钥存在暴露风险,可通过特定方法提取并用于解密各类通信流量。
密钥协商过程剖析
Merlin Agent的加密通信涉及两个关键阶段:
-
身份认证阶段:
- 使用预共享密钥(psk)配置信息作为初始通信密钥
- 通过SHA256运算生成预共享密钥
-
加密通信阶段:
- 使用OPAQUE协议进行身份验证后获得新的共享密钥
- 新密钥存储在
client.secret变量中 - 后续通信使用新密钥加密
关键代码特征:
- 共享密钥存放于
client.secret变量 client.secret在两处被赋值:- psk配置信息的SHA256哈希值
- OPAQUE协议认证后生成的新密钥
OPAQUE认证协议分析
Merlin Agent使用github.com/cretz/gopaque项目实现OPAQUE协议:
- OPAQUE是一种非对称密码身份验证密钥交换协议
- 基于离散对数问题保障安全(类似RSA)
- 使用Ed25519数字签名算法
- 关键特征:Ed25519签名长度固定为64字节
密钥特征识别
通过分析发现:
- Merlin Agent生成的共享密钥均为64字节长度
- 密钥以字符串形式存储在
client.secret变量中 - 内存中可以搜索到完整的64字节密钥字符串
加密流量破解方法
总体流程
- 提取加密流量载荷
- 尝试使用psk初始密钥解密
- 对无法解密的部分:
- 提取内存dump文件
- 搜索64字节字符串
- 尝试作为新密钥解密
详细步骤
1. 提取加密流量载荷
- 使用Wireshark导出通信载荷
- 或手动从数据包中提取
2. 初始身份认证解密
// 使用psk生成预共享密钥
preSharedKey := sha256.Sum256([]byte(pskConfig))
// 尝试解密初始通信
3. 内存提取通信密钥
- 使用ProcessHacker或System Informer提取内存dump
- 使用正则表达式匹配64字节字符串:
[a-zA-Z0-9+/=]{64}
4. 解密后续通信
// 使用找到的64字节字符串作为密钥
// 基于Merlin的transformers库构建解密函数
func decryptWithKey(ciphertext []byte, key string) ([]byte, error) {
// 实现解密逻辑
}
自动化脚本实现
脚本结构:
/merlin_decrypt
/transformers # 来自merlin-agent项目的解密库
main.go # 主解密逻辑
merlin_xx/ # 特定协议解密实现
merlin_xx.go
关键功能:
- 自动识别流量类型
- 尝试多种解密方式
- 输出解密结果
各类通信流量破解实践
HTTP上线通信解密
- Transformers: jwe,gob-base
- 载荷特征:以
eyJhbGciOiJQQkVTMi1IUzUxMitBMjU2S1ci...开头 - 内存中可找到64字节密钥
H2C上线通信解密
- Transformers: jwe,gob-base
- 与HTTP类似但使用HTTP/2明文协议
- 同样可从内存提取64字节密钥
跳板通信解密
支持多种跳板协议:
SMB跳板通信
- 载荷格式与上线通信不同
- 同样可被64字节密钥解密
TCP跳板通信
- 原始TCP载荷
- 解密后显示内部协议结构
UDP跳板通信
- 短小数据包
- 解密方法与TCP类似
不同Transformers组合下的解密
Merlin支持多种Transformers算法组合,测试发现:
-
aes,gob-base
- HTTP/SMB/TCP/UDP各有不同载荷格式
- 但均可被相同方法解密
-
其他组合
- base64-string,gob-base
- hex-byte,gob-base
- hex-string,gob-base
- gob-string,gob-base
- rc4,gob-base
- xor,gob-base
关键发现:
- 不同Transformers组合产生不同流量格式
- 但密钥提取方法通用
- 解密方法只需适配不同Transformers
总结
- 漏洞本质:Merlin Agent将64字节通信密钥以明文存储在内存中
- 利用方法:
- 从内存dump中搜索64字节字符串
- 作为密钥解密各类通信
- 影响范围:
- 所有通信类型(HTTP/H2C/SMB/TCP/UDP)
- 所有Transformers组合
- 防御建议:
- 改进密钥存储方式
- 定期轮换密钥
- 使用内存加密技术
附录:关键代码片段
密钥搜索代码
func findKeyInMemory(dump []byte) string {
re := regexp.MustCompile(`[a-zA-Z0-9+/=]{64}`)
matches := re.FindAllString(string(dump), -1)
for _, match := range matches {
if isValidKey(match) {
return match
}
}
return ""
}
解密流程代码
func decryptTraffic(traffic []byte, psk string) {
// 尝试用PSK解密
preKey := sha256.Sum256([]byte(psk))
result, err := decryptWithKey(traffic, string(preKey[:]))
if err != nil {
// PSK解密失败,尝试从内存找密钥
memKey := findKeyInMemory(getMemoryDump())
result, err = decryptWithKey(traffic, memKey)
}
return result
}
通过上述方法,安全研究人员可有效分析Merlin Agent的通信内容,提升对这类威胁的检测和防御能力。