name: binary-re-triage description: 当首次遇到未知的二进制文件、ELF文件、可执行文件或固件镜像时使用。通过rabin2进行快速指纹识别 - 架构检测(ARM、x86、MIPS)、ABI识别、依赖映射、字符串提取。关键词 - “这是什么二进制文件”、“识别架构”、“检查文件类型”、“rabin2”、“文件分析”、“快速扫描”
二进制文件初步分析(第一阶段)
目的
在进行深入分析之前,快速建立基线事实。在几秒钟内完成,而不是几分钟。
使用时机
- 首次接触未知的二进制文件
- 需要为工具选择获取架构/ABI信息
- 快速能力评估
- 在投入耗时分析之前
关键原则
快速收集事实,推迟分析。
此阶段识别二进制文件是什么,而不是如何工作。
分析流程
步骤 1:文件识别
# 基本识别
file binary
# 预期输出模式:
# ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3
# ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1
提取信息:
- 架构(ARM、ARM64、x86_64、MIPS)
- 位宽(32/64)
- 字节序(LSB/MSB)
- 链接类型(静态/动态)
- 解释器路径(libc指示器)
步骤 2:结构化元数据(rabin2)
# 所有元数据以JSON格式输出
rabin2 -q -j -I binary | jq .
# 关键字段:
# .arch - "arm", "x86", "mips"
# .bits - 32 或 64
# .endian - "little" 或 "big"
# .os - "linux", "none"
# .machine - "ARM", "AARCH64"
# .stripped - true/false
# .static - true/false
步骤 3:ABI检测
# 解释器检测
readelf -p .interp binary 2>/dev/null
# 或通过rabin2
rabin2 -I binary | grep interp
# ARM特定:浮点ABI
readelf -A binary | grep "Tag_ABI_VFP_args"
# hard-float: "VFP registers"
# soft-float: 缺失或 "compatible"
解释器 → Libc映射:
| 解释器 | Libc | 说明 |
|---|---|---|
/lib/ld-linux-armhf.so.3 |
glibc | ARM 硬浮点 |
/lib/ld-linux.so.3 |
glibc | ARM 软浮点 |
/lib/ld-musl-arm.so.1 |
musl | ARM 32位 |
/lib/ld-musl-aarch64.so.1 |
musl | ARM 64位 |
/lib/ld-uClibc.so.0 |
uClibc | 嵌入式 |
/lib64/ld-linux-x86-64.so.2 |
glibc | x86_64 |
步骤 4:依赖项
# 库依赖项
rabin2 -q -j -l binary | jq '.libs[]'
# 常见模式:
# libcurl.so.* → HTTP客户端
# libssl.so.* → TLS/加密
# libpthread.so.* → 线程
# libz.so.* → 压缩
# libsqlite3.so.* → 本地数据库
步骤 5:入口点与导出
# 入口点
rabin2 -q -j -e binary | jq .
# 导出(针对共享库)
rabin2 -q -j -E binary | jq '.exports[] | {name, vaddr}'
步骤 6:快速字符串扫描
# 所有带元数据的字符串
rabin2 -q -j -zz binary | jq '.strings | length' # 先计数
# 过滤感兴趣的字符串(URL、路径、错误信息)
rabin2 -q -j -zz binary | jq '
.strings[] |
select(.length > 8) |
select(.string | test("http|ftp|/etc|/var|error|fail|pass|key|token"; "i"))
'
步骤 7:导入分析
# 所有导入
rabin2 -q -j -i binary | jq '.imports[] | {name, lib}'
# 按功能分组
rabin2 -q -j -i binary | jq '
.imports | group_by(.lib) |
map({lib: .[0].lib, functions: [.[].name]})
'
功能映射
| 导入模式 | 功能 |
|---|---|
socket, connect, send |
网络客户端 |
bind, listen, accept |
网络服务器 |
open, read, write |
文件I/O |
fork, exec*, system |
进程创建 |
pthread_* |
多线程 |
SSL_*, EVP_* |
密码学 |
dlopen, dlsym |
动态加载 |
mmap, mprotect |
内存操作 |
输出格式
初步分析后,记录结构化事实:
{
"artifact": {
"path": "/path/to/binary",
"sha256": "abc123...",
"size_bytes": 245760
},
"identification": {
"arch": "arm",
"bits": 32,
"endian": "little",
"os": "linux",
"stripped": true,
"static": false
},
"abi": {
"interpreter": "/lib/ld-musl-arm.so.1",
"libc": "musl",
"float_abi": "hard"
},
"dependencies": [
"libcurl.so.4",
"libssl.so.1.1",
"libz.so.1"
],
"capabilities_inferred": [
"network_client",
"tls_encryption",
"compression"
],
"strings_of_interest": [
{"value": "https://api.vendor.com/telemetry", "type": "url"},
{"value": "/etc/config.json", "type": "path"}
],
"complexity_estimate": {
"functions": "unknown (stripped)",
"strings": 847,
"imports": 156
}
}
知识记录
初步分析完成后,为情景记忆记录发现:
[BINARY-RE:triage] {filename} (sha256: {hash})
识别信息:
架构:{arch} {bits}位 {endian}
Libc:{glibc|musl|uclibc} ({interpreter_path})
已剥离符号:{是|否}
大小:{bytes}
事实:链接到 {library} (来源:rabin2 -l)
事实:包含 {N} 个感兴趣的字符串 (来源:rabin2 -zz)
事实:从 {library} 导入 {function} (来源:rabin2 -i)
推断的功能:
- {功能_1} (证据:{导入/字符串})
- {功能_2} (证据:{导入/字符串})
假设:{二进制文件可能的功能} (置信度:{0.0-1.0})
问题:{需要调查的未知点}
下一阶段:{静态分析|动态分析}
所需系统根目录:{路径 或 "从设备提取"}
示例记录条目
[BINARY-RE:triage] thermostat_daemon (sha256: a1b2c3d4...)
识别信息:
架构:ARM 32位 小端序
Libc:musl (/lib/ld-musl-arm.so.1)
已剥离符号:是
大小:153,600 字节
事实:链接到 libcurl.so.4 (来源:rabin2 -l)
事实:链接到 libssl.so.1.1 (来源:rabin2 -l)
事实:包含字符串 "api.thermco.com" (来源:rabin2 -zz)
事实:导入 curl_easy_perform (来源:rabin2 -i)
推断的功能:
- HTTP客户端 (证据:libcurl导入)
- TLS加密 (证据:libssl导入)
- 网络通信 (证据:URL字符串)
假设:向 api.thermco.com 报告的遥测客户端 (置信度:0.6)
问题:它收集和传输什么数据?
下一阶段:静态分析
所需系统根目录:musl ARM (从设备或Alpine提取)
决策点
初步分析后,确定:
- 系统根目录选择 - 基于架构 + libc
- 分析工具链 - r2 vs Ghidra vs 两者
- 动态分析可行性 - 基于架构的QEMU可行性
- 初始假设 - 这个二进制文件可能做什么?
后续步骤
→ 进入 binary-re-static-analysis 进行函数枚举
→ 或者 binary-re-dynamic-analysis 如果行为观察是优先事项