DIICOT · Chapter 34
DIICOT: One syllable apart
Comes from chapter 33 · DIICOT: Ciocolata flavour
The executor from the last chapter calls a machine I already knew and keeps as a fallback a domain that looks far too much like one that did exist. Pulling on that one-syllable difference brings out its big brother, the previous C2 and the slot it uses to get into its victims. In the end, I asked the other side what it sends.
The last chapter left the critter open on the table: a command executor that calls 91.92.47.220:222, introduces itself with Ciocolata and hands bash whatever it's sent. And it left two loose ends. The fallback domain, which rang a bell. And the first line the server sends, which the critter throws away without looking at it.
Neither gets resolved inside the binary. I started with the address, because that one I already knew.
01The thread to DIICOT
It was the one that made me look twice. This is what ties the critter to the series, split into what I saw and what I deduce:
seen 91.92.47.220: here, the C2 on 222. In chapter 27, the mesh's seed on 8081
seen same network: AS197170 TechTies
seen the same range, 77.239.124.0/24, dropped into /tmp/cache the mesh bot (7-9 Oct) and this executor (15 Oct)
seen Go, 2026, and the same kind of obfuscator: every string encrypted, decrypted right before use
seen nothing of the mesh inside: no 8081, no Telegram, no peers.dat, no DIICOT-BOTNET, no miners
seen its hash matches no sample from chapters 23 to 28
deduced another piece of the same setup: not the mesh bot, something elseThen I looked at the machine without touching it: what Shodan and Censys had already gathered on their own, without me sending it a single packet.
91.92.47.220 AS197170 TechTies · Netherlands or United Kingdom, depending on the source
22 SSH same key from August to October, updated month by month
1337 distribution served a file to an intruder on the decoy in October
8081 mesh seed visible: answers «auth:bad»
222 this executor invisible to Shodan and to Censys
… hundreds more ports, the pattern of a scannerShodan has scanned it 878 times since August, on 652 different ports. Port 222 hasn't shown up once, and not in Censys either, not even as an open, silent port. Maybe the server stays quiet until someone says Ciocolata to it, or maybe that port hasn't been open for long: this C2 appears with the sample, in mid-October. From the outside you can't tell which.
The SSH tells a different story: the same machine key for months, and the SSH server moving up a version with every patch. It isn't an abandoned machine: someone looks after it.
Last, I searched for other machines with that same key, in case the operator had cloned the image onto more servers. Shodan gave me one candidate that turned out to be a coincidence in its own index (a different service that happened to share the same internal number), so I discarded it. Censys, which is the right source for this, returned a single result: the machine itself.

