
Detector não destrutivo para CVE-2026-64638 (XSS2Shell) — primitiva de reflexão XSS pré-autenticação em WordPress
Detector não destrutivo e sem dependências para a primitiva de reflexão da CVE-2026-64638 ("XSS2Shell") no wp-login.php do WordPress.
A CVE-2026-64638 é um XSS refletido de pré-autenticação no núcleo do WordPress, divulgada pela PWN.AI em 07/08/2026 (CVSS 8.9, CWE-79) e corrigida na versão 7.0.3 com backports para todos os ramos mantidos (6.9.6, 6.8.7, 6.7.6, 6.6.6, 6.5.9, …).
A causa raiz é uma divergência de parser entre o strip_tags() do PHP e o sanitizador KSES do WordPress:
strip_tags() se recusa a reconhecer uma tag quando há espaço em branco após <, então um nome de usuário como < area id=x> sobrevive como texto simples.<area id="x"> vivo dentro da mensagem de erro de login.Isso resulta em injeção de DOM escolhida pelo atacante com atributos id// selecionados — a primitiva por trás da cadeia de múltiplos estágios publicada (DOM clobbering → REST JSONP → roubo de senhas de aplicativo → upload de plugin → RCE contra uma vítima administradora logada).
classhrefDuas sondas não destrutivas (uma tentativa de login malsucedida com um nome de usuário marcador aleatório):
<b>marker</b> aparece sem escape na resposta de erro.< area id=marker> sobrevive ao strip_tags() e reaparece como um elemento vivo/normalizado (ex.: area id="marker") na resposta.Nenhum payload executa nada; a ferramenta apenas verifica se o HTML do atacante é renderizado como DOM vivo. Extras opcionais:
--version — identifica a versão do núcleo via a tag <generator> do feed.--jsonp — verifica se o envelope REST JSONP (_jsonp/_envelope) usado pela cadeia publicada está acessível.python3 xss2shell_check.py https://example.com
python3 xss2shell_check.py --jsonp --verbose https://example.com
python3 xss2shell_check.py --version https://example.com
python3 xss2shell_check.py --json https://example.com
Python 3.6+, apenas stdlib. Sem dependências.
| Flag | Finalidade |
|---|---|
--version | identifica a versão do núcleo (tag generator do feed, fallback meta da homepage) |
--jsonp | também verifica se o envelope REST JSONP (_jsonp/_envelope) está acessível |
-v, --verbose | exibe trechos das respostas das sondas (evidências para relatórios) |
--json | resultado JSON legível por máquina (CI / automação) |
| Código | Significado |
|---|---|
| 0 | VULNERÁVEL (primitiva de reflexão presente) |
| 1 | CORRIGIDO / NÃO VULNERÁVEL |
| 2 | ERRO (inalcançável, desafio WAF, resposta inesperada) |
| Comportamento observado | Veredito | Saída |
|---|---|---|
<b>marker</b> ecoado sem escape | RAW_HTML — vulnerável | 0 |
< area id=marker> re-parseado em um <area id="marker"> vivo (qualquer estilo de aspas / forma void) | AREA_BYPASS — vulnerável | 0 |
| Nome de usuário com escape HTML | ESCAPED — não vulnerável | 1 |
| Tags removidas, texto permanece | STRIPPED — não vulnerável | 1 |
< area …> bruto passa adiante, mas nunca é re-parseado | RAW_TEXT_ONLY — texto inerte, não vulnerável | 1 |
| Nenhum eco | NOT_REFLECTED — não vulnerável | 1 |
| Sonda bloqueada (HTTP ≥ 400 / página de desafio) ou alvo inalcançável | ERROR | 2 |
<area id="…">). As aspas dos atributos variam conforme a geração do KSES (parser customizado antigo: <area id=x>; DOMDocument: <area id="x"> / <area id="x" />), portanto todas as formas são reconhecidas. Um < area …> bruto que passa sem re-parse é texto inerte no navegador, não a primitiva — ele é reportado como RAW_TEXT_ONLY e não gera falso positivo.login_errors personalizado ou CDN/WAF reescrever as respostas, ou se o erro de login nunca ecoar o nome de usuário.Apenas testes de segurança autorizados. Esta ferramenta destina-se exclusivamente a testar sistemas que você possui ou para os quais você tem permissão explícita por escrito para avaliar. Testes não autorizados são ilegais na maioria das jurisdições.