Hooked on Linux: Rootkit Detection Engineering
This article details behavioral detection engineering strategies for Linux rootkits, emphasizing the failure of static signatures against trivial binary modifications. It provides actionable detection logic for userland and kernel-space rootkits, including emerging threats leveraging eBPF and io_uring, alongside common persistence and defense evasion techniques.
Source:Elastic Security Labs
Key Takeaways
- Static detection for Linux rootkits is highly fragile; appending a single null byte significantly degrades AV detection rates.
- Userland rootkits frequently abuse LD_PRELOAD and dynamic linker configurations to inject malicious shared objects.
- Kernel-space rootkits (LKMs) can be detected dynamically by monitoring init_module/finit_module syscalls, kernel taint logs, and unusual kill signals.
- Emerging techniques leverage eBPF (e.g., bpf_probe_write_user) and io_uring for stealthy execution and evasion.
- Rootkits employ various persistence and evasion tactics, including udev rules, process masquerading (e.g., as kworker), and log clearing via shred or dmesg.
Affected Systems
- Linux
Attack Chain
Attackers deploy rootkits either in userland (via shared objects and LD_PRELOAD) or kernel-space (via LKMs using insmod or direct init_module syscalls). To maintain stealth, they may compile payloads in memory-backed filesystems like /dev/shm and masquerade processes as benign kernel threads like kworker. Persistence is established through shell configuration modifications, dynamic linker hijacking, systemd services, or udev rules. Finally, attackers evade detection by clearing shell history, wiping kernel logs with dmesg or journalctl, and securely deleting deployment artifacts using shred.
Detection Availability
- YARA Rules: No
- Sigma Rules: No
- Snort/Suricata Rules: No
- KQL Queries: No
- Splunk SPL Queries: No
- EQL Queries: Yes
- Other Detection Logic: Yes
- Platforms: Elastic Security, Auditd
The article provides numerous Elastic EQL queries and Auditd configuration rules to detect rootkit behaviors such as LKM loading, eBPF abuse, io_uring activity, and defense evasion tactics.
Detection Engineering Assessment
EDR Visibility: High — EDRs with syscall telemetry (like Elastic Defend) can monitor init_module, bpf, and file creation events in sensitive directories. Network Visibility: Low — Rootkits primarily operate locally to hide processes and files; network activity is secondary, though some use port knocking. Detection Difficulty: Hard — Rootkits actively subvert the OS, meaning userland telemetry can be manipulated. Detecting them requires kernel-level visibility (eBPF, Auditd) and careful tuning to avoid false positives from legitimate system processes.
Required Log Sources
- Auditd
- Syslog
- Kernel logs (dmesg)
- Process execution logs (execve)
- File creation/modification logs
Hunting Hypotheses
| Hypothesis | Telemetry | ATT&CK Stage | FP Risk |
|---|---|---|---|
| Attackers are loading hidden kernel modules by bypassing standard utilities. | Auditd init_module and finit_module syscalls. | Persistence/Privilege Escalation | Low |
| Rootkits are using high-numbered kill signals for C2 communication. | Auditd kill syscalls with signal > 32. | Command and Control | Low |
| Attackers are compiling and executing payloads from shared memory to avoid disk forensics. | Process execution and file creation in /dev/shm. | Execution/Defense Evasion | Medium |
| Malicious processes are masquerading as kernel threads. | Process execution with parent kworker or kthreadd spawning userland shells. | Defense Evasion | Medium |
Control Gaps
- Static AV signatures are easily bypassed by trivial modifications like appending a null byte.
- EDRs lacking syscall-level visibility may miss direct init_module or io_uring abuse.
Key Behavioral Indicators
- Kernel taint logs (out-of-tree or unsigned modules)
- Unusual LD_PRELOAD environment variables
- File creation in /etc/ld.so.conf.d/ or /etc/modules-load.d/
- Execution of shred, dmesg -c, or journalctl --vacuum
False Positive Assessment
- Medium
Recommendations
Immediate Mitigation
- Monitor for kernel taint messages in syslog.
- Audit /etc/ld.so.preload and /etc/ld.so.conf.d/ for unauthorized shared objects.
Infrastructure Hardening
- Enable Lockdown Mode, KASLR, and SMEP/SMAP.
- Restrict kernel module usage by disabling dynamic loading or enforcing module signing.
- Remount sensitive filesystems with restrictive flags and disable access to /dev/mem.
User Protection
- Deploy EDR solutions with syscall-level visibility (e.g., Auditd or eBPF-based sensors).
- Minimize process privileges using seccomp-bpf and Linux capabilities.
Security Awareness
- Educate SOC analysts on the limitations of static analysis for Linux binaries.
- Train responders to look for behavioral anomalies like processes executing from /dev/shm.
MITRE ATT&CK Mapping
- T1014 - Rootkit
- T1574.006 - Hijack Execution Flow: Dynamic Linker Hijacking
- T1547.006 - Boot or Logon Autostart Execution: Kernel Modules and Extensions
- T1546.004 - Event Triggered Execution: Unix Shell Configuration Modification
- T1543.002 - Create or Modify System Process: Systemd Service
- T1036.004 - Masquerading: Masquerade Task or Service
- T1070.003 - Indicator Removal: Clear Command History
- T1070.004 - Indicator Removal: File Deletion
- T1070.006 - Indicator Removal: Timestomp
Additional IOCs
- File Paths:
/etc/ld.so.preload- Dynamic linker preload file often abused by userland rootkits for global shared object injection./etc/ld.so.conf.d/- Directory containing dynamic linker configuration files, targeted for hijacking library resolution paths./etc/modules-load.d/- Configuration directory abused to load malicious kernel modules at boot./etc/udev/rules.d/- Directory for udev rules, abused by rootkits like Reptile and Sedexp for event-triggered persistence./dev/shm/- Shared memory directory frequently used by attackers to compile and execute payloads without touching the physical disk.
- Command Lines:
- Purpose: Load a kernel module manually | Tools:
insmod,kmod| Stage: Execution |insmod "$MODULE_DIR/$MODULE_NAME.ko" - Purpose: Trigger rootkit actions via covert communication channel | Tools:
kill| Stage: Command and Control |kill -64 <pid> - Purpose: Clear the kernel ring buffer to hide LKM loading messages | Tools:
dmesg| Stage: Defense Evasion |dmesg -c - Purpose: Clear systemd journal logs to remove traces of activity | Tools:
journalctl| Stage: Defense Evasion |journalctl --vacuum-time= - Purpose: Securely delete rootkit deployment files to prevent forensic recovery | Tools:
shred| Stage: Defense Evasion |shred --remove - Purpose: Timestomp files to hide modification times | Tools:
touch| Stage: Defense Evasion |touch -t - Purpose: Masquerade a process name to blend in with legitimate system processes | Tools:
bash,exec| Stage: Defense Evasion |exec -a
- Purpose: Load a kernel module manually | Tools: