
PoC en Python que explota CVE-2026-19586, una inyección de comandos no autenticada en TP-Link Omada SSL VPN que ejecuta comandos arbitrarios como root mediante la inyección en el nombre de usuario de OpenVPN.
TP-Link Omada SSL VPN RCE no autenticada (CVE-2026-19586)
Una vulnerabilidad de inyección de comandos (CWE-78) en la ruta de autenticación del SSL VPN del firmware de las puertas de enlace TP-Link Omada permite a un atacante no autenticado ejecutar comandos arbitrarios como root. Cuando el servidor SSL VPN basado en OpenVPN está habilitado, OpenVPN pasa el nombre de usuario enviado por el cliente que se conecta a /usr/sbin/checkpsw.sh, el script asociado a la directiva auth-user-pass-verify. Ese script inserta el nombre de usuario sin comillas en un programa awk, por lo que un nombre de usuario que contenga una comilla doble cierra el literal de cadena de awk en el que se pega y el resto se analiza como código fuente de awk.
Un bloque BEGIN de awk se ejecuta una vez antes de que se lea la primera línea de entrada, por lo que la llamada inyectada a system() se ejecuta antes de que la contraseña enviada se compare con cualquier cosa, como root.
El servidor no requiere certificado de cliente y no lleva ninguna clave tls-auth ni tls-crypt, y su certificado de CA está codificado de forma fija en la imagen del firmware. El ca.crt de este repositorio es ese certificado, y es idéntico en todos los dispositivos que ejecutan el firmware afectado, por lo que cualquier atacante que pueda alcanzar el puerto VPN puede completar el handshake TLS y llegar a la inyección sin credenciales y sin acceso previo al dispositivo.
El nombre de usuario no puede contener espacios literales, porque el shell divide la expansión sin comillas en argumentos separados antes de que awk lo vea. Use ${IFS} en su lugar, que el shell invocado por system() expande de nuevo a un espacio. OpenVPN limita el nombre de usuario a 128 bytes; el andamiaje del payload usa 22 de ellos, dejando 106 para el comando.
Esta Prueba de Concepto (PoC) se probó contra el TP-Link Omada ER7212PC v2 (firmware 6.1.0.19). El script vulnerable es compartido en toda la línea de puertas de enlace Omada; las rutas, los números de línea y el comportamiento pueden diferir en otros modelos o versiones de firmware.
Esta PoC entrega un payload de nombre de usuario que se ejecuta como root en el dispositivo objetivo. Este problema se reportó a TP-Link y se corrigió en las versiones de firmware listadas en el aviso; ejecute esto contra hardware que posea o esté explícitamente autorizado a probar.
$ sudo python3 cve-2026-19586.py <target> -c '<command>'
Se requiere el cliente openvpn, y debe ejecutarse como root, ya que necesita CAP_NET_ADMIN para crear el dispositivo tun. Esto es un requisito del cliente OpenVPN local, no del objetivo.
Ejemplo de ejecución:
$ sudo python3 cve-2026-19586.py 10.0.0.100 -c 'id>/tmp/proof'
TP-Link Omada SSL VPN Unauthenticated RCE (CVE-2026-19586) - OpenVPN Username Injection
Target : 10.0.0.100:1194/udp
CA cert : ca.crt
Command : id>/tmp/proof
Username : x";BEGIN{system("id>/tmp/proof")};#
[*] Running: openvpn --client --dev tun --proto udp --remote 10.0.0.100 1194 --resolv-retry 1 --nobind --ca ca.crt --remote-cert-tls server --cipher AES-256-CBC --data-ciphers-fallback AES-256-CBC --reneg-sec 0 --auth-user-pass /tmp/ovpn_creds_m0ycjowy.txt --auth-nocache --verb 3
[openvpn client output]
El comando se ejecuta en el dispositivo antes de que se complete la autenticación, por lo que el propio cliente OpenVPN no se conectará. El intento de autenticación falla y el cliente sale, lo cual es lo esperado.
| Argumento | Descripción |
|---|
target | IP o nombre de host del dispositivo objetivo |
-c, --command | Comando a ejecutar como root en el objetivo. Use ${IFS} en lugar de espacios |
-p, --port | Puerto UDP del SSL VPN (predeterminado: 1194) |
--ca | Certificado de CA extraído del firmware (predeterminado: ca.crt) |