Honeypot capture
X86 ELF 32-bit LSB executable ddos-bot (59bdafde8769)
A honeypot sensor network captured an i386 ELF of 5939362 bytes (5.9 MB), stripped and statically linked. Every finding below comes from static reading of the file; the sample was never executed, and no recovered endpoint was contacted or resolved. Static recovery of its command-and-control channel — the channel an infected machine uses to reach its operator for instructions — produced one endpoint, 77[.]239[.]124[.]201 on tcp/9111. The host and port sit in .data as two plaintext Go string globals (0x85ea9c8→0x83aa880 and 0x85ea9d0→0x8389fbe), concatenated and handed to net.Dial("tcp", …) at 0x82795f9. A sweep of all 1061 .data string headers found no fallback endpoint list.
Both directions of the channel are newline-delimited ASCII with no magic bytes, length prefix, compression or encryption: the bot sends STATS|active|cpu|memtotal|memused|goarch\n and reads operator command lines of the form [verb] [target] [args…]\n. The verbs dispatch 26 of the 34 Botnet/Methods flood routines as goroutines.
A scanner goroutine runs in parallel with the command channel. It generates random public IPv4 addresses and exploits Boa/TOTOLINK-class router web interfaces to install the sample on them. A worm spreads by copying itself to further machines with no user action, and this scanner gives the sample that capability.
This report asserts no family name. The only naming evidence in the binary is the attacker-chosen Go module path Botnet/Bot recorded in .go.buildinfo, which is a build artefact. The same section gives the toolchain: go1.26.0, -tags=netgo, CGO_ENABLED=0, GOARCH=386, GO386=softfloat — a statically linked 32-bit build with no libc dependency, aimed at heterogeneous embedded and IoT Linux.
The plaintext command channel
The bot dials, and on success starts a telemetry goroutine at 0x827cbe0 that beacons every 2 s (0x827cc07), reading /proc/stat and /proc/meminfo through main.getCPUUsage (0x827da00) and main.getMemInfo (0x827dd80) and reporting CPU, memory and GOARCH. On a dropped connection it reconnects after a 5 s backoff (0x8279606), and there is a 120 s connection-lifetime watchdog at 0x82796b0. The beacon carries no jitter.
crypto/tls.Dial exists in the binary at 0x8205b30, but only two of the flood methods reach it and main.main never does. Entropy in .data, a measure of how random the bytes are that is used to spot compression or encryption, measures 3.55, and there is no embedded encrypted configuration; the endpoint is two plaintext string globals. A single sniffed line to or from the endpoint yields, with no key, the victim’s live CPU percentage, total and used memory, architecture and current attack count in the outbound direction, and the operator’s target, method and duration verbatim in the inbound one.
All 29 verbs the dispatcher accepts have handler addresses that resolve to valid function entries; the verb strings and handler entry points come from the length-bucketed comparison chain at 0x827978f–0x827b4a3, which reads lines with a bufio.Scanner and splits them with strings.Fields. The table below lists six of the 29 verbs.
| Verb | Handler | Behaviour |
|---|---|---|
udp | 0x8274470 | Botnet/Methods.UdpFlood |
raw-udp | 0x8271590 | raw-socket UDP flood |
tlsplusbypass | 0x8273630 | proxy-laundered TLS flood |
STOP | 0x8269f60 | cancel all attacks |
KILL | 0x8279e95 | strip crontab entry, re-exec, delete self, exit |
persist | 0x827ce50 | re-run persistence |
The dispatchable methods span volumetric floods (UDP, TCP, TLS, DNS, HTTPS, OVH and “bypass” variants) and application-layer exhaustion aimed at single services rather than links — Crash at 0x826a160, Freez at 0x826c760, Minecraft at 0x826e3b0, Discord at 0x826a510 — plus game-specific FiveM and Fortnite arms. Eight of the 34 Botnet/Methods entry points have no verb wired to them in the dispatcher, so the attack library is larger than the reachable command set. The numeric argument order after the target (duration, port, thread count, packet size) is fully decoded only for the udp arm, where the default packet size is 1400 bytes (0x578 at 0x827c29f). The client tool emits arguments positionally as the operator supplies them, and the reproduction notes record that neither gap blocks decoding or reproduction of the channel.
main.main.func2 at 0x82816b0 is a second, byte-for-byte parallel STATS frame builder — it references its own copy of the format string at 0x82817da and calls the same main.GetStats at 0x827d970 — with zero code cross-references, and nothing in the static view settles whether it is dead code.
The install and persistence routine
main.AutoStart (0x827ce50) walks a list of install directories — /usr/bin/, then /var/run/, then /data/local/tmp/ (an Android and embedded path), with /tmp/start as the fallback — and probes each one by creating and immediately deleting a zero-length test_write file. Execution requires only user privilege: the systemd, rc.local and /usr/bin routes all need root, and when they fail the binary lands in /tmp and persists through crontab instead.
A successful install leaves the following artefacts on disk, at the file offsets recorded for each behaviour.
| Kind | Value | Context | Offset |
|---|---|---|---|
| systemd | /etc/systemd/system/sysd.service | 164-byte unit: Description=System Daemon Service, ExecStart=[install path], Restart=always, RestartSec=5, WantedBy=multi-user.target; activated with systemctl daemon-reload / enable / start | 0x827d470 |
| cron | * * * * * [install path] > /dev/null 2>&1 | staged through /tmp/cron_tmp, installed with the crontab binary | 0x827d66d |
| file | /etc/rc.local, /etc/rc.d/rc.local, /etc/init.d/boot.local | init-script fallbacks on non-systemd hosts | 0x827d1b1 |
| process_name | sysd | installed filename, chosen to read like systemd | 0x8389fc2 |
| file | proxy/tlsplusbypass.txt | proxy list read relative to the working directory by Botnet/Methods.loadTLSProxies, then relayed through with Proxy-Authorization: Basic | 0x8273190 |
The write calls to the three rc files were located, but the exact line appended to them was not isolated. The strings and symbols recovered from the binary contain no anti-debug, anti-VM or sandbox-evasion checks, and the only ptrace reference is the Go stdlib wrapper. The operator-triggered KILL handler at 0x8279f5d is the only self-deletion path, with no timer or date trigger behind it.
The router exploit chain
main.StartScanner (0x827e190) generates random public IPv4 addresses, filters RFC1918 space, and fingerprints Boa and TOTOLINK router web interfaces over tcp/80. The router-exploit requests and the HTTP floods both draw on a six-entry User-Agent rotation pool whose literals begin at 0x839ff11, 0x83a0467, 0x83a1041, 0x83a164e, 0x83a1c17 and 0x83a2042. The scanner then takes one of two routes onto the device. On the first it logs in and solves the vendor CAPTCHA by posting {"topicurl":"setting/getSanvas"}. On the second it fetches the device’s /config.dat and runs it through main.Decode (0x827e610) to recover the stored credentials. The transform inside main.Decode was not reversed; it decodes victim router configuration and has no bearing on the C2 address.
With a session in hand, the scanner injects a shell command through POST /boafrm/formSysCmd. That command fetches the second stage over HTTP from a runtime-supplied host on a fixed port, built from the template http://%s:5001/bins.sh at 0x838fdb0. The second stage is the payload a loader fetches and holds the capability the operator wants. The host is filled in at runtime, so the static view names the port and the path but not the distribution server.
The sweep items not yet resolved
A byte sweep found 22 network indicators the recovered profile does not list, among them 1[.]1[.]1[.]1, 1[.]2[.]1[.]1, 1[.]2[.]2[.]1, 1[.]3[.]1[.]1, 119[.]0[.]0[.]0 and 120[.]0[.]0[.]0. The candidate embedded payload, a gzip stream at offset 0x1fbb45, still needs carving and analysing separately.
- Family
- unclassified
- First seen
- September 22, 2026
- Vector
- Runs as a ddos-bot/worm; the entry vector is not established by static analysis
- Format
- 5800 KB x86 ELF 32-bit LSB executable
- VirusTotal
- Not on VirusTotal
- Tags
- ddos-bot · elf · raw_tcp · worm · x86
- Sample
- By request. Email [email protected]
SHA-256
-
59bdafde87693987c862fee7e25d25f483fd732fe41f1555b67955aac5e6446eas captured
Analysis performed using an automatic malware analysis pipeline using Binary Ninja