Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Einreichen
ToolsExploitsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

FeedsKontaktDatenschutz© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2026-87902 — Python-PoC, das CVE-2026-87902 ausnutzt, einen unauthentifizierten Path Traversal in WordPress locate_template(), der zu LFI und PEAR-basierter RCE führt, mit sicherem Erkennungsmodus. | Kitploit
Tools/GitHubGitHub/crowsec-edtech/cve-2026-87902
SchwachstellenanalyseExploitationWebanwendungs-ExploitationWebsicherheitPenetrationstestsRemote-Access-ToolPayload-EntwicklungLabs & Praxis
GitHubcrowsec-edtech/cve-2026-87902

CVE-2026-87902

Python-PoC, das CVE-2026-87902 ausnutzt, einen unauthentifizierten Path Traversal in WordPress locate_template(), der zu LFI und PEAR-basierter RCE führt, mit sicherem Erkennungsmodus.

342vor 24 TagenNoch nicht geprüft
Repository anzeigen

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

CVE-2026-87902 — PoC: nicht authentifizierter Path Traversal bei der Auflösung von page-template in WordPress

Exploit-Datei: exploit_locate_template_rce.py — Python 3.6+ (nur stdlib).

Pipeline in einem einzigen Befehl: sichere Erkennung (LFI-Differential, ohne Schreiben) →, falls verwundbar, RCE über das Gadget pearcmd.php, das den Befehl Ihrer Wahl ausführt (--command/-c). Verwenden Sie --validate-only, um vor der Schreibphase zu stoppen.

Testet CVE-2026-87902 in WordPress-Versionen ohne den Fix des Commits 5fde0bb7 — "Themes: Restrict path traversal in locate_template()" (WordPress 7.1.2, Backports bis 4.7.37).

CVECVE-2026-87902 (CWE-98, CVSS 4.0 9.2 Critical / v3.1 8.1 High)
AdvisoryGHSA-7hp8-65ch-5whp
BetroffenWordPress 4.7.0 – 7.1.1 (alle Branches)
Fix7.1.2, 7.0.6, 6.9.9 … 4.7.37
Fix-Commit5fde0bb7b9775523959094bf280cc54bfa78af51 (Merge des Changesets 63792)
Dateienwp-includes/template.php (get_page_template(), locate_template(), _wp_is_template_path_allowed())
AuthentifizierungKeine — kein Benutzer, Cookie, Nonce oder Plugin
CreditsEntdeckung und Disclosure: Robert Ressl

⚠️ Nur für autorisierte Tests. Verwenden Sie es in Umgebungen, die Sie kontrollieren (das folgende Lab ist isoliert) oder mit ausdrücklicher Genehmigung des Eigentümers.


1. Die Schwachstelle

In Versionen ohne den Fix stellt die Verkettung get_page_template() → locate_template() → template-loader niemals sicher, dass das ausgewählte Template innerhalb des Themes bleibt.

Vor dem Fix (wp-includes/template.php):

// get_page_template(): decode TARDE, sem validate_file()
$pagename_decoded = urldecode( $pagename );
if ( $pagename_decoded !== $pagename ) {
    $templates[] = "page-{$pagename_decoded}.php";
}

// locate_template(): só testa existência — nenhum confinamento de caminho
if ( file_exists( $wp_stylesheet_path . '/' . $template_name ) ) {
    $located = $wp_stylesheet_path . '/' . $template_name;
    break;
}

Nach dem Fix (Commit 5fde0bb7):

if ( $pagename_decoded !== $pagename && 0 === validate_file( $pagename_decoded ) ) { ... }
...
if ( _wp_is_template_path_allowed( $candidate ) ) {   // realpath + confinamento
    $located = $candidate;                            // dentro de tema/parent/theme-compat
    break;
}

Exploit-Kette (Repository-Code)

  1. pagename und page_id sind öffentliche Query-Vars — akzeptiert im Body eines anonymen POST. Die POST-Methode lässt redirect_canonical() (canonical.php) früh zurückkehren — es wirkt nur bei GET/HEAD, also wird nichts umgeleitet.
  2. Der Traversal ist doppelt kodiert (templates%252f%252e%252e%252f...) und übersteht das Sanitizing: WP_Query::get_posts() (Z.2191) schreibt den pagename mit sanitize_title_for_query( wp_basename( ... ) ) um — wp_basename() bricht nicht bei %2F (formatting.php Z.5768) und das Sanitizing bewahrt %XX-Oktette (Z.2395).
  3. page_id (Z.2252) überschreibt das WHERE ("$where =", nicht ".=") — die echte Seite wird geladen, kein 404, und der bösartige pagename bleibt im Query-Objekt.
  4. get_page_template() führt ein spätes urldecode() aus und baut page-<traversal>.php ohne validate_file().
  5. locate_template() ruft vor dem Patch nur file_exists() auf → der Include entkommt aus dem Theme.

