内存泄漏在Curl_auth_create_ntlm_type3_message函数中
报告摘要
报告ID: #3393539
提交者: tjbecker_theori
提交时间: 2025年10月21日 23:41 UTC
漏洞描述
在处理NTLMv2认证时,如果解码后的type-2 “TargetInfo"足够大,使得ntresplen+header_size超过NTLM_BUFSIZE(1024),代码会提前返回而没有释放ntlmv2resp,导致内存泄漏。
漏洞位置:
https://github.com/curl/curl/blob/7d5d0645e5562f65005488fbc7fd270a71239a5f/lib/vauth/ntlm.c#L789
安全影响
安全影响等级: 低
恶意对等方可以将TargetInfo设置为超过阈值,导致客户端内存泄漏。通过重复连接,可以逐渐耗尽客户端资源。
该漏洞是使用Theori的Xint Code(AI驱动工具)发现的,但经过我们人类研究人员的验证和确认。
受影响版本
影响最新版本8.16.0
复现步骤
使用curl模糊测试器作为PoC问题的方法,但在实际环境中,该问题可能由恶意HTTP服务器触发。
-
构建curl模糊测试器:
1
2
|
git clone https://github.com/curl/curl-fuzzers.git
cd curl-fuzzers && ./mainline.sh
|
-
运行附加的脚本生成PoC输入:
1
|
python poc.py # 输出 ./input.bin
|
-
在生成的输入上运行模糊测试器:
1
|
./build/curl_fuzzer_http input.bin
|
内存泄漏详情
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
=================================================================
==2757954==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 964 byte(s) in 1 object(s) allocated from:
#0 0x563de804999d in calloc
#1 0x563de80e4a90 in curl_dbg_calloc
#2 0x563de84520ca in Curl_ntlm_core_mk_ntlmv2_resp
#3 0x563de83e6420 in Curl_auth_create_ntlm_type3_message
#4 0x563de8357698 in Curl_output_ntlm
#5 0x563de82ed9f2 in output_auth_headers http.c
#6 0x563de82ed30f in Curl_http_output_auth
#7 0x563de82e3afd in Curl_http
#8 0x563de812b460 in multi_do multi.c
#9 0x563de81288a9 in state_do multi.c
#10 0x563de8116b00 in multi_runsingle multi.c
#11 0x563de8114894 in curl_multi_perform
#12 0x563de808c3f7 in fuzz_handle_transfer(fuzz_data*)
#13 0x563de808a70d in LLVMFuzzerTestOneInput
#14 0x563de9487ff9 in main
#15 0x7f5e7782a1c9 in __libc_start_call_main
#16 0x7f5e7782a28a in __libc_start_main
#17 0x563de7fae964 in _start
SUMMARY: AddressSanitizer: 964 byte(s) leaked in 1 allocation(s).
|
技术讨论
初始补丁
bagder (curl工作人员) 提供了初始补丁:
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
|
diff --git a/lib/vauth/ntlm.c b/lib/vauth/ntlm.c
index 791fc87d11..d860fbbd50 100644
--- a/lib/vauth/ntlm.c
+++ b/lib/vauth/ntlm.c
@@ -786,35 +786,35 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
});
/* ntresplen + size should not be risking an integer overflow here */
if(ntresplen + size > sizeof(ntlmbuf)) {
failf(data, "incoming NTLM message too big");
- return CURLE_OUT_OF_MEMORY;
+ result = CURLE_TOO_LARGE;
+ goto error;
}
DEBUGASSERT(size == (size_t)ntrespoff);
memcpy(&ntlmbuf[size], ptr_ntresp, ntresplen);
size += ntresplen;
DEBUG_OUT({
curl_mfprintf(stderr, "\n ntresp=");
ntlm_print_hex(stderr, (char *)&ntlmbuf[ntrespoff], ntresplen);
});
- free(ntlmv2resp);/* Free the dynamic buffer allocated for NTLMv2 */
-
DEBUG_OUT({
curl_mfprintf(stderr, "\n flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ",
LONGQUARTET(ntlm->flags), ntlm->flags);
ntlm_print_flags(stderr, ntlm->flags);
curl_mfprintf(stderr, "\n****\n");
});
/* Make sure that the domain, user and host strings fit in the
buffer before we copy them there. */
if(size + userlen + domlen + hostlen >= NTLM_BUFSIZE) {
- failf(data, "user + domain + hostname too big");
- return CURLE_OUT_OF_MEMORY;
+ failf(data, "user + domain + hostname too big for NTLM");
+ result = CURLE_TOO_LARGE;
+ goto error;
}
DEBUGASSERT(size == domoff);
if(unicode)
unicodecpy(&ntlmbuf[size], domain, domlen / 2);
@@ -840,10 +840,13 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
size += hostlen;
/* Return the binary blob. */
result = Curl_bufref_memdup(out, ntlmbuf, size);
+error:
+ free(ntlmv2resp);/* Free the dynamic buffer allocated for NTLMv2 */
+
Curl_auth_cleanup_ntlm(ntlm);
return result;
}
|
最大泄漏大小
通过将target_info_len设置为65535,确认最大泄漏大小为65KB:
1
|
Direct leak of 65599 byte(s) in 1 object(s) allocated from:
|
独立复现方法
构建curl:
1
2
3
|
./buildconf
./configure --with-ssl
CFLAGS="-fsanitize=address" make -j
|
运行PoC:
1
2
|
cat resp.bin | nc -l 8000 &
./src/curl --ntlm -u "user:pass" http://localhost:8000
|
安全影响评估
攻击场景
- 长运行进程代表外部/用户请求发出请求的系统
- 定期轮询端点(例如健康检查、状态报告等)
- 接受来自非受信任用户的请求URL的应用程序(例如webhooks、回调、SSO等)
实际风险
由于此泄漏实际上需要中间人攻击才能发生,而此类攻击者有更大的潜力造成实际损害,而不是每次认证错误触发64K泄漏,因此这被视为"只是一个错误"而不是安全漏洞。
修复状态
该错误已在git中合并,并将包含在下一个版本8.17.0中。