SecurityHeroblog

The Same File, Twice Over — and They Left the Label Inside

On September 7, an address that had never appeared in 22 days of records showed up for the first time. The two executables downloaded from it are nearly identical in size and do the same thing — two builds differing only in the order they read numbers. Whoever made them sent them out without stripping the labels inside the files.

You have probably hesitated before plugging in a charger while traveling abroad. Korean outlets take two round pins; some countries take two flat pins, and some take three. Even if the parts inside are the same, it does no good if the shape that plugs in is different.

So companies that sell a lot of product make several versions of the same item, one per country’s plug. They stack them side by side in a warehouse, and when an order comes in, they pull out the one that fits that country and ship it.

What came into our server yesterday looked exactly like that.

First, what happened yesterday afternoon

FACT At 3:41 p.m. on September 7, someone came into our honeypot over telnet. A honeypot is a fake server left deliberately wide open. It is there so we can watch what an attacker does, so what happens here is not real damage but an observation record. Telnet is a very old remote-access method, and it has the problem that the characters exchanged travel in the clear, unencrypted.

FACT We assigned the alias ATK-33267B to the party that came in. An alias is not an identity. It is only a marker so we can refer to the same masked source across briefs. This alias is a brand-new alias that never appeared in the 22 days of our archive from August 16 to September 6.

Laid out in chronological order, it looks like this. Pay attention to the seconds at the far right, and to the intervals between sessions.

  1. FACT ATK-33267B connects over telnet and logs in successfully. 3 commands and 3 downloads over 24.3 seconds. TTY recorded
  2. FACT The same alias reconnects. 22.5 seconds, 3 commands, 3 downloads — values identical to the first session
  3. FACT Third round. 22.4 seconds, 3 commands, 3 downloads. 2 minutes 7 seconds after the second
  4. FACT Fourth round. 23.4 seconds, 3 commands, 3 downloads. 1 minute 27 seconds after the third — four times within the 11 minutes from 06:41 to 06:52
  5. FACT Fifth round. 23.1 seconds, 3 commands, 3 downloads. 2 hours 0 minutes 39 seconds after the start of the first
  6. FACT The observation counts for the 3 files delivered by this alias total 12+10+5=27, and all three have ATK-33267B alone as delivered_by
  7. INFERRED At 3 downloads per session, 27 corresponds to about 9 sessions — the 5 exposed in notable_sessions are the most complete of those
  8. INFERRED That the fifth round falls exactly 2 hours after the first, and that session lengths cluster within 22.4–24.3 seconds, points not to a person typing but to automation on a scheduler

FACT All five visits are the same. Successful login, 3 commands, 3 downloads. Time spent ranges from 22.4 to 24.3 seconds. The difference between the longest and the shortest is 1.9 seconds. It is hard for a person typing five times to produce that.

FACT The channel this alias came in through is telnet port 2223. No client-program fingerprint is left here. SSH exchanges a greeting to negotiate parameters on connect, and a fingerprint (hassh) can be taken from the shape of that, but telnet has no such step at all. In the records, the fingerprint field and the client field are empty strings.

INFERRED So “there is no fingerprint” must not be read as “they came and went quietly.” Our instrumentation simply cannot see it on that channel to begin with.

The three files they took

This is where today’s main point begins.

FACT Three files were taken in each session, all from the same address: hxxp://131[.]123[.]40[.]104/. Writing the address this strangely is not a typo. It is the practice of changing http to hxxp and dots to [.] so nobody connects by accidentally clicking it. It means defang — pulling the teeth out.

FACT Neither this address nor the hashes of the three files downloaded from it appear even once in the 22 days of our archive. The address, the hashes, the file names, and the alias are all things we are seeing for the first time.

Here is the file list. Look at the two sizes, and at the letters MSB and LSB beside them.

