Exercise 7 - VLC Media Player
一、实验背景
CVE-2019-14776是一个越界读取漏洞,可以通过精心制作的WMV/ASF (Windows Media Video)文件触发。越界读取是当程序读取数据超过预期缓冲区的末尾或开始之前时发生的漏洞。因此,它允许远程攻击者导致拒绝服务或可能从进程内存中获取潜在的敏感信息。
越界读取漏洞(https://cwe.mitre.org/data/definitions/125.html)
部分仪器仪表
使用进化覆盖引导的模糊器的优点之一是,它能够自己找到新的执行路径。然而,这通常也是一个缺点。当我们面对具有高度模块化架构的软件(如VLC媒体播放器)时,每个模块执行特定的任务。
那么,假设我们给监控器提供了一个有效的MKV文件。但是在对输入文件进行了几次修改之后,“magic bytes”文件发生了变化,现在我们的程序将输入文件视为AVI文件。因此,这个“变异的MKV文件”现在由AVI Demux处理。一段时间后,文件魔术字节再次改变,现在文件被视为MPEG文件。在这两种情况下,这个新修改的文件增加代码覆盖率的可能性都很低,因为这个新文件没有任何有效的语法结构。
简而言之,如果我们不对代码覆盖率施加限制,模糊测试者很容易选择错误的路径,从而使模糊测试过程效率降低。
为了解决这个问题,afl++包含了一个部分插装特性,它允许指定应该使用或不使用插装来编译哪些函数/文件。这有助于模糊器专注于程序的重要部分,通过执行无趣的代码路径来避免不必要的噪声和干扰。
为了使用它,我们在编译时设置环境AFL_LLVM_ALLOWLIST变量。这个环境变量必须指向一个包含所有应该检测的函数/文件名的文件。
afl++部分仪器(https://github.com/AFLplusplus/AFLplusplus/blob/stable/instrumentation/README.instrument_list.md)
二、实验目的
模糊VLC媒体播放器。目标是在VLC 3.0.7.1中找到CVE-2019-14776的崩溃/PoC
三、实验环境:
win10,VMware,Ubuntu 20.04.2 LTS(虚拟机用户名密码均为fuzz)
四、实验步骤
1、下载并构建目标
得到模糊目标,为要模糊化的项目创建一个新目录
1 | cd $HOME |
下载并解压vlc-3.0.7.1.tar.xz
1 | wget https://download.videolan.org/pub/videolan/vlc/3.0.7.1/vlc-3.0.7.1.tar.xz |
发现下载链接连接失败,用管理员身份下载,解决问题
2、构建VCL
1 | ./configure --prefix="$HOME/fuzzing_vlc/vlc-3.0.7.1/install" --disable-a52 --disable-lua --disable-qt |
报错
解决方案
安装一些必要的依赖库
1 | apt-get install libxcb-composite0-dev libxcb-glx0-dev libxcb-dri2-0-dev libxcb-xf86dri0-dev libxcb-xinerama0-dev libxcb-render-util0-dev |
安装完依赖库后,重新运行.config,成功构建VCL
测试工作是否正确
1 | ./bin/vlc-static --help |
如看到以下页面,说明工作正确
3、种子语料库创建
可以在ffmpeg示例库中找到大量视频示例。
建议挑选一些样本,然后使用视频编辑器将视频文件缩小到尽可能小的大小。
以下是一些开源视频编辑器的例子:
——(OpenShot) (https://www.openshot.org/)
——(Shotcut) (https://shotcut.org/)
或者复制short2.wmv和veryshort.wmv文件到AFL输入文件夹
4、fuzzing线束
如果尝试直接模糊“vlc-static”二进制文件,将看到AFL每秒只执行几次。这是因为VLC启动非常耗时。这就是为什么为模糊测试VLC创建一个自定义模糊测试线束。
修改’ ‘ ./test/vlc-demux-run.c ‘ ‘文件以包含模糊测试工具。通过这种方式,只需执行以下操作即可编译该harness:
1 | cd test |
由于该错误存在于ASF解模中,所以调用vlc_demux_process_memory函数。这个函数尝试删除先前存储在内存中的数据缓冲区。可以在这里找到代码修改(./fuzzing_harness.patch)
5、部分仪器化
一开始,尝试只包括ASF拆模所涉及的文件名。不幸的是,这种方法不起作用。似乎文件名匹配是并不总是可能的,所以选择了一个混合的方法,包括函数匹配和文件名匹配
可以下载部分检测文件(./Partial_instrumentation)
6、小改动
为了加快ASF模糊测试的速度,建议将这个补丁应用到modules/demux/libasf.c (目前没有更多的线索;)):[speeup .patch](./ speeup .patch)
7、fuzzing
使用afl-clang-fast作为编译器并启用ASAN构建VLC的时间
1 | CC="afl-clang-fast" CXX="afl-clang-fast++" ./configure --prefix="$HOME/fuzzing_vlc/vlc-3.0.7.1/install" --disable-a52 --disable-lua --disable-qt --with-sanitizer=address |
构建模糊控制装置
1 | cd test |
运行fuzzer
1 | afl-fuzz -t 100 -m none -i './afl_in' -o './afl_out' -x asf_dictionary.dict -D -M master -- ./test/vlc-demux-run @@ |
注意事项:超时参数严重依赖于计算机,需要调整这个值
过一段时间,可以看到多个崩溃
8、Triage
ASan跟踪可能看起来像
9、修复问题
修复这两个bug后重建目标,并检查PoC不再使程序崩溃
五、总结
通过这个实验,我了解了CVE-2019-14776漏洞,学会如何使用部分仪器只对程序的相关部分进行仪器检测,如何编写模糊测试工具来更有效地测试大型应用程序