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-2010-4221-lab — De l'exploit à l'exécution de code : exploit artisanal pour CVE-2010-4221 (débordement de pile TELNET IAC dans ProFTPD), avec le parcours complet guidé par les échecs documenté | Kitploit
Outils/GitHubGitHub/diegslva/cve-2010-4221-lab
Frameworks d'ExploitationAnalyse des VulnérabilitésExploitationRétro-ingénierieTests d'IntrusionApprentissage et ÉducationExploitation de BinairesLabs et Pratique
GitHubdiegslva/cve-2010-4221-lab

cve-2010-4221-lab

De l'exploit à l'exécution de code : exploit artisanal pour CVE-2010-4221 (débordement de pile TELNET IAC dans ProFTPD), avec le parcours complet guidé par les échecs documenté

19il y a 21 joursPas encore vérifié
Voir le dépôt

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-2010-4221 — Débordement de pile TELNET IAC dans ProFTPD : du patch au RCE

Un laboratoire entièrement reproductible et un exploit écrit à la main, basé sur des sockets brutes, pour CVE-2010-4221 — le débordement de pile pré-authentification dans pr_netio_telnet_gets() de ProFTPD — conçu comme exercice d'apprentissage en recherche de vulnérabilités et développement d'exploits.

Chaque échec est documenté. Le chemin idéal est un mensonge ; les détours sont la leçon.


Avis légal et éthique — à lire en premier

Ce dépôt est un artefact pédagogique. Il existe pour que les personnes qui ne peuvent pas se permettre un mentor ou une formation puissent apprendre comment un exploit de corruption mémoire naît réellement : d'un patch, à travers les échecs, jusqu'à une preuve de concept fonctionnelle dans un laboratoire qui vous appartient.

Le travail Red Team — la sécurité offensive réelle et professionnelle — se définit par un seul mot : autorisation. Tout ce qu'un professionnel fait se déroule dans le cadre d'un accord écrit : un document signé de règles d'engagement qui nomme le périmètre, les cibles, les techniques autorisées, la fenêtre temporelle et les personnes qui l'ont approuvé. Sans ce papier, les mêmes frappes clavier ne sont pas une profession — ce sont un crime dans pratiquement toutes les juridictions de la planète.

Voici donc le contrat pour ce dépôt, non négociable :

  • Exécutez ceci uniquement contre le laboratoire Docker fourni ou des systèmes qui vous appartiennent.
  • Jamais contre quoi que ce soit sans autorisation écrite et explicite.
  • Si vous apprenez : bienvenue, ceci a été construit pour vous.
  • Si vous cherchez une arme à utiliser contre autrui : fermez cet onglet. Cette faille date de 2010 ; elle ne vous apportera qu'un casier judiciaire.

Le métier vaut la peine d'être appris. Le métier ne vaut quelque chose qu'avec la discipline qui l'accompagne.


La faille

ProFTPD parle les séquences d'échappement TELNET sur le canal de contrôle FTP. En TELNET, 0xFF (IAC, « Interpret As Command ») est l'octet d'échappement ; un 0xFF littéral est envoyé comme 0xFF 0xFF.

pr_netio_telnet_gets() copie les octets du client dans un buffer de pile (char buf[PR_DEFAULT_CMD_BUFSZ+1] de pr_cmd_read, 4104 octets avec MAXPATHLEN=4096 de glibc), en suivant l'espace restant dans buflen — un size_t, non signé.

Le chemin vulnérable (1.3.3a, netio.c) :

case TELNET_IAC:
  switch (cp) {
    ...
    default:
      *bp++ = TELNET_IAC;   // écriture #1
      buflen--;             // décrément #1
      telnet_mode = 0;
      break;
  }
  break;
...
*bp++ = cp;                 // écriture #2
buflen--;                   // décrément #2  <-- aucun contrôle entre les deux

Deux écritures, deux décréments, aucun contrôle de zéro entre eux. Lorsque buflen vaut exactement 1, la paire le décrémente à 0, puis le fait passer sous zéro jusqu'à SIZE_MAX (18 quintillions). La boucle croit désormais que le buffer est infini et continue d'écrire des octets contrôlés par l'attaquant vers le haut de la pile — par-dessus les registres sauvegardés, le RBP sauvegardé et l'adresse de retour.

Pré-authentification. La fonction s'exécute avant que USER/PASS ne soient jamais traités.

Le patch