Voraussetzungen

#VoraussetzungGrund
1Veröffentlichte Seite, anonym zugänglich, über page_id auswählbar und ohne custom templateDie Anfrage muss zu einer Page aufgelöst werden; ein custom template käme früher in der Hierarchie
2Top-Level-Verzeichnis im aktiven Theme (Child oder Parent), das mit page- beginnt (z. B. page-templates/)WP stellt das feste Präfix page- voran; darüber gelangt der Traversal hinein. Es genügt, dass es existiert und traversierbar ist (kann leer sein). Vorhanden in Twenty Twelve/Fourteen, Neve, Hestia, Sydney
3Lokales .php-Ziel existiert und ist lesbarDer Loader hängt .php an und prüft is_file()/is_readable()
4(nur für RCE) pearcmd.php lesbar + register_argc_argv=On + beschreibbares Verzeichnis (z. B. /tmp)PEAR→RCE-Route: config-create schreibt die PHP-Payload auf den Server

2. Was das Skript tut

Stufe 1 — sichere Erkennung (läuft immer zuerst)

Drei anonyme POSTs gegen die veröffentlichte Seite — ohne Schreiben auf die Festplatte:

AnfragepagenameErwartete Antwort (verwundbar)
A — Baseline—200, normaler Body (~23 KB)
B — KontrolleTraversal → nicht existierende Datei200, normaler Body (Fallback page.php)
C — ProbeTraversal → wp-content/index.php ("Silence is golden")200 mit leerem Body

Signatur: C leer + A/B normal ⇒ der Include ist aus dem Theme entkommen ⇒ VERWUNDBAR. Die Erkennung durchsucht automatisch: Kandidaten-Theme-Verzeichnisse (page-templates, page-template) × Tiefen 1–12. Das Ergebnis (theme-dir + depth) speist die RCE-Stufe.

Mit --validate-only stoppt das Skript hier (Exit 0, falls verwundbar).

Stufe 2 — RCE über pearcmd.php (Schreiben)

Stufe 1  POST /?+config-create+/<payload>+/tmp/wp-pear-rce.php
           body: page_id=2&pagename=templates%252f...%252fusr%252flocal%252flib%252fphp%252fpearcmd
           → der Traversal inkludiert /usr/local/lib/php/pearcmd.php
           → argv kommt aus dem rohen Query-String (register_argc_argv=On)
           → config-create SCHREIBT die Payload nach /tmp/wp-pear-rce.php (12 serialisierte Kopien)

Stufe 2  POST /  body: page_id=2&pagename=templates%252f...%252ftmp%252fwp-pear-rce
           → derselbe Traversal inkludiert die erzeugte Datei → system(<--command>) läuft als www-data

Formatdetails (alle Einschränkungen werden vom Skript behandelt):

  • POST, nicht GET: Der Body trägt page_id + pagename; der Query-String trägt ausschließlich das argv von PEAR (?+config-create+<root>+<out>).
  • Payload ohne jegliches Anführungszeichen: wp_magic_quotes() (load.php Z.1290) wendet add_magic_quotes($_SERVER) an und pearcmd liest das argv aus $_SERVER['argv'] — jedes Anführungszeichen würde zu \' werden und die erzeugte Datei beschädigen. Jeder PHP-String wird zu chr()-Verkettung: '/tmp' → chr(47).chr(116).chr(109).chr(112).
  • Byte-exaktes Request-Target (http.client): Die rohen Bytes +, <, > des Query-Strings sind das argv — nichts darf auf dem Weg neu geschrieben/neu kodiert werden.
  • config-create erfordert einen absoluten Root-Pfad — die Payload wird als der Root selbst injiziert (/<php>), präfixiert mit dem Marker ___WP_RCE_OK___, der die Ausgabe abgrenzt.
  • Die RCE probiert Tiefen ab der erkannten (interne Reihenfolge 7, 6, 8, 5, …) und mehrere Pfade zu pearcmd.php (offizielles Docker, Debian/Ubuntu, XAMPP) — bei Bedarf mit --pear-path/--output anpassen.

Es gibt keinen "Upload": Das Ziel der Erkennung ist eine Datei, die jedes WordPress von Werk aus mitbringt (wp-content/index.php); die RCE-Payload wird vom Server selbst über das PEAR-Gadget geschrieben, das als www-data läuft.


3. Verwendung

# 1) Só validar a vulnerabilidade (LFI probe, sem escrita)
python exploit_locate_template_rce.py --url http://127.0.0.1:8080 --validate-only
Tool herunterladen