curl配置文件解析中的任意释放漏洞分析报告
报告编号: #3434543 报告平台: HackerOne 提交时间: 2025年11月20日 报告者: letshack9707 项目: curl 状态: 已公开(被评估为信息性,非安全问题)
漏洞概要
在cURL解析配置文件的过程中,存在一个任意释放(arbitrary free)漏洞。攻击者可以通过特制的配置文件,控制传递给free()函数的指针值。根据程序的具体情况和攻击者在释放指针后所能进行的操作,这可能引发双重释放(double-free)、释放后使用(use-after-free)或内存损坏(memory corruption)。
声明:报告中使用了AI来帮助整理与此错误相关的一些资源。
受影响版本
- curl 8.17.0 (x86_64-pc-linux-gnu)
- libcurl/8.17.0 OpenSSL/3.4.1 zlib/1.3.1 brotli/1.1.0 zstd/1.5.7 libidn2/2.3.8 libpsl/0.21.2 nghttp2/1.64.0 librtmp/2.3 OpenLDAP/2.6.9
- 发布日期: 2025-11-05
- curl 8.16.0 同样受影响(配置文件中可控参数和样本不同)。
操作系统/内核:
- Linux kali 6.3.0-kali1-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.3.7-1kali1
复现步骤
- 创建并编辑配置文件
host0.bin:1 2touch host0.bin vim host0.bin - 将以下内容粘贴到
host0.bin中:1 2 3 4--url "http://google.com/iernay{1-2}kFORFNUUklOR1JBTkRTVFJJTkdSQU5EU1RSSU5HUkFORFNUUklOR1JBTkRTVFJJTkdSQU5EU1RSSU5HUkFORFNUUklOR1JBTkRTVFJJT" --url "http://[::%2-socks5]:8080/" --url google.com-Z[.-p].example.com" --doh-url=127.0.0.1 - 使用GDB运行cURL并加载该配置文件:
程序将在
1gdb -ex "r" --args curl --config host0.bin__GI___libc_free函数中因段错误(SIGSEGV)而停止。寄存器$rdi(free函数的参数)的值为0x2e302e302e373231,经反转后对应字符串127.0.0.。这表明我们能够控制(针对此配置文件)传递给free()的数据。
漏洞利用与控制验证
为了进一步证明对free()参数的控制能力,报告者编写了一个Python脚本 mutate.py。该脚本可以将堆中的可控数据(127.0.0.)替换为我们希望传递给__GI___libc_free的任意地址,并生成新的配置文件 vuln.conf。
|
|
执行后,程序同样在free()中崩溃,但此时寄存器$rdi的值变为0x4242424242424242(BBBBBBBB),证实了攻击者可以完全控制释放的指针。
堆栈跟踪分析:
崩溃发生在tool_urlglob.c文件的glob_cleanup函数中(第499行):
|
|
tool_safefree最终调用了标准库的free()。回溯显示,调用链为:main -> operate -> run_all_transfers -> … -> glob_url -> glob_cleanup -> free。
双重释放(Double-Free)演示
通过ltrace工具跟踪free调用,可以更清晰地观察内存操作。首先关闭地址空间布局随机化(ASLR)以便观察:
|
|
如果我们将一个已经被释放的地址写入配置文件(通过mutate.py设置),则会触发tcache的双重释放检测机制:
|
|
输出结果显示:
|
|
程序因SIGABRT(中止信号)而终止,这正是glibc的tcache机制检测到双重释放时的行为。
漏洞影响与评估
潜在影响:
控制传递给free()的指针,可能导致双重释放/释放后使用,进而可能引发远程代码执行(RCE)或权限提升。具体影响取决于运行cURL的环境。
利用前提:
- 需要诱使用户执行恶意的配置文件(例如通过
~/.curlrc)。 - 需要额外的漏洞(如任意读取、内存泄漏)来绕过ASLR和Tcache缓解机制,或者利用同一漏洞构建读/写原语来实现绕过。
严重性评级: 低 (Low) 报告者将严重性设置为“低”,原因如下:
- 利用需要诱骗用户运行特制的配置文件。
- cURL本身已经具备执行命令的能力(此漏洞源于cURL处理配置文件的方式,而非其固有的命令执行能力)。
- 需要额外的漏洞来绕过ASLR/Tcache缓解机制。
维护者响应与修复
cURL安全团队(bagder, dgustafsson)在收到报告后迅速做出了回应。
初步评估:
维护者起初认为这是一个无害的bug。bagder指出:这是cURL工具中一次realloc后对(未初始化的)堆内存的释放。它不与其他线程共享内存空间,攻击者无法控制或滥用这次释放——即使用户提供了特制的配置文件。结果很可能是无害的或导致崩溃。在这种上下文中,cURL工具崩溃是无害的,因为cURL无论如何都会退出,并且给定一个任意的配置文件,无法期望有特定的定义行为,因为输入是未知的。因此,他们认为这不是一个安全漏洞。
修复尝试: 尽管不认为是安全漏洞,维护者仍然提供了修复代码。最初的补丁被认为“过于天真和不完整”,随后他们提交了一个更完善的修复尝试,并成功通过了glob相关测试用例: GitHub Pull Request #19614
报告者反驳:
报告者letshack9707重申,他已经证明了可以通过配置文件控制传递给free()的指针,并导致了tcache中的双重释放检测。他询问这与经典的已知双重释放漏洞有何不同,并提出了理论上的利用思路:首先需要绕过tcache双重释放检测,然后触发cURL中分配与之前释放块大小相同的内存分配。如果分配器随后在malloc()调用中返回该地址,返回的指针将指向攻击者控制的区域(我们释放的地址),允许我们在选定的地址获得一个伪造的块(fake chunk)。
最终结论与报告处理:
经过多轮讨论,cURL安全团队坚持认为,鉴于cURL工具本身的性质(单进程、以用户权限运行、可接受外部配置文件并已有执行命令的能力),即使能够控制free()的地址,也无法构成比现有能力更严重的威胁。他们无法找到将此bug转化为实际漏洞的方法。
因此,报告状态被更改为 Informative(信息性),并于2025年11月23日公开披露。未分配CVE ID,也未发放赏金。
报告者总结
报告者letshack9707在报告关闭后表示,鉴于cURL配置文件解析漏洞在此项目中被视为普通bug或cURL的正常能力范围,未来类似的问题将直接提交到GitHub,而非HackerOne平台。他同时感谢cURL团队为改进工具安全性所付出的努力和时间。