使用 afl-fuzz fuzz pdfium
下载源码
先在 https://pdfium.googlesource.com/pdfium/ 下载源码.
mkdir repo
cd repo
gclient config --unmanaged https://pdfium.googlesource.com/pdfium.git
gclient sync
cd pdfium
gclient 命令在 depot_tools 中, 需要安装 参考下面的文章
http://www.chromium.org/developers/how-tos/install-depot-tools
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
export PATH=`pwd`/depot_tools:"$PATH"
主要gclient sync 同步时需要翻墙,可以简单的使用环境变量的方法。
https_proxy=http://localhost:8118 gclient sync
下载 download google storage过
程中还会遇到一个网络问题,需要编写配置文件 ~/.boto
[Boto]
proxy = 127.0.0.1 # 不带 http://
proxy_port= 8118
export NO_AUTH_BOTO_CONFIG=~/.boto
源码包非常大,大概有1G多,需要耐心等待。
编译
编译需要使用 ubuntu 或者 Debian 系统,其他系统的依赖问题解决起来比较麻烦,
如果是上面两种操作系统的话,有脚本自动安装依赖。
./build/install-build-deps.sh
安装完所以依赖后就可以开始编译了,首先要先生成 gn 文件 (2016 年google 放弃使用原来的 gyp 编译方式)
gn args out/afl
会调用vim 编译器, 输入下面的内容
# Build arguments go here.
# See "gn args <out_dir> --list" for available build arguments.
use_goma = false # Googlers only. Make sure goma is installed and running first.
is_debug = false # Enable debugging features.
pdf_use_skia = true # Set true to enable experimental skia backend.
pdf_use_skia_paths = false # Set true to enable experimental skia backend (paths only).
pdf_enable_xfa = true # Set false to remove XFA support (implies JS support).
pdf_enable_v8 = true # Set false to remove Javascript support.
pdf_is_standalone = true # Set for a non-embedded build.
is_component_build = false # Disable component build (must be false)
v8_static_library = true
clang_use_chrome_plugins = false # Currently must be false.
use_sysroot = false # Currently must be false on Linux, but entirely omitted on windows.
use_afl = true
#is_asan = true
enable_nacl = true
optimize_for_fuzzing = true
symbol_level=1
使用 ASAN 编译会报错,暂时不开启,接下来要解决 afl 的问题了, pdfium 的 third_party
中不包含 afl-fuzz 的源代码,需要到 chromium.googlesource.com 项目下载。
chromium 项目支持 libfuzzer 和 afl-fuzz,只要使用开关, use_libfuzzer = true
或者 use_afl = true
即可打开。
要编译生成 pdfium_test, 必须指定 pdf_is_standalone = true, pdfium 源码仓库中没有
afl-fuzz 的代码,需要自己下载。
https://chromium.googlesource.com/chromium/src/third_party/+/master/afl/
可以直接下载 .tgz 文件
https://chromium.googlesource.com/chromium/src/third_party/+archive/master/afl.tar.gz
下载后将源码 copy 到 ~/repo/pdfium/third_party/afl 中, 使用 ninja -C out/afl
编译整个项目。
使用 is_debug=false
可以明显提高fuzzing 速度,应该开启。另外一个比较有用的是symbol_level
, 设置 symbol_level=1 可以添加必要的调试符号,便于gdb调试。
在编译 skia backend 支持时,需要额外处理, 使用 C++14
use_cxx11 = false
afl-fuzz
随着 chromium 代码的更新, afl 源码编译出现了一些小问题,需要处理。
src/third_party/afl/patches/0001-fix-build-with-std-c11.patch
diff --git a/afl-fuzz.c b/afl-fuzz.c
index 01b4afef0ecc..f0d564a33037 100644
--- a/afl-fuzz.c
+++ b/afl-fuzz.c
@@ -23,7 +23,9 @@
#define AFL_MAIN
#define MESSAGES_TO_STDOUT
+#ifndef _GNU_SOURCE
#define _GNU_SOURCE
+#endif
#define _FILE_OFFSET_BITS 64
#include "config.h"
diff --git a/types.h b/types.h
index 784d3a7a286d..d24d1fdd97e8 100644
--- a/types.h
+++ b/types.h
@@ -78,7 +78,7 @@ typedef int64_t s64;
#define STRINGIFY(x) STRINGIFY_INTERNAL(x)
#define MEM_BARRIER() \
- asm volatile("" ::: "memory")
+ __asm__ volatile("" ::: "memory")
#define likely(_x) __builtin_expect(!!(_x), 1)
#define unlikely(_x) __builtin_expect(!!(_x), 0)
afl-fuzz 的使用和其他项目一样。初始的种子文件有几个地方可以获取:
- https://pdfium.googlesource.com/pdfium/+/refs/heads/master/testing/resources/
- https://github.com/mozilla/pdf.js/tree/master/test/pdfs
./afl-fuzz -M 01 -m 1024 -i /home/henices/input -o /home/henices/out -x /tmp/pdf.dict -- ./pdfium_test @@
参考资料
- https://mariomalwareanalysis.blogspot.com/2012/02/how-to-embed-javascript-into-pdf.html
- https://www.blackhat.com/docs/asia-17/materials/asia-17-Liu-Dig-Into-The-Attack-Surface-Of-PDF-And-Gain-100-CVEs-In-1-Year.pdf
- https://chromium.googlesource.com/chromium/src/+/master/testing/libfuzzer/getting_started.md
- https://chromium.googlesource.com/chromium/src/+/master/testing/libfuzzer/efficient_fuzzer.md
- https://chromium.googlesource.com/chromium/src/+/master/testing/libfuzzer/reproducing.md
- https://fuzzing-project.org/tutorial2.html
- https://blog.chromium.org/2012/04/fuzzing-for-security.html
- https://chromium.googlesource.com/chromium/src/+/lkcr/docs/linux_debugging.md
- https://web.archive.org/web/20141010035745/http://gnupdf.org/Introduction_to_PDF
- https://mariomalwareanalysis.blogspot.com/2012/02/how-to-manually-create-pdf.html
- https://mariomalwareanalysis.blogspot.com/2012/02/how-to-embed-javascript-into-pdf.html