Honeypot capture

mirai (pboc)

C2 verifiedProtocol documented

An automatic pipeline recovered four command-and-control endpoints from an 84,240-byte ELF sample that was loaded as data and never executed; C2 is the channel an infected machine uses to reach its operator for instructions. All four are hostnames held encrypted in the sample: slursbeback[.]ru, seris[.]gd, slursontel[.]ru and myrepis[.]gd. A honeypot sensor network captured the sample.

On start the bot decrypts an embedded configuration table with RC4, takes a single-instance lock, masquerades its process name, daemonises, and connects over raw TCP to one of the first three domains, rotating between them on each reconnect. Over that channel an operator can task the bot with the registered flood methods, or start a telnet scanner that brute-forces IoT default credentials.

The i386 sample and its Mirai lineage

The sample is a Mirai-lineage Linux IoT DDoS bot and telnet worm for i386, statically linked and stripped, submitted under the attacker-supplied filename jklx86. Its hashes are:

  • SHA-256 c9727a1237b59d5331a1d682e427056257415e13d8772b742c1777a69288bdde
  • MD5 55f7a97a9333dd3a7f844597777b7bad
  • SHA-1 eb95c0a65a1ce52616e1741397066e1114e3eb97
  • ssdeep 1536:TXmTJjc9efi6a2PODl4d//ENySt3H7mWEGU3AMnYzXgdcX1TT:TXudcgi6BPODadntaLmW7mRYDlTT — a fuzzy hash, which stays close under small edits and so matches near-identical variants of the same build.

The loader offers victims an architecture-name payload table, arm5/arm6/arm7/mips/mpsl/ppc/spc/sh4. The five architectures the campaign builds for are led by arm and mips, which the report reads as the signature of a campaign aimed at routers, cameras and other embedded devices rather than at servers.

The strings /bin/busybox and ncorrect carry the family signature. The sample diverges from baseline Mirai in three respects: RC4 in place of the single-byte XOR for the config, the random-port C2 table of 121 ports, and TLS-ClientHello and HTTP/2 flood methods. The decrypted config also carries an operator watermark, The Peoples Bank of China., which together with the hostname PBOC marker gives the variant its name, pboc.

The RC4 config decryptor

RC4 is the only cryptography in the sample, and the bot applies it only to the configuration at rest. RC4 at 0x8055be0 decodes 11 config records with a 256-byte key hardcoded at 0x805b920; there is no IV, and the S-box is re-keyed from offset 0 for every record. The compiled swap is an XOR swap that zeroes S[i] when i == j (0x8055cba), and that behaviour is required to decrypt each record past its first 16 bytes. Because textbook RC4 does not zero S[i], both the extractor and the packet dissector implement the compiled behaviour instead.

Two non-endpoint strings come out of the same table: the watermark above, and TSource Engine Query, the Valve A2S query used by one of the reflection floods.

The four decrypted hosts

Values as decrypted from the config table, with the virtual address of each string and the pipeline’s confidence score. The port shown is the first entry of the 121-entry table at 0x805af40, spanning 38242–46812; the connector at 0x80506e0 picks one at random per attempt.

ValuePortProtoRoleVAConf
slursbeback[.]ru38242tcpprimary0x805b8880.90
seris[.]gd38242tcpfallback0x805b8970.90
slursontel[.]ru38242tcpfallback0x805b8a00.90
myrepis[.]gd—httploader / report0x805b8ae0.75

Blocking should cover the whole 38242–46812 range rather than the single port shown.

The wire protocol

The wire format is a fixed 16-byte header, assembled at 0x80522f0 and parsed at 0x8051e80: a 4-byte session magic (00000000 in this build), a version byte 0x03, an XOR’d message-type byte, flags, reserved, a big-endian 32-bit sequence/parameter, a big-endian 16-bit length at offset 12 capped at 0x400, and a big-endian 16-bit checksum at offset 14. The transport is raw TCP with a non-blocking connect, and the channel carries no TLS.

