SecurityHeroblog

Not a Single File Left Behind, but the Keys Have Been Piling Up for Three Days

A single 63-second session left behind zero samples and planted nothing but an SSH public key. The same key hash showed up three days running — 8/16, 8/17, 8/18 — and the number of sources planting it grew from 10 to 12 to 16. Here's how to notice a compromise when there's no file for antivirus to catch.

Apartment management offices keep something called a standing visitor vehicle registry. Once your plate is on it, the barrier gate lifts on its own. But that registry is a single sheet of paper. You can change the front door code, you can install new CCTV — none of that erases a name from the registry. And nobody ever looks at the registry, because nothing has gone missing.

What happened in our honeypot yesterday looked exactly like that.

63 Seconds, 17 Commands, 0 Samples Saved

FACT ATK-C17F4E (169.58.x.x) successfully logged in over telnet. It stayed for about 63 seconds and ran 17 commands. Five categories of intent were classified within that window — reconnaissance (system), file download, granting execute permission, execute-after-download, and persistence (planting an SSH key).

FACT And yet this session’s download_count is 0. Not a single sample was saved.

FACT Of yesterday’s top 5 sessions by completeness, this was the only one where the chain ran from reconnaissance all the way through to persistence.

A quick word on terminology: persistence means “setting up in advance a way to get back in next time.” In SSH, that way is usually a text file called authorized_keys. If a single public key line sits in that file, whoever holds the matching key can log in without a password. It’s the same as one plate number going onto the visitor vehicle registry.

389 Bytes, the Same Hash Three Days Running

FACT Across yesterday’s entire observation window, a 389-byte OpenSSH RSA public key (sha256 a8460f44…) was observed 16 times from 16 different sources. No URL is recorded for this file — meaning it wasn’t downloaded from outside, it was generated inside the session.

FACT We cross-checked the archive. A public key with the same hash is recorded from 10 sources on 8/16 and 12 sources on 8/17. Yesterday it was 16. The same key three days running, and the number of places planting it is growing.

INFERRED Antivirus, EDR — in the end, they’re tools that look for “bad files.” But what’s left here is an ordinary single line of text, 389 bytes long. It’s a file with nothing wrong with it structurally, and in fact someone writes that same file legitimately every day. There’s no basis to flag it.

FACT And yesterday, commands classified as ‘persistence — planting an SSH key’ numbered 18, while ‘indicator removal’ numbered 19. There was more wiping of traces than planting of keys.

  1. FACT ATK-57608F successful telnet login. 586 commands over about 16 minutes 30 seconds — one session accounting for roughly 20% of yesterday's 2,966 total commands (averaging one per 1.7 seconds). 1 download. TTY recorded (contents not included)
  2. FACT ATK-A4A3FE successful telnet login. About 68 seconds · 31 commands · 1 download. Intent was file download → grant execute permission → execute after download
  3. FACT ATK-C17F4E successful telnet login. About 63 seconds · 17 commands. 5 intent categories (reconnaissance-system · file download · grant execute permission · execute after download · persistence SSH key planting). download_count 0. The only session yesterday that ran from reconnaissance through to persistence
  4. FACT ATK-2A2021 successful telnet login. About 88 seconds · 31 commands · 1 download. Identical to ATK-A4A3FE in command count and intent combination
  5. FACT ATK-ABE8B7 successful telnet login. About 75 seconds · 22 commands · 11 downloads. Intent was 'impair defenses' alone. All 11 were 1-byte empty files with no magic number (01ba4719…), and this was the only delivery source for this file yesterday
  6. FACT 389-byte OpenSSH RSA public key (a8460f44…) observed 16 times from 16 different sources. No URL recorded — a file generated inside the session, not an external download
  7. FACT A public key with the same hash: 10 sources on 8/16, 12 sources on 8/17, 16 yesterday. Identical hash three days running, with the source count trending upward
  8. FACT Intent classification — persistence (SSH key planting) 18, indicator removal 19, impair defenses 1, reconnaissance (network) 2
  9. FACT 2,027 sessions / 249 unique origins / 1,581 login attempts / 2,966 commands / 1,424 TTY recordings. Port 2222 (SSH) 1,657, port 2223 (telnet) 370 — telnet is about 18%, yet the top 5 sessions by completeness were all telnet (three days running)

The Side That Fingerprints and the Side That Actually Gets Breached Are Different

This is the part of yesterday’s data that bothered me most.

FACT Yesterday there were 36 SSH client fingerprint clusters, the largest being f555226d… (client string SSH-2.0-libssh_0.9.6, 16 IPs yesterday · 124 cumulative). But all 7 fingerprint clusters observed yesterday have delivered_samples=false. On the SSH side, where fingerprints are left behind, not one source actually delivered a sample.

FACT The actual intrusion, downloading, and key planting all happened over telnet. And telnet sessions have no SSH client fingerprint to begin with — the fingerprint and client values for yesterday’s subject session are likewise empty.

INFERRED This means the traffic that clusters nicely and the traffic that actually causes damage sit in different layers. If you only look at the side that classifies well, the side that actually gets breached never shows up on your screen.

FACT To add: identical fingerprints mean the same tool and the same build were used, not the same organization. Unrelated people using the default client from the same distribution will have the same value.

How They Got In — Still Passwords

FACT Yesterday there were 1,581 login attempts from 249 origins. That’s an average of 6.4 per origin. Narrowing to combinations observed from 3 or more distinct IPs gives this.

Username Password IPs observed
admin admin 26
345gs5662d34 345gs5662d34 16
root admin 9
root 3245gs5662d34 8
root root 7
root password 6
root (empty password) 5
root 1234 5
root 12345 5
support support 4

FACT And 1,388 combinations are not listed. Those are the ones observed from fewer than 3 distinct IPs (up from 934 on 8/16 and 830 on 8/17). A combination seen from only one place could be an account actually leaked somewhere, so we don’t write the values — we count only the number.

FACT In yesterday’s observations there was no path referencing a CVE or an exploit. Every one was a “find the right password” path.

What They Left

sha256
a8460f446be540410004b1a8db4083773fa46f7fe76fa84219c93daa1669f8f2389-byte OpenSSH RSA public key · observed 16 times · no URL recorded (generated inside the session) · same hash as 8/16 and 8/17 · 16 delivery sources
sha256
a6296a79f44e21b76604d2d2bbf795d2cf380f70e39d45fbf166707ff3b4a6a4306-byte POSIX shell script · observed 13 times · 13 delivery sources · same hash on 8/17 too · same URL
url
hxxp://185[.]93[.]89[.]72/wgetthe address the shell script above was downloaded from
sha256
6aa5054a95d23277df417a5f69cf292e19bc2ef0406bc0c1884935a44e3ce7971,608-byte bash script · delivery source ATK-10149C
url
hxxp://5[.]182[.]210[.]174/okthe address the script above was downloaded from
sha256
4af5a5c98ad132095c6fbe7b02c242153a190a01cc321e50a916a0ca46fbaa629-byte ASCII text · observed 12 times · no URL recorded · delivery source ATK-BECAD3
sha256
01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b1 byte · empty file with no magic number · observed 11 times · delivery source ATK-ABE8B7 · 121 times on 8/17 · 2 sources

The addresses are deliberately broken (hxxp://, [.]). Pasting them as-is will not connect.

FACT The last line catches the eye. The 1-byte empty file was the subject on 8/17. What was 121 occurrences from 2 sources then dropped to 11 occurrences from 1 source yesterday. Why it dropped can’t be determined from the data, so we record it as fact only.

Mapped to Attack Stages

Mapping the observed behavior to MITRE ATT&CK techniques gives this. All of it is [INFERRED] — what we saw were commands, not the attacker’s intent.

  • T1110.001Brute Force: Password GuessingINFERRED
  • T1078Valid AccountsINFERRED
  • T1059.004Command and Scripting Interpreter: Unix ShellINFERRED
  • T1082System Information DiscoveryINFERRED
  • T1016System Network Configuration DiscoveryINFERRED
  • T1105Ingress Tool TransferINFERRED
  • T1222.002File and Directory Permissions Modification: Linux and MacINFERRED
  • T1098.004Account Manipulation: SSH Authorized KeysINFERRED
  • T1070Indicator RemovalINFERRED
  • T1562Impair DefensesINFERRED

If This Looks Familiar

INFERRED The entry structure is the same as the Mirai botnet family that has continued since 2016. Get in with default telnet credentials, then download CPU-architecture-specific binaries in sequence from a /bins/ path on a web server and run only the one that fits. The filename conventions observed yesterday (parm, parm5, parm64, pmips, psh4, x86_64 …) match that practice, and the fact that all completed sessions were telnet fits as well.

This is a case with U.S. Department of Justice indictment and guilty plea records on file, and public analysis reports from multiple vendors. That said, yesterday’s subject — SSH public key persistence — is the part this case does not explain. This isn’t a place to wave it through with “it’s similar,” so we note it separately.

So What Should You Do

INFERRED The order yesterday’s data points to is this.

  1. Open ~/.ssh/authorized_keys and look at it yourself. If there’s even one key you don’t recognize, that’s the whole story. Key-planting intent came up 18 times, from 16 sources.
  2. Get alerted when that file changes. Even if you change every password and block brute force, a key that’s already in stays in.
  3. Store logs off the machine. Indicator removal was observed 19 times, impair defenses once. The reason we could reconstruct yesterday’s picture at all is that 1,424 TTY recordings survived (contents not included in this post).
  4. Don’t expose management ports directly to the internet. Telnet is about 18% of all sessions, yet every completed session was telnet. Prioritize by session count and you miss the 18% that actually gets breached.
  5. Block outbound. But that alone isn’t enough — ATK-C17F4E had 0 downloads and still reached key planting.

Yesterday in Full

Sessions 2,027
Unique IPs 249
Login attempts 1,581
Commands executed 2,966
SSH (2222) 1,657
Telnet (2223) 370

All 2,966 commands were executed after a successful login.

The distribution points and C2 observed yesterday were reported to C-TAS. Only transport-layer success is confirmed; whether KISA ingested them requires separate confirmation.

The 60-Second Version

We also made a short video of the same observation window.

What We Don’t Know

This blog writes down what it knows and what it doesn’t, separately. Here is what could not be confirmed in yesterday’s observations.

  • Whether ATK-C17F4E failed to download, or downloaded something that wasn’t saved. The intents include ‘file download’ and ‘execute after download,’ but download_count is 0. The data doesn’t distinguish between the two. All that’s certain is “the intent was classified and no sample was saved.”
  • Whether the 16 sources that planted the public key and the 16 IPs in the largest fingerprint cluster are the same set. The numbers merely match; there’s no basis to connect the two sets. Telnet sessions have no fingerprint at all.
  • Whether the sources on 8/16, 8/17, and 8/18 overlap with each other. Aliases (ATK-XXXXXX) are generated with a salt, so they can’t be tracked across dates. That’s why we cannot add 10+12+16 and say “38 sources.”
  • Whether matching fingerprints mean the same organization. They don’t. It means the same tool and the same build were used, and unrelated people using the default client from the same distribution will have the same value.
  • Why ATK-ABE8B7 had yesterday’s highest completeness score (42). Its only intent was ‘impair defenses,’ yet its score is the highest. The formula isn’t in the data, so we can’t explain it.
  • Why the 1-byte empty file declined. 121 occurrences · 2 sources → 11 occurrences · 1 source. The cause of the decline can’t be determined from the data.
  • What the 9-byte ASCII text (4af5a5c9…) is. It was observed 12 times, but the contents aren’t in the brief, so we can’t judge.
  • One Discord webhook URL. It isn’t specified which session or which sample it connects to, so we didn’t include it in yesterday’s established facts.
  • Whether the aggregate figures cover the full day. The 5 main sessions cluster between 00:45 and 04:49 UTC, but the generation time is 15:05Z. The observation window isn’t specified.
  • Why 16 sources planted the same key. Whether it’s the result of using the same tool or the result of sharing a key, we can’t tell. The same item remains unresolved in the 8/16 and 8/17 briefs as well.
  • Public incidents in the SSH authorized_keys persistence family. We couldn’t confirm a source, so we didn’t include one as a case study.
  • Background vulnerability statistics (4,252 CVEs / 341 CISA KEV / 95 ransomware-linked). These are statistics based on KISA security advisories and aren’t directly connected to yesterday’s observations.

And then there are the things we have no means of confirming in the first place. This is different from not knowing — here, not guessing is the correct answer.

  • ASN · ISP — we don’t have GeoIP or ASN databases. We don’t guess.
  • Geolocation — same. IP geolocation isn’t a basis for attribution to begin with.
  • VPN · Tor · cloud status — we have no means of determining this.
  • VirusTotal detection results — not integrated. Sample classification uses MalwareBazaar tags.
  • User-Agent — SSH and telnet have no User-Agent at all. HTTP attacks are a separate source.
  • CVE linkage — SSH and telnet attacks mostly don’t reference vulnerabilities, and yesterday’s observations were after credentials too.

One name went onto the registry. Three days in, the number of places it went onto has grown from ten to sixteen. If nobody opens the registry because nothing has gone missing, it will keep growing.


This post is based on honeypot observations from 2026-08-18. Origin IPs are written exactly in the masked form used in the brief, and distribution addresses have been defanged so they will not connect. Quoted credentials include only combinations observed from 3 or more distinct IPs; the 1,388 combinations observed from fewer than that are reported by count only, with no values included.