libFuzzer Tutorial - 未完



https://github.com/google/fuzzer-test-suite/blob/master/tutorial/libFuzzerTutorial.md

For clang on C with C++ libfuzzer.a:
clang-4.0 sqlite3.c -lstdc++ -Wno-incompatible-pointer-types -pthread -g -fsanitize=address -fsanitize-coverage=trace-pc-guard ~/libFuzzer.a -o sql

libFuzzer教程

导言
在本教程中,您将学习如何使用libFuzzer–一个覆盖引导的进程内模糊引擎。
您还将学习AddressSaniizer的基础知识–一个用于C/C++的动态内存错误检测器。
先决条件:有C/C++和Unixshell的经验。

设置环境
首先,你应该为环境做好准备。
我们建议在GCE上使用VM。
更简单的解决方案是使用Google Docker(您可能无法完成与云存储相关的任务)。
您也可以使用自己的Linux机器,但是使用效果就因人而异了。

GCE上的VM
·登录到您的GCE帐户或创建一个。
·为它创建一个新的VM和ssh。
推荐Ubuntu 16.04,其他VM可能工作,也可能不工作。
尽可能多地选择CPU。
选择”Access scopes” = “Allow full access to all Cloud APIs”

·安装依赖关系:

# Install git and get this tutorial
sudo apt-get --yes install git
git clone https://github.com/google/fuzzer-test-suite.git FTS
./FTS/tutorial/install-deps.sh  # Get deps
./FTS/tutorial/install-clang.sh # Get fresh clang binaries
# Get libFuzzer sources and build it
svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk/lib/fuzzer Fuzzer
Fuzzer/build.sh

Dock Worker
此选项测试较少;此外,您的笔记本电脑的核心数量也将限制。
`Install Docker
`Run docker run –cap-add SYS_PTRACE -ti libfuzzertutorial/prebuilt

Verify the setup
Run:

clang++ -g -fsanitize=address -fsanitize-coverage=trace-pc-guard FTS/tutorial/fuzz_me.cc libFuzzer.a
./a.out 2>&1 | grep ERROR

and make sure you see something like

==31851==ERROR: AddressSanitizer: heap-buffer-overflow on address...

Note: this tutorial uses LLVM/Clang 5.0, where libFuzzer uses the flags -fsanitize=address -fsanitize-coverage=trace-pc-guard. In newer versions the flags were renamed to -fsanitize=address,fuzzer, see http://libfuzzer.info

定义:Fuzz目标是一个函数,它具有以下特征,并对其参数执行一些有趣的操作:

extern “C” int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
DoSomethingWithData(Data, Size);
return 0;
}

看看这样一个fuzz目标的例子:./fuzz_me.cc。 https://github.com/google/fuzzer-test-suite/blob/master/tutorial/fuzz_me.cc
你能看到bug吗?
要为这个目标构建一个fuzz二进制文件,您需要使用最近的Clang编译器编译源代码,并使用以下额外标志:
-fsanitize-coverage=trace-pc-guard(必需):向libFuzzer提供进程内覆盖信息。
-fsanitize=Address(推荐):启用AddressSaniizer。
-g(推荐):启用调试信息,使错误消息更易于阅读。
然后,您需要链接目标代码与提供main()函数的libFuzzer.a。

clang++ -g -fsanitize=address -fsanitize-coverage=trace-pc-guard FTS/tutorial/fuzz_me.cc libFuzzer.a

Now try running it:

./a.out
You will see something like this:

INFO: Seed: 3918206239
INFO: Loaded 1 modules (14 guards): [0×73be00, 0×73be38),
INFO: -max_len is not provided, using 64
INFO: A corpus is not provided, starting from an empty corpus
#0 READ units: 1
#1 INITED cov: 3 ft: 3 corp: 1/1b exec/s: 0 rss: 26Mb
#8 NEW cov: 4 ft: 4 corp: 2/29b exec/s: 0 rss: 26Mb L: 28 MS: 2 InsertByte-InsertRepeatedBytes-
#3405 NEW cov: 5 ft: 5 corp: 3/82b exec/s: 0 rss: 27Mb L: 53 MS: 4 InsertByte-EraseBytes-…
#8664 NEW cov: 6 ft: 6 corp: 4/141b exec/s: 0 rss: 27Mb L: 59 MS: 3 CrossOver-EraseBytes-…
#272167 NEW cov: 7 ft: 7 corp: 5/201b exec/s: 0 rss: 51Mb L: 60 MS: 1 InsertByte-
=================================================================
==2335==ERROR: AddressSanitizer: heap-buffer-overflow on address 0×602000155c13 at pc 0×0000004ee637…
READ of size 1 at 0×602000155c13 thread T0
#0 0×4ee636 in FuzzMe(unsigned char const*, unsigned long) FTS/tutorial/fuzz_me.cc:10:7
#1 0×4ee6aa in LLVMFuzzerTestOneInput FTS/tutorial/fuzz_me.cc:14:3

artifact_prefix=’./’; Test unit written to ./crash-0eb8e4ed029b774d80f2b66408203801cb982a60

你看到类似的输出了吗?恭喜你,你造了一个模糊系统,发现了一个错误。让我们看看输出。

INFO: Seed: 3918206239

模糊开始于这种随机的种子。
用-SEED=3918206239重新运行它,以获得相同的结果。

INFO: -max_len is not provided, using 64
INFO: A corpus is not provided, starting from an empty corpus

默认情况下,libFuzzer假定所有输入都是64字节或更小。
若要更改此操作,请使用-max_len=N或使用非空种子语料库运行。

#0 READ units: 1
#1 INITED cov: 3 ft: 3 corp: 1/1b exec/s: 0 rss: 26Mb
#8 NEW cov: 4 ft: 4 corp: 2/29b exec/s: 0 rss: 26Mb L: 28 MS: 2 InsertByte-InsertRepeatedBytes-
#3405 NEW cov: 5 ft: 5 corp: 3/82b exec/s: 0 rss: 27Mb L: 53 MS: 4 InsertByte-EraseBytes-…
#8664 NEW cov: 6 ft: 6 corp: 4/141b exec/s: 0 rss: 27Mb L: 59 MS: 3 CrossOver-EraseBytes-…
#272167 NEW cov: 7 ft: 7 corp: 5/201b exec/s: 0 rss: 51Mb L: 60 MS: 1 InsertByte-

libFuzzer已经尝试了至少272167个输入(#272167),并且已经发现了总计201个字节的5个输入(corp:5/201b),总共覆盖了7个覆盖点(cov:7)。
您可能会认为覆盖率点是代码中的基本块。

==2335==ERROR: AddressSanitizer: heap-buffer-overflow on address 0×602000155c13 at pc 0×0000004ee637…
READ of size 1 at 0×602000155c13 thread T0
#0 0×4ee636 in FuzzMe(unsigned char const*, unsigned long) FTS/tutorial/fuzz_me.cc:10:7
#1 0×4ee6aa in LLVMFuzzerTestOneInput FTS/tutorial/fuzz_me.cc:14:3

在其中一个输入上,AddressSaniizer检测到了堆缓冲区溢出错误,并中止了执行。

artifact_prefix=’./’; Test unit written to ./crash-0eb8e4ed029b774d80f2b66408203801cb982a60

在退出进程之前,libFuzzer已经在磁盘上创建了一个文件,其中包含触发崩溃的字节。
看看这个文件。
你看到什么了?
为什么会引发crash?
若要再次再现崩溃,请运行w/o模糊运行。

./a.out crash-0eb8e4ed029b774d80f2b66408203801cb982a60

Monday, January 29, 2018 by blast