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, 代码覆盖率, 协议测试, 回归测试, 安全测试, 开源框架, 开源项目, 持续集成, 攻击性安全, 特征检测, 白盒测试, 网络安全, 自动笔记, 软件质量保证, 逆向工具, 隐私保护, 黑盒测试