1989年的模糊测试技术
随着2019年临近,让我们回顾历史寻求改进。我们将目光投向30年前,重新审视模糊测试的开山之作:Barton P. Miller教授1990年发表的《UNIX工具可靠性实证研究》及其1995年续作《模糊测试再探》。
本文将使用原始论文中完全相同的测试工具,在现代Ubuntu Linux系统中寻找漏洞。这两篇论文不仅提供了研究背景,更包含了惊人的预见性------它们准确预测了随后十年代码中普遍存在的漏洞类型。
技术概览
模糊测试程序通过生成随机字符流(可选择可打印字符/控制字符/非打印字符)进行测试,其核心特性包括:
- 使用随机种子确保结果可复现(现代模糊测试工具常缺失此功能)
- 通过脚本自动检测程序崩溃(生成core dump)
- 手动识别程序挂起
- 适配器支持交互式程序(1990)、网络服务(1995)和X图形程序(1995)测试
原始研究覆盖4种处理器架构(i386/CVAX/Sparc/68020)和5个操作系统(4.3BSD/SunOS/AIX/Xenix/Dynix)。结果显示:
- 1990年测试中25-33%工具存在故障
- 1995年测试中GNU/Linux故障率最低(9%)
现代复现方法
我们使用1995年代码库fuzz-1995-basic进行测试,仅更新测试目标列表以适配现代Linux环境。测试工具链保持原始状态,仅对部分过时软件包进行等效替换:
原始工具 | 现代替代 | 替换原因 |
---|---|---|
cfe | cc1 | C预处理器等效 |
dbx | gdb | 调试器等效 |
ditroff | groff | 排版系统继任者 |
... | ... | ... |
测试结果对比
系统版本 | 崩溃数 | 挂起数 | 测试总数 | 故障率 |
---|---|---|---|---|
Slackware 2.1.0 (1995) | 4 | 1 | 55 | 9% |
Ubuntu 14.04 (2014) | 2 | 2 | 81 | 5% |
Ubuntu 18.10 (2018) | 1 | 1 | 81 | 2% |
典型漏洞分析
-
glibc缓冲区溢出
在
ul
工具中发现的实际上是glibc漏洞(2016年报告仍未修复),表现为sprintf
写入固定长度缓冲区的经典问题:cerrstr(const char *s, const char *t) { char buff[100]; sprintf(buff, s, t); // 缓冲区溢出风险 err(buff); }
-
拼写检查死锁
spell
与ispell
通过管道通信时产生经典死锁:spell
阻塞写入超过4096字节的行ispell
阻塞等待确认已读取修正数据
-
Fortran编译器崩溃
f2c
转换器中的错误处理函数存在30年历史遗留漏洞,其变更日志可追溯至1989年。
历史启示
原始论文的三大预言至今有效:
- C语言类型系统存在根本缺陷
- 基础模糊测试始终有效
- 开发者修复漏洞意愿低下
尽管现代Linux系统故障率已从9%降至2%,但完全消除基础性漏洞仍需持续努力。这项研究证明,即使是最简单的自动化测试方法,经过30年仍能发现当代软件中的关键缺陷。
(全文完)