应用高级模糊测试技术提升cURL安全性

本文详细介绍了Trail of Bits如何通过改进cURL的模糊测试代码来提升安全性和代码覆盖率,包括增加种子文件、启用关键选项和环境变量,以及提出结构感知模糊测试等高级技术建议。

我们如何将高级模糊测试技术应用于cURL - Trail of Bits博客

背景介绍

2022年底,Trail of Bits受开源技术改进基金(OSTIF)委托,对cURL文件传输命令行工具及其库libcurl进行安全评估。我们的工作范围包括代码审查、威胁建模,以及本文重点讨论的内容:分析和改进cURL模糊测试代码的工程实践。

cURL的模糊测试机制

cURL使用Google为开源项目提供的免费服务OSS-Fuzz作为持续模糊测试基础设施。OSS-Fuzz支持C/C++、Rust、Go、Python和Java代码库,并使用覆盖引导的libFuzzer、AFL++和Honggfuzz模糊测试引擎。cURL于2017年7月1日加入OSS-Fuzz,相关代码存放在GitHub的curl-fuzzer仓库中。

该仓库包含模糊测试cURL和libcurl所需的代码(设置脚本、测试用例生成器、测试工具等)和语料库(初始测试用例集)。它设计用于模糊测试单个目标,即libcurl支持的协议,如HTTP(S)、WebSocket和FTP。curl-fuzzer会下载最新版本的cURL及其依赖项,编译它们,并针对这些目标构建二进制文件。

每个目标接受特殊结构的输入文件,使用适当的libcurl调用进行处理,然后退出。每个目标都有一个关联的语料库目录,其中包含要模糊测试的协议的有趣种子文件。这些文件使用自定义的类型-长度-值(TLV)格式进行结构化,不仅编码原始协议数据,还编码协议的特定字段和元数据。

初步发现:HSTS和Alt-Svc覆盖不足

我们首先分析了libcurl的模糊测试覆盖率。通过查看OSS-Fuzz定期生成的覆盖率报告,我们发现几个源文件的覆盖率极低,包括一些实现安全功能或负责处理不可信数据的文件。

例如,负责解析和处理Strict-Transport-Security响应头的hsts.c文件,在OSS-Fuzz上运行五年多后,行覆盖率仅为4.46%,函数覆盖率为18.75%,区域覆盖率为2.56%。处理Alt-Svc响应头的altsvc.c文件同样存在覆盖率不足的问题。

调查发现原因有三:语料库缺少包含Strict-Transport-Security和Alt-Svc头的测试用例;模糊测试器从未设置CURLOPT_HSTS选项;HSTS规范要求用户代理在通过未加密HTTP发送时忽略Strict-Transport-Security头,这在模糊测试上下文中造成问题。

改进措施

我们实施了以下改进:

  1. 向curl-fuzzer添加Strict-Transport-Security和Alt-Svc的种子文件
  2. 在curl-fuzzer中启用CURLOPT_HSTS
  3. 添加检查允许libcurl的调试版本在设置CURL_HSTS_HTTP环境变量时绕过HSTS的HTTPS限制,并在curl-fuzzer中设置CURL_HSTS_HTTP和CURL_ALTSVC_HTTP环境变量

改进后,两个文件的覆盖率显著提升:hsts.c的行覆盖率翻倍,altsvc.c的行覆盖率增加了近五倍。

扩展测试范围

我们进一步探索了提升覆盖率的其他机会,特别是语料库中的种子文件集。虽然libcurl支持众多协议和功能,但并非所有功能都在语料库中有对应的种子文件。

我们为以下功能创建了新的种子文件:

  • CURLOPT_LOGIN_OPTIONS:为IMAP、LDAP、POP3和SMTP设置协议特定登录选项
  • CURLOPT_XOAUTH2_BEARER:指定用于HTTP、IMAP、LDAP、POP3和SMTP服务器的OAuth 2.0 Bearer访问令牌
  • CURLOPT_USERPWD:指定用于身份验证的用户名和密码
  • CURLOPT_USERAGENT:指定User-Agent头的值
  • CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256:设置SSH连接的远程服务器预期SHA256哈希
  • CURLOPT_HTTPPOST:设置POST请求数据

高级改进建议

我们向cURL团队提出了几个战略性建议:

字典优化

为libcurl支持的其他协议创建字典文件,枚举协议上下文中有趣的字符串,如关键字、分隔符和转义字符。这可以加快搜索速度并更快地发现新错误。

命令行参数模糊测试

使用AFL++的argv-fuzz-inl.h头文件持续模糊测试cURL的命令行界面。

结构感知模糊测试

当前TLV格式的脆弱性使模糊测试效率低下。我们建议实现结构感知模糊测试,通过编写自定义变异器来协助libFuzzer:尝试将来自libFuzzer的输入数据解包为TLV;如果数据无法解析为有效TLV,返回语法正确的虚拟TLV;如果数据构成有效TLV,对解析出的字段进行变异,然后序列化并返回结果TLV。

后续工作

2023年底,我们在OSTIF支持的另一次审计中重新审视了cURL及其模糊测试代码。敬请关注我们后续博客文章中的重点内容。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计