Hi GNU Inetutils / Savannah Security Team,
I would like to report a security vulnerability in GNU Inetutils telnetd.
Summary
The telnetd server has a buffer overflow in the LINEMODE SLC (Set Local Characters) suboption handler. An unauthenticated attacker can trigger it by connecting to port 23 and sending a crafted SLC suboption with many triplets. No login is required; the bug
is hit during option negotiation, before the login prompt. The overflow corrupts memory and can be turned into arbitrary writes. In practice this can lead to remote code execution. Because telnetd usually runs as root (e.g. under inetd or xinetd), a successful
exploit would give the attacker full control of the system.
Affected Component
telnetd/slc.c (functions add_slc, process_slc, do_opt_slc; buffer slcbuf at line 59)
Versions: All GNU Inetutils through 2.7, including current development HEAD. Any telnetd derived from the BSD codebase that still uses this SLC implementation may also be affected.
Root Cause
The SLC response is built in a fixed 108-byte buffer, slcbuf, with only 104 bytes used for data after a 4-byte header. The function add_slc() (lines 162-175) appends 3 bytes per SLC triplet but never checks whether the buffer is full. The pointer slcptr is just incremented each time.
When the server gets an SLC suboption, it calls process_slc() for each triplet. For any triplet with function code greater than 18 (NSLC), the server calls add_slc() to queue a "not supported" reply. There is no limit on how many such replies are queued.
The client can send a long SLC suboption (the suboption buffer is 512 bytes, so about 170 triplets). After about 35 triplets with func > 18, the 104-byte space is exceeded and the code writes past the end of slcbuf. That corrupts whatever lies after it in BSS
(including the slcptr pointer). Later, end_slc() uses the corrupted slcptr to write the suboption end marker, which gives the attacker an arbitrary write in memory. So the bug is a classic buffer overflow with no bounds check (CWE-120, CWE-787).
Impact
CVSS 3.1: AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (9.8 Critical)
CWE-120 (Buffer Copy without Checking Size of Input), CWE-787 (Out-of-bounds Write)
Any unauthenticated attacker with network access to port 23 can trigger the overflow with a single telnet connection and a crafted SLC suboption.
Successful exploitation can lead to arbitrary code execution as root and full compromise of the host (backdoors, data exfiltration, pivot, etc.).
Proof of Concept
1. Start GNU Inetutils telnetd (e.g. with inetd or run telnetd manually) so it listens on port 23.
2. From another machine, connect to the telnet port and complete the initial handshake. When the server sends DO LINEMODE, reply with WILL LINEMODE so the server enters LINEMODE negotiation.
3. Send a single LINEMODE SLC suboption containing at least 40 to 50 triplets, each with a function code greater than 18 (e.g. 19, 20, 21, ... 68). Each triplet is 3 bytes (func, flag, value). Use 0x00 for flag and value. The suboption must be properly framed with IAC SB LINEMODE LM_SLC at the start and IAC SE at the end.
4. The server will call add_slc() for each triplet. After about 35 triplets it will write past the end of slcbuf. You should observe a crash, or (if you craft the overflow) memory corruption and possibly code execution.
Credit Request
We kindly request that the following researchers be credited for this discovery:
Adiel Sol, Arad Inbar, Erez Cohen, Nir Somech, Ben Grinberg, Daniel Lubel - DREAM Security Research Team
Best regards,
DREAM Security Research Team