The payload is XORed with a 4-byte rolling key taken from the session context at 0x805d574, but nothing ever writes that context, so the key is 00000000, the transform is the identity, and captured traffic is plaintext under the header. The report leaves open whether the session context is ever seeded. A build that seeds it would make the header magic and the payload XOR live. The codec structure stays the same, and the tools’ KEY and SESSION_MAGIC constants would need updating.

The bot resolves one of the three domains in rotation (mod 3), connects on a random port at no more than one attempt per second, then beacons a status report roughly every 30 seconds and dispatches inbound command frames as they arrive. The dispatcher at 0x8050490 handles three inbound opcodes alongside the outbound report.

OpcodeHandlerBehaviour
10x80522f0client report (outbound status frame)
20x8051d20request_report — server asks for a status frame
30x8048250attack — duration, method id, target CIDR list, options
70x8055a90scanner_control — start/stop the telnet scanner and loader

The report documents two protocol messages to the byte, and two recorded test vectors replay through the dissector. The dissector decodes one report frame to the victim’s process name and beacon sequence, and one attack frame to the full tasking — target list, method id, duration and destination port. The reproduction tooling includes a client and an emulator, and carries its own warning in the report:

The reproduction/ tools are live-C2 code. They touch the network only when explicitly pointed at a --target/--listen. Run them only in an isolated lane.

The telnet scanner and the loader chain

The telnet scanner at 0x8054190 brute-forces default credentials over TCP/23 from a built-in dictionary of more than 60 entries (T1110.001). On a successful login it writes a busybox wget/tftp/ftpget/curl download-and-execute chain into the victim’s shell (0x80555d9) to fetch an architecture-matched second stage, the payload that holds the capability the operator wants. One of those transfer methods, TFTP, is a minimal file-transfer protocol over UDP with no authentication, common on embedded devices and often reachable where HTTP is not. The resolved syscalls include no execve and no clone, so the bot sends the shell strings to the victim and the victim runs them.

The chain leaves three host indicators on the victim: the hostname set via /bin/busybox hostname PBOC as an infection and territorial marker, the second-stage binary name in the chain’s tail ; ./dvrHelper selfrep, and the dropped .d file in /var/tmp or /dev/shm. The bot itself is memory-resident and installs no autostart persistence, consistent with the family.

Rival killing and watchdog suppression

The bot walks /proc/net/tcp and kills competing processes (0x804fd70, T1057). At startup it also reads the KERN_SECURELEVEL environment variable and issues an ioctl on the watchdog path to keep the device from rebooting (0x8051569, T1562.001). Watchdog suppression is scored 0.50, the lowest confidence of the seven capabilities, because the single ioctl site at 0x805a24a was not read through to its request constant, so the interpretation rests on the KERN_SECURELEVEL string alone.

What was ruled out

The decompiled attack table at 0x80485b0 overturned a phase-5 hypothesis of the pipeline’s own, which had the HTTP/2-over-TLS machinery as the primary C2 transport. The registration table shows that machinery as flood methods 0x12 and 0x13, and the www.example.com SNI and :authority values are flood-packet templates. The sample also has no C2 listener. accept has zero code cross-references, and the only bind and listen is the single-instance lock.

Open questions

The analysis is static only and no endpoint was contacted, so whether any of the recovered infrastructure is still live is unresolved, as is what second stage myrepis[.]gd and the scanned peers hand out. Nothing here is observed behaviour, so runtime timing, retries and post-execution activity are outside what static analysis can show. The exact membership of the 15 flood methods and the method-id-to-name mapping also stay open.

Family
mirai
First seen
September 10, 2026
Vector
Runs as a ddos-bot/worm; the entry vector is not established by static analysis
Format
82 KB x86 ELF 32-bit LSB executable
VirusTotal
42/74 engines: trojan.mirai/ddos
Tags
ddos-bot · elf · raw_tcp · worm · x86
Sample
By request. Email [email protected]

SHA-256

  • c9727a1237b59d5331a1d682e427056257415e13d8772b742c1777a69288bdde as captured

Analysis performed using an automatic malware analysis pipeline using Binary Ninja

← All captures