CVE-2009-3895

首先在NVD找到漏洞描述如下:

大致意思是说:libexif 0.6.18 中的 libexif/exif-entry.c 中的 exif_entry_fix 函数中基于堆的缓冲区溢出允许远程攻击者导致拒绝服务或可能通过无效的 EXIF 图像执行任意代码

接下来找到libexif 0.6.18 ,官方在0.6.19版本修复了此漏洞:

CVE-2012-2836

同样在NVD中找到漏洞描述:

大致意思:0.6.21 之前的 EXIF 标签解析库(又名 libexif)中的 exif-data.c 中的 exif_data_load_data 函数允许远程攻击者造成拒绝服务(越界读取)或可能通过精心设计的方式从进程内存中获取敏感信息图像中的 EXIF 标签。简单来说也就是存在越界访问漏洞

官方在0.6.21版本修复了此漏洞:

实验目的

  • 使用外部应用程序Fuzz库文件
  • 使用afl-clang-lto,这是一种无碰撞检测,它比afl-clang-fast更快并提供更好的结果

实验环境

所有测试都在Ubuntu 20.04.2 LTS上测试过。强烈建议您使用相同的操作系统版本以避免不同的Fuzz结果,并在物理机而不是虚拟机上运行 AFL++ ,以获得最佳性能

Fuzz过程

下载相关文件

首先创建一个文件夹用于存放Fuzz目标:

mkdir libexif && cd libexif

找到libexif文件,下载并解压:

wget https://sourceforge.net/projects/libexif/files/libexif/0.6.18/libexif-0.6.18.tar.gz
tar -zxvf libexif-0.6.18.tar.gz
cd libexif-0.6.18

因为libexif编译后是一个库文件,所以还需要下载使用库接口的应用程序,这里选择exif命令行0.6.15

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

构建

首先回到libexif库文件目录下进行编译:

cd ..
sudo apt-get install autopoint libtool gettext libpopt-dev
autoreconf -fvi
./configure --enable-shared=no --prefix="/home/fuzz/libexif/install/"
make
make install

此时库文件已经编译好了,再进入exif目录进行编译:

cd exif-exif-0_6_15-release/
autoreconf -fvi
./configure --enable-shared=no --prefix="/home/fuzz/libexif/install/" PKG_CONFIG_PATH=$HOME/libexif/install/lib/pkgconfig
make
make install

测试exif能否运行只需要输入:

$HOME/libexif/install/bin/exif

此时应该看到如下内容:

执行Fuzz

首先要确定程序是做什么的,要输入什么内容,希望返回什么内容,可以先阅读程序帮助信息,并测试程序功能。

Exif是一种文件格式,这是在网上搜索到的相关描述:

可交换图像文件格式(英语:Exchangeable image file format,官方简称Exif),是专门为数码相机的照片设定的,可以记录数码照片的属性信息和拍摄数据。

举个例子,就像下面这样:

那么就需要找到这样的文件样本,好在万能的GitHub啥都有,可以直接下载:

git clone https://github.com/ianare/exif-samples.git

下载好后进入目录,使用exif命令随便查看一张图片的信息:

$HOME/libexif/install/bin/exif Nikon_D70.jpg

可以看到如下结果:

现在程序功能已经知道了,需要使用afl编译器重新编译程序来执行Fuzz。这次使用afl-clang-lto作为编译器来构建程序,afl-clang-lto相比于afl-clang-fast是更好的选择,因为它是一种无碰撞检测,而且比afl-clang-fast 快。

如果不确定何时使用哪种编译器,可参考如下内容:

+--------------------------------+
| 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)

使用编译器重新构建程序:

rm -r $HOME/libexif/install
cd $HOME/libexif/libexif-0.6.18
make clean
export LLVM_CONFIG="llvm-config-11"
CC=afl-clang-lto ./configure --enable-shared=no --prefix="$HOME/libexif/install"
make
make install
cd $HOME/libexif/libexif-0.6.18/exif-exif-0_6_15-release
make clean
export LLVM_CONFIG="llvm-config-11"
CC=afl-clang-lto ./configure --enable-shared=no --prefix="$HOME/libexif/install/" PKG_CONFIG_PATH=$HOME/libexif/install/lib/pkgconfig
make
make install

