Critical Telnet Vulnerability Enables Unauthenticated Root Access After 27 Years; Urgent Fixes Needed

Critical 27-Year-Old Telnet Vulnerability Grants Unauthenticated Root Access

A recently identified vulnerability in the telnet daemon (telnetd) within GNU Inetutils has resurrected a 27-year-old security flaw, enabling attackers to gain root access by exploiting improper sanitization of environment variables, all without requiring authentication.

Designated as CVE-2026-24061, this flaw is present in GNU Inetutils up to version 2.7. It allows remote authentication bypass when a malicious client supplies `-f root` as the value for the `USER` environment variable.

Security researcher Ron Ben Yizhak’s discovery prompted a deeper investigation into whether the remnants of CVE-1999-0073—a 1999 vulnerability that permitted attackers to inject environment variables like `LD_LIBRARY_PATH` to subvert system libraries—still lingered in modern telnet implementations.

The core issue lies in how telnetd launches `/bin/login`. Both processes operate in a root-to-root context, causing the Linux kernel to set `AT_SECURE` to 0 in the process’s auxiliary vector.

This value is critical; when positive, `AT_SECURE` signals the dynamic linker (`ld-linux.so`) and glibc to enter secure-execution mode, which automatically discards or neutralizes dangerous environment variables like `LD_LIBRARY_PATH`, `GCONV_PATH`, and others.

With `AT_SECURE` at zero, the dynamic linker treats the session as fully trusted, meaning every environment variable passed by a telnet client is accepted without restriction. This shifts the burden of sanitization entirely onto telnetd itself—a responsibility it fails to meet.

Although a recent commit (`4db2f19f`) introduced `unsetenv(CREDENTIALS_DIRECTORY)` to address part of the problem, the fix remains dangerously incomplete. Telnetd currently attempts to block harmful variables using a blacklist approach, filtering by prefix or full variable name. Researchers have confirmed this is insufficient.

An attacker can inject GNU gettext-specific variables such as `OUTPUT_CHARSET` and `LANGUAGE`, alongside the glibc variable `GCONV_PATH`, directly through the telnet protocol. By declaring a character set mismatch (e.g., injecting `ISO-8859-1` against a UTF-8 system), an attacker tricks gettext into calling `iconv_open()`.

Since `AT_SECURE` is 0, `iconv_open()` blindly follows the attacker-supplied `GCONV_PATH` to locate a custom `gconv-modules` file—and from there, loads arbitrary shared objects as root.

Proof of Concept (PoC):

In a demonstrated proof of concept by Justin Swartz, a low-privileged local user (`abuser`) injected environment variables through a standard telnet session to load a malicious shared library (`libcash2trash.so`).

When `/bin/login` attempted to display a localized prompt, gettext triggered the exploit chain. The payload executed silently before the connection dropped—copying `/bin/sh` with SUID/SGID permissions.

The resulting binary ran with `euid=0 (root)` and `egid=0 (root)`, granting full root privileges to the unprivileged user. No telnetd authentication was performed or required.

Recommendations:

Researchers suggest consolidating a single CVE for Improper environment sanitization in telnetd to cover both the `CREDENTIALS_DIRECTORY` vector and this dynamic linker escape comprehensively.

The recommended remediation moves away from the flawed blacklist model entirely. Following the OpenSSH AcceptEnv-style approach, building a strict whitelist of safe environment variable names for `/bin/login`, paired with rigorous input sanitization on their values, is considered the only reliable long-term fix.

Organizations still running telnet services are urged to disable telnetd immediately and migrate to SSH. Where telnet cannot be avoided, upgrading GNU Inetutils and applying strict network-level access controls is essential until a comprehensive patch is released.