This first part examines the NeTiS sample’s role as a Gafgyt/BASHLITE-derived Linux IoT botnet implant: its multi-architecture propagation model, downloader orchestration, process masquerading, competitor suppression, and trap-based anti-analysis behavior. The focus is on how the sample gets resident, spreads across heterogeneous IoT targets, and shapes the local environment before the encrypted C2 and Cloudflare-aware beaconing logic come into play.
Key Judgments
· NeTiS extends established Gafgyt/BASHLITE tradecraft with a propagation model that stages 12 payload names across 9 architecture families, allowing one infected device to seed heterogeneous IoT fleets.
· The implant uses a runtime-supplied command-and-control endpoint and a length-prefixed encrypted TCP protocol, which reduces the value of static blocklists and shifts detection toward protocol fingerprints and execution behavior.
· The malware parses and reuses cf_clearance cookies inside browser-mimicking HTTP requests, enabling operators to place tasking or staging behind Cloudflare-gated infrastructure while making the traffic look less like a bot.
· The bot increases dwell time on constrained devices by killing competing processes, masquerading as httpd, and dropping staged binaries into standard writable locations such as /tmp and /var.
· Anti-analysis is built into normal execution. The initialization path installs a SIGTRAP handler, drives a trap-based state machine, and routes system interaction through function-pointer tables rather than stable call sites.
Overview
NeTiS is a Linux IoT botnet implant in the Gafgyt/BASHLITE lineage. The analyzed sample is a MIPS big-endian ELF recovered from an embedded device and built to participate in distributed denial-of-service operations while propagating architecture-specific binaries across routers, DVRs, IP cameras, NAS devices, and other embedded Linux targets.
Zenyard Agent produced this analysis from a raw MIPS ELF binary and Ghidra-derived static artifacts, with no prior context or labeling provided and no human analyst involvement. The sample self-identifies through an embedded taunting banner containing the name “NeTiS,” carries a set of 12 payload filenames spanning 9 architecture families, and implements downloader logic that cycles through wget, curl, ftpget, tftp, and busybox to maximize install success on stripped-down firmware builds. The embedded profane banner is reproduced verbatim only where needed as a clustering artifact and indicator, not as Zenyard’s language.
What makes this sample worth a full technical write-up is not the family label. It is the way familiar Gafgyt mechanics are combined with more modern operator conveniences: encrypted control traffic, runtime infrastructure assignment, browser-shaped HTTP beaconing, and cf_clearance reuse layered onto an implant still optimized for noisy botnet scale.
Technical Findings
Initialization and execution flow
The sample does not rely on a heavyweight packer. Its execution flow is dominated instead by staged initialization, process control, downloader orchestration, and fan-out across multiple target architectures. Early in execution, the implant performs one-shot environment setup guarded against re-entry. That logic initializes internal communication state, resets transient structures, and prepares the bot for long-running daemonized operation. The recovered setup code also imposes a 2 MB-aligned stack-related boundary that is consistent with avoiding out-of-memory triggers on resource-constrained devices, although the static evidence shows the limit exists rather than the developer’s explicit intent.
From there, the core propagation path is straightforward. The malware derives or receives a C2 or staging location at runtime, selects a target binary name based on platform, and attempts download-and-execute using whatever transfer utility exists on the device. The sequence is intentionally redundant:
The writable directories are exactly the places defenders would expect on embedded Linux systems: /tmp, /var, /mnt, /root, /boot, and /data/local/tmp. The payload names embedded in the sample are main_x86, main_x86_64, main_mips, main_mipsel, main_arm, main_arm5, main_arm6, main_arm7, main_ppc, main_m68k, main_sh4, and main_spc. That is 12 payload names covering 9 architecture families if the ARM variants are grouped together. This single MIPS implant is therefore a propagation hub, not a universal binary.
Once resident, the process daemonizes and renames itself to blend into appliance workloads. The primary masquerade string is httpd, with additional names such as telnetd, dropbear, encoder, and system available from an embedded table. On stripped-down firmware where process listings are sparse and operators rely on familiar service names, that disguise is enough to buy time.
The supplied function naming included set_persistence_registry_values, but that label is analytically wrong for a Linux ELF. The code is better understood as writing internal configuration slots that preserve C2 and startup-related state for later reuse. The important fact is not the decompiler label. The important fact is that the sample stores control data redundantly and sets flags consistent with autostart, respawn, and network persistence behavior elsewhere in the execution path.
Anti-analysis techniques
NeTiS treats anti-analysis as part of normal execution. The most explicit mechanism is a four-stage initialization state machine that installs signal handlers, zeroes status structures, and then deliberately triggers a trap instruction path that becomes unstable under debugger control. In a normal run, the malware’s own SIGTRAP handler absorbs the event and execution continues. Under interactive debugging, the trap is surfaced to the analyst instead, interrupting or derailing the session.
This matters because the trap path is wired into initialization. Analysts cannot simply skip “the anti-debug function” without also skipping setup required for later behavior. That design raises the cost of dynamic inspection on real hardware and on emulated appliance images.
The sample also hides intent by routing system interaction through global function-pointer tables rather than stable imported call sites. On ELF malware that already runs on minimal systems with reduced symbol visibility, this pushes more recovery work onto the analyst. String protection is lighter but still deliberate. Several attack identifiers are XOR-encoded with key 0x2E, including strings associated with Source Engine traffic and completion markers, which removes easy wins from naive static string extraction.
A second layer of defense is operational rather than analytical. The implant enumerates running processes and kills unapproved ones with SIGKILL, while exempting its own process and honoring a runtime-populated allowlist. That is competitor suppression, but it also functions as environment shaping: it removes rival implants, interrupts watchdogs or admin tooling that might expose instability, and reduces the number of local artifacts analysts can correlate after infection.
Part 1 Conclusion
Part 1 shows NeTiS as a propagation-focused IoT implant that does not need a heavyweight packer to complicate analysis. Its strength is in redundancy and fit-for-purpose execution: multi-architecture staging, fallback downloader logic, writable-directory deployment, process masquerading, competitor suppression, and trap-based initialization all support long-running operation on constrained embedded devices.
Part 2 continues with the sample’s stream-cipher-based C2 protection, Cloudflare-aware cf_clearance reuse, DDoS tasking behavior, attribution limits, detection opportunities, IOCs, and YARA hunting logic.
Annex A: Indicators of Compromise
Annex B: YARA Hunting Rules
This rule is scoped to the NeTiS-labeled Gafgyt variant and adds the hardcoded encryption key as an alternate anchor. That keeps the rule useful even if a future build strips the taunting banner but preserves the same crypto material and surrounding execution artifacts.