Le correctif (commit 3cc69b8388, « Bug#3521 - Telnet IAC processing stack overflow », publié dans la 1.3.3c) fait douze lignes. Toute la frontière de sécurité est :

if (buflen == 0) {
  break;
}

Voir patch.diff. Lire le patch vous indique où se trouvait la blessure — c'est cela, la compétence.

Le laboratoire

Le Dockerfile compile ProFTPD 1.3.3a à partir des sources historiques du snapshot Debian, délibérément non sécurisé (voilà à quoi ressemblait 2010) :

  • -fno-stack-protector — pas de canari
  • -z execstack — pile exécutable (pas de NX)
  • -no-pie — adresses binaires fixes
  • exécution sous gdb, qui désactive l'ASLR par défaut → pile déterministe
docker build -t proftpd-133a .
docker rm -f lab133 2>/dev/null
docker run -d --name lab133 --cap-add SYS_PTRACE \
  --security-opt seccomp=unconfined -p 127.0.0.1:2122:21 \
  proftpd-133a sh -c 'gdb -batch -ex "set follow-fork-mode child" \
  -ex "run" -ex "continue" --args /usr/local/sbin/proftpd -n -d1 \
  > /tmp/gdb.txt 2>&1; sleep 600'
python3 exploit.py

Sortie attendue :

[S] 220 ProFTPD 1.3.3a Server (lab-iac) ...
[S] THE SERVER SAID: b'PWNED!!PWNED!!'

(Le shellcode écrit sur les descripteurs 0, 1 et 2 car nous ne voulions pas dépendre de la connaissance de celui qui porte le canal de contrôle — deux d'entre eux répondent.)

L'architecture de l'exploit

"SITE " + NOP sled + shellcode + [inondation \xff\xff] + padding + [ret] + "\n"
 ^^^^^^^^^^^^^^^^^^^^                             ^^^^
 le shellcode vit DANS le buffer                la queue du débordement ne
 de commande — la région que personne            délivre QU'UNE adresse
 ne touche
  1. « SITE » maintient l'analyseur FTP en vie — la commande se traite proprement.
  2. Le shellcode est le contenu de la commande. Le buffer est l'endroit le plus sûr de la pile : après la lecture, seul buf[4102] est touché (NUL de troncature). Tout ce qui se trouve sous les variables locales vivantes du cadre est calme.
  3. L'inondation IAC conduit buflen au passage sous zéro (voir « Le voyage » pour le problème de parité).
  4. L'emplacement ret (buf + 4152) reçoit l'adresse du milieu du NOP sled. Lorsque pr_cmd_read atteint return 0 après l'analyse, le CPU atterrit dans le sled et glisse dans le shellcode.

Cette architecture inversée — payload d'abord, inondation ensuite, adresse en dernier — a été validée contre le module Metasploit canonique (proftp_telnet_iac), qui utilise la même disposition. Leurs cibles avaient NX, ils avaient donc besoin d'une chaîne ROP avec un « quadruple déréférencement » du pointeur res ; notre laboratoire a une pile exécutable, donc un simple retour direct suffit.

Le voyage (le véritable intérêt de ce dépôt)

L'exploit final fait 60 lignes. Ce qu'il a coûté :

  1. Inondation \xff aveugle → rien. Le serveur a poliment fermé la session. Cause racine : buflen commence à 4102 (PAIR) et chaque paire IAC décrémente de 2 — il atterrit proprement sur 0, jamais sur 1. Le passage sous zéro nécessite une parité brisée. Leçon : lire la machine à états vaut mieux que d'arroser.

  2. Mauvaise taille de buffer. La première tentative calibrée supposait un buffer de 1024 octets. Le vrai fait MAXPATHLEN+8 = 4104 sous Linux/glibc. L'inondation s'est arrêtée 3 Ko avant la cible. Leçon : mesurez la cible, ne supposez pas la cible.

  3. Premier SIGSEGV. Le motif cyclique de Bruijn (Aa0Aa1...) a placé l' emplacement de retour à buf+4152, validé deux fois (calcul du cadre + décalage du motif). Leçon : le motif cyclique est un mètre ruban, pas un exploit.

  4. Contrôle de RIP. Régler l'emplacement à 0x4141414141414141 a fait planter l'instruction ret elle-même — x86-64 refuse les adresses non canoniques, et le défaut atterrit sur ret, avec notre valeur en attente dans la backtrace. Leçon : un crash sur ret avec votre valeur dans le cadre = contrôle.

  5. Shellcode au-dessus de l'emplacement ret → écrasé. 8 octets écrasés par un pointeur de tas (0x4d7838 — identifié plus tard comme l'allocation du pool cmd_rec). Les cadres de pile au-dessus de l'emplacement appartiennent à des fonctions qui continuent de travailler entre l'atterrissage et le détournement. Leçon : le débordement n'est pas la dernière écriture ; le programme continue de vivre sur la pile que vous venez de vandaliser.

Télécharger l’outil