centipede是谷歌的新的分布式模式测试工具,不过现在合并到了https://github.com/google/fuzztest,
没合并之前,有个人搞了个Blender,据说是Automatic whole-program fuzzing,就是不需要编写模糊目标函数,而是直接接受要测试的二进制文件(最好是使用了内存检测和覆盖率的编译结果,但不需要修改源代码)。
https://github.com/dvyukov/centipede/tree/dvyukov-blender/blender
根据README的描述,此工具是拦截系统调用,忽略程序的所有输出(写入磁盘/网络的数据),并向输入提供随机数据(从磁盘/网络读取的数据)。
此外,运行一个随机的未知二进制文件是不安全的(它可能会格式化磁盘、删除文件等)。系统调用拦截的第二个重要作用是隔离。在 Blender 下,二进制文件完全被隔离,并且不会对真实世界产生任何影响。这使得可以安全地运行带有随机输入的随机二进制文件。
使用
Blender 有2种使用模式:
1、独立使用:在这种模式下,二进制文件以随机方式执行一次。
2、结合Centipede使用,Centipede 其实类似于libfuzzer,二进制文件将使用Centipede进行循环测试。
独立使用
构建Blender
1 | bazel build -c opt blender:all |
以bash为例
1 | git clone https://git.savannah.gnu.org/git/bash.git |
运行二进制文件并使用 Blender 进行模糊测试(在运行时进行模糊测试)
1 | LD_PRELOAD=/XXX/XXX/bazel-bin/blender/blender.so ./bash |
但是会报错:
1 | blender.cc:238: FAIL: close_range (errno: Function not implemented) |
后来发现close_range() 是一个 Linux 特定的系统调用,它在内核版本 5.9 中被引入。而ubuntu 20.04的默认内核是5.4,所以使用下面命令升级内核
1 | apt update |
上面使用了LD_PRELOAD,如果你可以将一个额外的库链接到二进制文件中,那么你可以链接 bazel-bin/blender/libblender.pic.lo 代替。
如果没有检测到错误,它将不会打印任何内容并以0状态退出(没有正常输出和状态)。如果检测到错误,将打印错误报告并以非0状态退出。
作者说可以与压力工具一起用作一种简易的模糊测试工具
1 | go get golang.org/x/tools/cmd/stress |
结合Centipede使用
build Centipede 和 Blender
1 | bazel build -c opt :all blender:all |
使用一些额外的标志构建目标二进制文件
1 | CC=clang CFLAGS="-fsanitize=address,undefined -g -fno-builtin -fsanitize-coverage=trace-pc-guard,pc-table,trace-cmp" \ |
使用Centipede运行
1 | mkdir /tmp/workdir |