Exercise 6 - GIMP
一、实验背景
CVE-2016-4994是一个可以通过精心制作的XCF文件触发的Use-After-Free漏洞。当程序在释放指针后继续使用指针时,会发生释放错误。这可能会产生许多不良后果,从破坏有效数据到执行任意代码。
Use-After-Free漏洞(https://cwe.mitre.org/data/definitions/416.html)
持久模式
AFL持久模式基于进程内fuzzers: fuzzers利用单个进程,将代码注入目标进程并更改内存中的输入值。full -fuzz支持一种工作模式,它结合了进程内模糊测试的优点和更传统的多进程工具的健壮性:持久模式。在持久模式下,afl++在单个分叉进程中对目标进行多次模糊处理,而不是为每次执行模糊处理都创建一个新进程。该模式可将模糊测试速度提高20倍。
目标的基本结构如下
1 | //Program initialization |
afl++持久模式(https://github.com/AFLplusplus/AFLplusplus/blob/stable/instrumentation/README.persistent_mode.md)
二、实验目的
模糊GIMP图像编辑器。目标是在GIMP 2.8.16中找到CVE-2016-4994的崩溃/PoC
三、实验环境:
win10,VMware,Ubuntu 20.04.2 LTS(虚拟机用户名密码均为fuzz)
四、实验步骤
1、下载并构建目标
得到模糊目标,为要模糊化的项目创建一个新目录
1 | cd $HOME |
安装依赖项
1 | sudo apt-get install build-essential libatk1.0-dev libfontconfig1-dev libcairo2-dev libgudev-1.0-0 libdbus-1-dev libdbus-glib-1-dev libexif-dev libxfixes-dev libgtk2.0-dev python2.7-dev libpango1.0-dev libglib2.0-dev zlib1g-dev intltool libbabl-dev |
下载并构建GEGL 0.2(通用图形库)
1 | wget https://download.gimp.org/pub/gegl/0.2/gegl-0.2.0.tar.bz2 |
对源代码做两个小的修改
1 | sed -i 's/CODEC_CAP_TRUNCATED/AV_CODEC_CAP_TRUNCATED/g' ./operations/external/ff-load.c |
构建并安装Gegl-0.2
1 | ./configure --enable-debug --disable-glibtest --without-vala --without-cairo --without-pango --without-pangocairo --without-gdk-pixbuf --without-lensfun --without-libjpeg --without-libpng --without-librsvg --without-openexr --without-sdl --without-libopenraw --without-jasper --without-graphviz --without-lua --without-libavformat --without-libv4l --without-libspiro --without-exiv2 --without-umfpack |
如果在测试阶段看到一些错误消息,不要担心
下载并解压GIMP 2.8.16
1 | cd .. |
使用afl-clang-lto作为编译器构建GIMP的时间(可能需要一些时间)
1 | CC=afl-clang-lto CXX=afl-clang-lto++ PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$HOME/Fuzzing_gimp/gegl-0.2.0/ CFLAGS="-fsanitize=address" CXXFLAGS="-fsanitize=address" LDFLAGS="-fsanitize=address" ./configure --disable-gtktest --disable-glibtest --disable-alsatest --disable-nls --without-libtiff --without-libjpeg --without-bzip2 --without-gs --without-libpng --without-libmng --without-libexif --without-aa --without-libxpm --without-webkit --without-librsvg --without-print --without-poppler --without-cairo-pdf --without-gvfs --without-libcurl --without-wmf --without-libjasper --without-alsa --without-gudev --disable-python --enable-gimp-console --without-mac-twain --without-script-fu --without-gudev --without-dbus --disable-mp --without-linux-input --without-xvfb-run --with-gif-compression=none --without-xmc --with-shm=none --enable-debug --prefix="$HOME/Fuzzing_gimp/gimp-2.8.16/install" |
2、持久模式
有两种非常简单的方法:
第一个是修改’ ‘ app.c ‘ ‘文件,并将AFL_LOOP宏包含到for循环中
第二种方法是在’ ‘ xcf_load_invoker ‘ ‘函数中插入AFL_LOOP宏
虽然第一个允许我们针对不同的输入格式,第二个更快,我们将有更多的机会抓住错误。
下载第二个补丁在这里
2、种子语料库创建
建议创建多个GIMP项目并保存它们以获得多个.xcf示例,或者,可以将SampleInput.xcf文件复制到您的AFL输入文件夹中
3、fuzzing
由于该漏洞影响GIMP核心,可以通过删除不需要的插件来节省一些启动时间
1 | rm ./install/lib/gimp/2.0/plug-ins/* |
使用以下命令运行fuzzer
1 | ASAN_OPTIONS=detect_leaks=0,abort_on_error=1,symbolize=0 afl-fuzz -i './afl_in' -o './afl_out' -D -t 100 -- ./install/bin/gimp-console-2.8 --verbose -d -f @@ |
笔记:
- gimp-console-2.8是GIMP的控制台版本
- 我建议启用确定性突变(-D)
- 代码中还有一个无限循环的bug,所以我们需要设置一个较低的超时限制(例如-t 100)。此超时限制取决于您的机器功能,因此您需要根据具体情况对其进行调整
几分钟后可以看见有多个崩溃
4、Triage
ASan跟踪可能看起来像
5、修复问题
修复这两个bug后重建目标,并检查PoC不再使程序崩溃
五、总结
通过这个实验,我了解了CVE-2016-4994漏洞,学会如何使用持久模式加快模糊测试,如何模糊交互/ GUI应用程序