Exercise 2 - libexif

Exercise 2 - libexif

一、实验背景

CVE-2009-3895是一个基于堆的缓冲区溢出,可以通过无效的EXIF图像触发。基于堆的缓冲区溢出是发生在堆数据区域的一种缓冲区溢出,它通常与显式动态内存管理(使用malloc()和free()函数进行分配/回收)有关。因此,远程攻击者可以利用此问题在使用受影响库的应用程序上下文中执行任意代码。

基于堆的缓冲区溢出漏洞(https://cwe.mitre.org/data/definitions/122.html)

CVE-2012-2836是一个越界读取漏洞,可以通过带有精心制作的EXIF标签的图像触发。越界读取是当程序读取数据超过预期缓冲区的末尾或开始之前时发生的漏洞。因此,它允许远程攻击者导致拒绝服务或可能从进程内存中获取潜在的敏感信息。

越界读取漏洞(https://cwe.mitre.org/data/definitions/125.html)

二、实验目的

这次我们将模糊libexif EXIF解析库。目标是在libxif 0.6.14中找到CVE-2009-3895CVE-2012-2836的崩溃/PoC。

三、实验环境:

win10,VMware,Ubuntu 20.04.2 LTS(虚拟机用户名密码均为fuzz)

四、实验步骤

1、下载并构建目标

为模糊的项目创建一个新目录

1
2
cd $HOME
mkdir fuzzing_libexif && cd fuzzing_libexif/

下载并解压libexif-0.6.14

1
2
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

image

构建并安装libexif

1
2
3
4
5
6
cd libexif-libexif-0_6_14-release/
sudo apt-get install autopoint libtool gettext libpopt-dev
autoreconf -fvi
./configure --enable-shared=no --prefix="$HOME/fuzzing_libexif/install/"
make
make install

image

image

image

image

image-20230727232107643

2、选择一个接口应用程序

libexif是一个库,我们需要另一个应用程序来使用这个库,这个应用程序将被模糊化。对于这个任务,我们将使用exif command-line,下载并解压exif command-line 0.6.15:

1
2
3
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

image

image

构建并安装exif command-line实用程序

1
2
3
4
5
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
make install

image

image-20230727232415273

image

image

测试是否正常工作

1
$HOME/fuzzing_libexif/install/bin/exif

看到如下页面说明工作正常

image

3、创建种子语料库

现在我们需要一些出口样本。我们将使用以下repo中的样例图像:https://github.com/ianare/exif-samples。通过以下指令下载

1
2
3
cd $HOME/fuzzing_libexif
wget https://github.com/ianare/exif-samples/archive/refs/heads/master.zip
unzip master.zip

image

举例

1
$HOME/fuzzing_libexif/install/bin/exif $HOME/fuzzing_libexif/exif-samples-master/jpg/Canon_40D_photoshop_import.jpg

可以看到如下输出

image

4、Afl-clang-lto

使用afl-clang-lto作为编译器来构建libexif。

1
2
3
4
5
6
7
rm -r $HOME/fuzzing_libexif/install
cd $HOME/fuzzing_libexif/libexif-libexif-0_6_14-release/
make clean
export LLVM_CONFIG="llvm-config-11"
CC=afl-clang-lto ./configure --enable-shared=no --prefix="$HOME/fuzzing_libexif/install/"
make
make install
1
2
3
4
5
6
cd $HOME/fuzzing_libexif/exif-exif-0_6_15-release
make clean
export LLVM_CONFIG="llvm-config-11"
CC=afl-clang-lto ./configure --enable-shared=no --prefix="$HOME/fuzzing_libexif/install/" PKG_CONFIG_PATH=$HOME/fuzzing_libexif/install/lib/pkgconfig
make
make install

image

image-20230727233607562

image

image

image

image

image

image-20230727233940330

使用了afl-clang-lto而不是afl-clang-fast。一般来说,afl-clang-lto是最好的选择,因为它是一个无冲突的工具,而且它比afl-clang-fast快。

如果不确定何时使用afl-clang-ltoafl-clang-fast,可以检查从[AFLplusplus:检测目标]提取的下图(https://github.com/AFLplusplus/AFLplusplus#1-instrumenting-that-target)

](https://github.com/AFLplusplus/AFLplusplus#1-instrumenting-that-target)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
+--------------------------------+
| clang/clang++ 11+ is available | --> use LTO mode (afl-clang-lto/afl-clang-lto++)
+--------------------------------+ see [instrumentation/README.lto.md](instrumentation/README.lto.md)
|
| if not, or if the target fails with LTO afl-clang-lto/++
|
v
+---------------------------------+
| clang/clang++ 6.0+ is available | --> use LLVM mode (afl-clang-fast/afl-clang-fast++)
+---------------------------------+ see [instrumentation/README.llvm.md](instrumentation/README.llvm.md)
|
| if not, or if the target fails with LLVM afl-clang-fast/++
|
v
+--------------------------------+
| gcc 5+ is available | -> use GCC_PLUGIN mode (afl-gcc-fast/afl-g++-fast)
+--------------------------------+ see [instrumentation/README.gcc_plugin.md](instrumentation/README.gcc_plugin.md) and
[instrumentation/README.instrument_list.md](instrumentation/README.instrument_list.md)
|
| if not, or if you do not have a gcc with plugin support
|
v
use GCC mode (afl-gcc/afl-g++) (or afl-clang/afl-clang++ for clang)

5、fuzzing

使用以下命令运行fuzzer

1
afl-fuzz -i $HOME/fuzzing_libexif/exif-samples-master/jpg/ -o $HOME/fuzzing_libexif/out/ -s 123 -- $HOME/fuzzing_libexif/install/bin/exif @@

image

几分钟后可以看见有多个崩溃

image

可以在这里找到崩溃的图像文件

image

6、动态调试

编译出带调试信息的可执行文件

image

image

image

image

image

image

image

image-20230728003925454

放到gdb中,跑出clash

clash1

image

报错信息**Program received signal SIGSEGV, Segmentation fault.**存在内存泄漏

报错位置in exif_data_load_data (data=0x4538c0, d_orig=, ds_orig=) at exif-utils.c:94 94 return ((buf[1] << 8) | buf[0]);

注意这里的报错,内存地址无法访问,再看地址,猜测为堆缓冲区溢出

clash2

image

报错信息**Program received signal SIGSEGV, Segmentation fault.**存在内存泄露

报错位置in exif_data_load_data (data=0x4538c0, d_orig=, ds_orig=) at exif-utils.c:94

clash3

image

报错信息**Program received signal SIGSEGV, Segmentation fault.**存在内存泄露

报错位置in exif_data_load_data (data=0x4538c0, d_orig=, ds_orig=) at exif-utils.c:94

7、漏洞修复

https://github.com/libexif/libexif/commit/8ce72b7f81e61ef69b7ad5bdfeff1516c90fa361

https://github.com/libexif/libexif/commit/00986f6fa979fe810b46e376a462c581f9746e06

五、总结

通过这个实验,我了解了CVE-2009-3895漏洞和CVE-2012-2836漏洞,学习了libexif,找到一个使用libexif库的接口应用程序,创建一个出口样本的种子语料库使,用afl-clang-lto编译libexif和选择的应用程序,模糊libexif,直到有一些独特的崩溃,分类崩溃以找到每个漏洞的PoC