## https://sploitus.com/exploit?id=E8D3D809-C0D7-50FE-9708-4AA43EF9D6CA
# CVE-2026-24061 - telnetd auth bypass
## o co chodzi
argument injection w `telnetd` z GNU InetUtils. Wersje 1.9.3 do 2.7. CVSS 9.8. W CISA KEV od 26.01.2026, czyli aktywnie eksploitowane na wolnosci.
Caly trick polega na tym ze telnetd bierze wartosc zmiennej srodowiskowej `USER` od klienta przez NEW-ENVIRON (RFC 1572) i wkleja ja bez zadnej walidacji prosto do wywolania `login(1)`. Jesli klient wysle `USER="-f root"`, to telnetd uruchomi:
```
/usr/bin/login -p -h -f root
```
Flaga `-f` w login oznacza "zaloguj tego usera bez hasla". Shell roota, zero uwierzytelniania.
## mechanizm
W `telnetd/telnetd.c` jest szablon wywolania login:
```c
char *login_invocation = PATH_LOGIN " -p -h %h %?u{-f %u}{%U}";
```
`%u` to user z autentykacji telnet (zaufany). `%U` to raw wartosc env `USER` od klienta (niezaufany). Kiedy autentykacja nie jest aktywna, uzywa sie `%U`.
Ekspansja zmiennych siedzi w `telnetd/utility.c`, funkcja `_var_short_name`:
```c
case 'U':
return getenv("USER") ? xstrdup(getenv("USER")) : xstrdup("");
```
Zero filtrowania. Cokolwiek klient wysle w USER leci prosto do command line login. Nie tylko `-f root` dziala, teoretycznie kazdy argument ktory login akceptuje mozna wstrzyknac.
Bug wprowadzony w upsreamowym safe-guard commicie z 2015-03-19 (`fa3245ac`). Ironicznie, ten commit mial poprawic obsluge zmiennej USER. Debian mial patch na to w 2019 (`0028-telnetd-Scrub-USER-from-environment.patch`), ale przy fixie CVE-2020-10188 w Debian 10 patch sie zgubil i bug wrocil. Wiec podatne sa tez Debian 10+, Ubuntu i pochodne.
## jak dziala poc
`main.py` to minimalny klient telnet ktory:
1. laczy sie na port 23
2. w negocjacji akceptuje NEW-ENVIRON, reszta opcji WONT
3. na request SEND odpowiada `IAC SB NEW_ENVIRON IS VAR "USER" VALUE "-f root" IAC SE`
4. telnetd odpala `login -f root`, dostajesz shell
5. dalej dziala jak interaktywna sesja, filtruje IAC i ANSI escape z outputu
```
klient serwer
|--- tcp connect ------------------->|
||
||
| [telnetd: login -p -h x -f root]|
|
python3 main.py -p
```
Ctrl+C konczy sesje.
## co nie robic
Nie probuj tego na systemach ktore nie maja `inetutils-telnetd`. Pakiet `telnetd` z netkit to inny kod, nie jest podatny na ten konkretny bug. Jesli polaczysz sie i dostajesz normalny login prompt zamiast shella to albo serwer ma juz patch, albo to nie jest inetutils telnetd.
Nie zmieniaj payloadu na `-f ` oczekujac ze zadziala na kazdym systemie. login(1) z niektorych dystrybucji ma dodatkowe ograniczenia na `-f`. Na standardowym Debian/Ubuntu `-f root` dziala bez problemu.
## dotykane wersje
| soft | wersje |
|---|---|
| GNU InetUtils | 1.9.3 - 2.7 |
| Debian 10+ | inetutils-telnetd (do patcha) |
| Debian 11 | naprawione w 2:2.0-1+deb11u3 |
| Ubuntu | inetutils-telnetd (do patcha) |
## patch
Oficjalny fix dodaje funkcje `sanitize()` ktora odrzuca wartosci zaczynajace sie od `-` albo zawierajace shell metachars. Zastosowana do wszystkich zmiennych w ekspansji, nie tylko USER.
```c
static char *
sanitize (const char *u)
{
if (u && *u != '-' && !u[strcspn(u, "\t\n !\"#$&'()*;?[\\^`{|}~")])
return u;
else
return "";
}
```
- `fd702c0` - patch USER
- `ccba9f7` - sanityzacja wszystkich zmiennych