Linux ELF Botnet Agent Analysis

Complete static & dynamic triage of a Mirai/Gafgyt family variant in an isolated lab environment.

Critical Threat Host-Only Isolated
Author Evans Emmanuel Davou (Weng)
Date August 2026
Target Architecture ELF 32-bit LSB (Intel 80386, Static)
Malware Family Mirai / Gafgyt Variant
SHA256: 2ae7dc16ca036cb5c2c7ce2cd8099edb07d96b8846188c92eb39a7feba2fec08
Phase 01 • Network & Lab Setup
Host-Only Network Architecture & INetSim Configuration
lab-setup/ →

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.

lab-setup/network-topology.txt
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]
Lab VM Overview & Network Interfaces
01. Network Interface Verification
INetSim Startup & Services
02. INetSim Startup Validation
DNS Fix - Disable systemd-resolved
25. DNS Port 53 Resolution
Hosts File DNS Bypass Test
05. Manual Hosts Redirection
Phase 02 • Acquisition & Static Triage
Header Extraction, Symbol Triage & String Artifacts
extract_strings.sh →

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
Sample Extraction & File Identification
08. Sample Extraction & Identification
readelf Header & Dropped Paths
06. readelf Header & Sections
Suspicious Strings Extraction
07. Suspicious Strings Triage
Systemd Persistence Strings
09. Systemd Persistence Artifacts
Phase 03 • Detonation & Defense Evasion
Execution Staging & Anti-Debugging SIGKILL Discovery
dynamic_run.sh →

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.

Anti-Debugging Defense Evasion (MITRE T1622)

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.

SCP File Transfer
22. Internal SCP Binary Transfer
Sample in /tmp
20. Staged Sample in /tmp
strace Anti-Debug SIGKILL Evidence
11. strace SIGKILL Evasion Caught
CPU Spike During Execution
19. CPU Usage Spike Under Detonation
Phase 04 • Network & C2 Traffic Capture
104,810 Packets Captured & C2 Activity on Port 6767
iocs.yaml →

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
tcpdump Live Capture
13. Live tcpdump Capture Session
104,810 Packets Captured
14. 104,810 Packets Captured
Captured C2 DNS Queries
16. Intercepted C2 DNS Requests
Traffic Review
17. Live SYN Traffic Review
Phase 05 • Host Forensics & Teardown
Tri-Directory Persistence Identified & Clean State Restore
iocs.txt →

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
Dropped Files Confirmation
12. Dropped File Discovery
ELF Verification Hexdump
15. Dropped Binary Hexdump Match
Session Wrapup
23. Post-Detonation State Audit
INetSim Resource Panel
21. INetSim Teardown & Metrics
Structured Indicators of Compromise (IoCs) View iocs.yaml on GitHub →
iocs/iocs.yaml
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)
iocs/iocs.txt
# 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
MITRE ATT&CK Matrix Mapping Enterprise Matrix v14
T1059.004 • Execution
Unix Shell

Executes commands via shell wrappers to stage dropped binaries and maintain execution loops.

T1543.002 • Persistence
Systemd Service

Embedded strings contain target path /etc/systemd/system/network-dispatch.service to establish boot persistence.

T1622 • Defense Evasion
Debugger Evasion

Parses TracerPid from /proc/self/status and immediately exits via SIGKILL when an attached debugger is detected.

T1222 • Defense Evasion
File Permissions & Hidden Files

Hides binary copies by prepending a dot prefix (.network-dispatch) across world-writable temporary folders.

T1057 • Discovery
Process Discovery

Queries procfs to inspect process states and parent execution lineage.

T1573 • Command & Control
Encrypted / Custom Channel

Establishes communication sessions via proprietary TCP packet structures over non-standard port 6767.

T1568.002 • Command & Control
Dynamic Resolution

Leverages dynamic DNS services (duckdns.org) for resilient command server infrastructure.

T1496 • Impact
Resource Hijacking (DDoS)

High-volume outbound packet flooding generating over 104,810 packets within 60 seconds.

Detection Engineering & Automation Scripts Open scripts/ on GitHub →
iocs/yara-rules/network_dispatch.yar
GitHub File →
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)
}
scripts/dynamic_run.sh GitHub →
#!/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
scripts/extract_strings.sh GitHub →
#!/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
Technical Challenges Encountered & Solutions
Challenge 1: INetSim DNS Service Failed to Bind Port 53

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.

Challenge 2: Anti-Debugging Evasion Under strace

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.

Challenge 3: Loopback Routing Missing From Physical Interface Capture

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.

Formal Analysis Report View raw REPORT.md on GitHub →

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 the noexec mount option to neutralize initial dropper execution.
  • Detection Engineering: Deploy the custom YARA rule (malware_linux_network_dispatch) across host-based endpoint monitoring systems.
Copied to clipboard