A 32-year-old buffer overflow walks into a server that 99% of enterprises already unplugged
CVE-2026-32746 is a classic BSS-segment buffer overflow in the add_slc() function within telnetd/slc.c of GNU inetutils through version 2.7. During LINEMODE SLC (Set Local Characters) negotiation — which happens *before* any authentication — the server appends 3-byte triplets to a fixed 108-byte slcbuf buffer without bounds checking. An unauthenticated attacker on the network can send 40+ crafted SLC triplets during the Telnet option handshake to overflow this buffer and corrupt adjacent BSS variables including slcptr, slcchange, and critically the def_slcbuf pointer. The vulnerability was discovered by the DREAM Security Research Team (Adiel Sol, Arad Inbar, Erez Cohen, Nir Somech, Ben Grinberg, Daniel Lubel) and disclosed on 2026-03-13. Affected: all GNU inetutils versions through 2.7. Patches are available from Debian (2:2.7-4 in unstable; backports for bullseye through trixie) and Ubuntu (all supported releases). Upstream fix commit: 6864598a29b652a6b69a958f5cd1318aa2b258af.
The vendor CVSS 9.8 CRITICAL rating treats this as a fully weaponizable pre-auth RCE — and on paper, the vector AV:N/AC:L/PR:N/UI:N looks terrifying. Reality is far more constrained. watchTowr's deep-dive found no working RCE exploit on any tested system. On 64-bit x86 (the vast majority of modern deployments), pointer values contain null bytes that cannot be written given SLC triplet encoding constraints, making code execution *significantly more difficult*. On 32-bit Debian, an arbitrary-free primitive via def_slcbuf overwrite is possible, but modern glibc heap validation blocks practical exploitation. Public PoCs (Jeff Barron on ExploitDB/GitHub, kaleth4 on GitHub) confirm the overflow and memory corruption but achieve crash/DoS at best — not code execution. Meanwhile, Censys counts only 3,362 internet-facing telnetd instances globally, and most modern enterprises have zero telnetd in production. The 9.8 is a theoretical ceiling that wildly overstates actual risk for any shop that moved to SSH in the last two decades.
5 steps from start to impact.
Locate an exposed GNU inetutils telnetd
- Target must have GNU inetutils telnetd installed and running
- TCP/23 must be reachable from the attacker's network
- Almost no modern enterprise runs telnetd — SSH replaced it decades ago
- Firewalls and segmentation typically block port 23 from the internet
- Only ~3,362 internet-exposed instances globally per Censys
GNU Inetutils Telnetd Out-Of-Bounds Write CVE-2026-32746 Attempt in March 2026.Initiate Telnet negotiation and enable LINEMODE
DO LINEMODE sequences. The server must advertise LINEMODE support — not all telnetd configurations do. The attacker also delays the TTYPE response to force deferred SLC processing, which is critical for reaching the exploitable code path on some targets.- Server must support and advertise LINEMODE
- Attacker must properly sequence TTYPE/TSPEED/XDISPLOC negotiation
- LINEMODE must be enabled in the server configuration
- Timing-sensitive negotiation sequence required
Send overflow SLC payload
NSLC). Each triplet is 3 bytes (func, flag, value), and the 108-byte slcbuf overflows after approximately 35 triplets. The overflow corrupts slcptr, slcchange, and the def_slcbuf pointer in adjacent BSS memory. The PoC by Jeff Barron (ExploitDB #52556) and the watchTowr detection method confirm the overflow via leaked marker values in SLC responses.- Valid Telnet negotiation must be established
- SLC triplet bytes have encoding constraints (func cannot be 0 or exceed 0x1E, 0xFF bytes get doubled)
- Total packet size capped at 0x200 bytes, limiting overflow window to ~0x190 bytes
- Byte-value constraints severely limit attacker control over overwritten data
Attempt code execution via memory corruption
def_slcbuf to achieve an arbitrary-free primitive when deferred SLC processing triggers free() on the controlled pointer. On 64-bit targets, partial pointer overwrites on little-endian systems are the only feasible path. In both cases, achieving reliable code execution requires target-specific exploitation development. No public exploit achieves RCE. watchTowr explicitly concluded that exploitation is blocked by modern glibc heap validation on 32-bit and null-byte pointer constraints on 64-bit.- 32-bit target with older glibc for best exploitation odds
- Target-specific knowledge of memory layout and glibc version
- Custom exploit development beyond any public PoC
- On 64-bit x86: consecutive null bytes in pointers cannot be written via SLC triplets
- On 32-bit: modern glibc heap hardening blocks the arbitrary-free primitive
- ASLR randomizes heap and library addresses
- No public working RCE exploit exists as of October 2026
Achieve root shell (theoretical)
- Successful code execution from Step 4
- telnetd running as root (default for inetd-spawned services)
- Entire chain from Step 4 is unproven
- SELinux/AppArmor policies may confine telnetd even if exploited
- Enterprise environments running telnetd likely have other compensating controls
inetutils-telnetd. This eliminates 100% of the attack surface. Do this immediately — there is no noisgate mitigation SLA for MEDIUM, so go straight to remediation within the 365-day window, though disabling an unused service should take hours, not months.- SSH tunneling/wrapping telnet does not help — the vulnerability is in the telnetd server-side SLC handler, not the transport layer. Tunneling telnet through SSH still delivers the malicious SLC payload to the vulnerable parser.
- ASLR alone is insufficient — while ASLR raises the bar for reliable exploitation, the BSS overflow itself is deterministic. ASLR does not prevent the crash/DoS impact and only partially mitigates RCE attempts.
- Rate-limiting connections to port 23 — the overflow is triggered with a single connection during normal negotiation. Rate limiting does not prevent a one-shot exploit attempt.
The supporting signals.
| In-the-Wild Exploitation | No confirmed exploitation. GreyNoise observed low-volume probing/scanning in March 2026 and released a detection tag, but no weaponized attacks confirmed. Not on CISA KEV. |
|---|---|
| Proof-of-Concept Availability | Multiple PoCs, none achieve RCE. jeffaf/cve-2026-32746 (Jeff Barron) — confirms overflow via SLC response analysis. kaleth4/CVE-2026-32746 — similar crash PoC. ExploitDB #52556 — buffer overflow PoC. watchTowr — deep technical analysis with non-destructive detection probe but explicitly found no working RCE on any tested platform. |
| EPSS Score | 0.02448 (2.4%) — relatively low probability of exploitation in the next 30 days, consistent with the lack of weaponized exploits. |
| KEV Status | Not listed. Note: the related CVE-2026-24061 (telnetd auth bypass) was added to KEV on 2026-01-26, but this distinct overflow CVE has not been added. |
| CVSS Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H — 9.8. Vector assumes trivially achievable RCE (AC:L), which does not match demonstrated exploit maturity. A realistic assessment would use AC:H (high attack complexity), dropping the score to ~8.1 on paper, further reduced by real-world deployment scarcity. |
| Affected Versions | GNU inetutils telnetd all versions through 2.7. Also affects BSD-derived telnetd implementations sharing the SLC codebase. |
| Fixed Versions | Upstream commit 6864598a. Debian: 2:2.7-4 (unstable), 2:2.0-1+deb11u4 (bullseye), 2:2.4-2+deb12u3 (bookworm), 2:2.6-3+deb13u3 (trixie), 2:2.8-3 (sid/forky). Ubuntu: 2:2.7-2ubuntu1.1 (26.04 LTS), plus backports for 25.10 through 16.04 ESM. |
| Scanning/Exposure Data | Censys: ~3,362 internet-facing telnetd instances globally (March 2026). Shodan: ~221,000 devices on port 23, but most are NOT GNU inetutils (Cisco, busybox, etc.). GreyNoise: Low-volume probing observed; detection tag active since March 2026. |
| Disclosure & Researchers | Disclosed 2026-03-13 by DREAM Security Research Team (Adiel Sol, Arad Inbar, Erez Cohen, Nir Somech, Ben Grinberg, Daniel Lubel). Independent deep-dive by watchTowr Labs published shortly after. |
| Related Vulnerability | CVE-2026-24061 — GNU inetutils telnetd authentication bypass (environment variable injection), CVSS 9.8, on CISA KEV, actively exploited. Same component, different bug class. Enterprises hit by one are likely hit by both. |
Sources.
Why this verdict
- No weaponized exploit exists: watchTowr's thorough analysis explicitly found no working RCE on any tested platform — 64-bit systems block exploitation due to null-byte pointer constraints, and 32-bit systems are protected by modern glibc heap hardening. Public PoCs only trigger crash/DoS. This alone warrants treating AC as High, not Low.
- Vanishing attack surface: Censys counts only ~3,362 internet-exposed GNU inetutils telnetd instances globally. In a typical 10,000-host enterprise, the number of hosts running telnetd is effectively zero. SSH replaced Telnet in enterprise environments over 20 years ago.
- Byte-encoding constraints cripple the overflow: SLC triplet encoding restricts which byte values can be written (func capped at 0x1E, 0xFF doubling, 0x00 discarded), severely limiting attacker control over corrupted memory. This is not a clean arbitrary-write — it is a constrained corruption with a ~0x190 byte window.
- DoS-only confirmed impact: The proven impact is service crash / memory corruption causing telnetd to die. For a service that almost nobody runs, this represents minimal business impact. inetd/xinetd will typically restart the service, further limiting DoS duration.
- Role multiplier: OT/ICS environments — Telnet IS present in some OT/ICS systems (PLCs, HMIs, legacy SCADA) where SSH adoption lags. If the chain succeeded to RCE in these environments, the blast radius would be safety-critical (operational impact). However: (1) no RCE exploit works, (2) OT telnet is typically on air-gapped or heavily segmented OT networks not reachable from IT networks, and (3) many OT devices run busybox telnetd or vendor-specific implementations, not GNU inetutils. Estimated share of GNU inetutils telnetd installs in high-value OT roles: <5%. The floor of HIGH would apply only if the chain reliably succeeded — it does not.
- Role multiplier: Enterprise Linux servers — For the rare enterprise Linux host still running telnetd, compromise yields a single host. No identity-scale, fleet-scale, or supply-chain blast radius. telnetd is not a domain controller, hypervisor, CI/CD system, or backup server component.
- Not on KEV, no active exploitation, EPSS 2.4% — All threat-intelligence signals indicate this is not being weaponized. The related CVE-2026-24061 (auth bypass) IS on KEV and actively exploited — attackers have a much easier bug in the same component, making investment in this harder exploit unnecessary.
Why not higher?
A HIGH or CRITICAL rating would require either a working RCE exploit or a significantly larger exposed attack surface. Neither exists. The vendor's 9.8 assumes trivial exploitation complexity (AC:L), but independent research demonstrates exploitation is architecture-dependent and has not been achieved on any modern system. The OT/ICS angle is real but constrained by network segmentation and the lack of a working exploit chain. Upgrading this to HIGH would overstate the risk relative to the hundreds of other CVEs competing for patching resources in a 10,000-host fleet.
Why not lower?
Despite the exploitation barriers, this IS a confirmed pre-auth memory corruption vulnerability in a root-privileged network service. The overflow is proven and reproducible. A sufficiently motivated attacker with target-specific knowledge could potentially develop a working exploit for specific 32-bit configurations. The DoS impact alone (crashing a root-level service via unauthenticated network access) warrants more than LOW. Additionally, the OT/ICS presence of telnetd, even if segmented, means the theoretical worst case is non-trivial.
Crowdsourced verification payload.
Run this script on each Linux host where inetutils-telnetd *might* be installed. Execute as any user (no root required for package version checks). Example: chmod +x check_cve_2026_32746.sh && ./check_cve_2026_32746.sh
#!/bin/bash
# CVE-2026-32746 Check — GNU inetutils telnetd LINEMODE SLC Buffer Overflow
# Checks if inetutils-telnetd is installed, running, and whether the installed
# version is patched. Outputs: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 2=VULNERABLE, 0=PATCHED, 1=UNKNOWN
set -euo pipefail
RESULT="UNKNOWN"
# --- Check if telnetd package is installed ---
PKG_INSTALLED=false
PKG_VERSION=""
if command -v dpkg-query &>/dev/null; then
PKG_VERSION=$(dpkg-query -W -f='${Version}' inetutils-telnetd 2>/dev/null || true)
if [ -n "$PKG_VERSION" ]; then
PKG_INSTALLED=true
fi
elif command -v rpm &>/dev/null; then
PKG_VERSION=$(rpm -q --qf '%{VERSION}-%{RELEASE}' inetutils-telnetd 2>/dev/null || true)
if [ -n "$PKG_VERSION" ] && ! echo "$PKG_VERSION" | grep -q 'not installed'; then
PKG_INSTALLED=true
else
PKG_VERSION=""
fi
fi
if [ "$PKG_INSTALLED" = false ]; then
# Check if telnetd binary exists even without package manager info
if [ -x /usr/sbin/in.telnetd ] || [ -x /usr/sbin/telnetd ]; then
echo "[!] telnetd binary found but package version could not be determined."
echo "[!] Manually verify: strings /usr/sbin/in.telnetd | grep -i inetutils"
RESULT="UNKNOWN"
else
echo "[+] inetutils-telnetd is NOT installed on this host."
RESULT="PATCHED"
fi
else
echo "[*] inetutils-telnetd is installed. Version: $PKG_VERSION"
# --- Check if telnetd is actually running ---
RUNNING=false
if pgrep -x 'in.telnetd|telnetd' &>/dev/null; then
RUNNING=true
echo "[!] telnetd process is RUNNING."
elif ss -tlnp 2>/dev/null | grep -q ':23 '; then
RUNNING=true
echo "[!] Something is listening on port 23."
else
echo "[*] telnetd does not appear to be running (port 23 not listening)."
fi
# --- Version comparison for known-fixed Debian/Ubuntu versions ---
FIXED=false
if command -v dpkg &>/dev/null; then
# Known fixed versions (minimum patched version per release)
# Debian unstable/sid: 2:2.7-4
# Ubuntu 26.04: 2:2.7-2ubuntu1.1
# We compare against the upstream version component
if dpkg --compare-versions "$PKG_VERSION" ge "2:2.7-4" 2>/dev/null; then
FIXED=true
elif dpkg --compare-versions "$PKG_VERSION" ge "2:2.7-2ubuntu1.1" 2>/dev/null; then
FIXED=true
elif dpkg --compare-versions "$PKG_VERSION" ge "2:2.6-3+deb13u3" 2>/dev/null && \
dpkg --compare-versions "$PKG_VERSION" lt "2:2.7" 2>/dev/null; then
FIXED=true
elif dpkg --compare-versions "$PKG_VERSION" ge "2:2.4-2+deb12u3" 2>/dev/null && \
dpkg --compare-versions "$PKG_VERSION" lt "2:2.5" 2>/dev/null; then
FIXED=true
elif dpkg --compare-versions "$PKG_VERSION" ge "2:2.0-1+deb11u4" 2>/dev/null && \
dpkg --compare-versions "$PKG_VERSION" lt "2:2.1" 2>/dev/null; then
FIXED=true
elif dpkg --compare-versions "$PKG_VERSION" ge "2:2.8-3" 2>/dev/null; then
FIXED=true
fi
fi
if [ "$FIXED" = true ]; then
echo "[+] Installed version ($PKG_VERSION) includes the fix for CVE-2026-32746."
RESULT="PATCHED"
else
echo "[-] Installed version ($PKG_VERSION) is VULNERABLE to CVE-2026-32746."
if [ "$RUNNING" = true ]; then
echo "[!!] SERVICE IS RUNNING AND VULNERABLE. Disable telnetd or apply patches."
fi
RESULT="VULNERABLE"
fi
fi
echo ""
echo "=== RESULT: $RESULT ==="
case "$RESULT" in
VULNERABLE) exit 2 ;;
PATCHED) exit 0 ;;
UNKNOWN) exit 1 ;;
esac