
Python PoC, эксплуатирующий CVE-2026-19586 — неаутентифицированную инъекцию команд в TP-Link Omada SSL VPN, позволяющую выполнять произвольные команды с правами root через инъекцию в имя пользователя OpenVPN.
TP-Link Omada SSL VPN Неаутентифицированное RCE (CVE-2026-19586)
Уязвимость внедрения команд (CWE-78) в пути аутентификации SSL VPN прошивки шлюза TP-Link Omada позволяет неаутентифицированному злоумышленнику выполнять произвольные команды с правами root. Когда SSL VPN-сервер на базе OpenVPN включён, OpenVPN передаёт имя пользователя, отправленное подключающимся клиентом, в /usr/sbin/checkpsw.sh — скрипт, привязанный к директиве auth-user-pass-verify. Этот скрипт вставляет имя пользователя без кавычек в программу awk, поэтому имя пользователя, содержащее двойную кавычку, закрывает строковый литерал awk, в который оно вставлено, а остаток разбирается как исходный код awk.
Блок BEGIN в awk выполняется один раз до чтения первой строки ввода, поэтому внедрённый вызов system() выполняется до того, как отправленный пароль будет с чем-либо сравнён, с правами root.
Сервер не требует клиентского сертификата и не содержит ключа tls-auth или tls-crypt, а его сертификат CA жёстко зашит в образ прошивки. Файл ca.crt в этом репозитории — это тот самый сертификат, и он идентичен на каждом устройстве с уязвимой прошивкой, поэтому любой злоумышленник, способный достичь порта VPN, может завершить TLS-рукопожатие и добраться до внедрения без учётных данных и без предварительного доступа к устройству.
Имя пользователя не может содержать буквальные пробелы, поскольку оболочка разбивает неэкранированное раскрытие на отдельные аргументы до того, как их увидит awk. Используйте вместо них ${IFS}, которую оболочка, вызванная через system(), раскрывает обратно в пробел. OpenVPN ограничивает имя пользователя 128 байтами; каркас полезной нагрузки использует 22 из них, оставляя 106 для команды.
Данный Proof of Concept (PoC) был протестирован на TP-Link Omada ER7212PC v2 (прошивка 6.1.0.19). Уязвимый скрипт является общим для всей линейки шлюзов Omada; пути, номера строк и поведение могут отличаться на других моделях или версиях прошивки.
Данный PoC доставляет полезную нагрузку в имени пользователя, которая выполняется с правами root на целевом устройстве. Об этой проблеме было сообщено в TP-Link, и она была исправлена в версиях прошивки, перечисленных в рекомендациях по безопасности; запускайте это только против оборудования, которым вы владеете или на тестирование которого у вас есть явное разрешение.
$ sudo python3 cve-2026-19586.py <target> -c '<command>'
Требуется клиент openvpn, и его необходимо запускать с правами root, поскольку ему нужен CAP_NET_ADMIN для создания tun-устройства. Это требование локального клиента OpenVPN, а не целевого устройства.
Пример запуска:
$ 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]
Команда выполняется на устройстве до завершения аутентификации, поэтому сам клиент OpenVPN не подключится. Попытка аутентификации завершается неудачей, и клиент завершает работу, что и ожидается.
| Аргумент | Описание |
|---|
target | IP-адрес или имя хоста целевого устройства |
-c, --command | Команда для выполнения с правами root на цели. Используйте ${IFS} вместо пробелов |
-p, --port | UDP-порт SSL VPN (по умолчанию: 1194) |
--ca | Сертификат CA, извлечённый из прошивки (по умолчанию: ca.crt) |