sha256
8e06754e5e64bdf5f61dd604a5f12e9bc10f5502316b5379fb258f84a5d84702924-byte loader script (ASCII text) · 12 times today · new hash
url
hxxp://131[.]123[.]40[.]104/bins.shDistribution point for the loader above. A new address not present in the 22 days of archive
sha256
30c7d351e70323915566d2bb648b4313c9722b34252929a8c7050f6495ae14fc304,889 bytes, ELF 32-bit MSB (big-endian) MIPS MIPS-I · statically linked · not stripped · 10 times today · new hash
url
hxxp://131[.]123[.]40[.]104/GHfjfgvjPath of the MSB executable above
sha256
7cc0b40e8819ec9139ffae5942add2db1c26e168edaeda57302c9047f23dfb6c305,654 bytes, ELF 32-bit LSB (little-endian) MIPS MIPS-I · statically linked · not stripped · 5 times today · new hash. 765 bytes different in size from the MSB build
url
hxxp://131[.]123[.]40[.]104/JIPJIPJjPath of the LSB executable above
sha256
a6296a79f44e21b76604d2d2bbf795d2cf380f70e39d45fbf166707ff3b4a6a4306-byte POSIX shell script · 10 times today · delivered by 10 different aliases. Same hash continuously since first observed on 8/17
url
hxxp://185[.]93[.]89[.]72/wgetDistribution point for the script above. Not today's subject — background
sha256
a8460f446be540410004b1a8db4083773fa46f7fe76fa84219c93daa1669f8f2389-byte OpenSSH RSA public key · 6 times today · 6 different aliases. The same file observed repeatedly since 8/16. URL not recorded
sha256
4af5a5c98ad132095c6fbe7b02c242153a190a01cc321e50a916a0ca46fbaa629-byte ASCII text · 9 times today · 1 source. The 8/28 and 8/30 briefs also have the same 9-byte entry. URL not recorded

FACT There are two lines in the table to look at. 304,889 bytes and 305,654 bytes. The difference is only 765 bytes. Out of 300,000 bytes, 765 bytes is 0.25%. And both are for the same MIPS CPU family; the only difference is a single set of letters in the parentheses. One is MSB, one is LSB.

MSB and LSB — the order in which numbers are read

FACT Computers split large numbers across several slots to store them. But which digit gets written first differs from machine to machine. Some machines write 1234 front-first as 1-2-3-4; others write it back-first as 4-3-2-1. The front-first kind is called big-endian (MSB), the back-first kind little-endian (LSB).

FACT Same value, opposite writing order. So if you put a program built for one kind of machine on the other kind, it reads numbers wrongly and simply stops. It is exactly like an outlet whose holes don’t match.

INFERRED So the makers prepared two builds. They built the same program separately for two CPU families with opposite byte order. The 765-byte size difference is about what you get from rebuilding that way. There is no need to know in advance what shape a given house’s outlet is. Keep both builds in the warehouse, and when a door opens, send both down.

FACT The 924-byte item at the front is not an executable but a script made of text. It is about the size of ten text messages. One executable is roughly 330 times that, so it looks like two heavy crates following in behind a single thin instruction sheet.

They didn’t strip the label inside

FACT The file information carries the words not stripped. When you build a program, plenty of labels put there by the person who made it end up inside it — markers noting which part has which name. Normally these are removed before distribution. It shrinks the size, and it makes it harder for others to take apart. not stripped means they didn’t remove them.

INFERRED It amounts to shipping a garment with the factory label still sewn inside. For the side taking it apart, that is welcome. There is no wrapping to peel off — the markers inside can be read as they are.

FACT The reason this stands out is that another list we hold is the exact opposite. Our unpack_only_iocs list contains 12 URLs: parm · parm5 · parm6 · parm64 · parm7 · pm68k · pmips · pmpsl · pppc · psh4 · pspc · x86_64 under hxxp://31[.]77[.]227[.]121/bins/. Those 12 are indicators that only emerged after unpacking. Once something is squeezed down with a tool called UPX, not a single address is visible on the surface.

