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é.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-97332-PoC — PoC indépendant et environnement de laboratoire reproductible pour CVE-2026-97332 — divulgation non authentifiée de fichiers privés dans User Private Files < 2.2.0 sur WordPress Multisite. | Kitploit
Outils/GitHubGitHub/kolya080808/cve-2026-97332-poc
Outils DéfensifsAnalyse des VulnérabilitésExploitationExploitation d'Applications WebCollecte d'InformationsSécurité WebTests d'IntrusionLabs et Pratique
GitHub
kolya080808/cve-2026-97332-poc

CVE-2026-97332-PoC

PoC indépendant et environnement de laboratoire reproductible pour CVE-2026-97332 — divulgation non authentifiée de fichiers privés dans User Private Files < 2.2.0 sur WordPress Multisite.

Voir le dépôtSite web
41il 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-97332 — WordPress User Private Files < 2.2.0 Divulgation de fichiers privés sans authentification (Multisite)

CVE Severity Affected Fixed Requires PoC Ethics

[!NOTE] Ce dépôt est une reproduction indépendante et une preuve de concept pour CVE-2026-97332.

Découverte originale de la vulnérabilité : Akshat Parikh (SN1PER). CNA / avis : WPScan. PoC et reproduction indépendantes : Kolya080808.

Divulgation non authentifiée des fichiers privés d'autres utilisateurs dans le plugin WordPress User Private Files (slug wp.org user-private-files) antérieur à 2.2.0 sur les installations multisite. Le plugin stocke les documents privés de chaque utilisateur dans l'arborescence d'uploads en clair et les protège par une unique RewriteRule ajoutée au .htaccess racine, qui fait passer les requêtes de fichiers par une vérification d'accès en PHP. Sur un réseau multisite, cette règle n'est jamais atteinte : un simple GET — sans cookies, sans en-têtes, sans connexion — renvoie le fichier privé d'un autre utilisateur en tant que contenu statique. Contrôle d'accès défaillant, CWE-284, CVSS 3.1 5.3 (AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N).

Ce dépôt contient un exploit Python fonctionnel et sans dépendances, ainsi qu'un lab Docker à deux conteneurs (version vulnérable 2.1.9 et version corrigée 2.2.0, toutes deux en WordPress multisite) pour reproduire l'attaque de bout en bout.

[!CAUTION] Ce contenu est fourni uniquement à des fins de recherche en sécurité autorisée et de tests défensifs (voir l'avertissement en bas de page). Attaquer des systèmes que vous ne possédez pas ou n'exploitez pas sans autorisation écrite est illégal.

La vulnérabilité

Le plugin conserve les fichiers privés sous forme de pièces jointes ordinaires dans un sous-répertoire d'uploads plat, propre à chaque site — wp-content/uploads/upf-docs/ (site principal) et wp-content/uploads/sites/N/upf-docs/ (sous-site N) — sans isolation par utilisateur. Le contrôle d'accès ne se situe pas sur le répertoire ; il réside dans le PHP (dl-file.php : 403 pour les utilisateurs anonymes, puis vérification de l'auteur ou de la liste d'autorisation) et n'est atteint que via une règle de réécriture émise à l'activation du plugin dans le .htaccess racine :

# appended by 2.1.9 (upvf_actdeact.php), AFTER the WordPress block
RewriteRule ^wp-content/uploads/upf-docs/(.*)$ https://site/?file=$1 [QSA,L]

Sur un site multisite, cela ne se déclenche jamais, pour deux raisons indépendantes :

  1. Le fichier .htaccess du réseau court-circuite d'abord les fichiers existants. WordPress multisite écrit son propre ensemble de règles dans le fichier .htaccess racine :

    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^ - [L]
    

    Une requête correspondant à un fichier physiquement existant termine la réécriture à cet endroit — Apache le sert comme contenu statique, et mod_rewrite n'atteint jamais le bloc du plugin à la fin du fichier. (WordPress mono-site utilise des conditions négatives !-f/!-d, ce qui explique pourquoi le même plugin fonctionne dans ce cas.) Cela expose déjà les fichiers du site principal du réseau.

  2. Les chemins des sous-sites ne correspondent pas du tout au motif. Sur multisite, chaque site possède ses propres uploads — wp-content/uploads/sites/N/…, plus le préfixe d'URL /siteN/ dans les réseaux en sous-répertoire — alors que la règle est codée en dur sur ^wp-content/uploads/upf-docs/ à partir de l'URL de base du site principal. Même après que la réécriture interne du réseau a retiré le préfixe /siteN/, le segment sites/N/ ne correspond toujours pas.

Ainsi, pour tout réseau multisite (en sous-répertoire comme en sous-domaine), un attaquant non authentifié récupère directement les fichiers privés :

GET /wp-content/uploads/upf-docs/victim.pdf HTTP/1.1            (main site)
GET /site2/wp-content/uploads/sites/2/upf-docs/victim.pdf HTTP/1.1  (subsite)

La réponse est 200 avec le corps du fichier — servi par Apache directement depuis uploads/, la vérification d'accès du plugin n'est jamais exécutée.

Les noms de fichiers sont prévisibles

Rien dans l'URL n'est secret. Le plugin construit les noms à partir de l'identifiant numérique du propriétaire et du timestamp unix (en secondes) de l'upload :

Générateur (2.1.9)Nom sur disque
interface moderne, inc/functions-file.php:73-77usr{ID}_{unixtime}_{original}
template classique, inc/classic-user-functions.phpuser_{ID}_doc_{unixtime}.{ext}

Les identifiants utilisateur sur un réseau multisite sont de petits entiers séquentiels issus d'une table wp_users partagée, donc un attaquant n'a besoin que d'une estimation approximative de l'heure d'upload (une fenêtre de ±2 minutes représente ≈240 requêtes) et soit du nom de fichier original, soit simplement de son extension. Les suffixes de collision (-1, -2) existent mais sont rares.

Le correctif (2.2.0)

La version 2.2.0 a remplacé la réécriture du fichier racine par un .htaccess upf-docs/ au niveau du dossier — RewriteRule ^(.*)$ {home}/?file=$1 [R=302,QSA,L], plus Require all denied lorsque mod_rewrite est absent — recréé à chaque admin_init (auto-réparateur, par sous-site). Une règle par répertoire s'applique à tout chemin physique sous upf-docs/ quel que soit le préfixe de l'URL, donc le GET direct devient désormais un 302 vers la vérification d'accès et, pour les utilisateurs anonymes, un 403. Les fichiers ne sont pas déplacés ; seul le mécanisme d'interception change. Cette distinction 302-vs-statique est aussi ce que l'exploit utilise comme détecteur comportemental.

Versions affectées

  • User Private Files < 2.2.0 (vérifié sur les sources 2.1.9 ; les tags SVN 1.0.1–2.1.9 portent la même conception de réécriture racine)
  • Uniquement les déploiements multisite (sous-répertoire et sous-domaine). Les installations mono-site sont protégées par la règle racine tant qu'Apache lit .htaccess et que le fichier était accessible en écriture à l'activation (nginx nécessite la réécriture manuelle du fournisseur — voir le readme du plugin).
  • Référence : avis WPScan d6a144b3-84e3-43eb-92d3-fd4505dd0e1c (publié le 2026-10-02, chercheur Akshat Parikh / SN1PER).

Fonctionnement de l'exploit

exploit.py est en Python 3 pur, bibliothèque standard uniquement (http.client), ne suit aucune redirection et n'envoie aucun cookie :

Télécharger l’outil