90 lines
3.4 KiB
Markdown
90 lines
3.4 KiB
Markdown
# [种子] Go 恶意软件逆向(stripped + Garble)
|
||
|
||
## 场景分类
|
||
二进制分析
|
||
|
||
## 目标概述
|
||
分析一个 stripped 且 Garble 混淆的 Go 编译恶意软件,恢复函数名和字符串,定位 C2 通信逻辑。
|
||
|
||
## 完整执行链路
|
||
|
||
1. `file` 确认 ELF x86_64,静态链接,6MB+
|
||
2. `strings | grep "go1\."` → 确认 Go 版本(如 go1.21.5)
|
||
3. GoReSym 尝试恢复符号 → 部分成功(pclntab 存在但函数名被 Garble 随机化)
|
||
4. GoResolver 用 CFG 签名匹配 → 恢复了 80% 的标准库函数名
|
||
5. GoStringUngarbler 解密字符串 → 发现 C2 域名、API 路径、加密密钥
|
||
6. IDA 加载 + 导入 GoReSym 符号 → 过滤掉 runtime.* 聚焦 main.*
|
||
7. 从解密出的 C2 域名交叉引用 → 定位网络通信函数
|
||
8. 分析通信协议(HTTP POST + AES 加密 body)
|
||
9. 提取 AES 密钥 → 解密样本通信
|
||
|
||
## 踩坑记录
|
||
|
||
| 问题 | 原因 | 解决方案 | 耗时 |
|
||
|------|------|---------|------|
|
||
| IDA 加载后 5 万+ 函数看不过来 | Go 静态链接整个 runtime | 用 GoReSym 恢复名字后按包名过滤,只看 main.* | 15min |
|
||
| 字符串窗口几乎为空 | Garble 加密了所有字符串 | GoStringUngarbler 自动解密 | 5min |
|
||
| GoReSym 恢复的函数名全是随机字符 | Garble 混淆了用户函数名 | GoResolver CFG 匹配恢复标准库,剩下的手动分析 | 1h |
|
||
| 反编译结果中 interface 调用看不懂 | Go interface 是间接调用(itab) | 找到 itab 表,手动标注接口类型 | 30min |
|
||
| AES 密钥在哪 | 密钥是运行时从多个常量拼接的 | 跟踪 crypto/aes.NewCipher 的参数来源 | 45min |
|
||
|
||
## 工具链发现
|
||
|
||
- GoReSym 即使对 Garble 混淆的二进制也能恢复 pclntab 结构(函数边界)
|
||
- GoResolver 是对抗 Garble 的最佳工具(CFG 签名不受函数名混淆影响)
|
||
- GoStringUngarbler 能识别 Garble 的字符串加密模式并批量解密
|
||
- Go 二进制的 AES 密钥通常在 `crypto/aes.NewCipher` 的调用参数中
|
||
|
||
## 关键代码/命令
|
||
|
||
```bash
|
||
# 恢复符号
|
||
GoReSym -t -d -p malware > symbols.json
|
||
|
||
# CFG 去混淆
|
||
GoResolver -binary malware -output resolved.json
|
||
|
||
# 字符串解密
|
||
GoStringUngarbler -i malware -o malware_deobf
|
||
|
||
# 过滤用户代码函数
|
||
cat symbols.json | jq '.Functions[] | select(.PackageName == "main")'
|
||
```
|
||
|
||
## 对本包的改进建议
|
||
|
||
- go-reverse.md 应该加入"如何从 crypto/aes.NewCipher 追踪密钥"的具体方法
|
||
- 建议加入 Go interface/itab 的逆向解析方法
|
||
|
||
## 可复用的模式/脚本片段
|
||
|
||
**Go 恶意软件分析标准流程**:
|
||
```text
|
||
1. 确认 Go 版本 → 2. GoReSym 恢复结构 → 3. GoResolver 去混淆
|
||
→ 4. GoStringUngarbler 解密字符串 → 5. 从字符串找 C2/密钥
|
||
→ 6. 交叉引用定位通信函数 → 7. 分析协议 → 8. 提取 IOC
|
||
```
|
||
|
||
**Go 二进制中定位加密密钥**:
|
||
```text
|
||
搜索 crypto/aes.NewCipher 或 crypto/cipher.NewGCM 的调用
|
||
→ 回溯第一个参数([]byte)的来源
|
||
→ 通常是硬编码常量拼接或从配置解密
|
||
```
|
||
|
||
## 进化动作
|
||
- [ ] 无需更新路由矩阵
|
||
- [ ] 无需更新 bootstrap-manifest
|
||
- [x] go-reverse.md 已覆盖大部分内容
|
||
|
||
## 环境信息
|
||
- OS: Linux x86_64
|
||
- 工具版本: GoReSym latest, GoResolver latest, IDA Pro
|
||
- 目标平台: Linux x86_64, Go 1.21+
|
||
|
||
## 脱敏要求
|
||
本条目为种子数据,基于公开技术模式编写,不涉及真实目标。
|
||
|
||
---
|
||
<!-- [社区贡献] 种子数据,无需 PR -->
|