curl/curl-fuzzer

GitHub: curl/curl-fuzzer

curl 官方的模糊测试项目,集成 OSS-Fuzz 对 curl 和 libcurl 进行持续安全测试与漏洞挖掘。

Stars: 94 | Forks: 38

# curl-fuzzer 用于 curl 和 libcurl 模糊测试的代码与语料库。 这是 curl 模糊测试项目 [OSS-Fuzz](https://github.com/google/oss-fuzz/tree/master/projects/curl) 为我们持续运行的测试。 ## 我只想开始模糊测试! 太棒了!运行 `./mainline.sh`。它将为您下载一份最新的 curl 副本,使用 `clang` 进行编译,将其安装到一个临时目录中,然后针对 curl 编译 fuzzer。它还会运行回归测试用例。 如果您有想要使用的本地 curl 副本,可以将其路径作为 参数传递给 `./mainline.sh`。它会转而将那个 curl 编译并安装到 一个临时目录中。 `./mainline.sh` 由 Github Actions 负责执行回归测试。 ## 我想查看代码覆盖率 运行 `./codecoverage.sh`。它会使用基于 LLVM 源码的覆盖率插桩 构建每个 fuzzer,通过它们重放检入的语料库,并生成: - `build-coverage/coverage/summary.txt` - `llvm-cov report`(每个文件的行/区域/函数 百分比,仅限于 curl 的 `lib/` 和 `src/` 目录)。 - `build-coverage/coverage/html/index.html` - 可浏览的 HTML 报告。 与 `mainline.sh` 类似,传递 `-c /path/to/curl` 可以针对本地的 curl 代码库而不是 git master 分支的最新节点来测量覆盖率。 `Coverage` GitHub Actions 工作流可以按需运行相同的脚本 (Actions → Coverage → "Run workflow"),并将报告作为 artifact 上传;其摘要也会发布到作业摘要页面,因此无需 下载任何内容即可查看总体数据。它是手动 触发而不是在每次 push 时运行,以保持主 CI 路径的高速运行。 ## 我想在运行单个或多个测试用例时获取更多信息 设置 `FUZZ_VERBOSE` 环境变量即可开启 curl 的详细日志记录。 这在调试单个测试用例时非常有用。 ## 我想从 OSS-Fuzz 下载公共语料库测试文件 运行 `./scripts/download_public_corpus.sh`。它会为 `scripts/fuzz_targets` 中列出的每个目标拉取公开的 `public.zip`,并将其放入 `ossfuzz_corpus//` 中,同时会跳过那些没有发布 zip 的目标。 传递 `-f` 可以强制刷新已下载的语料库。 当 `ossfuzz_corpus//` 目录存在时,`./codecoverage.sh` 会在重放检入的 `corpora//` 的 同时自动重放该目录,因此 本地覆盖率数据能够反映出 OSS-Fuzz 集群所发现的内容。`Coverage` CI 工作流每周运行相同的下载任务(按 ISO 周进行缓存)。 每个目标的公共语料库链接也可以直接访问: - [curl_fuzzer_dict](https://storage.googleapis.com/curl-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/curl_fuzzer_dict/public.zip) - [curl_fuzzer_file](https://storage.googleapis.com/curl-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/curl_fuzzer_file/public.zip) - [curl_fuzzer_ftp](https://storage.googleapis.com/curl-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/curl_fuzzer_ftp/public.zip) - [curl_fuzzer_gopher](https://storage.googleapis.com/curl-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/curl_fuzzer_gopher/public.zip) - [curl_fuzzer_http](https://storage.googleapis.com/curl-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/curl_fuzzer_http/public.zip) - [curl_fuzzer_https](https://storage.googleapis.com/curl-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/curl_fuzzer_https/public.zip) - [curl_fuzzer_imap](https://storage.googleapis.com/curl-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/curl_fuzzer_imap/public.zip) - [curl_fuzzer_ldap](https://storage.googleapis.com/curl-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/curl_fuzzer_ldap/public.zip) - [curl_fuzzer_mqtt](https://storage.googleapis.com/curl-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/curl_fuzzer_mqtt/public.zip) - [curl_fuzzer_pop3](https://storage.googleapis.com/curl-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/curl_fuzzer_pop3/public.zip) - [curl_fuzzer_rtmp](https://storage.googleapis.com/curl-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/curl_fuzzer_rtmp/public.zip) - [curl_fuzzer_rtsp](https://storage.googleapis.com/curl-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/curl_fuzzer_rtsp/public.zip) - [curl_fuzzer_scp](https://storage.googleapis.com/curl-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/curl_fuzzer_scp/public.zip) - [curl_fuzzer_sftp](https://storage.googleapis.com/curl-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/curl_fuzzer_sftp/public.zip) - [curl_fuzzer_smb](https://storage.googleapis.com/curl-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/curl_fuzzer_smb/public.zip) - [curl_fuzzer_smtp](https://storage.googleapis.com/curl-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/curl_fuzzer_smtp/public.zip) - [curl_fuzzer_tftp](https://storage.googleapis.com/curl-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/curl_fuzzer_tftp/public.zip) - [curl_fuzzer_ws](https://storage.googleapis.com/curl-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/curl_fuzzer_ws/public.zip) - [curl_fuzzer](https://storage.googleapis.com/curl-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/curl_fuzzer/public.zip) - fuzz_url:暂无公开链接。 ## 我想重现 OSS-Fuzz 隔夜发现的错误 查看 [REPRODUCING.md](REPRODUCING.md) 获取更详细的说明。 ## 如何安装 Python 工具? - 使用您最喜欢的方法创建一个虚拟环境。 - 例如: python3 -m venv .venv - 在该虚拟环境中,从此代码库的根目录安装工具,使用命令 pip install . - 或者,您也可以使用 `uv`;通过 uv sync uv pip install -e . 来同步您的环境,或者直接 uv run 。 ## 这个测试用例里有什么? 要查看测试用例的内容,请运行 ``` read_corpus ``` 这将会打印出文件内部的内容列表。 ## 我想要一个用于语料库文件的 HTML 解码器 生成一个独立的 HTML 页面,可以直接在您的浏览器中检查 TLV 语料库: ``` python -m curl_fuzzer_tools.generate_decoder_html ``` 默认情况下,生成器会写入到 `docs/corpus-decoder/index.html`。该页面完全在客户端运行;它永远不会上传所选的文件。您可以直接从文件系统打开输出,例如 `file:///.../docs/corpus-decoder/index.html`。 **查看最新发布的解码器:** [curl 语料库解码器 (GitHub Pages)](https://curl.github.io/curl-fuzzer/corpus-decoder/index.html) GitHub Pages 被配置为每当 `main` 分支更新时,自动从 `docs/` 文件夹进行部署。如果您需要刷新发布的站点,请在推送前在本地使用上述命令。 ### 可选的浏览器冒烟测试 (Playwright) Playwright 回归测试是可选的,这样可以使默认安装保持轻量。如果您想运行它: ``` pip install -e '.[browser-tests]' playwright install chromium pytest tests/browser/test_corpus_decoder.py ``` 这些命令通过在 headless Chromium 运行中上传样本 TLV 语料库,来对生成的 HTML 执行测试。 ## 我想生成一个新的测试用例 要生成一个新的测试用例,请运行 ``` generate_corpus ``` 并附带合适的选项 - 传递 `--help` 查看所有选项。 # 我想增强 fuzzer! 太棒了!这里有一些您可能需要了解的信息。 ## 文件格式 测试用例采用 Type-Length-Value(即 TLV)格式编写。每个 TLV 包含: - 16 位的类型 (Type) - 32 位的 TLV 数据长度 (Length) - 0 到 length 字节的数据。 TLV 类型编号在 corpus.py 和 curl_fuzzer.h 中均有定义。 ## 添加新的 TLV。 要添加新的 TLV: - 在 Python 脚本中添加对它的支持:`generate_corpus.py`,`corpus.py`。 这意味着需要添加选项,以便从用户(或 从文件,或从测试数据中)读取 TLV 的值。 - 在 fuzzer 中添加对它的支持:`curl_fuzzer.cc`,`curl_fuzzer.h`。这 通常意味着要将 TLV 的处理逻辑添加到 `fuzz_parse_tlv()` 中。 - 确保您的附加 TLV 能够被 `FUZZ_CURLOPT_TRACKER_SPACE` 包含! - 如果您在创建了 TLV 编号并生成了测试用例之后决定更改它, 请重新运行测试用例生成,以确保您当前的 TLV 编号能如 预期那样映射您的测试用例。
标签:CISA项目, clang, curl, DNS解析, Fuzzing, GitHub Actions, libcurl, LLVM, OSS-Fuzz, UML, 代码覆盖率, 协议测试, 回归测试, 安全测试, 开源框架, 开源项目, 持续集成, 攻击性安全, 特征检测, 白盒测试, 网络安全, 自动笔记, 软件质量保证, 逆向工具, 隐私保护, 黑盒测试