Campaign comparison

The DDoS Zombie That Won't Let Go vs The Backdoor Key That Puts Itself Back

2026-09-10  ·  2026-09-02

Link signals

Analytic Same stage(s) reached by different techniques: persistence, defense-evasion, impact — same objective, different method
Commodity Shared ATT&CK technique(s): T1059.004, T1562.001 — commodity, many actors share these

Actor & objective

Actor unattributed vs unattributed different
Objective DDoS-for-hire botnet recruitment: conscripts the host as an on-demand flooding zombie, not data theft. The lockdown behavior exists to keep the machine exclusively under the operator's control. vs credential harvesting (Jenkins secrets, cloud credentials, SSH keys), banked for later use or resale rather than used immediately, plus opportunistic cryptomining once the initial access is established different

Kill chain

= same stage & technique   same stage, different technique   unique to one campaign

The DDoS Zombie That Won't Let Go

  1. shared step: 1. initial-access · T1190
    Jenkins Script Console reachable from the internet without a password; Groovy code execution as the service account, no exploit required
  2. unique step: 2. execution · T1059.004
    delivery command tries five writable directories and three download tools (wget/curl/busybox wget) in turn, then runs the binary four times in a row
  3. divergent step: 3. persistence · T1543.002
    writes /etc/systemd/system/system-helper.service ("System Helper", Restart=always), enables it, then deletes its own file from disk
  4. divergent step: 4. defense-evasion · T1562.004
    adds firewall chain LOCKER_INPUT dropping inbound traffic on SSH/Telnet/RDP/VNC ports so remote access cannot be restored
  5. divergent step: 5. impact · T1489
    kills sshd, dropbear, ftpd, vncserver, xinetd and in.telnetd before the firewall rules go in
  6. shared step: 6. defense-evasion · T1562.001
    sets 19 download-tool binaries (wget/curl/tftp/scp/aria2c and others) to permission 000, and SIGKILLs ps/top/netstat/tcpdump/strace/gdb and a dozen other analysis tools the instant they start
  7. divergent step: 7. defense-evasion · T1070.002
    deletes and recreates empty auth.log, syslog, messages, secure, wtmp, btmp, lastlog, faillog, dmesg, kern.log and the journal/audit directories
  8. divergent step: 8. defense-evasion · T1070.003
    wipes .bash_history and .zsh_history for the current user and root
  9. divergent step: 9. defense-evasion · T1027
    the process-blocklist table (gdb, strace, ltrace, objdump, readelf, strings, radare2, iaito, ghidra, binwalk) is stored XOR'd with 0xE7 at a fixed offset so it never appears in a strings dump; identical across both builds
  10. divergent step: 10. defense-evasion · T1622
    background thread every 10 seconds: self-ptrace, TracerPid check, FNV-1a memory hash against a baseline, and a scan for the 0xCC breakpoint byte; any hit kills and relaunches the process from /proc/self/exe
  11. divergent step: 11. defense-evasion · T1036.004
    renames its running process to kworker/0:0, mimicking a kernel worker thread that would never hold a network socket
  12. unique step: 12. command-and-control · T1571
    hardcoded IPv4 literal and fixed port (83.168.69[.]95:9482); plain-text single-line protocol, no domain, no DNS lookup, no encryption, no fallback
  13. divergent step: 13. impact · T1498
    on command, floods a named target using one of 11 methods (udpplain, syn, std, pps, ack, raknet, ssh, http, tcpstomp, minecraft, ovh)

The Backdoor Key That Puts Itself Back

  1. shared step: 1. initial-access · T1190
    unauthenticated Jenkins Script Console reachable from the internet; Groovy code execution as the Jenkins user, no exploit required
  2. unique step: 2. discovery · T1082
    host profiling (id, nproc, uname, free) before any deployment decision
  3. unique step: 3. discovery · T1083
    checked for aws/kubectl tooling to gauge cloud and Kubernetes access before deploying anything
  4. unique step: 4. credential-access · T1555
    in a three-second window, read credentials.xml plus both keys that decrypt it (secrets/master.key, secrets/hudson.util.Secret), the complete set needed to decrypt the whole store offline
  5. unique step: 5. credential-access · T1552.004
    read /root/.ssh/id_rsa and id_ed25519 (private key material); neither key was ever presented back to any sensor afterward
  6. unique step: 6. credential-access · T1552.001
    read /root/.aws/credentials
  7. divergent step: 7. persistence · T1098.004
    SSH public key spliced into the middle of authorized_keys (not appended), execute bit set as a side effect
  8. divergent step: 8. persistence · T1053.006
    systemd timer re-checks and re-adds the key every 5 minutes, 2 minutes after every reboot
  9. divergent step: 9. defense-evasion · T1036.005
    backdoor script disguised as an apt update checker; genuinely runs apt-get -s upgrade so the disguise produces real, plausible log output
  10. unique step: 10. credential-access · T1550.001
    used the stolen AWS keys to call sts get-caller-identity and request a federation token, escalating from programmatic keys toward console access
  11. divergent step: 11. impact · T1496
    XMRig cryptominer, CPU-throttled to the exact core count profiled earlier, pool connection pinned into /etc/hosts to survive DNS-based blocking
  12. shared step: 12. defense-evasion · T1562.001
    kills seven competing cryptojacking families on arrival