然后可以开始愉快的Fuzz了:

afl-fuzz -i /home/fuzz/libexif/exif_samples/jpg/ -o /home/fuzz/libexif/out -s 123 -- /home/fuzz/libexif/install/bin/exif @@

漏洞复现及修复

漏洞复现

几分钟后可获得多个crash:

使用GDB将crash文件输入到程序中:

gdb --args /home/fuzz/libexif/install/bin/exif ./crash1.jpg

查看栈回溯:

可看出明显是malloc_printerr使程序crash,那么再往父函数找,找到exif_content_fix函数,在此处下断点,重新运行程序,单步跟踪,看看是什么原因使程序崩溃。跟踪到__GI___libc_realloc函数时,在_int_realloc报错,查看参数如下:

_int_realloc函数定义:void* _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize, INTERNAL_SIZE_T nb) ,单步跟进_int_realloc,得到如下结果:

查看堆中内容,观察到下一chunk的size域已经堆溢出被破坏,无法malloc导致程序crash:

修复

可以在GitHub中查看修复代码:

Fix a buffer overflow on corrupt EXIF data. · libexif/libexif@8ce72b7

Fix a buffer overflow on corrupted JPEG data · libexif/libexif@00986f6

总结

  • 在进行Fuzz时,信息收集同等重要,如果是复现,需要知晓Fuzz目标的CVE信息。如果是漏洞挖掘过程,则难度会更上一个等级。

  • 熟悉程序的构建过程、程序的功能是必不可少的步骤,如果完全不知道程序是干嘛的,那漏洞挖掘也就无从下手。

  • 在复现漏洞时,应该考虑怎么去证明这个漏洞,以及程序是如何崩溃的,可以在崩溃时的上层函数打上断点单步跟踪,观察参数和函数调用过程

  • 另外:可以使用Eclipse-CDT 代替 GDB 进行调试,这是一个界面化的工具,需要有Java环境,下载链接:

    CDT Downloads | The Eclipse Foundation

    具体使用方法就不赘述了,网上有得很。工具都无所谓,看自己喜欢哪种,我就习惯GDB

AFL++ Fuzz一个libexif例子的更多相关文章

  1. AFL++初探-手把手Fuzz一个PDF解析器

    CVE-2019-13288 目前漏洞在正式版本已经被修复,本文章仅供学习Fuzz过程,不存在漏洞利用的内容 这是一个pdf查看器的漏洞,可能通过精心制作的文件导致无限递归,由于程序中每个被调用的函数 ...

  2. AFL Fuzz安装及完成一次简单的模糊测试

    关于AFL fuzz AFL fuzz是一个模糊测试工具,它封装了一个GCC/CLang编译器,用于对被测代码重新编译的过程中进行插桩.插桩完毕后,AFL fuzz就可以给其编译过的代码输入不同的参数 ...

  3. SQL Server Reporting Service(SSRS) 第一篇 我的第一个SSRS例子

    很早就知道SQL SERVER自带的报表工具SSRS,但一直没有用过,最近终于需要在工作中一展身手了,于是我特地按照自己的理解做了以下总结: 1. 安装软件结构 SSRS全称SQL Server Re ...

  4. 一个简单例子:贫血模型or领域模型

    转:一个简单例子:贫血模型or领域模型 贫血模型 我们首先用贫血模型来实现.所谓贫血模型就是模型对象之间存在完整的关联(可能存在多余的关联),但是对象除了get和set方外外几乎就没有其它的方法,整个 ...

  5. java连接mysql的一个小例子

    想要用java 连接数据库,需要在classpath中加上jdbc的jar包路径 在eclipse中,Project的properties里面的java build path里面添加引用 连接成功的一 ...

  6. java操作xml的一个小例子

    最近两天公司事比较多,这两天自己主要跟xml打交道,今天更一下用java操作xml的一个小例子. 原来自己操作xml一直用这个包:xstream-1.4.2.jar.然后用注解的方式,很方便,自己只要 ...

  7. MVVM模式的一个小例子

    使用SilverLight.WPF也有很长时间了,但是知道Binding.Command的基本用法,对于原理性的东西,一直没有深究.如果让我自己建一个MVVM模式的项目,感觉还是无从下手,最近写了一个 ...

  8. Lea指令计算地址(用于四则混合运算),附上一个函数调用例子及其反汇编代码,很清楚

    比如你用local在栈上定义了一个局部变量LocalVar,你知道实际的指令是什么么?一般都差不多像下面的样子:     push   ebp     mov   esp,   ebp     sub ...

  9. (转)Java中使用正则表达式的一个简单例子及常用正则分享

    转自:http://www.jb51.net/article/67724.htm 这篇文章主要介绍了Java中使用正则表达式的一个简单例子及常用正则分享,本文用一个验证Email的例子讲解JAVA中如 ...

