The Paradigm Shift in Linux Malware
For decades, securing the Linux kernel was a battle fought on familiar terrain. Attackers seeking deep system persistence relied on Linux Kernel Modules (LKMs). These modules allowed malicious code to run with ring 0 privileges, hiding processes, manipulating files, and sniffing network packets. However, LKMs had a fatal flaw: they were notoriously unstable. A single null-pointer dereference or memory corruption in an LKM would trigger a kernel panic, instantly crashing the server, alerting system administrators, and leaving a glaring footprint behind.
Today, the landscape has fundamentally shifted. Sophisticated threat actors have abandoned unstable LKMs in favor of a technology designed for performance and observability: eBPF (Extended Berkeley Packet Filter). Originally developed to filter network packets without leaving kernel space, eBPF has evolved into a fully-fledged, in-kernel virtual machine. It allows users to run sandboxed programs inside the Linux kernel dynamically, safely, and without modifying kernel source code.
But the very features that make eBPF a superpower for cloud-native observability and network performance make it an unmatched tool for stealthy exploitation. Welcome to the era of the eBPF rootkit. In this post, we will dissect how these modern rootkits operate, walk through a realistic attack scenario, and explore practical digital forensics and defense strategies to hunt down these invisible threats.
Why Attackers Love eBPF
To understand why eBPF is highly prized by advanced persistent threat (APT) groups, we must examine the safety guarantees of the eBPF ecosystem. Before any eBPF program is loaded into the kernel, it must pass through the eBPF Verifier. The verifier ensures the program cannot crash the system, contains no infinite loops, and respects strict memory boundaries.
This paradox is highly beneficial to attackers: the kernel itself guarantees that the attacker’s rootkit will run safely and will not cause a system crash.
Beyond stability, eBPF offers several unique advantages for malicious actors:
- Total Stealth: Traditional endpoint detection and response (EDR) agents and host-based intrusion detection systems (HIDS) operate primarily in user space, relying on monitoring system calls (syscalls). Because eBPF programs run directly inside the kernel, they can intercept and manipulate syscall data before it ever reaches user space, effectively blinding security tools.
- Bypassing Integrity Checks: Unlike LKMs, eBPF programs do not require loading traditional kernel drivers. They are loaded via the
bpf()system call, meaning kernel module signing restrictions (which prevent unauthorized LKMs from loading on secure systems) are bypassed entirely. - No File Footprint: eBPF programs can be compiled, loaded directly from memory, and run without ever touching the disk, leaving traditional file-integrity monitoring tools completely unaware of their presence.
Anatomy of an eBPF Attack: Intercepting Plaintext Data
How does an eBPF rootkit actually execute its payload? The answer lies in probes and tracepoints. eBPF programs can attach to almost any function within the kernel (using kprobes) or user space (using uprobes).
Consider a scenario where an attacker has gained root privileges on a target server. To establish stealthy, permanent credential theft, they target user space SSH processes. Normally, SSH encrypts traffic before sending it over the network. However, by attaching an eBPF uprobe to the decryption or read functions inside the openssh or libcrypto binaries, the attacker can intercept passwords and session keys in plaintext.
“By hooking user-space libraries with uprobes, an eBPF program can capture passwords and SSH keys directly from memory, completely bypassing network-level encryption.”
Similarly, an attacker can attach a kprobe to the kernel’s sys_enter_getdents64 system call (the system call used to list directory contents). When an administrator runs ls to inspect a directory, the eBPF rootkit intercepts the returned structure and surgically removes the attacker’s files and malware directories from the list before returning the modified data back to the user. To the administrator, the system looks pristine.
Digital Forensics: Hunting the Unseen
If eBPF rootkits can hide so effectively from user-space monitoring tools, how can a digital forensics and incident response (DFIR) professional detect them? The secret lies in using the kernel’s own diagnostic tools against the attacker.
1. Inspecting Loaded eBPF Programs
The primary tool for managing and inspecting eBPF objects on modern Linux systems is bpftool. If a system has been compromised, your first step should be to query the kernel directly for all currently loaded eBPF programs:
sudo bpftool prog showThis command outputs a list of all active eBPF programs. When analyzing this output, look for anomalous entries. A typical, legitimate output might show programs managed by trusted system utilities like systemd, cilium, or datadog. An attacker’s program will often lack a clear name or associate with unusual helper functions. Pay close attention to the type field (e.g., kprobe, tracepoint, or raw_tracepoint) and the helper functions they use.
2. Dumping the Instructions
If you discover a suspicious program ID, you can dump its translated bytecode to see what it is actually doing in the kernel:
sudo bpftool prog dump xlated id <program_id>While analyzing assembly-like instructions requires some reverse-engineering skill, sudden spikes in memory accesses, hooks into file-system-related syscalls, or obfuscated strings are strong indicators of compromise.
3. Auditing eBPF Maps
eBPF programs use “maps” (key-value stores in kernel memory) to communicate with user space. An attacker’s rootkit will use maps to exfiltrate stolen credentials or receive command-and-control instructions. You can list all active maps using:
sudo bpftool map showIf you find a map associated with a suspicious eBPF program, you can dump its contents to inspect the payload data:
sudo bpftool map dump id <map_id>This step can yield immediate, actionable intelligence, such as captured plaintext passwords, stolen API keys, or IP addresses pointing to the attacker’s infrastructure.
Defensive Strategies and Hardening
Detecting a rootkit post-compromise is vital, but prevention is always the preferred security posture. To defend your Linux architecture against malicious eBPF usage, implement the following security controls:
Enforce Strict Sysctl Controls
By default, older Linux distributions allowed unprivileged users to load eBPF programs. This is a massive security risk. Ensure that unprivileged eBPF loading is completely disabled on all production servers. You can enforce this by modifying your sysctl configuration:
sudo sysctl -w kernel.unprivileged_bpf_disabled=1Setting this value to 1 restricts the bpf() system call strictly to processes with the CAP_SYS_ADMIN or CAP_BPF capabilities, effectively neutralizing unprivileged privilege-escalation vectors.
Leverage Linux Kernel Lockdown
For high-security environments, consider enabling the Linux Kernel Lockdown LSM (Linux Security Module). When configured in confidentiality mode, Lockdown restricts access to user-space memory and direct kernel memory modifications, severely limiting an attacker’s ability to hook critical kernel structures or deploy arbitrary kprobes.
Implement eBPF-Based Security Tools
To fight fire with fire, utilize advanced security tools that leverage eBPF to monitor eBPF activity. Open-source runtime security projects like Tetragon (by Cilium) and Falco can monitor the bpf() syscall itself. They can alert you in real-time whenever a new eBPF program is loaded, especially if it attempts to hook highly sensitive kernel tracepoints.
Conclusion: The Future of Kernel Security
eBPF is one of the most powerful innovations in modern computing, driving massive efficiency gains in cloud-native networking, observability, and tracing. However, technology is neutral; its advantages are always available to both defenders and adversaries. As traditional host security mechanisms become more adept at stopping user-space malware, the battleground has shifted to the kernel.
By understanding the mechanics of eBPF execution, proactively auditing system probes using tools like bpftool, and hardening our kernels against unprivileged execution, we can ensure that this revolutionary technology remains a defensive shield rather than an attacker’s invisible sword.
