《软件安全》上机实验二
第二次上机作业:课本239页第15题
一、实验内容
综合实验:使用AmericanFuzzy Lop(http://Icamtuf.coredump.cx/afl/)工具挖掘 C/C++程序漏洞。完成实验报告。
二、实验环境
- 操作系统:Linux
- 分析工具版本:afl-2.52b
三、实验原理
1.模糊测试
模糊测试是一种自动化的软件测试技术,它的核心思想是向目标程序提供大量非预期的、无效的或随机的输入数据,然后监控程序是否会发生异常,例如崩溃(C rash)、断言失败(Assertion Failure)或内存泄漏(Memory Leak)。这些异常情况通常暗示着程序中存在潜在的安全漏洞,如缓冲区溢出、空指针解引用等。
可以将模糊测试通俗地理解为,像一个“淘气的用户”一样,胡乱地操作软件,看它会不会在某个奇怪的输入下崩溃。
2.American Fuzzy Lop (AFL)
American Fuzzy Lop (AFL)是一种模糊测试(Fuzzing)工具。
传统的模糊测试,是一种黑盒测试,它完全是随机的,效率很低。而AFL是一种覆盖率引导的灰盒模糊测试工具,它并非“盲目”地进行测试,而是有策略地、“聪明”地生成输入数据。AFL工具主要通过两项关键技术编译时插桩和遗传算法实现:
编译时插桩:编译测试程序时,AFL向程序的汇编代码中插入了大量的“探针”,这些探针并不会改变程序的原有逻辑,但它们会记录每一份输入数据执行了程序中的哪些代码路径。当程序运行时,AFL会根据这些探针收集到的信息,绘制出一张“代码覆盖率地图”,AFL由此可以知道,某个输入A覆盖了路径1、2、3,而另一个输入B覆盖了路径 1、3、5。
遗传算法:AFL的测试过程遵循一种类似生物进化的“优胜劣汰”策略:
1 2 3 4
1. 初始种群:AFL从我们提供的种子文件(afl_in目录)开始。 2. 变异 (Mutation):对种子文件进行各种微小的、随机的修改(如位翻转、字节替换、数据块的增删改等),产生一批新的输入。 3. 评估 (Evaluation):用新输入去运行被插桩的程序,并利用“眼睛”(插桩代码)观察代码覆盖率。 4. 选择(Selection):如果一个新输入能够触发一条前所未见的代码路径,AFL就认为它是一个“有价值的”输入。它会将这个输入保存下来,加入到种子队列中,作为下一轮变异的基础。如果一个输入没有产生任何新路径,它就会被丢弃。
通过这种“发现新路径–>保留–>在此基础上继续变异”的正反馈循环,AFL能够像一个有经验的黑客一样,逐步渗透到程序的深层逻辑中,从而高效地发现隐藏在代码深处的漏洞。
四、实验步骤
1.准备测试项目
MD4C (Markdown for C) 是一个高性能、高符合度的开源Markdown解析器库,完全由C语言编写。它作为一个用C语言实现的复杂文本格式解析器,其代码中包含了大量处理边界情况和复杂逻辑的分支,是检验模糊测试工具(AFL)在真实世界项目中发现潜在漏洞能力的理想案例。
1
2
# 克隆md4c源码仓库
git clone https://github.com/mity/md4c.git
2.配置AFL
步骤1:安装AFL编译依赖
步骤2:下载、解压并编译AFL
3.使用afl编译md4c项目
步骤1:进入md4c目录并创建build目录
步骤2:运行cmake来配置项目
步骤3:执行编译
4.运行模糊测试
步骤1:准备测试用例和目录
AFL需要一个输入目录afl_in,里面放一些“种子”文件(合法的输入),它会基于这些种子进行变异;同时,它还需要一个输出目录afl_out,用来存放测试结果。
1
2
3
4
5
6
7
# 创建输入目录和输出目录
mkdir afl_in
mkdir afl_out
# 创建一个简单的Markdown测试用例,放入输入目录
echo "# Heading" > afl_in/seed1.md
echo "*bold text*" > afl_in/seed2.md
步骤2:执行AFL模糊测试器
1
2
3
4
5
# afl-fuzz: 启动AFL的主程序
# -i afl_in: 指定我们刚创建的输入目录
# -o afl_out: 指定我们刚创建的输出目录
# ./md4c/build/md2html/md2html: 要测试的、已经被插桩的目标程序# @@: 占位符,AFL在运行时会自动替换成它当前正在测试的文件名
afl-fuzz -i afl_in -o afl_out ./md4c/build/md2html/md2html @@
步骤3:执行结果
经过一个多小时的测试,并未发现崩溃,如下图所示total crashes:0。