随机推荐

  1. JS 之循环 应用案例1

    应用场景:将el-select下拉框的lab值,显示在下面的详情text框,见下图 用到了 el-select 传值,js循环判断options.code是否等于传进来的值,等于就break; tex ...

  2. Apache OfBiz 反序列化命令执行漏洞(CVE-2020-9496)

    影响版本 - Apache Ofbiz:< 17.12.04 访问 https://192.168.49.2:8443/webtools/control/xmlrpc 抓包 进行数据包修改 pa ...

  3. 从小白角度探索Android事件分发机制

    今早来上班时看到郭神这边文章超赞,剧情很好引人入胜,特此备份! https://mp.weixin.qq.com/s?__biz=MzA5MzI3NjE2MA==&mid=2650244386 ...

  4. MySQL 优化特定类型的查询

    优化COUNT()查询 COUNT() 是一个特殊的函数,有两种非常不同的作用: 统计某个列值的数量,也可以统计行数.在统计列值时要求列值是非空的(不统计NULL ).如果在COUNT() 的括号中指 ...

  5. 【UGUI源码分析】Unity遮罩之Mask详细解读

    遮罩,顾名思义是一种可以掩盖其它元素的控件.常用于修改其它元素的外观,或限制元素的形状.比如ScrollView或者圆头像效果都有用到遮罩功能.本系列文章希望通过阅读UGUI源码的方式,来探究遮罩的实 ...

  6. 字节跳动五面都过了,结果被刷了,问了hr原因竟说是...

    说在前面,面试时最好不要虚报工资.本来字节跳动是很想去的,几轮面试也通过了,最后没offer,自己只想到几个原因:1.虚报工资,比实际高30%:2.有更好的人选,这个可能性不大,我看还在招聘.我是面试 ...

  7. SpringCloud升级之路2020.0.x版-9.如何理解并定制一个Spring Cloud组件

    本系列为之前系列的整理重启版,随着项目的发展以及项目中的使用,之前系列里面很多东西发生了变化,并且还有一些东西之前系列并没有提到,所以重启这个系列重新整理下,欢迎各位留言交流,谢谢!~ 我们实现的 S ...

  8. Linux中配置ftp传输

    .personSunflowerP { background: rgba(51, 153, 0, 0.66); border-bottom: 1px solid rgba(0, 102, 0, 1); ...

  9. JVM学习笔记-第六章-类文件结构

    JVM学习笔记-第六章-类文件结构 6.3 Class类文件的结构 本章中,笔者只是通俗地将任意一个有效的类或接口锁应当满足的格式称为"Class文件格式",实际上它完全不需要以磁 ...

  10. LiteFlow 2.6.0版本发行注记,项目逻辑解耦的利器

    前言 自从LiteFlow 2.5.X版本发布依赖,陆续经历了10个小版本的迭代.社区群也稳固增长,每天都有很多小伙伴在问我问题. 但是我发现最多人问我的还是:什么时候能支持界面编排? 从LiteFL ...