本文主要是介绍Fuzzing-101 Exercises,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 前言
- AFL++ 环境搭建
- Exercise-1 Xpdf CVE-2019-13288
- Xpdf 环境搭建
- 种子库获取 && 前期准备
- 开始 fuzz && 分析 crash
- 总结
- Exercise-2 libexif CVE-2009-3895/CVE-2012-2836
- libexif 环境搭建
- 种子库获取 && 前期准备
- 开始 fuzz && 分析 crash
- 总结
前言
笔者将 AFL
源码审计的差不多了,打算接着 Fuzzing-101 这个项目来练练手,学习一下 Fuzz
工具的使用
AFL++ 环境搭建
sudo apt install llvm
sudo apt install clang
git clone https://github.com/AFLplusplus/AFLplusplus && cd AFLplusplus
make
sudo make install
如果想要使用 trace-pc-guard
模式,则需要 llvm
版本为 13+
Exercise-1 Xpdf CVE-2019-13288
Xpdf
是一个免费的 pdf
查看器和工具包,具体文本提取、图像转换等功能
CVE-2019-13288 是 Xpdf
中的一个漏洞,可以通过构造恶意文件,使得 Parser.cc
中的 Parser::getObj()
函数被循环调用,从而导致栈内存耗尽。攻击者可以利用该漏洞实现 DOS
攻击
Xpdf 环境搭建
cd $HOME
mkdir fuzzing_xpdf && cd fuzzing_xpdf/wget https://dl.xpdfreader.com/old/xpdf-3.02.tar.gz
tar -xvzf xpdf-3.02.tar.gz
cd xpdf-3.02
在 xpdf-3.02
目录下,存在一个 configure
,其是用来生成 Makefile
的:
这里我们设置编译时采用 afl-clang-fast
,以此来进行插桩:
export CC=/home/xiaozaya/fuzz/AFLplusplus/afl-clang-fast
export CXX=/home/xiaozaya/fuzz/AFLplusplus/afl-clang-fast++
插桩编译 xpdf
:编译好的二进制程序在 $HOME/fuzzing_xpdf/install/bin
目录下
./configure --prefix="$HOME/fuzzing_xpdf/install/"
make
sudo make install
根据插桩关键字 __sanitizer_cov
确认下是否成功插桩:
cd $HOME/fuzzing_xpdf/install/bin
strings pdftotext | grep __sanitizer_cov
结果如下,可以看到我们已经成功完成插桩编译:
种子库获取 && 前期准备
在笔者看来,种子库是 fuzz
效率的关键或者决定性因素,如果编写好的种子是一门艺术。当然这也得不断积累,但是笔者刚刚入门,这里仅仅只是为了熟练下工具的使用,所以这里按照实验说明是直接下载别人的种子
cd $HOME/fuzzing_xpdf
mkdir pdf_examples && cd pdf_examples
wget https://github.com/mozilla/pdf.js-sample-files/raw/master/helloworld.pdf
wget http://www.africau.edu/images/default/sample.pdf
wget https://www.melbpc.org.au/wp-content/uploads/2017/10/small-example-pdf-file.pdf
这里需要注意的时,helloworld.pdf
这个文件所在的项目已经没有了。所以这里得单独下载:
git clone https://github.com/mozilla/pdf.js-sample-files.git
然后第二个文件 sample.pdf
也找不到了,所以最后找到的种子如下:
测试下种子是否可用:利用 pdfinfo
查看下 helloworld.pdf
的信息
$HOME/fuzzing_xpdf/install/bin/pdfinfo -box -meta $HOME/fuzzing_xpdf/pdf_examples/helloworld.pdf
然后关闭系统的核心转储,防止 fuzz
过程中出现 crash
导致程序崩溃中止
sudo su
echo core >/proc/sys/kernel/core_pattern
exit
开始 fuzz && 分析 crash
使用如下命令开始 fuzz
:
$HOME/fuzz/AFLplusplus/afl-fuzz -i $HOME/fuzzing_xpdf/pdf_examples/ -o $HOME/fuzzing_xpdf/out/ -M fuzzer1 -- $HOME/fuzzing_xpdf/install/bin/pdftotext @@ $HOME/fuzzing_xpdf/output
相关路径可以视情况而修改
参数说明:
-i in_dir
:指定输入文件夹,即种子库-o out_dir
:指定输出文件夹,存放fuzz
过程中的一些信息-M fuzzer_name
:并行fuzz
,指定主fuzzer
。可以使用-S
指定从fuzzer
,但是输出路径要保持一致--
:分隔符,后面跟测试目标@@
:表示测试目标的输入是文件,不加代表是stdin
这里可以使用 -S
指定 fuzzer2
进行并行 fuzz
crash
分析
笔者跑了 20 多分钟,最后有 5 个 crash
,整体还是不错的
最后导致 crash
的测试用例在输出目录的 crashes
文件夹下:
删除插桩编译的目标文件,然后重新利用 gcc
编译:
sudo rm $HOME/fuzzing_xpdf/install/ -rf
cd $HOME/fuzzing_xpdf/xpdf-3.02/
make clean
CFLAGS="-g -O0" CXXFLAGS="-g -O0" ./configure --prefix="$HOME/fuzzing_xpdf/install/"
make
sudo make install
然后就可以用 gdb
调试了
cd $HOME/fuzzing_xpdf/install/bin/
gdb pdftotext
set args /home/xiaozaya/fuzzing_xpdf/out/fuzzer1/crashes/id:000000,sig:11,src:000658,time:279572,execs:105141,op:havoc,rep:11
r
此时程序崩溃在 _int_malloc
的一个 push rbx
指令处,注意此时的 rsp
可以看到这里的 rsp
已经到达栈顶边界了
通过 bt
回溯看下函数调用链:可以看到一直在循环调用
总结
主要就简单的学习了下 AFL++
的基本使用
- 使用
afl-clang-fast
对目标程序进行插桩编译 - 准备种子库
afl-fuzz
直接fuzz
@@
指明输入为文件
gdb
调试分析crash
Exercise-2 libexif CVE-2009-3895/CVE-2012-2836
libexif
是一个用于解析、编辑和保存 EXIF
数据的库
EXIF
:可交换图像文件格式,是专门为数码相机的照片设计的,可以记录数码照片的属性信息和拍摄数据
CVE-2009-3895 是一个堆溢出漏洞,发生在 exif-data.c
文件下的 exif_data_load_data
函数中
CVE-2012-2836 是一个越界读漏洞,发生在 exif-entry.c
文件下的 xif_entry_fix function
函数中
libexif 环境搭建
cd $HOME
mkdir fuzzing_libexif && cd fuzzing_libexif/
wget https://github.com/libexif/libexif/archive/refs/tags/libexif-0_6_14-release.tar.gz
tar -xzvf libexif-0_6_14-release.tar.gz
按照一些必要的依赖和库:
sudo apt-get install autopoint libtool gettext libpopt-dev
然后生成 configure
程序:
cd libexif-libexif-0_6_14-release
autoreconf -fvi
这里设置一下 $CC
为 afl-clang-fast
实现插桩编译
export CC=/home/xiaozaya/fuzz/AFLplusplus/afl-clang-fast
然后进行插桩编译:生成的文件在 $HOME/fuzzing_libexif/install
目录下
./configure --enable-shared=no --prefix="$HOME/fuzzing_libexif/install/"
make
make install
可以看到插桩编译成功:
种子库获取 && 前期准备
这里值得注意的是这里的目标是一个链接库,其无法直接执行,所以我们得找一个可以调用该库的程序。其中 libexif 官网 就提供了 fuzz
的目标程序。然后该实验本身也提供了,这里就直接用
cd $HOME/fuzzing_libexif
wget https://github.com/libexif/exif/archive/refs/tags/exif-0_6_15-release.tar.gz
tar -xzvf exif-0_6_15-release.tar.gz
然后安装一下就行了,注意用 PKG_CONFIG_PATH
指定一下链接库的位置,最后生成的二进制文件同样在 instball
目录下,只是存放在了 bin
子目录下
cd exif-exif-0_6_15-release/
autoreconf -fvi
./configure --enable-shared=no --prefix="$HOME/fuzzing_libexif/install/" PKG_CONFIG_PATH=$HOME/fuzzing_libexif/install/lib/pkgconfig
make
sudo make install
最后可以看到成功插桩编译:
准备种子语料库
程序本身是解析 EXIF
文件的,所以种子找一些 EXIF
文件就好了。可以找一些 EXIF
文件生成器生成,这里直接用实验给的
cd $HOME/fuzzing_libexif
wget https://github.com/ianare/exif-samples/archive/refs/heads/master.zip
unzip master.zip
简单测试一下:
$HOME/fuzzing_libexif/install/bin/exif $HOME/fuzzing_libexif/exif-samples-master/jpg/Canon_40D_photoshop_import.jpg
开始 fuzz && 分析 crash
$HOME/fuzz/AFLplusplus/afl-fuzz -i $HOME/fuzzing_libexif/exif-samples-master/jpg/ -o $HOME/fuzzing_libexif/out/ -M fuzzer1 -s 123 -- $HOME/fuzzing_libexif/install/bin/exif @@
-s seed
:使用固定的随机种子【主要就是为了复现用的】
crash
分析
跑了 20 多分钟,共触发了 14 次 crash
这里其实也可以直接用 gdb
调试,而不一定去重新编译非插桩代码
这里 crash
发生在 exif_data_load_data
函数中,应该是 CVE-2009-3895
另外一个漏洞好像没有跑出来
总结
通过这个实验学习到了如何对链接库进行 fuzz
:
- 对链接库进行插桩编译
- 寻找一个调用该库的程序,并对其进行插桩编译
这篇关于Fuzzing-101 Exercises的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!