FACT Reading those 12 names, the CPU types are written right into them. Five in the arm family, m68k, mips, mipsel, two ppc, sh4, x86_64. It has the shape of a menu board with one program built 12 ways, one per CPU type. The one MIPS big-endian build and one little-endian build taken yesterday correspond to exactly two slots on that menu.

INFERRED The distribution points differ, though. The 12 indicators came from 31[.]77[.]227[.]121, while yesterday’s was 131[.]123[.]40[.]104. We have no grounds to say it is the same infrastructure or run by the same person. What we can say goes as far as the structures resemble each other — and that a side that squeezed the outside to hide addresses and a side that hid nothing at all came into the same observation surface on the same day.

The first two octets matched

FACT The IP the connection came from is 131.123.x.x. The last two slots are masked. We do not restore them. And the address the files were downloaded from is 131[.]123[.]40[.]104. The first two slots match.

INFERRED We can say as far as this: the point that intruded and the point that delivered the goods are within the same range. No further. Since the third and fourth slots are masked, our data cannot determine whether it is the same computer or a different computer in the same neighborhood. We did not try to undo the masking and match them, and we did not write that it is the same host.

The key that opened the door

FACT Yesterday there were 2,841 login attempts across one day, coming from 271 different places. Divided across 24 hours, that amounts to someone trying an ID and password roughly once every 30 seconds.

FACT There were 2,547 combinations attempted. Only 20 of them are reproduced in this post. For the remaining 2,527 we count them but do not write the values. Our rule is to quote verbatim only combinations repeated from three or more different IPs. A combination that showed up from only one or two places could be someone’s real account leaked from somewhere.

ID Password Distinct sources
admin admin 20
345gs5662d34 345gs5662d34 6
root 1234 6
root xmhdipc 5
ubuntu ubuntu 5
root 12345 5
support support 4
root admin 4
root root 4
root root123 4
root 123456 4
root 12345678 4
root 123456789 4
root linux 4
root password 4
root uClinux 3
username password 3
admin password 3
vagrant vagrant 3
runner runner 3

FACT Look at uClinux and xmhdipc toward the bottom of the list. These are not passwords a person makes up and uses, but factory default passwords put into devices like routers, CCTV recorders, and cameras. This dictionary is aimed not at servers but at the small machines in homes and offices.

FACT And the attempts these 20 produced number 139 — only 4.9% of the total 2,841. The conspicuous admin/admin is the tip of the iceberg. 95% of attempts came from a tail we cannot name.

The whole of yesterday

This is the day as recorded by Honeypot 01 (SSH/telnet). Look at the far-right column comparing against the day before.

Item September 7 vs. September 6
Sessions 3,406 2,207 → +54.3%
Distinct sources 271 414 → −34.5%
Sessions per source 12.57 5.33 → 2.4×
Login attempts 2,841 1,889 → +50.4%
Commands 3,537 2,711 → +30.5%
SSH (port 2222) 2,854 sessions 1,883 → +51.6%
Telnet (port 2223) 551 sessions 324 → +70.1%
TTY recordings 2,628 —

INFERRED It reads a little oddly. The number of places that came fell, while sessions rose. It means each place came in an average of 12.57 times. That is 2.4× yesterday’s figure. Fewer parties stayed longer.

FACT Of the 3,537 commands, 2,962 (83.7%) had an intent classified. Inside that, it looks like this.

What they were trying to do Count
Reconnaissance — looking over the system 2,407
Granting execute permission 298
Download then execute 121
File download 121
Persistence — planting an SSH key 8
Removing traces 7

FACT “File download” and “download then execute” are exactly the same, 121 each. Every file downloaded yesterday went on to be executed, without exception. And commands granting execute permission number 298, 2.5× more than downloads.

FACT The combination observed in ATK-33267B’s sessions is the three-step “file download → grant execute permission → download then execute.” This alias’s sessions contain neither SSH key planting nor trace removal. The 8 instances of leaving a key behind and the 7 of erasing traces were the work of other aliases.

