
Verifica o WordPress Core 4.7.0–7.1.1 em busca de LFI não autenticado (CVE-2026-87902) por meio de travessia de pagename com dupla codificação, com escalonamento opcional para RCE via PEAR config-create e varredura em massa.
Ferramenta de Exploração de Path Traversal em get_page_template() / locate_template() do Núcleo do WordPress
Apenas para testes de segurança autorizados. O acesso não autorizado a sistemas computacionais é ilegal.
| Item | Detalhes |
|---|---|
| ID CVE | CVE-2026-87902 |
| ID GHSA | GHSA-7hp8-65ch-5whp |
| Tipo de Vulnerabilidade | CWE-98 — Controle Impróprio de Nome de Arquivo para Include/Require |
| CVSS v3.1 | 8.1 (Alta) / CVSS 4.0: 9.2 (Crítica) |
| Componente Afetado | Núcleo do WordPress |
| Versões Afetadas | 4.7.0 até 7.1.1 (todos os ramos) |
| Versões Corrigidas | 7.1.2 (e backports até 4.7.37) |
| Autenticação Necessária | Nenhuma (Não Autenticada) |
| Vetor de Ataque | Uma única requisição GET |
| Descoberto Por | Robert Ressl (via programa HackerOne do WordPress) |
| Data de Divulgação | 22 de setembro de 2026 |
| Explorada em Ambiente Real | Sim — listada no catálogo CISA KEV |
CVE-2026-87902 é uma vulnerabilidade de path traversal e inclusão local de arquivo (LFI) não autenticada no Núcleo do WordPress que afeta todas as versões do WordPress lançadas desde 2016 (4.7.0 a 7.1.1). Um atacante não precisa de conta ou autenticação. Ao forjar um parâmetro de consulta pagename malicioso, o atacante pode fazer com que o mecanismo de resolução de template de página do WordPress inclua qualquer arquivo .php legível fora do diretório do tema ativo. Sob condições específicas do servidor (PHP register_argc_argv = On e um pearcmd.php legível), a vulnerabilidade pode ser escalada para execução remota de código (RCE).
| Ramo | Versão Corrigida |
|---|---|
| 4.7.x | 4.7.37 |
| 5.0.x | 5.0.29 |
| 5.3.x | 5.3.25 |
| 5.9.x | 5.9.18 |
| 6.0.x | 6.0.16 |
| 6.6.x | 6.6.9 |
| 6.9.x | 6.9.9 |
| 7.0.x | 7.0.6 |
| 7.1.x | 7.1.2 |
A vulnerabilidade reside em get_page_template() em wp-includes/template.php. Quando a variável de consulta pagename está presente, a função constrói page-{$pagename}.php, mas falha em chamar validate_file() sobre esse valor para verificar path traversal de diretório. O nome de arquivo candidato é então passado para locate_template(), que o concatena com o caminho do diretório do tema e apenas verifica file_exists() — não verifica se o caminho resolvido permanece dentro do diretório do tema. Um nome de template contendo ../ pode, portanto, resolver para um arquivo PHP legível fora do tema ativo e ser incluído e executado.
GET /?page_id=&pagename= → WP_Query resolves page_id, matches a published page (avoids 404) → get_page_template() urldecode()s pagename, builds page-{$pagename}.php → locate_template() concatenates candidate to theme directory, resolves via file_exists() → template-loader executes realpath() + include
O WordPress aplica sanitize_title_for_query() a pagename, que substitui pontos literais (.) por hífens (-) para bloquear path traversal. Ela opera sobre a entrada já decodificada uma vez e não decodifica recursivamente. O atacante envia %252e%252e%252f (../ com dupla codificação):
%252e → %2e, %252f → %2fsanitize_title_for_query() vê %2e%2e%2f (sem pontos literais) e o deixa passarget_page_template() chama internamente urldecode() novamente: %2e%2e%2f → ../page- (por exemplo, page-templates/).page_id..php (o WordPress acrescenta a extensão).Nota sobre Hosts Windows: O Win32 normaliza .. lexicalmente, então o path traversal pode funcionar mesmo que o diretório page- não exista. No Linux, esse diretório deve existir de fato.
Condições:
register_argc_argv do PHP está definido como Onpearcmd.php legível no servidorO atacante inclui pearcmd.php via LFI e abusa do seu comando config-create para gravar um arquivo PHP no servidor, e então inclui esse arquivo novamente via LFI para executar comandos arbitrários.
A CVE-2026-87902 foi descoberta e reportada por Robert Ressl, um pesquisador de segurança baseado na Suíça.
Reportada por meio do programa HackerOne do WordPress em julho de 2026. A Equipe de Segurança do WordPress coordenou a correção e a lançou junto com o WordPress 7.1.2 em 22 de setembro de 2026.
| Data | Evento |
|---|---|
| Julho de 2026 | Robert Ressl reporta a vulnerabilidade por meio do programa HackerOne do WordPress |
| 22 de setembro de 2026 | WordPress 7.1.2 lançado com a correção; aviso publicado |
| 22 de setembro de 2026 | Backports de segurança lançados para os branches 7.0 até 4.7 |
| 23 de setembro de 2026 | Atacantes começam a sondar sites vulneráveis |
| 25 de setembro de 2026 | CISA adiciona a CVE-2026-87902 ao catálogo KEV |
| Recurso | Descrição |
|---|---|
| Fingerprinting de Versão | Identifica a versão do WordPress via meta generator, feed RSS, OPML, readme.html, ?ver= de assets |
| Veredito Inteligente de Versão | Usa mapeamento de versões corrigidas para determinar se o alvo está no intervalo afetado |
| Descoberta de Tema | Extrai o slug do tema ativo, detecta o tema pai, descobre diretórios page-* |
| Descoberta de Page ID | Encontra IDs de página válidos via REST API, classe de corpo page-id-, shortlinks |
| Validação de Oráculo LFI | Usa arquivos seguros como wp-links-opml.php e wp-trackback.php como oráculos com controles negativos |
| Travessia com Dupla Codificação | Codifica automaticamente em dupla porcentagem / e . para contornar sanitize_title_for_query() |
| Exploração de RCE via PEAR | Tenta caminhos PEAR comuns, grava e executa arquivos marcadores via config-create |
| Varredura em Massa | Varredura concorrente multithread de listas de alvos |
| Saída de Resultados | Persiste resultados em vuln_lfi.txt e vuln_lfitorce.txt |
pip install requests
python3 CVE-2026-87902.py
Menu interativo:
[1] Single Scan LFI [2] Single Scan LFI + RCE [3] Mass Scan LFI [4] Mass Scan LFI + RCE [5] Exit
Escolha [1], insira a URL do alvo:
url > https://target.example.com
Escolha [2], insira a URL e o comando (padrão id):
url > https://target.example.com cmd > id
Escolha [3] ou [4], insira o arquivo contendo as URLs dos alvos (uma por linha, # para comentários):
file > targets.txt
| Arquivo | Conteúdo |
|---|---|
| vuln_lfi.txt | Alvos com LFI confirmado |
| vuln_lfitorce.txt | Alvos com RCE bem-sucedido |
TIMEOUT = 8 # Request timeout (seconds) THREADS = 200 # Concurrent threads for mass scanning USE_ALL_ORACLES = False # Use all oracles (more accurate but slower)