OSS-fuzz模糊测试aiohttp发现crash并复现
模糊测试是一种众所周知的用于发现软件中的编程错误的技术。检测出的多种类型的漏洞,如缓冲区溢出,可能会产生严重的安全隐患。Google 通过部署Chrome 组件的引导式进程内模糊测试发现了数千个安全漏洞和稳定性错误,我们现在希望与开源社区共享该服务。OSS-Fuzz与Core Infrastructure Initiative和OpenSSF合作,旨在通过将现代模糊测试技术与可扩展的分布式执行相结合,使通用开源软件更加安全和稳定。不符合 OSS-Fuzz 条件的项目(例如闭源)可以运行自己的ClusterFuzz或ClusterFuzzLite实例。
OSS-fuzz支持libFuzzer、AFL++和Honggfuzz模糊引擎与Sanitizers以及ClusterFuzz,一个分布式模糊执行环境和报告工具,OSS-Fuzz的架构如下图所示。目前,OSS-Fuzz 支持 C/C++、Rust、Go、Python 和 Java/JVM 代码。LLVM支持的其他语言也可以工作。OSS-Fuzz 支持对 x86_64 和 i386 构建进行模糊测试。
aiohttp是我们本次模糊测试的目标。它是一个异步的http 客户端/服务器框架具有以下几个特点:
支持 HTTP 协议的客户端和服务器端。
开箱即用地支持客户端和服务器 Web-Sockets 并避免回调地狱。
为 Web 服务器提供中间件和可插入路由
下面开始使用OSS-Fuzz对aiohttp进行模糊测试
1. oss-fuzz 环境搭建
1.1 下载项目到本地
$ gitclonehttps://github.com/google/oss-fuzz.git
在project中可以看到包含的所有开源项目
进入到要测试的aiohttp 的文件夹下此时可以看到有三个文件:project.yaml ,Dockerfile和build.sh。
在priject.yaml文件中记录项目的基本信息
homepage: 项目地址main_repo: 托管代码的源代码存储库的路径laguange: 项目本编写的编程语言primary_contact, auto_css: 联系人列表fuzzing_engines: 模糊测试所使用的引擎:本次使用的是libfuzzersanitizer: 消毒剂,支持ASAN 和MSAN ,可以有效的提高模糊测试发现crash的概率,-address,-undefined是可选的参数
dockerfile用于构建项目镜像
2. 开始fuzz
构建基础镜像
在OSS-fuzz路径下:
$ python infra/helper.py build_image aiohttp
在构建过程遇到问题可以参考 zxynull的文章:https://bbs.pediy.com/thread-273014.htm
构建完成如下图所示
2.构建fuzz 目标
$ pythoninfra/helper.py build_fuzzers aiohttp
构建完成后在oss-fuzz/build/out文件中会有生成的harness文件 fuzz_http_parser
3.开始模糊测试
$ Pythoninfra/helper.py run_fuzzer aiohttp fuzz_http_parser
经过一段时间的运行之后发现崩溃:
3.崩溃复现
拉取最新的镜像
$ pythoninfra/helper.py pull_images
构建镜像和模糊器
$ pythoninfra/helper.py build_image aiohtttp
$ pythoninfra/helper.py build_fuzzers --sanitizeraddress aiohttp
报告中使用的是Sanitizer列sanitizer中的值。它是以下之一:
AddressSanitizer 的地址。MemorySanitizer 的内存。UndefinedBehaviorSanitizer 的未定义。备注:
architecture仅当您要指定i386配置时,才需要该参数。一些错误(特别是与指针和整数溢出相关的错误)只能在 32 位模式或 64 位模式下重现。如果您无法为 x86_64 重现特定的错误构建,请尝试为 i386 构建。
复现错误命令参数如下:
python infra/helper.py reproduce $PROJECT_NAME <fuzz_target_name> <testcase_path>
执行:
$ pythoninfra/helper.py reproduce aiohttp fuzz_http_parser build/out/aiohttp/crash-41992178b5d90748ec1b3bd7b866cf45f334e9e1
通过分析源码发现此问题是由于没有抛出异常,导致的服务崩溃。
参考链接:
oss-fuzz:
https://github.com/google/oss-fuzz/tree/master/projects
环境搭建: