SecurityHeroblog

Nine Executables, Three Commands — 33 Seconds, Twice

On September 8, an address absent from 23 days of records dropped nine executables at once, differing only in CPU type. The intrusion that collected them typed exactly three commands and was over in 33.25 seconds. Then, 1 minute 12 seconds later, a 33.26-second run came through again.

You’ve probably opened a toolbox to mount a single shelf on a wall. You thought the screw head was a Phillips, so you grabbed a Phillips driver — but it turns out to be a flathead. Some are hex. Some are star-shaped.

That’s why people who use tools often don’t carry a single screwdriver. They bring the whole set, ten or so bits sorted by head shape. It removes the need to know in advance what kind of screw is waiting. If just one fits, the screw turns.

What arrived on our server yesterday was exactly that kind of set. A nine-piece one.

What happened yesterday at 4:45 p.m.

FACT We run a honeypot server. A honeypot is a decoy server left deliberately insecure so we can watch who does what. So what happens here is not real damage — it’s an observation record.

FACT On September 8 at 4:45:31 p.m., someone came in over Telnet and logged in successfully. Telnet is a very old remote-access method, and its problem is that the characters exchanged travel in the clear, unencrypted. We assigned the incoming side the alias ATK-2872E4 (94.154.x.x). An alias is not an identity. It is merely a marker so we can refer to the same masked source consistently across posts. This alias is a new one, absent from anywhere in our archive between August 16 and September 7.

FACT This session lasted 33.25 seconds. Within it, the attacker typed three commands and downloaded ten files. Ten files in 33.25 seconds is one every 3.3 seconds. Of all sessions observed yesterday, this one had the densest record (completeness 41 — yesterday’s highest).

Laid out in chronological order, it looks like this. Watch the seconds, and the gap between one session and the next.

  1. FACT ATK-640E4E(59.126.x.x) connected over Telnet and logged in successfully. 31 commands and 1 download over 67.06 seconds. Three intents — file download, granting execute permission, and execute-after-download — and the screen was recorded
  2. FACT ATK-245F71(59.125.x.x) connected over Telnet and logged in successfully. 67.24 seconds, 31 commands, 1 download, and the same three intents as the previous session — identical. Both aliases appear on the list of 8 sources that delivered the 306-byte shell script at hxxp://185[.]93[.]89[.]72/wget
  3. INFERRED Two different sources came in 13 minutes apart and left the same shape: "about 67 seconds, 31 commands, 1 download." This pattern also appears in the 8/20 brief (four sources matching even in command count at 31) and the 9/02 brief (five sources at about 67 seconds and 31 commands) — meaning the same automated tool is in circulation
  4. FACT ATK-50016C(220.135.x.x) connected over Telnet and logged in successfully. 23.76 seconds, 20 commands, 11 downloads. Yet the intent list is empty. All 11 files collected are 1-byte empty files
  5. FACT ATK-2872E4(94.154.x.x) connected over Telnet and logged in successfully. Over 33.25 seconds there were only 3 commands but 10 downloads. All three intent stages were attached and the screen was recorded. Completeness 41, the day's highest
  6. FACT Exactly 72.01 seconds after the session ended, the same alias came back in
  7. FACT Second session. 33.26 seconds, 3 commands, 10 downloads, same intents, completeness 41. The duration differs from the first session by 0.01 seconds
  8. INFERRED Ten files arriving on three commands means a person did not type them one line at a time — a script that had been fetched did the rest. In fact, the samples this alias delivered include one 1,875-byte shell script (hxxp://94[.]154[.]43[.]221/cat.sh)
  9. FACT Excluding cat.sh, the remaining 9 are all ELF executables named iran.x86_64 · iran.aarch64 · iran.m68k · iran.mips · iran.mipsel · iran.powerpc · iran.sparc · iran.sh4 · iran.arc. Each sample was observed exactly 2 times — one set per session, arriving twice. 10 types × 2 times = 20, which matches the two sessions' 10 + 10 downloads exactly
  10. INFERRED Only x86_64 and aarch64 belong to the 64-bit server and modern-device lineage; the other seven (m68k · MIPS big-endian · MIPS little-endian · PowerPC · SPARC · Renesas SH · Synopsys ARC) are CPUs from the embedded-device side — routers, NVRs, set-top boxes, industrial controllers. This is not a set aimed at one kind of server but a distribution set aimed at "anything that runs Linux"
  11. FACT 8 of the 9 are statically linked and stripped, but iran.sparc alone is dynamically linked (interpreter /lib/ld-uClibc.so.0) and at 43,832 bytes is the only one at a quarter to a fifth the size. The rest cluster between 142,140 and 211,648 bytes. The 9 total 1,464,352 bytes
  12. INFERRED The masked source 94.154.x.x and the distribution point 94[.]154[.]43[.]221 share their first two octets. The last two are masked and we do not restore them — so we cannot even establish whether this is "the same device" or "the same range." The same shape as the 9/07 brief's 131.123.x.x ↔ 131[.]123[.]40[.]104 reappeared just two days later
  13. FACT 1,824 sessions · 175 unique sources · 1,523 login attempts · 1,980 commands · 1,390 screen recordings. Intents were reconnaissance 1,281 · granting execute permission 179 · execute-after-download 34 · file download 34 · trace deletion 26 · SSH key planting 19. "File download" and "execute-after-download" are exactly equal at 34
  14. FACT 67,401 contacts · 675 unique sources. Of these, 65,322 (96.9%) went to screen-sharing (VNC) port 5900 alone. It surpassed the 48,605 that the 9/06 brief recorded as "the highest across 12 days of observation" just two days later

FACT The lines to focus on here are the bottom two. 33.25 seconds and 33.26 seconds. The same alias came in twice, 1 minute 12 seconds apart, and the difference in time spent was 0.01 seconds. It is hard for a person typing twice to produce that.

The ten that were collected

FACT All ten downloaded files came from the same address: hxxp://94[.]154[.]43[.]221/. Writing the address this oddly is not a typo. It’s the practice of turning http into hxxp and dots into [.] so no one connects by accidentally clicking it. It’s called defanging — pulling out the teeth.

FACT This address appears nowhere in our 23 days of archive. The iran.<CPU name> file-naming convention is also one we’re seeing for the first time.

FACT One of the ten is not an executable but a text script: cat.sh, 1,875 bytes. About the size of twelve text messages. The other nine are all ELF executables. ELF is the name of the format program files use on Linux.

INFERRED There were three commands but ten files. Fetching ten times in three lines is difficult. We take it that the script fetched in the first line fetched the rest on its behalf. Put in toolbox terms, they didn’t swap bits by hand one at a time — they pulled out a power driver that changes its own bits first.

Why nine sets

FACT The nine names are these: iran.x86_64 · iran.aarch64 · iran.m68k · iran.mips · iran.mipsel · iran.powerpc · iran.sparc · iran.sh4 · iran.arc. Everything after the dot is a CPU type name.

FACT The CPU, a computer’s brain, understands a different language depending on its type. Put a program built for one into another and it won’t even start — it just stops. It’s the same as putting a flathead driver to a Phillips screw.

INFERRED So whoever built this prepared nine copies of the same program, one per CPU type. Of those, only two — x86_64 and aarch64 — are common on servers or modern devices. The other seven (m68k · two MIPS builds · PowerPC · SPARC · Renesas SH · Synopsys ARC) are CPUs that go into things like routers, CCTV recorders, set-top boxes, and industrial controllers. ARC in particular is an embedded-only chip, never used in servers.

INFERRED This is not a set aimed at one kind of server. It’s a set aimed at “anything that runs Linux.” It means they never asked what kind of screw head is in whose house — and had no intention of asking.

FACT The nine CPU types observed in a single day is the maximum within the range we can verify in our archive. The previous maximum was five types seen on August 23–25 (armv5l · armv6l · armv7l · mips · mipsel), and the day right before, September 7, had two (MIPS big-endian and little-endian). This is the day it went from five to nine.

FACT Add up all nine and you get 1,464,352 bytes, about 1.4 megabytes. Roughly one smartphone photo. That one photo’s worth came in as twenty items across two visits.

Only one was different

FACT Eight of the nine are built identically. They are statically linked and stripped. Static linking means the program packs every part it needs inside itself, built as one piece. It runs fine even in someone else’s house, because it doesn’t need to borrow parts. Stripped means the internal markers the builder left behind were removed before distribution. It becomes harder to take apart.

FACT But iran.sparc alone is different. This one is dynamically linked. It means it doesn’t pack the parts inside but intends to borrow them from the machine it lands on (the place to borrow from is written as /lib/ld-uClibc.so.0). At 43,832 bytes, it’s also the only one at a quarter to a fifth the size. The other eight cluster between 142,140 and 211,648 bytes.

INFERRED It’s a nine-bit set where one bit is made of a different material. The build tool for that one may have differed, or building it as one piece may have failed and they fell back to borrowing parts. Which of the two, we cannot tell from our data.

72 seconds later, once more

FACT The first session ended at 4:46:04 p.m. Then, exactly 72.01 seconds later, at 4:47:16, the same alias came back in. The second session: 33.26 seconds, 3 commands, 10 downloads. Same as the first.

FACT That the nine sample types were each observed exactly 2 times fits here too. 10 types × 2 times = 20, exactly matching the two sessions’ 10 + 10 downloads. They dropped the same set, whole, twice.

INFERRED It is hard to see this as a person coming twice. A person is either faster or slower the second time. A 0.01-second difference is not a number a human hand produces.

The first two octets matched

FACT The incoming side’s IP is 94.154.x.x. The last two octets are masked, and we do not restore them. And the address the files came down from is 94[.]154[.]43[.]221. The first two octets match.

INFERRED This is as far as we can go. Because the last two octets are masked, we cannot determine whether it’s the same computer or a different computer in the same neighborhood. We did not reverse the masking to check, and we did not write that it’s the same device. That said, this shape also appeared on September 7. That day, 131.123.x.x came in and collected files from 131[.]123[.]40[.]104. That the same shape reappeared within two days — that much is fact.

What was left at the door yesterday

FACT We’re reproducing the values as-is so you can use them for defense. Click a value to copy it. The addresses have been altered so they can’t be connected to, so use them as they are. Compare the top ten lines with the ones below — the top are values that first appeared yesterday, the bottom are values that haven’t changed in over three weeks.

sha256
4de34e22fec36167a9fabbe29b8eb38482ad5d16e59bce2fdd735b7ac15a0a861,875-byte POSIX shell script · 2 times today · 1 source · new hash, absent from 23 days of archive
url
hxxp://94[.]154[.]43[.]221/cat.shDistribution point for the script above. A new address, absent from 23 days of archive
sha256
de1de068b151fa14fdf94ba39d0503f0ee10a05fe0f9146c43928a96db25e084iran.x86_64 · 164,272 bytes · ELF 64-bit LSB x86-64 · statically linked · stripped · 2 times today · new hash
sha256
e102ee5bbf9282a4c5f5b38c5554668eefc67a9782004631d1aa837e18dfe159iran.aarch64 · 194,552 bytes · ELF 64-bit LSB ARM aarch64 · statically linked · stripped · 2 times today · new hash
sha256
b77142d8fa79f421c402fae649e041589c6e3584e69def5789b704af6b522535iran.m68k · 182,244 bytes · ELF 32-bit MSB Motorola m68k 68020 · statically linked · stripped · 2 times today · new hash
sha256
dea6d274c1c7c34d160bd12c87a27ef5c5edb1f4934c4557bb54f1857c7be360iran.mips · 209,376 bytes · ELF 32-bit MSB (big-endian) MIPS MIPS-I · statically linked · stripped · 2 times today · new hash
sha256
abc54ab37e423461c6a67b7d65f342451e42fbd93e4ba83fd571c3236cfcfc25iran.mipsel · 211,648 bytes · ELF 32-bit LSB (little-endian) MIPS MIPS-I · the largest of today's 9 types · only 2,272 bytes apart from iran.mips above, so it appears to be the same program in two endianness builds · 2 times today · new hash
sha256
7b46bce6515f1189593f7fbd7edb24ce2e152e0fbb6b57808515db882b331060iran.powerpc · 158,956 bytes · ELF 32-bit MSB PowerPC or cisco 4500 · statically linked · stripped · 2 times today · new hash
sha256
60bd242f448228391063d6a1521233087ba3602f5521f526a784d6325ffe8377iran.sparc · 43,832 bytes · ELF 32-bit MSB SPARC · the only one of the 9 that is dynamically linked (interpreter /lib/ld-uClibc.so.0), and alone at a quarter to a fifth the size · 2 times today · new hash
sha256
b610ed02b56e1634c71f36076e61e7bf69aca774e745df6c698d5d9f470d48b8iran.sh4 · 142,140 bytes · ELF 32-bit LSB Renesas SH · statically linked · stripped · 2 times today · new hash
sha256
b5099a274a6192b76e132488df1a051b2e6ccb68fc916901ddf73ef9d0f01fe2iran.arc · 157,332 bytes · ELF 32-bit LSB Synopsys ARCompact ARC700 · ARC is an embedded-only core, not used in servers · 2 times today · new hash
url
hxxp://94[.]154[.]43[.]221/All 9 executables above and cat.sh came from under this address. The file-naming convention is iran.<CPU type>
sha256
a6296a79f44e21b76604d2d2bbf795d2cf380f70e39d45fbf166707ff3b4a6a4306-byte POSIX shell script · 8 times today · delivered by 8 different sources · the same hash for 23 days now since first observed on 8/17 (background, not today's subject)
url
hxxp://185[.]93[.]89[.]72/wgetDistribution point for the 306-byte script above. Not one bit of the file has changed in 23 days
sha256
a8460f446be540410004b1a8db4083773fa46f7fe76fa84219c93daa1669f8f2389-byte OpenSSH RSA public key · 19 times today · 14 different sources · the address column is empty, so we take it as a file created inside the session rather than fetched externally · the same hash for 24 days since 8/16
sha256
4cec26851bdf98ec62e9bb7df003efe139b4014e5dc19f1ec7d56c3b79c4116d1,608-byte Bourne-Again shell script · 1 time today · 1 source · since 8/17 the size is 1,608 bytes every time but the hash keeps changing · today's is also a hash absent from the archive
url
hxxp://5[.]182[.]210[.]174/okDistribution point for the script above. The 9/06 brief recorded this address's cumulative hashes as "at least 14 types"
sha256
01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b1-byte empty file · 11 times today · 1 source (ATK-50016C) · a lineage repeatedly recorded as "1 source · 11 times" in the 8/17 · 8/18 · 8/21 · 8/22 · 8/23 · 8/30 · 9/03 · 9/06 briefs as well
sha256
4af5a5c98ad132095c6fbe7b02c242153a190a01cc321e50a916a0ca46fbaa629-byte ASCII text · 8 times today · 1 source · a constant hash appearing almost daily since 8/18 · address not recorded · the contents are not in our data, so we make no judgment
sha256
151cc94bab7928de2aacf2e9bdd9a2c362a70082dbb3749d35354f45fd303ddd3,514,627 bytes · sensor 02 · 3 times today · 1 source · there is no address column at all · new hash, absent from 23 days of archive
sha256
01bc2eccefe19f057c593875010187cb28608d03267034ef006206061b88234a3,518,723 bytes · sensor 02 · 2 times today · 1 source · new hash · exactly 4,096 bytes apart in size from the file above, but there is no basis for what that means

FACT There’s one more line here that catches the eye. The 1-byte empty file observed 11 times yesterday. One byte is one character’s worth. ATK-50016C, which came in at 1:09 p.m., typed 20 commands over 23.76 seconds and collected 11 files — and all 11 were this empty file. The same hash is written in eight briefs since August 17, identically, as “1 source · 11 times.”

INFERRED It’s as if they opened the bit set and the case was empty. We take it as a lineage that succeeded at intrusion but failed at delivery. A door being open doesn’t always mean something comes in.

This time the names just happened to be visible

FACT Yesterday, the CPU type was written right into the names of the nine files. That’s how we could count “nine types.” Normally it isn’t this visible.

FACT We separately have 12 distribution addresses that only emerged after decompression. They are parm · parm5 · parm6 · parm64 · parm7 · pm68k · pmips · pmpsl · pppc · psh4 · pspc · x86_64, under hxxp://31[.]77[.]227[.]121/bins/. When an executable is squeezed down with a tool called UPX, not a single line of address is visible on the surface. You have to peel the shell off.

INFERRED The trailing parts of these 12 names are CPU types too. m68k · mips · mipsl · ppc · sh4 · spc · x86_64 · several ARM builds — so the composition overlaps with the set that arrived yesterday. But this is not a basis for “the same group.” There is no value in our data linking the two distribution points. There is one thing to read here — that the approach of targeting embedded Linux wholesale, building one copy per CPU, is common across multiple lineages.

INFERRED And one more thing. Yesterday’s had the names written right on the surface, so we could count them. Had it been the squeezed-and-hidden kind, not one line of the nine would have been visible. The nine we counted today is a number that exists only because the other side didn’t bother to hide it.

The passwords that opened the door

FACT Yesterday’s login attempts totaled 1,523, coming from 175 different sources. Divide the day into seconds and it’s about one every 57 seconds — roughly once a minute, someone tried an ID and password.

FACT At least 944 combinations were tried. Of those, only 20 are reproduced in this post. The remaining 924 are counted but their values are not written down. Our rule is to quote verbatim only combinations repeated from three or more different IPs. A combination that appeared from only one or two sources could be someone’s real account leaked from somewhere.

The 20 below are the opposite. They repeated from many sources, so they can be regarded as factory defaults that belong to no one.

ID Password Distinct sources
admin admin 17
345gs5662d34 345gs5662d34 13
user user 6
support support 5
root root 5
root 12345678 5
root 111111 5
root 1234 5
root admin 4
root password 4
guest guest 4
test test 4
root 123321 4
root 12345 4
root 123456 4
root 123456789 4
root 1234567890 4
root 1q2w3e4r 4
root vizxv 3
admin password 3

FACT In half of the twenty lines, the ID and the password are identical. The rest are just the paths a finger traces across a keyboard. Only vizxv at the bottom is of a different character. This is not a password a person makes up — it’s an initial password put in at the factory on devices like routers and cameras.

INFERRED This dictionary was not built to target us. It’s a list of values that work anywhere, tried in order. Which means the reason the door opened yesterday was not “because it was us.”

The whole day yesterday

FACT This is the daily tally for the side where doors actually open (sensor 01). Please read the right-hand column along with it — a single number alone doesn’t convey scale.

Item September 8 For comparison
Sessions 1,824 an average of 10.4 per source
Unique sources 175 —
Login attempts 1,523 about one every 57 seconds over the day · an average of 8.7 per source
Commands 1,980 about one every 44 seconds over the day
Port 2222 (SSH) 1,561 sessions 85.6% of the total
Port 2223 (Telnet) 263 sessions yet yesterday’s five complete sessions were all on this side
Screen recordings 1,390 of which 247 are viewable
Samples in storage 113 —

FACT The per-port sum (1,561 + 263) matches the session total of 1,824 exactly. And the neighboring server (sensor 02) counts in different units, so we do not add them together. The sum of unique sources across the two servers has unknown overlap, so 850 is an upper bound and the actual value is smaller.

FACT Counting yesterday’s on-server activity by type looks like this.

What they tried to do Count For comparison
Reconnaissance — surveying the system 1,281 64.7% of all 1,980 commands
Granting execute permission 179 5.3× the 34 downloads
Execute after download 34 —
File download 34 exactly equal to the above
Trace deletion 26 —
Persistence — planting SSH keys 19 —

FACT “Granting execute permission” is the act of attaching a mark to a file saying “this file may be executed.” On Linux, without that mark, even a program simply won’t run.

FACT “File download” at 34 and “execute after download” at 34 are exactly equal. It means everything downloaded yesterday led, without exception, to an execution stage.

FACT That said, the intents attached to yesterday’s protagonist ATK-2872E4’s sessions are only three. File download → granting execute permission → execute after download. No reconnaissance, no key planting, no trace deletion in these sessions. Those 19 and 26 counts are what other aliases did. Being in the daily tally does not mean we transfer it onto this session.

A different door rang at the neighboring server

FACT We have two servers set up. The second (sensor 02) is a shallow trap that doesn’t let anyone in past the entrance, so all that remains is “which door, how many sources, how many times.” No login successes, no commands, no credentials exist here.

Door (service) Port Knocks Sources
VNC (screen sharing) 5900 65,322 (96.9%) 416
RDP (remote desktop) 3389 1,443 110
SMB (file sharing) 445 331 80
LDAP (account lookup) 389 222 41
MSSQL (database) 1433 57 12
ADB (Android debugging) (not recorded) 26 (not recorded)

FACT 65,322 screen-sharing knocks, divided across the day, is one every 1.3 seconds. Since 416 sources produced them together, one source knocked an average of 157 times. This value surpassed, within two days, the 48,605 that the September 6 brief recorded as “the highest across 12 days of observation.”

FACT The protocol version the other side offers first is recorded too. On screen sharing, 003.003 appeared 63,822 times and 003.008 1,052 times — the older 003.003 at 98.4%. On the file-sharing side: NT LM 0.12 116 · LANMAN1.0 107 · LM1.2X002 107 · PC NETWORK PROGRAM 1.0 54 · Windows for Workgroups 3.1 54 — 1990s vocabulary rides at the front of the list. Remote desktop cookies were hello 845 · <ip> 442 · empty 5 · random 9-digit 3.

INFERRED Offering an old protocol version first means the other side is using a scanner that accommodates even old systems — not that our server is old.

Mapping the attacker’s techniques to the international catalog

MITRE ATT&CK is an international list that assigns a number to each attack technique. Matching yesterday’s behavior to those numbers looks like this. Press an ID to go to the original description — we link so you can verify directly rather than take our word for it.

  • T1110.001Brute Force: Password Guessing — 1,523 login attempts, 20 quotable combinationsINFERRED
  • T1078.001Valid Accounts: Default Accounts — admin/admin from 17 sources, many root/1234-family entries, all 5 complete sessions began with a successful loginINFERRED
  • T1105Ingress Tool Transfer — "file download" 34 times, 10 per ATK-2872E4 sessionINFERRED
  • T1222.002File and Directory Permissions Modification: Linux and Mac — "granting execute permission" 179 timesINFERRED
  • T1059.004Command and Scripting Interpreter: Unix Shell — "execute after download" 34 times, cat.sh a 1,875-byte POSIX shell scriptINFERRED
  • T1098.004Account Manipulation: SSH Authorized Keys — "persistence — planting SSH keys" 19 times, a 389-byte public key from 14 sourcesINFERRED
  • T1070Indicator Removal — "trace deletion" 26 timesINFERRED
  • T1082System Information Discovery — "reconnaissance — system" 1,281 times, yesterday's top intentINFERRED
  • T1046Network Service Discovery — on sensor 02, 675 sources made 67,401 contacts across five services: VNC · RDP · SMB · LDAP · MSSQLINFERRED

FACT Note that all nine lines carry an [INFERRED] badge. What we hold goes as far as the commands’ “intent classification results” and “how many times.” We do not have the original commands. Matching things to a catalog is always interpretation, and where it’s interpretation, we write that it is.

FACT And of the nine lines, yesterday’s protagonist stepped on only three. T1105 (bringing in files) · T1222.002 (granting execute permission) · T1059.004 (running what was fetched). Exactly 3 stages, 33 seconds.

There have been shapes like this before

INFERRED Mirai botnet (2016). Its structure was to log into Linux devices using a dictionary of default Telnet accounts, then have them download a selected ELF executable built separately per CPU type. It is the same lineage of distribution method as the nine-set iran.<CPU type> observed yesterday. There are three points of overlap: ① Telnet + default-account dictionary ② a loader script trying per-CPU executables in order ③ targeting embedded CPUs like MIPS, ARM, PowerPC, SPARC, SH, and m68k alongside x86. (Source types: published source code · US-CERT/CISA alert TA16-288A · analysis reports from multiple vendors)

INFERRED Bashlite / Gafgyt (2014–2016). An early IoT botnet lineage that used the same three-stage structure before Mirai. Default password → shell script loader → per-CPU executable. The point is that nearly ten years later, yesterday, the same shape still came into our sensors. (Source type: technical analysis reports from multiple security vendors)

FACT We stop here. We have not integrated a sample classification service. We do not render a judgment that the nine we received yesterday belong to this lineage. What resembles is the construction method, not a label.

So what should be done

We have no way to stop bit sets from being made. What can be changed is how far our own screws stick out.

FACT 1. Default accounts and easy passwords still in use · high likelihood All twenty lines in the table above are values that devices or distributions ship with from the factory. Yesterday’s 1,523 attempts came in from this dictionary, and the five sessions with records begin, without exception, after a successful login. Our server was opened on purpose, but it shows exactly which dictionary is being tried. After a single password was breached, ten external files were uploaded within 33 seconds. Had it been a real server, those 33 seconds are the moment of compromise.

FACT 2. Password login allowed, key-based method unused · high likelihood Every authentication attempt that came in yesterday went by the password path. Had it been key-based, 1,523 attempts would not be possible. And the intruding side, once successful, hangs its own key first. Yesterday there were 19 key-planting events, and a 389-byte SSH public key appeared from 14 different sources. An SSH public key is, put simply, a spare key that lets you in without a password. Once one line is written into the server’s authorized_keys (the list of permitted keys) file, that key keeps working even if you change the password later. This file has not changed by a single bit for 24 days since August 16. That said, yesterday’s highest-completeness sessions were Telnet, and Telnet has no key-authentication option to begin with.

FACT 3. Management ports left open to the internet · high likelihood We have never announced our server’s address anywhere. Even so, 175 sources came to the side where doors open, and 675 to the neighboring server. Combined across the two, an upper bound of 850. 65,000 knocks in a day landed on the screen-sharing door alone. Had it been a real server, it means the admin screen was one of the candidates among those 65,000. Exposure itself is the condition.

INFERRED 4. Relying only on count-based blocking (fail2ban and the like) · medium likelihood Yesterday was not a case of one source hammering the same server repeatedly. It was an average of 8.7 per source, and even admin/admin was 38 times from 17 sources — 2.2 per source. 345gs5662d34 was 14 times from 13 sources, 1.08 per source. A rule like “lock after 5 failures” would not even have fired for most of yesterday’s sources. So we cannot say the absence of this control was yesterday’s decisive factor, and we leave it at “medium.” Locking by IP alone is nearly powerless against attempts spread this thin. You have to apply per-account and total-attempt thresholds together to catch it.

FACT 5. Outbound connections not blocked · high likelihood This is the core of yesterday. “File download” at 34 and “execute after download” at 34 are exactly equal. Every stage that produces real damage yesterday was the server reaching outward to fetch a file. The distribution points are three: hxxp://94[.]154[.]43[.]221/ · hxxp://185[.]93[.]89[.]72/wget · hxxp://5[.]182[.]210[.]174/ok. Had the outbound path been blocked, all 34 of these would fail. Intrusion is a key problem, but arming is a network problem.

INFERRED 6. Logs kept only on the server · medium likelihood Yesterday, 26 events were classified as intent to erase traces. We are a honeypot, so sessions are recorded whole (1,390 yesterday), but on a real server, if logs aren’t shipped off-box, nothing remains after they’re erased. That said, yesterday’s protagonist’s sessions did not include trace deletion, so we leave it at “medium.” A 33-second session may leave no traces by the next morning.

FACT The newly confirmed distribution point hxxp://94[.]154[.]43[.]221/ is subject to reporting to C-TAS (the Korea Internet & Security Agency’s cyber threat information sharing system). That said, what we can confirm goes only as far as the transmission having succeeded; whether it was actually ingested on the other side has to be verified separately.

What We Don’t Know

This is where this blog differs from others. We spend more time writing down what we don’t know than what we do.

What cannot be confirmed about yesterday’s subject

  • [Cannot confirm] All five sessions with records have an empty client-fingerprint column. This is because Telnet leaves no fingerprint (hassh). So we cannot attach yesterday’s protagonist ATK-2872E4 to any of the 39 fingerprint clusters we hold. The fingerprints that dropped samples yesterday were two in the SSH-2.0-Go family (16443846… · 98ddc5604…), but our data does not connect whether these have anything to do with the iran.* delivery.
  • [Cannot confirm] Whether the masked source 94.154.x.x and the distribution point 94[.]154[.]43[.]221 are the same device or different devices in the same range — we have no basis for judging. The last two octets are masked and we do not restore them.
  • [Cannot confirm] We cannot know the reason iran.sparc alone is dynamically linked at 43,832 bytes, unlike the other eight. We cannot distinguish whether the build tool differed or whether building it as one piece failed.
  • [Cannot confirm] The contents of yesterday’s samples, including cat.sh, are not in our hands. We have no basis for judging what these executables do (DDoS? mining? proxy?). External sample classification tags are not attached this time either.
  • [Cannot confirm] ATK-50016C had 20 commands and 11 downloads, yet the intent list is empty. We cannot distinguish whether the classifier failed to classify anything or whether there genuinely were no classifiable actions.
  • [Cannot confirm] We recorded the connection port as 2223 because the per-port tally’s 2223 (263) and the per-protocol tally’s Telnet (263) agree numerically. The session records themselves have no port column. This is an inferred mapping.
  • [Cannot confirm] The judgment “new, absent from the archive” is a comparison against the 23 briefs from August 16 to September 7, not an exhaustive comparison against the original logs. Samples not carried in a brief are not caught by this comparison.

What must be doubted about the data itself

  • [Cannot confirm] The fingerprints’ “cumulative IPs to date” value still sometimes decreases. f555226d… (SSH-2.0-libssh_0.9.6) went 289 sources on 8/29 → 366 on 8/30 → 226 yesterday. The “cumulative isn’t cumulative” state pointed out on September 5 is unchanged three days later. This column must not be read as “cumulative.”
  • [Cannot confirm] On sensor 02, we cannot compute whether one source swept multiple doors together. The per-service tally does not give a source list, and the top-sources list is not broken out by service. The 16-source gap between the per-service unique IP sum (659) and the total (675) also appears to be due to ADB sources, but it cannot be established. Writing 0 would be false, so we leave it as “cannot be computed.”
  • [Cannot confirm] Whether sensor 02’s 2 samples came in through the ADB channel is not stated. All we have is the circumstance that ADB is the only channel on 02 that can store a file and that the stored sample count of 2 matches. There is also no file type information, so we cannot know what they are.
  • [Cannot confirm] There is no basis for what it means that those two samples differ in size by exactly 4,096 bytes. On September 3 we recorded the same 4,096 difference in a different sample pair and reached the same conclusion (no basis).

What we deliberately did not connect

  • [Excluded] The vulnerability indicators that came in as background statistics (6,622 tracked CVEs · 390 CISA KEV · 98 confirmed ransomware-linked) are values pulled from KISA security notices. They do not connect to any session or sample observed yesterday, and yesterday’s intrusion did not use a CVE.
  • [Cannot confirm] C-TAS reporting is confirmed only as far as the transmission having succeeded. The same goes for the processing outcome of yesterday’s new distribution point.

What we make no judgment on at all

  • Carrier/organization (ASN·ISP) — we have no relevant database. We do not infer.
  • Geolocation — same as above. IP geolocation cannot serve as a basis for attribution in the first place. The file names contain the string iran, but this is merely a string the attacker attached. We have no basis whatsoever for connecting it to a country or an actor. This post does not name any country, company, or individual as the attacker.
  • VPN·Tor·cloud status — we have no means of determining this.
  • Sample classification (VirusTotal) — not integrated. Whether yesterday’s nine types belong to a known malware family is not adjudicated by this post.
  • Client string (User-Agent) — neither observation surface is web (HTTP). 01 is SSH and Telnet; 02 is SMB, RDP, VNC, MSSQL, LDAP, and ADB.
  • Vulnerability number (CVE) linkage — SSH and Telnet attacks mostly do not reference a specific vulnerability, and 02 is likewise at the protocol-negotiation stage.

Someone who carries the whole tool set doesn’t wonder what kind of screw head is in a given house. Since only one has to fit, there’s no reason to ask.

The nine sets that arrived on our server yesterday were nine for the same reason. Router, recorder, or set-top box — you don’t know what will catch, so you throw everything down and run whichever fits. We weren’t selected; we were caught on a list.

So what’s to be done on this side is not to stop the set from being made. That’s impossible. Change factory default passwords, don’t put management ports like Telnet straight out on the internet, and block the path by which devices fetch files from outside. Yesterday’s two 33-second sessions pointed exactly there.


The observation date is September 8, 2026, and this post was compiled the following day. The source IP was carried over exactly as masked in the brief (94.154.x.x) and was not restored. Distribution addresses were kept defanged (hxxp://, [.]) in both the body and the IOC block so they can’t be connected to by accident. Credentials were quoted verbatim for only the 20 combinations repeatedly observed from 3 or more different IPs; for the remaining 924, only the count is disclosed and no values are written. Items for which we have no means of measurement — carrier, nationality, VPN status — were left as “we don’t know” rather than inferred.