A different door rang on the server next door

FACT We put out two servers. The second (Honeypot 02) is a shallow trap that does not let anyone inside, so only “which door was knocked on, by how many places, how many times” remains. Successful logins, commands, and credentials do not exist here.

Service Port Contacts Distinct sources vs. September 6
VNC (screen sharing) 5900 58,811 285 48,605 → +21.0%
RDP (remote desktop) 3389 2,074 142 1,474 → +40.7%
SMB (file sharing) 445 627 49 200 → 3.1×
MSSQL (database) 1433 60 40 77 → decrease
LDAP (account lookup) 389 5 4 14 → decrease
ADB (Android Debug) — 50 — —

FACT 58,811 VNC contacts is about once every 1.5 seconds. Since 285 places produced it between them, each place knocked an average of 206 times. And 97.9% of these proposed RFB 3.3, the oldest version of the protocol, first. The SMB side is worse. Every dialect the other side offered was in the SMB1 family; not a single SMB2 or SMB3 was proposed.

INFERRED Deliberately throwing only obsolete protocol versions looks less like targeting a specific vulnerability and more like the behavior of a general-purpose scanner trying to draw out any response at all. Which vulnerability it connects to is not in our data.

FACT The 4 samples obtained on 02 (46,525 / 239,388 / 334,816 / 153,208 bytes, 773,937 bytes in total) all came in over the ADB channel, and the delivering alias is a single one, ATK-B987B3. These four hashes are the same as ones that already appeared in the August 28 and 30 briefs. The delivering aliases at the time were each different.

INFERRED The files are fixed and only the source changes. But a different alias only means the masked source is different; whether the party behind it is the same or different cannot be judged.

Mapped onto the international classification

Here is what the attacker’s methods look like mapped onto the common global classification (MITRE ATT&CK). Press an ID to check the original description yourself — you don’t have to take our word for it.

  • T1110.001Brute Force: Password Guessing — 2,841 login attempts / 271 unique sources. Of the 2,547 combinations observed, 2,527 are a tail appearing from fewer than 3 IPsINFERRED
  • T1078.001Valid Accounts: Default Accounts — admin/admin 41 times from 20 different IPs. Default combinations such as root/1234 and ubuntu/ubuntu filled the top of the listINFERRED
  • T1105Ingress Tool Transfer — 121 instances of "file download" intent, 6 samples obtained. ATK-33267B took 3 of them from hxxp://131[.]123[.]40[.]104/INFERRED
  • T1222.002File and Directory Permissions Modification: Linux and Mac — "grant execute permission" 298 times, 2.5× more than downloads (121)INFERRED
  • T1059.004Command and Scripting Interpreter: Unix Shell — "download then execute" 121 times. The 924-byte loader script was obtained as textINFERRED
  • T1082System Information Discovery — "reconnaissance — system" 2,407 times, 81.3% of today's classified intentsINFERRED
  • T1098.004Account Manipulation: SSH Authorized Keys — "persistence — planting an SSH key" 8 times; 6 aliases left a 389-byte public key. Not present in ATK-33267B's sessionsINFERRED
  • T1070Indicator Removal — "removing traces" 7 times. At 0.2% of all 3,537 commands, it was rare todayINFERRED
  • T1595Active Scanning — on Honeypot 02, 61,577 sessions across 5 services + 50 ADB sessions, 546 unique sources. Successful logins do not existINFERRED

FACT Of the nine lines, yesterday’s protagonist stepped on only three. T1105 (fetching files), T1222.002 (granting execute permission), T1059.004 (running what was fetched). Exactly three steps, 22 seconds. The other six lines were left by other guests.

We have seen shapes like this before

