浅尝AFL++
入门一下fuzzing
简单安装配置
这里先不用源码编译的方式, 直接pull 一个镜像来尝尝鲜
docker pull aflplusplus/aflplusplus:latest |
创建demo
创建一个目录
mkdir -p ~/afl-demo/in |
准备一个.c文件
|
这个程序故意把最多128字节读进32字节缓冲区里, 所以很容易被 fuzz 出崩溃。
程序是从文件获取输入的, 所以再准备一个文件
printf 'AAAA' > in/seed.txt |
启动
docker run -it --rm -v ~/afl-demo:/src aflplusplus/aflplusplus:latest |
启动之后我们的文件都在/src下, 现在开始编译程序
cd /src |
-O0 表示编译的时候不做优化, 跟gcc的参数是一样的
-g 生成调试符号
简单运行测试一下
./demo in/seed.txt |
正常是不会有输出的, 也不会卡住什么的
开始fuzz
afl-fuzz -i in -o out -- ./demo @@ |
因为这个程序是从文件读输入, 所以命令里要用 @@
这是 AFL++ 官方 quick start 的标准写法:如果目标从文件读取,AFL++ 会把 @@ 替换成自动生成的测试用例路径
大概页面是这样, 说明已经在fuzzing了
它是不会自动停止的, 这里大概跑了11min, saved crashes 变为了1, 说明有一个样例导致这个程序崩溃了.
这时我们按下 ctrl + c就能停止, 导致程序crash的输入会存放在out/default/crashes/目录下
[AFL++ 8f4d96b5a055] /src # ls out/default/crashes |
README不用管, 我们直接看id:000000,sig:11,src:000001,time:271,execs:413,op:havoc,rep:7
[AFL++ 8f4d96b5a055] /src # cat out/default/crashes/id\:000000\,sig\:11\,src\:000001\,time\:271\,execs\:413\,op\:havoc\,rep\:7 |
gdb一下
可以看到最终是在main函数返回之前的canary验证这里就死了
确实是溢出导致覆盖了canary
fuzzing 101 通关以及踩坑记录
1.Exercise 1 - Xpdf (Afl-clang-fast, Afl-fuzz, GDB)
复现一下 Vulnerability Details : CVE-2019-13288
下载目标程序并解压, 最好提前创建一个目录
wget https://dl.xpdfreader.com/old/xpdf-3.02.tar.gz |
正常构建(非必要)
cd xpdf-3.02 |
这里下载些pdf来进行测试
cd $HOME/fuzzing_xpdf |
测试一下
$HOME/fuzzing_xpdf/install/bin/pdfinfo -box -meta $HOME/fuzzing_xpdf/pdf_examples/helloworld.pdf |
能正常使用, 说明安装没什么问题, 现在使用 afl-cc 和 afl-c++ 来编译安装xpdf. 先把之前的目标文件和可执行文件清理一下
rm -r $HOME/fuzzing_xpdf/install |
接着用afl特制编译器来再做一次编译安装的动作, 因为我是用docker镜像的, 所以稍微会有点不一样, 先启动一下
docker run -it --rm -v ~/afl-demo/fuzzing_xpdf:/src aflplusplus/aflplusplus:latest |
然后进入之前clone的源码的目录下
cd /work/xpdf-3.02 |
用官方镜像的话就不需要更换llvm了
export CC=afl-cc |
配置并编译
./configure --prefix="$HOME/fuzzing_xpdf/install/" |
之前做测试的pdf被删了, 重新搞一下
cd $HOME/fuzzing_xpdf |
因为教程中后面两个示例pdf都404了, 这里我们的初始语料库就只能有一个pdf. 可以非常直观的看到语料库对fuzz的影响.
返回上级目录, 然后开始fuzz
cd .. |
等待
我这里跑了大概7分钟才跑出来第一个crash, 但是知乎的这个师傅只用了1分多钟
ok, 得到样例之后我们可以复现一下这个漏洞.
…中间出现了一点插曲, 不小心按错退出了docker, 因为在run的时候加了 –rm, 他直接就给我删掉了, out的路径还不是挂载的那个目录, 所以得再来一次. 建议还是把out放在挂载在宿主机的目录下
重新编译, 加上-g方便后续调试
rm -r $HOME/fuzzing_xpdf/install # 记得换成自己安装的目录 |
然后gdb启动一下
gdb --args /src/work/xpdf/install/bin/pdftotext /src/work/out/default/crashes/id:000001 |
发现, 造成崩溃的原因跟 CVE-2019-13288 描述的不一样
这里应该是我的语料库太单调了, 只有一个 helloworld.pdf , 然后alf++ 对我的 helloworld.pdf 进行了疯狂的变异, 变了些神秘的16进制字符出来, 最后就死在了这个getchar()这, 既然这样, 我们就需要给语料库添加点素材
cd /in |
然后依旧是编译启动, 这里就省略了
居然这么快就跑了一个crash出来… 最后是跑了大概一分钟, 总共3个crash
依旧是
rm -r $HOME/fuzzing_xpdf/install # 记得换成自己安装的目录 |
然后就启动
gdb --args /src/work/xpdf/install/bin/pdftotext /src/work/out/default/crashes/id:000001,sig:11,src:000000,time:35363,execs:8962,op:havoc,rep:1 /dev/null |
发现依旧复现不出来…
这次是触发了一个空指针异常, 感觉是我找的pdf过于现代了, 包含了对象流和压缩结构这种比较新的东西, xpdf在解析对象的时候就 crash 了, 没法触发cve中所描述的无限递归导致的崩溃…
因为原课程中的另外两个pdf已经找不到了, 就没法很顺利的复现这个cve, 但不要紧, 个人认为能否复现cve不重要, 这个Exercise1 要我们做的就是熟悉Afl-clang-fast, Afl-fuzz, GDB而已, 我也确实做到了
Exercise 2 - libexif (Afl-clang-lto, Fuzz libraries, Eclipse IDE)
施工ing