sirredbeard/CVE-2025-60876
GitHub: sirredbeard/CVE-2025-60876
针对 BusyBox wget 的 CVE-2025-60876 HTTP 请求行注入漏洞,提供无回归的行为保留型百分号编码修复及完整的 PoC 与上游提交材料。
Stars: 0 | Forks: 1
# CVE-2025-60876: busybox wget request-target 注入修复
这是对 CVE-2025-60876(BusyBox `wget` 中的一个 HTTP header 注入漏洞)的行为保留型修复,还包括演示该漏洞的 proof-of-concept,以及向 BusyBox 上游提交修复的 artifacts。
## 漏洞详情
BusyBox `wget` 会将 URL 路径和查询参数原封不动地复制到 HTTP 请求行中。携带原始 CR (0x0D)、LF (0x0A) 或其他控制字符的 URL 会拆分请求行并注入攻击者控制的 header。空格 (0x20) 也会产生同样的效果:它会破坏 `METHOD SP request-target SP HTTP/1.1` 的结构。
受影响版本:BusyBox 1.37.0 及更早版本(即所有仍受支持的 Alpine 分支中附带的 `pkgver`)。该漏洞已于 2025 年 8 月在 BusyBox 邮件列表中报告;CVE 编号为 CVE-2025-60876(NVD CVSS 6.5,中危)。
## 修复方案
目前上游已经提出了两个补丁(Takeuchi Yuma,2025-08;Radoslav Kolev,2025-11)。这两个补丁都会 *拒绝* 违规 URL 并调用 `bb_error_msg_and_die`。这确实阻止了注入,但它也拒绝了普通的空格,因此以前可以正常工作的 URL(例如 `http://example.org/foo bar`)现在会报错。正是这种回归导致该修复一直未被下游采纳。Alpine 目前正在对此进行暂缓处理([工作项 17872](https://gitlab.alpinelinux.org/alpine/aports/-/work_items/17872))。
本修复方案以不同的方式处理路径和主机,这与 GNU wget 和 curl 的行为保持一致。
**路径:** `networking/wget.c` 中的 `percent_encode_target()` 会在构建请求行之前,对 request-target 中的控制字符(0x00 到 0x1f)、空格 (0x20) 以及 DEL (0x7f) 进行百分号编码:
- CR 和 LF 无法再进入请求行,从而封堵了注入漏洞。
- `http://example.org/foo bar` 会作为 `/foo%20bar` 发送,与 GNU wget 和 curl 一致。不会产生回归。
- 现有的 `%` 保持不变,因此已经编码过的路径不会被二次编码。
**主机:** URL 主机部分中如果包含相同的字符会被拒绝。合法的主机名不能包含控制字符或空格,并且 authority 组件不支持百分号编码。这一点在 proxy 模式下尤为重要:主机会被放入 absolute-form 的 request-target(`GET http://host/path`)和 `Host:` header 中,且不会在本地进行解析。如果不做处理,主机名中的原始 CR 或 LF 就会被攻击者用来进行注入。GNU wget(自 CVE-2017-6508 起)和 curl 同样会拒绝主机名中的控制字符。
此更改仅限于 `networking/wget.c`,并添加了一个辅助函数。
**不在此范围内:** FTP 控制通道(`ftpcmd` 会直接发送 `target->path` 以及原始的用户名/密码,这是上游已知的待办事项)属于另一种注入类型,不属于 CVE-2025-60876 的一部分,因此不在本次修复范围内。应单独对其进行追踪。
## 验证
使用 Alpine 采用的相同配置(关闭 `CONFIG_WERROR` 和 `CONFIG_TC`)针对 BusyBox 1.37.0 进行编译。通过本地监听器捕获 `wget` 在网络中发送的准确字节。
| 输入 URL | 原版 1.37.0 | 修复版 |
|-----------|----------------|---------|
| `/x` + CRLF + `Evil: injected` | `Evil: injected` 作为真实的 header 到达(存在漏洞) | `GET /x%0D%0AEvil:%20injected HTTP/1.1`,无注入的 header |
| `/foo bar` | 发送原始空格 | `GET /foo%20bar HTTP/1.1`(无回归) |
| `/foo%20bar`(已编码) | 无变化 | `GET /foo%20bar HTTP/1.1`(不会变成 `%2520`) |
| `/normal` | 无变化 | `GET /normal HTTP/1.1`(无变化) |
| proxy,host = `h` + CRLF + `PInjected: 1` | `PInjected: 1` 作为真实的 header 到达(存在漏洞) | 报错并提示 `bad character in URL host`,不发送任何内容 |
| proxy,host = `example.test` | 正常 | `GET http://example.test/p HTTP/1.1`(无变化) |
完整捕获记录:[`test/poc-output.txt`](test/poc-output.txt)。四个 BusyBox `testsuite/wget` 测试在修补后的构建版本中均通过([`test/testsuite-output.txt`](test/testsuite-output.txt));其中记录的其他完整测试套件失败情况与此无关(mount/taskset 需要 root 权限,以及一些已知的受限 container 异常行为)。aarch64 defconfig 的大小影响为 +185 字节(`wget_main` +142,`.rodata` +43,未添加或移除符号),该数据使用 `scripts/bloat-o-meter` 测量并记录在 [`cover-letter.txt`](cover-letter.txt) 中。
## 文件
| 文件 | 说明 |
|------|------------|
| `wget-cve-2025-60876.patch` | 针对 BusyBox `networking/wget.c` 的 `git format-patch` 修复补丁,可直接发送 |
| `commit-message.txt` | 提交信息(同时也是补丁的 header) |
| `cover-letter.txt` | 发送至邮件列表的 `[PATCH v3]` 附言,用于恢复现有的话题讨论 |
| `apply_fix.py` | 将更改应用到 `networking/wget.c` 的生成器脚本(用于生成补丁) |
| `test/serve_once.py` | 回显原始 HTTP 请求的单连接监听器 |
| `test/driver.sh` | 编译原版和修复版 BusyBox,并运行直接和 proxy 模式下的修复前后 PoC |
| `test/finalize.sh` | 完整运行流程:修复前后 PoC、`bloat-o-meter`、`testsuite/wget`,并重新生成补丁 |
| `test/poc-output.txt` | 捕获的修复前后请求字节(直接和 proxy 模式) |
| `test/testsuite-output.txt` | 修复版 BusyBox 构建的 `testsuite/wget` 结果 |
## 复现测试
`test/finalize.sh` 在带有 Docker 的 `alpine:edge` container 中运行,并复现所有内容(PoC、体积变化、测试套件、补丁):
```
docker run --rm -v "$PWD:/work" alpine:edge sh /work/test/finalize.sh
```
它会下载 BusyBox 1.37.0,编译原版(直接并通过 proxy 展示注入)、应用修复、重新编译、重放上述请求案例、运行 `bloat-o-meter` 和 wget 测试套件,并输出补丁文件。`test/driver.sh` 是一个更轻量的、仅包含 PoC 的变体脚本。
## 提交至上游
BusyBox 是一个基于邮件列表的项目。该修复将通过 `git send-email` 发送至 `busybox@busybox.net`,作为对 Radoslav Kolev 2025 年 11 月话题的 `[PATCH v3]` 回复,并向此前的报告者和审阅者致谢。详情请参阅 `cover-letter.txt`。该修复采用与 BusyBox 相同的 GPLv2 许可证。
## 参考
- CVE-2025-60876: https://www.cve.org/CVERecord?id=CVE-2025-60876
- BusyBox 邮件列表, Kolev v2 (2025-11): https://lists.busybox.net/pipermail/busybox/2025-November/091840.html
- BusyBox 邮件列表, Takeuchi 报告及补丁 (2025-08): https://lists.busybox.net/pipermail/busybox/2025-August/091710.html
- Alpine 工作项 17872: https://gitlab.alpinelinux.org/alpine/aports/-/work_items/17872
- Debian bug #1120795: https://bugs.debian.org/1120795
标签:BusyBox, CISA项目, Cutter, HTTP头注入, PoC, 安全修复, 暴力破解, 漏洞补丁, 请求拦截, 逆向工具