INFERRED The distribution pattern of “one loader script + executables split by CPU family” is not something we are seeing for the first time.

  • The Mirai botnet (2016) — after logging into embedded devices with default telnet credentials, a shell-script loader had them download, in order, ELF binaries split by CPU architecture (MIPS big-endian and little-endian, ARM, PPC, SH4, x86, and so on). The shape of the distribution method is the same as yesterday’s “924-byte loader + two MIPS MSB/LSB builds.” (Sources: US CISA (then US-CERT) alert TA16-288A and publicly released source code)
  • The Mozi botnet (2019) — the observed shape overlaps in initial access via weak telnet passwords and distribution of MIPS-family ELF binaries. We cannot confirm infection scale or damage figures from our data, so we do not write them. (Sources: public analysis reports from 360 Netlab, the Microsoft Security Blog, and others)

FACT We stop here. We have not integrated a sample classification service. So we do not render a judgment that the two ELFs obtained yesterday belong to these families. What resembles is the method of making them, not a name tag.

So what should be done

We cannot change the shape of the outlet. What we can change is how many outlets we are exposing on the outside of our own wall.

FACT 1. If you are still using default accounts and easy passwords — likelihood high. If you use even one of the combinations in the table above, getting through is not a matter of time but immediate. One session observed yesterday went from login to file execution in 22 seconds.

FACT 2. If you allow password login and don’t use key authentication — likelihood high. All five of yesterday’s most complete sessions succeeded with a password. And over telnet at that, so the credentials traveled without encryption. Separately, 8 times yesterday, from 6 different places, a single 389-byte public key file was left behind. This is a back door that survives even if you change the password. It is the classic path by which the time of compromise and the time of discovery end up months apart.

FACT 3. If you have left management ports open to the internet — likelihood high. We have never advertised our honeypot’s address anywhere. Even so, 271 places came, and the server next door got 58,811 contacts on VNC alone. If it is open, it will be found.

INFERRED 4. If you have no connection-rate limiting (something like fail2ban) — likelihood high. Yesterday the same place came in four times within 11 minutes, and the reconnection interval narrowed to 1 minute 27 seconds. That is a stretch that rate limiting alone would have cut off. Without blocking, the attacker pays no cost for failing.

FACT 5. If you are not blocking outbound connections — likelihood high. 121 file downloads and 121 download-then-execute are exactly the same. If outbound connections from this server to that address had been blocked, none of the three files would have arrived. Intrusion is a key problem, but arming is a communications problem. Even if login is breached, you can cut it at the payload stage.

INFERRED 6. If you are not shipping logs off the server — likelihood medium. Yesterday, intent to erase traces was observed 7 times. At 0.2% of all commands it was rare, and it was not present in yesterday’s protagonist’s sessions. So we set this at “medium” — yesterday’s data gives no grounds to claim organized log destruction. But a session that ends in 22 seconds is caught only in after-the-fact records unless you have real-time detection. If those records live only on the server, there is nothing to be done once they are erased.

FACT The newly observed distribution point 131[.]123[.]40[.]104 is subject to reporting to C-TAS (KISA’s Cyber Threat Analysis & Sharing system). But 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 checked separately.

What We Don’t Know

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

