JoeyZzZzZz/treasure-map
GitHub: JoeyZzZzZz/treasure-map
一个全自动的 IoT 固件逆向工程与漏洞挖掘系统,集成 ELF 分析、反编译、AI 摘要、漏洞扫描和知识库导出,大幅提升固件安全分析效率。
Stars: 0 | Forks: 0
# 🗺️ 藏宝图
**藏宝图** 是一个物联网固件逆向工程与漏洞挖掘系统。输入一个已提取的固件文件系统(或任何包含 ELF 二进制文件的目录),它将运行一个完全自动化的 10 步流水线:ELF 枚举 → 脚本解析 → Ghidra 反编译 → Capa 能力扫描 → SQLite 数据导入 → 跨二进制交叉引用图 → AI 摘要生成 → 针对性漏洞扫描 → ChromaDB 语义索引 → Obsidian 知识库导出。
[中文文档 →](docs/README_zh.md)
## ✨ 功能特性
- **全自动流水线** — ELF 发现 → Ghidra 反编译 → Capa 标记 → AI 摘要 → 目标漏洞扫描,全部通过 `make analyze` 一键完成
- **跨二进制引用图** — 三层 xref 策略:导入/导出符号匹配 + `DT_NEEDED` 依赖链 + IPC 字符串软链接
- **AI 逆向工程代理** — 支持自然语言查询:加密算法、认证逻辑、漏洞挖掘(BOF / 命令注入 / 格式化字符串 / UAF / 整数溢出 / OOB)、补丁建议
- **两遍漏洞分析** — 第 7 步在摘要时由 AI 标记危险函数;第 8 步对所有高风险函数执行专门的第二遍扫描,提高召回率
- **已知 CVE 匹配** — 从嵌入式版本横幅和文件名中检测第三方组件版本(OpenSSL、BusyBox、Dropbear、dnsmasq、curl、hostapd 等),然后与 NVD 的 CPE 进行匹配——揭示基于真实版本的 CVE(非 AI 猜测),并附带 CVSS 严重性等级。响应会被缓存以备离线重新运行。
- **Obsidian 知识库** — 导出结构化 Markdown;像看书一样浏览固件
- **多固件联合查询** — `make agent NAME=fw1,fw2` 通过 SQLite ATTACH 加载多个数据库,实现跨设备比较
- **完全容器化** — Docker 一键部署,跨平台(Windows WSL2 / Linux / macOS)
- **检查点恢复与干净中断** — `SIGTERM`/`Ctrl+C` 会通过流水线传递(不会残留孤立的 Ghidra JVM);输出 JSON 以原子方式写入,因此中断的运行会从最后一个完成的步骤恢复,不会损坏部分文件
## 🏗 架构
```
User: "Where is AES encryption implemented?"
│
▼
AI Agent (rev_agent.py) ←──── OpenAI-compatible API
│
├── ChromaDB (semantic / fuzzy search)
│
└── SQLite (exact queries, SQL)
├── binaries / functions / xrefs
├── imports / exports / strings
└── library_summaries
↑
┌─── Analysis Pipeline ────┐
│ 01 find_elfs │
│ 02 parse_scripts │
│ 03 ghidra_batch │
│ 04 capa_batch │
│ 05 populate_db │
│ 06 build_xrefs │
│ 07 ai_summarize │
│ 08 vuln_scan │
│ 09 build_rag │
│ 10 export_obsidian │
└──────────────────────────┘
```
两个 Docker 容器:
| 容器 | 镜像大小 | 角色 |
|-----------|-----------|------|
| `analyzer` | ~3 GB | Ubuntu 22.04 + OpenJDK 17 + Ghidra 11.1.2 + flare-capa |
| `agent` | ~1.7 GB | Python 3.11-slim + sentence-transformers + ChromaDB + OpenAI 客户端 |
## 📋 环境要求
| 组件 | 版本 |
|-----------|---------|
| Docker Desktop | 4.0+ |
| 操作系统 | Windows 10/11 (WSL2) / Linux / macOS |
| 内存 | 8 GB+(推荐 16 GB) |
| 磁盘 | 20 GB+(镜像约 5 GB) |
| API Key | 任意兼容 OpenAI 的端点(DeepSeek / Qwen / Gemini) |
## 🚀 快速开始
### 1. 克隆并初始化
```
git clone https://github.com/JoeyZzZzZz/Treasure-Map.git
cd Treasure-Map
bash setup.sh
```
`setup.sh` 会拉取预构建的 Docker 镜像(如果不可用则回退到本地构建),创建包含选定语言的 `.env` 文件,并设置工作目录。
### 2. 配置 API Key
编辑 `.env`(由 setup.sh 创建):
```
DEEPSEEK_API_KEY=sk-your-key-here
AI_BASE_URL=https://api.deepseek.com
AI_MODEL=deepseek-v4-flash # fast model for bulk summarization
AGENT_MODEL=deepseek-v4-pro # powerful model for agent queries
```
任意兼容 OpenAI 的端点均可——参见 `.env.example` 中的 Qwen / Gemini 示例。
### 3. 准备目标目录
将提取的固件文件系统(或任何 ELF 二进制文件)放入 `./target/` 目录:
```
target/
└── squashfs-root/ ← extracted filesystem
├── bin/
├── lib/
├── usr/
└── ...
```
### 4. 运行分析
```
# NAME 是可选的 — 默认为目标目录名称
make analyze TARGET=./target/squashfs-root NAME=router_fw
```
输出:
```
[Step 1/10] ELF enumeration and arch detection ...
[Step 2/10] Script file parsing ...
[Step 3/10] Ghidra batch analysis ...
...
✅ Analysis complete!
Total functions: 86 330
Summarized: 80 496
Vuln functions: 1 022
Next: make agent NAME=router_fw
```
### 5. 启动 AI 代理
```
make agent NAME=router_fw # specific firmware
make agent # interactive picker if multiple exist
make agent NAME=fw1,fw2 # federated multi-firmware query
```
示例会话:
```
>>> Where is AES encryption implemented?
🔧 find_crypto_implementation({"algorithm":"AES"})
AES encryption is in:
libcrypto.so.1.1 → AES_encrypt @ 0x00045a20
httpd → FUN_00401c34 — encrypts config data (AES-CBC) before writing to NVRAM
>>> Find all functions with potential command injection
🔧 find_vulnerable_functions({"vuln_type":"vuln_cmd"})
🔧 get_pseudocode({"binary_name":"httpd","func_name":"do_system"})
Found 23 functions tagged vuln_cmd:
httpd::do_system @ 0x00401234 — passes user-controlled CGI param to system()
...
```
## 📁 项目结构
```
Treasure-Map/
├── .env.example ← provider examples (Qwen / Gemini)
├── .gitignore
├── Makefile
├── README.md
├── requirements.txt
├── run_all.sh ← pipeline entry point (runs inside container)
├── setup.sh ← first-time initialization
│
├── docker/
│ ├── Dockerfile.analyzer ← heavy image: Ghidra + Capa
│ └── Dockerfile.agent ← light image: Python agent
│
├── docker-compose.yml
│
├── scripts/
│ ├── 01_find_elfs.py ELF enumeration and arch detection
│ ├── 02_parse_scripts.py Shell/Python/Lua script parsing (shell call graph)
│ ├── 03_ghidra_batch.sh Ghidra headless decompilation
│ ├── 04_capa_batch.py Capa capability scanning
│ ├── 05_populate_db.py Ingest results into SQLite
│ ├── 06_build_xrefs.py Cross-binary reference graph
│ ├── 07_ai_summarize.py AI function + library summarization
│ ├── 08_vuln_scan.py Targeted second-pass vulnerability scan
│ ├── 09_build_rag.py ChromaDB vector index
│ ├── 10_export_obsidian.py Obsidian Vault export
│ ├── test_api.py API connectivity test
│ └── ghidra_scripts/
│ └── ExportFunctions.java
│
├── agent/
│ └── rev_agent.py ← interactive AI query agent
│
├── database/ ← auto-created per firmware: /analysis.db
├── workspace/ ← intermediate files (Ghidra/Capa output)
├── obsidian_vault/ ← Obsidian Markdown export
└── target/ ← place firmware filesystem here
```
## 🛠 所有命令
```
# 首次设置
bash setup.sh
# 本地构建 Docker 镜像
make build
# 分析固件(NAME 默认为目标目录名称)
make analyze TARGET=./target/squashfs-root NAME=router_fw
make analyze TARGET=./target/ap_firmware NAME=ap_fw
# 启动 AI agent
make agent NAME=router_fw # single firmware
make agent # interactive picker
make agent NAME=router_fw,ap_fw # federated query
# FW= 是 NAME= 的短别名;.lastfw 记住上次的固件
make agent FW=router_fw
make agent # auto-uses last firmware
# 列出所有已分析的固件及其统计信息
make list
# 重新导出 Obsidian vault 而不重新分析
make obsidian NAME=router_fw
# 清理中间文件(保留数据库)
make clean NAME=router_fw # clear checkpoint for one firmware
make clean # clear all checkpoints
# 删除分析数据
make reset NAME=router_fw # delete database/router_fw/ (with confirmation)
make reset # delete all firmware data (with confirmation)
```
## ⚙️ 配置参考
所有设置均在 `.env` 文件中(由 `setup.sh` 创建;参见 `.env.example` 了解提供商示例):
| 变量 | 默认值 | 描述 |
|----------|---------|-------------|
| `DEEPSEEK_API_KEY` | — | API 密钥(AI 步骤必需) |
| `AI_BASE_URL` | `https://api.deepseek.com` | 任意兼容 OpenAI 的基础 URL |
| `AI_MODEL` | `deepseek-v4-flash` | 批量摘要生成使用的模型(第 7 步) |
| `AI_THINKING` | `false` | 为摘要生成启用思考模式 |
| `AI_CONCURRENCY` | `50` | 第 7 步中并发 AI 请求数(第 8 步固定为 16) |
| `AI_BATCH_SIZE` | `5` | 每次批量摘要调用包含的函数数(第 7 步) |
| `AI_TIMEOUT` | `120` | 每次 API 请求的超时时间(秒)(步骤 7 和 8) |
| `AGENT_BASE_URL` | 与 `AI_BASE_URL` 相同 | 代理查询的基础 URL |
| `AGENT_MODEL` | `deepseek-v4-pro` | 代理查询使用的模型 |
| `AGENT_THINKING` | `true` | 为代理启用思考模式 |
| `LANG_PREF` | `en` | 输出语言:`en` 或 `zh-CN` |
| `GHIDRA_WORKERS` | 自动 | Ghidra 并行工作线程数(默认:`min(cpu_count, available_GB)`) |
| `GHIDRA_BATCH_SIZE` | `8` | 共享一个 JVM 的 ELF 文件数(小型同架构文件) |
| `GHIDRA_BATCH_THRESHOLD` | `204800` | 大于此大小(字节)的文件将单独运行 |
| `GHIDRA_RETRY_TIMEOUT` | `3600` | 第 3 步无超时重试通道的时间上限(秒);`0` 表示禁用 |
| `CAPA_WORKERS` | `min(4, cpu_count)` | 第 4 步中并发 Capa 工作线程数 |
| `NVD_API_KEY` | — | 可选的 NVD 密钥,用于 CVE 匹配——可提高速率限制(5→50 请求/30 秒)。[免费申请一个](https://nvd.nist.gov/developers/request-an-api-key) |
| `CVE_MAX_PER_COMPONENT` | `150` | 每个检测到的组件的 CVE 数量上限 |
### 支持的 API 提供商
任意兼容 OpenAI 的端点均可。`.env.example` 中的示例:
- **DeepSeek**(推荐)— `https://api.deepseek.com`
- **阿里云 Qwen** — `https://dashscope.aliyuncs.com/compatible-mode/v1`
- **Google Gemini** — `https://generativelanguage.googleapis.com/v1beta/openai`
## 🔍 支持的 ELF 架构
| 架构 | Ghidra 反编译 | 能力标记 |
|-------------|---------------------|-------------------|
| ARM 32-bit (v7) | ✅ | ✅ Capa |
| ARM 64-bit (AArch64) | ✅ | ✅ Capa |
| MIPS 32/64 | ✅ | ⚠️ 导入启发式 |
| x86 / x86-64 | ✅ | ✅ Capa |
## 🔧 高级用法
### Ghidra 并行度调优
第 3 步会根据可用 RAM 自动检测工作线程数(`available_GB`,上限为 CPU 核心数——大约每 GB 一个工作线程)。可在需要时覆盖:
```
# 限制为 2 个 worker 以降低系统负载
GHIDRA_WORKERS=2 make analyze TARGET=./target/squashfs-root NAME=router_fw
```
或者将 `GHIDRA_WORKERS=2` 添加到 `.env` 中作为永久设置。
### 检查点恢复
流水线在每一步完成后会写入检查点。如果分析被中断,重新运行 `make analyze` 将自动跳过已完成的步骤。
```
# 查看进度
cat workspace/.checkpoint_router_fw
# 强制重新运行特定步骤(例如 AI 摘要)
sed -i '/^summarize_router_fw$/d' workspace/.checkpoint_router_fw
make analyze TARGET=./target/squashfs-root NAME=router_fw
# 强制重新运行定向 vuln 扫描
sed -i '/^vuln_scan_router_fw$/d' workspace/.checkpoint_router_fw
make analyze TARGET=./target/squashfs-root NAME=router_fw
```
### 多固件联合查询
```
make agent NAME=router_fw,ap_fw
# agent 内的跨设备 SQL:
>>> Compare command-injection functions across both devices
🔧 query_database({"sql":
"SELECT 'router_fw' AS fw, name, binary FROM functions WHERE func_types LIKE '%vuln_cmd%'
UNION ALL
SELECT 'ap_fw', name, binary FROM \"ap_fw\".functions WHERE func_types LIKE '%vuln_cmd%'"
})
```
### 手动运行流水线步骤
```
docker compose run --rm \
-e FIRMWARE_NAME=router_fw \
-v "$(pwd)/target/squashfs-root:/target:ro" \
analyzer
# 容器内部:
python3 /opt/iot_rev/scripts/07_ai_summarize.py
python3 /opt/iot_rev/scripts/08_vuln_scan.py
python3 /opt/iot_rev/scripts/09_build_rag.py
```
### SQLite 模式
```
binaries: id, name, path, arch, bits, sha256, file_type, dt_needed, capa_tags,
protections ← JSON: {nx, pie, canary, relro:"none|partial|full", fortify}
functions: id, binary_id, name, address, size_bytes, pseudocode, summary,
func_types, callees, vuln_hints, capa_tags, is_exported
scripts: id, name, path, interpreter, sha256, size_bytes
script_calls: id, script_id, command, raw_line, line_number, args_pattern,
has_user_input, vuln_hint
components: id, binary_id, product, version, cpe, source, evidence
cve_matches: id, component_id, binary_id, cve_id, cvss_score, severity,
summary, published, url
imports / exports / xrefs / strings / library_summaries
```
`func_types` 字段使用固定词汇表:
| 标签 | 含义 |
|-----|---------|
| `crypto` | 加密 / 解密 / 哈希 |
| `network` | 套接字 / 网络 I/O |
| `auth` | 认证 / 授权 |
| `cmd_exec` | 命令执行(system / popen / execve)|
| `file_io` | 文件读 / 写 |
| `nvram` | NVRAM / UCI / 配置访问 |
| `ipc` | IPC / 共享内存 |
| `parsing` | 数据包 / 数据格式解析 |
| `vuln_bof` | 缓冲区溢出 |
| `vuln_fmt` | 格式化字符串漏洞 |
| `vuln_cmd` | 命令注入 |
| `vuln_uaf` | 释放后使用 |
| `vuln_int` | 整数溢出 / 下溢 |
| `vuln_oob` | 越界读 / 写 |
## ❓ 常见问题
**问:我的固件还没有提取——应该用什么?**
答:此工具分析已提取的二进制文件。请先使用 [unblob](https://github.com/onekey-sec/unblob)(推荐)或 [binwalk](https://github.com/ReFirmLabs/binwalk) 提取固件,然后将 `TARGET=` 指向生成的目录。
**问:AI 摘要生成需要多少费用?**
答:DeepSeek 非常经济实惠(约 $0.0001/1K tokens)。一个中等规模的固件(约 2000 个函数)通常总共花费 0.50–1.50 美元。
**问:没有 API Key 可以运行吗?**
答:可以。第 1–6 步完全离线运行。代理也可以工作,但没有函数摘要,因此语义搜索的准确性会显著下降。
**问:如何打开 Obsidian 知识库?**
答:安装 [Obsidian](https://obsidian.md) → 以文件夹形式打开库 → 选择 `./obsidian_vault//`。
**问:分析似乎卡住了/发出了太多工具调用?**
答:代理会显示 `⏳ Thinking... [N/30]` 以指示进度。复杂的调用链查询可能会使用多轮。尝试更针对性的问题,或者先使用 `find_callers` / `get_binary_functions` 缩小范围。
## 📄 许可证
MIT 许可证——参见 [LICENSE](LICENSE)。
## 🙏 致谢
- [Ghidra](https://github.com/NationalSecurityAgency/ghidra) — NSA 开源逆向工程框架
- [flare-capa](https://github.com/mandiant/capa) — Mandiant 能力检测工具
- [ChromaDB](https://github.com/chroma-core/chroma) — 开源向量数据库
- [unblob](https://github.com/onekey-sec/unblob) — 固件提取工具
标签:AI安全, AI辅助逆向, Capa能力扫描, Chat Copilot, ChromaDB向量数据库, CVE匹配, DLL 劫持, ELF分析, Ghidra反编译, JS文件枚举, NIDS, NVD, Obsidian知识库, Petitpotam, SQLite数据库, UAF, 二进制分析, 云安全运维, 内核监控, 反向工程系统, 命令注入, 固件安全, 固件逆向, 多固件联合查询, 大语言模型, 容器化, 整数溢出, 格式字符串, 物联网安全, 第三方组件检测, 缓冲区溢出, 自动化分析, 语义索引, 请求拦截, 越界, 跨二进制引用, 跨站脚本, 逆向工具