02One syllable apart
Searching for the fallback domain, hotel.wildhorsehotnet.net, in case anyone had seen it, another almost identical one came up: hotel.wildhorsehotel.net. Where the critter says hotnet, that one says hotel. And it carries malware detections.
The first thing was to check I hadn't got it wrong when decrypting. I hadn't. On the wire, each piece of a domain name travels with its length in front, and the critter sent a 15. wildhorsehotnet has 15 letters; wildhorsehotel, 14. The binary asks for hotnet. The difference is its, not mine.
So I looked at the other one's history, without touching it: what passive DNS, VirusTotal and urlscan already had stored.
Feb 2025 served by Njalla # the favourite of those who'd rather not give a name
Jun-Oct 2025 hotel. → 5.178.96.15
Feb 2026 expires · "renew your domain" page
23 Apr 2026 someone else registers it · parked on Google CloudA domain somebody used for a year, let expire and lost. Today it belongs to someone else, with every sign of being a parked domain. The detections it carries are the legacy of its past; today it isn't an indicator.
And who used it? VirusTotal keeps track of which files asked for that name when run. There are eight. Two are called ciubuc_x86 (ciubuc is a Romanian word) and are a Mirai/Gafgyt from June 2025. The rest are big binaries, eight to eighteen megabytes packed with UPX, that wipe other people's cron, kill the competition by name and ask a service of their own what their public IP is; one of them sweeps SSH and installs itself in cron. In one of them that service is 31.57.105.94:42. The same one as in chapter 27: the first one the mesh bot asked.
And the 2025 IP, 5.178.96.15: VirusTotal has eleven files talking to it, between July 2025 and April 2026, and the ones I've looked at do so on port 222. ThreatFox lists it as a C2 since July, with these tags: Diicot, Mexals and ElPatrono1337, the signature on the SSH key in chapter 28.
Among those eleven was one of almost three megabytes, unpacked. I ran the fuzzy hash against ours: 13. The closer to zero, the more alike. That alone doesn't prove much: in two Go binaries almost everything is the engine, and the hash mostly measures the workshop. What proves it is the code, and I'm getting there. It arrived packed under the name cache, and it was dropped by those big bots, several of them named Update on disk. In chapter 26, /tmp/cache was already among the things the chain leaves behind. Our sample, seen through those eyes, also arrived packed and was also called cache.
The proof that mattered was still missing. I pulled the sibling from MalwareBazaar and, without running it, searched it for the call chain from the last chapter with a search tool that knows nothing about either of them; I'd tested it on ours first, and it pulled out the domain on its own:
sibling (2025) 28 numbers, K = 0x48 → hotel.wildhorsehotel.net:222
ours (2026) 29 numbers, K = 0x12 → hotel.wildhorsehotnet.net:222
^^^The same trick, in the same spot in the program and with the same port. The seed changes because the obfuscator draws it at random on every build. In the fallback, one syllable changes, and one more letter is one more number in the chain. In the bot, more changed: the new version's main function is twice the size, and it's the one that adds the ten-second wait and throws away the first line. The old one has neither.
C2 fallback
2025 → Oct 2026 5.178.96.15:222 hotel.wildhorsehotel.net:222 # the domain expires in February
Oct 2026 91.92.47.220:222 hotel.wildhorsehotnet.net:222 # nobody has registered itBoth versions came through my decoy three days apart. On 12 October, the old cache arrived with the worm, without anyone uploading it by name, and called 5.178.96.15:222 with its Ciocolata. On the 15th, the new one was uploaded straight over scp by the 77.239.124.0/24 range, and called 91.92.47.220:222. And earlier, from the 7th to the 9th, that same range had dropped something else into the same /tmp/cache: the mesh bot from chapter 26, same hash.
And the sibling left one more thing, as a gift. In March, in one of VirusTotal's sandboxes, its C2 was still answering. The critter ran this:
bash -c "ClientID: 27813"The server greets with a client number, and the old version handed it to bash as if it were a command. The new one, ours, throws away the first line without looking at it: the thing that puzzled me in the last chapter. It fits as a fix between versions, and the code backs it up: it's exactly what the old one lacks. In the next section, today's C2 shows it.
03What the other side said
For most of the investigation I held that you don't ask port 222 anything. In the end I thought it over again. What's behind it isn't a door hidden for one: it serves anyone who says Ciocolata, and it's built for hundreds of infected machines. One more connection doesn't stand out. The condition was that it shouldn't come from any machine of mine.
So it came from one that has nothing to do with the decoy, the lab or this blog. The program was very short and did one thing only: introduce itself the way the critter would, with a made-up machine name, and listen. It doesn't answer, doesn't obey, doesn't call back. Whatever arrives it stores in hexadecimal, and nothing more.
0.000 → Ciocolata · <made-up name> # the greeting, once only
0.053 ← ClientID: <n> # the banner: a number
0.054 ← 1,316 bytes, five lines of shell # the commands
… ← nothing else # we didn't answer; no heartbeatThe first line is a client number, like the ClientID the old C2 sent the sibling on VirusTotal. And that settles what puzzled me in the last chapter. The critter throws away the first line because the server always starts with it. If it ran it, bash would answer ClientID: command not found, which is exactly what the old version did. The real commands come after.
I'm not printing the exact number I got: it's the fingerprint of my connection. But there are two others that can be used, because the sibling received them in VirusTotal's sandboxes, from its C2 at the time:
10 Dec 2025 CAPE ClientID: 5842
5 Mar 2026 Zenbox ClientID: 27813
──────────────────────────
about 22,000 more in 85 days ≈ 260 a day · ≈ 11 an hourIf it's a counter, and if nobody reset it in between, that server was getting eleven calls an hour. But those are calls, not victims. The critter leaves after ten seconds if nobody talks to it, every time something relaunches it a new number gets used, and a single machine that keeps trying can burn through dozens a day. Sandboxes and curious people like me count too. It's the door's pulse, not the size of the fleet.
And what comes after the banner asks for nothing secret. It's five lines, five commands the bot runs one by one, and all of them ask for measurements:
1 how many cores nproc
2 how much memory free -m
3 how much disk df -m /
4 how much download against speed.cloudflare.com, up to four downloads at once
5 how much upload the same, uploading ten megabytes of zeros
with curl if it's there; otherwise, with wgetNo passwords, no files, no keys. It's what someone does when they have lots of machines and need to decide what to do with each one: this one has eight cores, this one has a fat pipe, this one is no good for anything. The first thing it asks every victim is how much it can deliver. And it isn't the first time I've seen it. Before uploading anything to the decoy, the 77.239.124.0/24 range asked the same thing another way: nproc, lspci, nvidia-smi looking for a graphics card. Two different pieces with the same obsession.
This, by the way, isn't something I uncovered. The first four commands were already out in the open: on 14 October, the day before the critter landed on the decoy, VirusTotal's sandboxes ran it, the C2 answered them and the triage was recorded, letter for letter the same. What the listening added is the banner, the order in which everything arrives and the fifth command, the upload one, which doesn't appear there.
What it does with those numbers afterwards, I don't know. To find out I'd have to send them back, and at that point I'd stop listening and start playing on their side.
04Indicators
The binary's are in the last chapter. These are the infrastructure's and the family's.
| Type | Value |
|---|---|
| Primary C2 | 91.92.47.220:222 (TCP, plain text; AS197170 TechTies; the same machine is the mesh seed on 8081, chapter 27, and distributes files on 1337) |
| Fallback C2 | hotel.wildhorsehotnet.net:222 (unregistered as of November 2026: dormant fallback) |
| Previous C2 | 5.178.96.15:222 (seen from July 2025 to October 2026; in ThreatFox as Diicot; rented IP, may change hands) |
| C2 banner | ClientID: <n> as the first line, before the commands |
| First commands seen | five-line triage: cores, memory, disk, download and upload against speed.cloudflare.com (legitimate service: what gives it away is the pattern, not the domain) · in VirusTotal sandboxes since 14 October 2026; received again, with the upload, on 2 November |
| Delivery | 77.239.124.0/24 (SSH brute force with a Go client, scp of /var/tmp/<8 letters> and /tmp/cache, /tmp/d.log marker holding the guessed password) |
| Downloads | hxxp://91.92.47[.]220:1337/<6 letters>/c (the same machine also distributes files) |
| Name on disk | /tmp/cache is a slot: it has held the mesh bot and both versions of this executor · the old one is dropped by the worm (Update), the new one arrives straight over scp |
| C2 SSH key | SHA-256 ba13ccd57a8dce8d84f49deacdcbe1697035bd8a577b34c5c63cb1758182448f · MD5 dc:d0:64:24:28:b0:cf:cc:cc:3d:8e:b7:c0:48:43:40 |
| SHA-256 sibling | 6041b27598fa7db6df3364ba1e1d94268616bef7ccab5cd48c2646b6a7d087e2 (unpacked from 640c817722a4cd22251fcff100fdba167b7dfff885f36b5f64f2d59c52514180) |
If a server, without anyone asking, starts measuring its speed against speed.cloudflare.com with several threads at once, someone is taking its measurements.
To be continued - the decoy stays lit. I already know the first thing its master sends every new machine: a tape measure. What comes after the measuring, only whoever sends the numbers back will find out, and nothing gets sent back from here. 🍯
Comments