利用AFL fuzz PDFium

下载源码

安装depot-tools后下载源码

1
2
3
4
5
6
7
8
9
# 安装depot-tools
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
export PATH=`pwd`/depot_tools:"$PATH"
# 下载pdfium
mkdir repo
cd repo
gclient config --unmanaged https://pdfium.googlesource.com/pdfium.git
gclient sync
cd pdfium

编译

ubuntu 或者 Debian 系统可直接使用 ./build/install-build-deps.sh安装依赖(不是的可以加上--unsupported试试,或者手动配置依赖),利用gn args out/afl生成编译参数文件,参考如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
is_debug = false
pdf_use_skia = true
pdf_use_skia_paths = false

pdf_enable_xfa = true
pdf_enable_v8 = true
pdf_is_standalone = true
is_component_build = false
v8_static_library = true

clang_use_chrome_plugins = false
use_sysroot = false

use_afl = true
is_asan = true
is_lsan = true
optimize_for_fuzzing = true
symbol_level=2

dcheck_always_on = false

pdfium 源码仓库中没有afl-fuzz 的代码,需要自己下载,当然也可以使用自己魔改过的afl(默认版本为2.52b,推荐使用2.57b)

https://chromium.googlesource.com/chromium/src/third_party/+/master/afl/

使用 ninja -C out/afl 编译全部文件,或者使用ninja -C out/afl <test target>编译自己想fuzz的目标。

开始Fuzz

afl-fuzz 的使用和其他项目一样。初始的种子文件有几个地方可以获取:

  • https://pdfium.googlesource.com/pdfium/+/refs/heads/master/testing/resources/
  • https://github.com/mozilla/pdf.js/tree/master/test/pdfs
1
./afl-fuzz -M 01 -m none -t 30000 -i /home/fuzz/input -o /home/fuzz/out -x /home/fuzz/pdf.dict -- ./pdfium_test @@

libjpeg-turbo编译与fuzz

https://github.com/libjpeg-turbo/libjpeg-turbo

libjpeg-turbo是pdfium中默认的JPEG编解码器

AFL插桩编译:

1
2
mkdir build && cd build && cmake -DCMAKE_C_COMPILER=afl-clang-fast -DCMAKE_C_FLAGS="-g -fsanitize=address" ..
CC=afl-clang-fast CXX=afl-clang-fast++ AFL_USE_ASAN=1 make

cjpeg为例选择目标进行fuzz:

1
afl-fuzz -M 1 -i ../seed-corpora/afl-testcases/bmp/ -o fuzzout -m none -t 60000  -x ~/AFLplusplus/dictionaries/bmp.dict  -- ./cjpeg-static -quality 95 -dct float -rgb -optimize  -outfile ./1.jpg @@

代码覆盖率测试

https://github.com/vanhauser-thc/afl-cov

1
2
3
4
cmake  -DCMAKE_C_FLAGS="-g -fprofile-arcs -ftest-coverage" -DCMAKE_CXX_FLAGS="-g  -fprofile-arcs -ftest-coverage" ..
make -j8

~/afl-cov/afl-cov -d ../build/jpegout/ --live --coverage-cmd "./jpegtran-static -progess AFL_FILE" --code-dir . --enable-branch-coverage --overwrite

Google project与AFLplusplus的适配

修改pdfium/third_party/afl/BUILD.gn, 将编译好的AFLplusplus文件夹拷贝到src中,重命名afl-cc为afl-clang和afl-clang++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

--- BUILD.gn.bak 2022-03-11 09:57:06.393190381 +0800
+++ BUILD.gn 2022-03-09 10:57:43.640532334 +0800
@@ -2,13 +2,10 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

+# Modified by Hanyu to fit AFLplusplus.
+
group("afl") {
deps = [
- ":afl-cmin",
- ":afl-fuzz",
- ":afl-showmap",
- ":afl-tmin",
- ":afl_docs",
":afl_runtime",
]
}
@@ -32,19 +29,11 @@ source_set("afl_runtime") {
"//build/config/gcc:symbol_visibility_hidden",
]

- sources = [
- "src/llvm_mode/afl-llvm-rt.o.c",
- ]
+ sources = [ "src/afl-llvm-rt-lto.o",
+ "src/afl-llvm-rt-64.o",
+ ]
}

-afl_headers = [
- "src/alloc-inl.h",
- "src/config.h",
- "src/debug.h",
- "src/types.h",
- "src/hash.h",
-]
-
config("afl-tool") {
cflags = [
# Include flags from afl's Makefile.
@@ -63,60 +52,4 @@ config("afl-tool") {
# we do not use. Therefore its value is unimportant.
"-DBIN_PATH=\"$root_build_dir\"",
]
-}
-
-copy("afl-cmin") {
- # afl-cmin is a bash script used to minimize the corpus, therefore we can just
- # copy it over.
- sources = [
- "src/afl-cmin",
- ]
- outputs = [
- "$root_build_dir/{{source_file_part}}",
- ]
- deps = [
- ":afl-showmap",
- ]
-}
-
-copy("afl_docs") {
- # Copy the docs folder. This is so that we can use a real value for for
- # -DDOC_PATH when compiling.
- sources = [
- "src/docs",
- ]
- outputs = [
- "$root_build_dir/afl/{{source_file_part}}",
- ]
-}
-
-executable("afl-fuzz") {
- # Used to fuzz programs.
- configs -= [ "//build/config/sanitizers:default_sanitizer_flags" ]
- configs += [ ":afl-tool" ]
-
- sources = [
- "src/afl-fuzz.c",
- ]
- sources += afl_headers
-}
-
-executable("afl-tmin") {
- configs -= [ "//build/config/sanitizers:default_sanitizer_flags" ]
- configs += [ ":afl-tool" ]
-
- sources = [
- "src/afl-tmin.c",
- ]
- sources += afl_headers
-}
-
-executable("afl-showmap") {
- configs -= [ "//build/config/sanitizers:default_sanitizer_flags" ]
- configs += [ ":afl-tool" ]
-
- sources = [
- "src/afl-showmap.c",
- ]
- sources += afl_headers
-}
+}


利用AFL fuzz PDFium
https://mundi-xu.github.io/2021/07/03/Use-AFL-fuzz-pdfium/
Author
寒雨
Posted on
July 3, 2021
Licensed under