符号执行入门:从理论到实战的桥梁
大家好,我是你们这堂课的老朋友。今天咱们聊聊符号执行的入门知识。说实话,我第一次接触符号执行时,也觉得这东西挺玄乎的。但干渗透测试久了,你会发现——很多漏洞,光靠人工看代码,真的看不出来。
符号执行,说白了就是让程序在「符号」的世界里跑一遍。不是具体的数字,而是抽象的符号。嗯,这里要注意,这个思路其实很早就有了。
符号执行发展史:从学术论文到实战利器
符号执行不是新鲜玩意儿。我给大家捋一捋它的发展脉络。
| 年代 | 里程碑 | 我的评价 |
|---|---|---|
| 1976年 | James King 提出符号执行概念 | 纯理论,跑不动真实程序 |
| 2005年 | KLEE、EXE 等工具诞生 | 开始能跑小项目了 |
| 2010年后 | Angr、S2E 等现代工具出现 | 真正能用于实战 |
| 现在 | 符号执行 + 模糊测试 + 渗透测试 | 我的日常标配 |
我记得2015年第一次用Angr分析一个二进制漏洞时,心里还在打鼓:这玩意儿靠谱吗?结果它帮我找到了一个隐藏了3年的缓冲区溢出。从那以后,我再也不敢小看符号执行了。
核心观点:符号执行不是替代人工,而是放大你的能力。你想想看,一个函数有100条路径,人工看一遍要多久?符号执行几分钟就搞定了。
符号执行核心概念:你必须搞懂的三个东西
符号执行有三个核心概念,我建议你死记硬背也要记住。因为实战中,你天天都会遇到它们。
1. 符号值 vs 具体值
普通程序跑的是具体值。比如 x = 5,那 x 就是 5。符号执行不一样,它把输入变成符号。比如 x = sym_input(),那 x 就是一个符号,代表「所有可能的整数」。
为什么会这样?因为我们要探索所有路径。如果 x 是具体值,那程序只能走一条路。但 x 是符号,程序就能走所有路。
我的习惯:在渗透测试中,我会把用户输入、网络数据包、文件内容都设为符号值。这样能覆盖所有攻击面。
2. 路径约束
程序每遇到一个分支,就会产生一个约束。比如:
if (x > 10) {
// 路径 A
} else {
// 路径 B
}
符号执行会记录:走路径 A 需要 x > 10,走路径 B 需要 x <= 10。这些约束条件,就是路径约束。
我曾经遇到过一个案例:一个登录验证函数,看起来只有两条路径(成功/失败)。但用符号执行一跑,发现其实有5条路径——因为中间有个隐藏的整数溢出分支。嗯,这就是符号执行的威力。
3. 约束求解
有了路径约束,怎么得到具体的输入值?这就需要约束求解器了。最常用的是 Z3,微软出品。
举个例子:如果路径约束是 x > 10 && x < 20,Z3 会告诉你:x = 11 就能走通这条路。
避坑指南:我曾经遇到一个坑——约束求解器不是万能的。遇到复杂的浮点运算或非线性约束,Z3 可能会卡死。这时候,我建议你手动简化约束,或者换用其他求解器。
符号执行与渗透测试的关系:为什么你必须学?
很多人问我:做渗透测试,手工挖洞就够了,为什么要学符号执行?
我的回答是:你想想看,现在一个软件动辄几百万行代码。人工审计,你审计得过来吗?符号执行就是你的自动化审计助手。
具体来说,符号执行在渗透测试中有三大应用场景:
- 漏洞发现:自动生成触发漏洞的输入。比如缓冲区溢出、整数溢出、格式化字符串等。
- 路径覆盖:确保测试用例覆盖所有代码路径。我见过太多「漏网之鱼」了。
- 逆向分析:分析恶意软件的行为。符号执行可以帮你理清恶意代码的逻辑。
我记得有一次做渗透测试,目标是一个嵌入式设备。固件里有个加密函数,我逆向了一整天都没搞明白。后来用符号执行跑了一下,直接找到了密钥生成的逻辑。嗯,从那以后,我的工具箱里就永远有符号执行的位置了。
一句话总结:符号执行不是银弹,但它是一把锋利的刀。用好了,你能砍开很多看似无解的漏洞。
实战前的准备:你需要什么?
在开始实战之前,我建议你准备好以下工具:
- Angr:我最常用的符号执行框架,支持 x86、ARM、MIPS 等架构。
- Z3:约束求解器,Angr 默认使用它。
- IDA Pro 或 Ghidra:用于反汇编和分析二进制文件。
- Python 3:Angr 是用 Python 写的,你至少得会写点 Python 脚本。
安装命令很简单:
pip install angr z3-solver
嗯,这里要注意:Angr 的版本更新很快,我建议你使用最新的稳定版。我曾经因为版本问题折腾了一整天,最后发现是 API 变了。
我的建议:刚开始学的时候,不要贪多。先拿一个简单的 C 程序练手,比如一个带 if-else 的登录验证函数。跑通了,再上真实的目标。
好了,这一章的内容就到这里。下一章,我们会真正动手,用符号执行分析第一个程序。到时候,你会看到符号执行到底是怎么工作的。
记住:理论是死的,工具是活的。只有动手实践,你才能真正掌握符号执行。