Linux ELF Botnet Agent Analysis
Complete static & dynamic triage of a Mirai/Gafgyt family variant in an isolated lab environment.
The lab was constructed using VirtualBox on macOS. Two virtual machines were joined to a dedicated Host-Only network (192.168.56.0/24) with zero external gateway or internet access. Ubuntu 24.04 acts as both the victim machine and fake internet server running INetSim 1.3.2, while Kali Linux operates as the analyst workstation.
Host-Only Network (192.168.56.0/24) │ ├── Ubuntu (Victim & Fake Server) → 192.168.56.101 (enp0s3) │ └── INetSim (DNS:53, HTTP:80, HTTPS:443) │ ├── Kali Linux (Analyst Station) → 192.168.56.102 (eth1) │ └── Static analysis tools, Ghidra, SCP client │ └── macOS Host (Gateway Stub) → 192.168.56.1 (vboxnet0) [No NAT/Bridge]
The sample was ingested on the Kali Linux workstation. Static inspection using file, readelf, and strings revealed a statically compiled, stripped 32-bit ELF binary targeting Intel i386. Embedded strings confirmed dropped persistence targets and spoofed Windows User-Agent headers.
| Property | Extracted Value | Technical Significance |
|---|---|---|
| File Type | ELF 32-bit LSB executable, Intel 80386 |
Broad architecture compatibility across Linux systems |
| Linking / Symbols | Statically linked, stripped |
Self-contained execution without shared library dependencies |
| Entry Point | 0x804bf70 |
Standard binary entry point; UPX packing not present |
| Target Dropped Paths | /tmp/.network-dispatch, /var/tmp/, /dev/shm/ |
Multi-location deployment across world-writable directories |
| Persistence Reference | /etc/systemd/system/network-dispatch.service |
Hardcoded systemd service unit installation targeting boot auto-start |
The sample was copied from Kali to the Ubuntu victim VM via SCP. Dynamic inspection using strace revealed that the malware actively evades debugging: it opens /proc/self/status, parses the TracerPid field, and if non-zero, immediately issues a SIGKILL to itself.
Under strace ./sample.elf, the process terminates instantly with exit status 137. To bypass this evasion, execution was performed uninstrumented while network activity was captured out-of-band via tcpdump -i any.
During unmonitored execution, a 60-second tcpdump recording on the pseudo-interface any captured 104,810 packets. Analysis showed repeated DNS queries for dynamic DNS C2 domains and continuous outbound TCP SYN packets targeted at port 6767.
| C2 Type | Observed Value | Protocol / Port | Action |
|---|---|---|---|
| C2 Domain (Primary) | cdn-edge-updates.hostcloud-eu.net |
DNS Query (UDP 53) | |
| C2 Domain (Dynamic DNS) | anasb3azbi.duckdns.org |
DNS Query (UDP 53) | |
| C2 IP Address 1 | 91.92.40.5 |
TCP 6767 | |
| C2 IP Address 2 | 45.61.161.207 |
TCP 6767 |
Post-execution forensics identified dropped files hidden under dot-prefix names in three directories. Hexdump comparisons proved that all three files are identical copies of the initial malware binary. The VM was then returned to its pre-infection snapshot.
| Dropped File Path | Filesystem Type | Reason Targeted by Malware |
|---|---|---|
/tmp/.network-dispatch |
Writable temporary folder | Immediate unprivileged file staging point |
/var/tmp/.network-dispatch |
Persistent temporary storage | Survives short-term automated system cleanup jobs |
/dev/shm/.network-dispatch |
RAM-backed tmpfs (shared memory) | Leaves minimal physical disk forensic artifacts |

