FACT

  • We don’t know the total number of times ATK-33267B came in during the day. Only 5 are recorded in detail, and the observation counts for the 3 files this alias delivered total 27. At 3 per session that would be about 9 sessions, but the per-file counts of 12, 10, and 5 are not even, so we cannot conclude that every session received the same 3 files.
  • It is a fact that the first two slots of the source 131.123.x.x and the distribution point 131[.]123[.]40[.]104 match. But because the last two slots are masked, we cannot determine whether it is the same IP or a different host in the same range. We did not attempt to restore them.
  • Yesterday’s protagonist came over telnet, so there is no client-program fingerprint. The clustering tool we use (actor_clustering) holds 38 clusters, but it is SSH-only, so it structurally does not apply to yesterday’s most complete intrusion.
  • Yesterday’s largest fingerprint group was the SSH-2.0-OpenSSH_7.4 family at 80 IPs. And yet this group did not leave behind a single file. The only fingerprint that delivered a sample yesterday was SSH-2.0-Go (6 IPs). Scale and effect are different axes. And a fingerprint is a fingerprint of a build, not of a person — unrelated people using the same distribution’s default OpenSSH produce the same value.
  • The problem noted on September 5 still holds. The “cumulative IPs to date” value for fingerprints sometimes goes down from day to day, so it is not confirmed to be a genuine cumulative figure. Yesterday’s values must be read under the same reservation.
  • On Honeypot 02, we cannot compute whether a single source swept multiple services. There is no per-source service mapping, and the sum of per-service unique IPs (520) is smaller than the total (546). Yesterday’s data cannot support whether this was targeted or indiscriminate scanning, so rather than writing it as 0 we left it as “unknown.”
  • The 4 samples on 02 have no URL or file-type fields at all. There are only sizes, hashes, and the delivering alias. What kind of files they are cannot be stated from this data.
  • The 389-byte public key and the 9-byte text have empty URL fields. They appear to have been recorded directly within a session, but the path is not disclosed.
  • A separate indicator includes one Discord webhook address, but the data does not reveal which of yesterday’s sessions or samples it connects to. It does not appear in any of yesterday’s download entries, so it appears to have been obtained through a separate path, and we did not narrate it as connected to yesterday’s incident. A webhook token is itself an abusable value, so we do not reproduce it in the body.
  • The vulnerability background indicators (6,622 CVEs tracked · 390 CISA KEV · 98 confirmed ransomware-linked) were drawn from KISA security notices. They are not connected to any session observed in the honeypot yesterday, and we did not write them as if they were.
  • The 12 URLs in unpack_only_iocs have no date for when they were observed. We cannot tell whether they were newly extracted yesterday or are a cumulative list, so we did not write “they appeared yesterday” and used them only as material for a structural comparison.
  • We confirmed the file types of the two ELFs, but what they do inside is not in our data. We cannot say whether it is mining, a DDoS bot, or a proxy. Yesterday’s account goes as far as “how they came in and what they took.”
  • Of the 3,537 commands, 2,962 have an intent attached. We do not know what the remaining 575 (16.3%) were.

And here are the things we cannot see at all because we have no instrumentation. These are not things that would emerge from investigating further.

  • Carrier/organization (ASN/ISP) — we have no database. We cannot know the source’s telecom operator or organization, and we do not infer it.
  • Geographic information — the same. IP geolocation is not grounds for attribution in the first place. This post does not name any country, company, or individual as an attacker.
  • VPN/Tor/cloud status — we have no means of determining this.
  • Sample classification (VirusTotal) — not integrated. This post does not render a judgment on whether the two ELFs obtained yesterday belong to a known malware family.
  • Client program string (User-Agent) — neither observation surface is web (HTTP). 01 is SSH/telnet; 02 is SMB/RDP/VNC/MSSQL/LDAP/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. We did not link yesterday’s observations to any specific vulnerability.

The reason people buy several travel adapters is not that they don’t know which country they are going to. It is that they intend to go to any of them.

The two-build file that came into our server yesterday was two builds for the same reason. Not knowing which machine would bite, they prepared both sides. So the job on this end is not to stop adapters from being made. That is impossible.

It is to reduce the number of holes in the wall. Turning off telnet, changing factory default passwords, blocking the path by which equipment fetches files from outside. That is exactly where yesterday’s five 22-second sessions pointed.


The observation date is September 7, 2026, and this post was written up the following day. The source IP is carried over in the masked form given in the brief (131.123.x.x) and was not restored. The distribution point address is kept in defanged form (hxxp://, [.]) in both the body and the IOC block so it cannot be connected to by accident. For credentials, only the 20 combinations repeatedly observed from 3 or more different IPs are quoted verbatim; for the remaining 2,527, only the count is given and the values are not written. Items for which we have no means of measurement — carrier, nationality, VPN status — are left as “we don’t know” rather than inferred.