Side by side

green = shared by both campaigns.

Attribute-by-attribute comparison of The DDoS Zombie That Won't Let Go and The Backdoor Key That Puts Itself Back. Values labelled "shared" appear in both campaigns.
The DDoS Zombie That Won't Let Go The Backdoor Key That Puts Itself Back
Procedures
AV/sandbox-domain hosts-file poisoning (21 entries to 0.0.0.0)XOR-obfuscated (0xE7) anti-analysis process-block tableanalysis-tool SIGKILL on launchdownload-tool permission-zeroing (chmod 000 across 19 paths, reversible via a saved permissions list)firewall-based remote-access denial (LOCKER_INPUT chain)iterative recompilation (2 builds, 7 days apart, from the same URL)kworker process-name masquerademulti-directory, multi-tool delivery fallback (5 candidate directories, 3 download tools, 4x execution)ptrace/TracerPid/memory-hash/breakpoint-byte anti-debug with self-relaunchrival bot/miner evictioncompeting-miner-killcredential-store-full-decrypt-key-theftdns-containment-evasion-etc-hostsmasquerade-as-update-checkermid-file-key-insertionsystemd-timer-self-heal
Toolmarks
C2 registration string format: "<arch> <group> <memMB> <cpus>"build 2 only: .cron_backup/, .locker.disabled, a "stealth" line appended to /etc/modulesfile names .locker.pid / .locker.lock / .locker.ready / .watchdog.pid / .disabled.list / .iptables.rulesfirewall chain LOCKER_INPUTprocess name t.me/flylegitservice unit system-helper.service ("System Helper")HUNTER_JK_OK_ / HUNTER_VERIFY_ tool markersWO<n>_RCE_OK / WO<n>_VERIFY_OK job markershost-monitor@main SSH key commentnet-maint-keepalive cron markerupdate-check.* masquerading unit names
C2 protocol
custom plain-text TCP on port 9482: registration string "<arch> <group> <memMB> <cpus>", ping/pong keepalive, unencrypted attack-order commands, 8-second retry cadence, gives up after 450 straight failuresnone: all commands arrived inbound as POST requests to the unauthenticated Jenkins Script Console, 855 of them; no outbound C2 channel was ever established
Tooling
mirai-derived custom DDoS bot (C, static uClibc, UPX-packed)groovy-script-console-abusesystemd-timer-persistencexmrig
Capabilities
hardcoded plain-text C2 over a non-standard port; no domain, no DNS, no encryption, no fallbackon-command DDoS flood across 11 methods (udpplain, syn, std, pps, ack, raknet, ssh, http, tcpstomp, minecraft, ovh)rival-bot and rival-miner eviction to keep the host exclusiveself-defense lockdown: kills remote-access daemons, firewalls off SSH/Telnet/RDP/VNC ports, zeroes permissions on 19 download tools, kills analysis tooling the instant it launches, poisons /etc/hosts against 21 AV/sandbox vendors, deletes logs and shell historysystemd persistence (Restart=always) plus a self-relaunch-from-memory routine triggered by anti-debug checksXMRig cryptomining with CPU throttling and DNS-block evasioncloud credential harvesting and AWS API escalation attemptsfull Jenkins credential-store decryption key theftself-healing SSH backdoor (systemd timer re-adds a planted key every 5 minutes)
C2
83.168.69.95:9482 (hardcoded plain-text control channel, both builds)163.192.1.64 (second address, fetches tooling from the staging server)213.171.5.66 (staging server, serves /cdn/ payloads)
ASNs
AS202520 (SkyPass Solutions, Warsaw, Poland — staging and C2 host, same machine on two ports)AS31898 (Oracle Cloud, second address)AS9123 (Timeweb, staging server)
Domains
gulf.moneroocean[.]stream (mining pool, pinned into /etc/hosts to survive DNS-based blocking)
Products
Jenkins (Script Console)Jenkins

← Compare a different pair