file:
- hash: 2ae7dc16ca036cb5c2c7ce2cd8099edb07d96b8846188c92eb39a7feba2fec08
type: ELF 32-bit
domain:
- cdn-edge-updates.hostcloud-eu.net
- anasb3azbi.duckdns.org
- api-relay-3.metrics-collector.io
ip:
- 91.92.40.5
- 45.61.161.207
port:
- 6767
file_path:
- /tmp/.network-dispatch
- /var/tmp/.network-dispatch
- /dev/shm/.network-dispatch
- /usr/bin/.network-dispatch
- /usr/sbin/.network-dispatch
anti_debug:
- /proc/self/status (TracerPid check)
# Hashes
2ae7dc16ca036cb5c2c7ce2cd8099edb07d96b8846188c92eb39a7feba2fec08
# Domains
cdn-edge-updates.hostcloud-eu.net
anasb3azbi.duckdns.org
api-relay-3.metrics-collector.io
# IPs & Ports
91.92.40.5:6767
45.61.161.207:6767
# Dropped Paths
/tmp/.network-dispatch
/var/tmp/.network-dispatch
/dev/shm/.network-dispatch
Executes commands via shell wrappers to stage dropped binaries and maintain execution loops.
Embedded strings contain target path /etc/systemd/system/network-dispatch.service to establish boot persistence.
Parses TracerPid from /proc/self/status and immediately exits via SIGKILL when an attached debugger is detected.
Hides binary copies by prepending a dot prefix (.network-dispatch) across world-writable temporary folders.
Queries procfs to inspect process states and parent execution lineage.
Establishes communication sessions via proprietary TCP packet structures over non-standard port 6767.
Leverages dynamic DNS services (duckdns.org) for resilient command server infrastructure.
High-volume outbound packet flooding generating over 104,810 packets within 60 seconds.
rule malware_linux_network_dispatch {
meta:
author = "Evans Emmanuel Davou (Weng)"
description = "Detects Linux ELF botnet agent (Mirai/Gafgyt variant)"
hash = "2ae7dc16ca036cb5c2c7ce2cd8099edb07d96b8846188c92eb39a7feba2fec08"
date = "2026-08-05"
strings:
$s1 = "/tmp/.network-dispatch" ascii
$s2 = "/var/tmp/.network-dispatch" ascii
$s3 = "/dev/shm/.network-dispatch" ascii
$s4 = "/etc/systemd/system/network-dispatch.service" ascii
$s5 = "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)" ascii
$s6 = "After=network.target" ascii
$s7 = "/tmp/pid.%s" ascii
$hex1 = { 6E 65 74 77 6F 72 6B 2D 64 69 73 70 61 74 63 68 }
condition:
(2 of ($s1, $s2, $s3, $s4)) or
($s5 and $s6) or
($s7 and $hex1)
}
#!/bin/bash
# Automated dynamic analysis script
if [ -z "$1" ]; then
echo "Usage: ./dynamic_run.sh <sample.elf>"
exit 1
fi
SAMPLE=$1
echo "[*] Starting tcpdump..."
sudo tcpdump -i any -n -v -w /tmp/capture.pcap &
sleep 2
echo "[*] Running sample..."
chmod +x $SAMPLE
./$SAMPLE &
echo "[*] Waiting 60 seconds..."
sleep 60
echo "[*] Killing sample..."
pkill -f $SAMPLE
sudo pkill tcpdump
echo "[*] Checking dropped files..."
find /tmp /var/tmp /dev/shm -name "*network-dispatch*" 2>/dev/null
#!/bin/bash
# Automated static analysis script
if [ -z "$1" ]; then
echo "Usage: ./extract_strings.sh <sample.elf>"
exit 1
fi
SAMPLE=$1
echo "[*] File Type:"
file $SAMPLE
echo -e "\n[*] Interesting Strings:"
strings $SAMPLE | grep -E "http|https|\.com|\.org|\.net|192\.|10\.|172\.|/bin/|/tmp/|\.sh" | head -30
echo -e "\n[*] ELF Headers:"
readelf -h $SAMPLE
Problem: INetSim's DNS daemon silently failed on 192.168.56.101:53. Queries were returned with connection refused.
Root Cause: INetSim 1.3.2 does not support dns_bind_address in configuration. In addition, Ubuntu had systemd-resolved already binding port 53.
Solution: Disabled systemd-resolved via sudo systemctl stop systemd-resolved and mapped test domains in /etc/hosts.
Lesson: Always verify active socket listeners using sudo ss -tulpn rather than trusting process startup logs.
Problem: Running the malware binary under strace ./sample.elf resulted in an instant self-termination with exit code 137.
Root Cause: The malware reads /proc/self/status to check for non-zero TracerPid and invokes SIGKILL.
Solution: Ceased inline tracer attachment; ran the binary uninstrumented and monitored network and filesystem artifacts externally.
Lesson: Anti-debugging techniques are standard in botnet droppers; always maintain independent out-of-band capture methods.
Problem: Initial tcpdump capture on enp0s3 did not register local HTTP requests directed at INetSim.
Root Cause: Packets originating from and terminating on the same host route internally through the loopback interface (lo).
Solution: Specified the Linux pseudo-interface any (sudo tcpdump -i any) to capture all interfaces simultaneously.
Executive Summary
A fully isolated malware analysis lab was established on an air-gapped host-only subnet (192.168.56.0/24) using VirtualBox on macOS. Kali Linux was utilized as the analyst workstation and Ubuntu 24.04 as the victim machine running INetSim 1.3.2 to emulate critical network services. A real-world Linux ELF botnet agent (SHA-256 2ae7dc16...) was statically analyzed and dynamically detonated.
The binary was categorized as a Mirai/Gafgyt variant exhibiting rapid multi-path dropper staging (/tmp, /var/tmp, /dev/shm), debugger evasion via /proc/self/status TracerPid inspection, dynamic DNS resolution (duckdns.org), and high-frequency command & control communication targeting TCP port 6767.
Defensive Recommendations
- Perimeter Egress Filtering: Restrict outbound TCP traffic on destination port 6767 at corporate gateway firewalls.
- Mount Hardening: Configure temporary filesystems (
/dev/shm,/tmp) with thenoexecmount option to neutralize initial dropper execution. - Detection Engineering: Deploy the custom YARA rule (
malware_linux_network_dispatch) across host-based endpoint monitoring systems.