eBPF rootkit installation attack

Cette page n'est pas encore disponible en français, sa traduction est en cours.
Si vous avez des questions ou des retours sur notre projet de traduction actuel, n'hésitez pas à nous contacter.

Goal

Detect eBPF rootkit installation and operation by correlating use of eBPF rootkit primitives with the context in which an eBPF program was loaded.

Strategy

Modern eBPF rootkits (e.g. LinkPro, VoidLink) rely on a small set of in-kernel helpers to tamper with the system from a BPF program: bpf_override_return to short-circuit kernel functions (hide files from getdents, silence kill, bypass LSM checks), bpf_probe_write_user to rewrite syscall return buffers in userspace (hide sockets from ss, doctor Netlink responses, tamper with argv), and bpf_send_signal / bpf_send_signal_thread to kill endpoint security tooling from a kprobe. Loading such a program from a world-writable directory or via bpftrace --unsafe is a strong indicator that the loader was dropped by an attacker rather than installed by a package manager.

This correlation rule groups events into four activity buckets:

  • eBPF tampering helpers: bpf_override_return_usage, bpf_probe_write_user_usage, bpf_send_signal_usage
  • eBPF tampering helpers (interactive): same set, scoped to events that occurred inside an interactive shell or Kubernetes exec session
  • Suspicious eBPF loading: ebpf_load_from_world_writable_dir, bpftrace_unsafe_bpf_prog_load
  • Suspicious eBPF loading (interactive): same set, interactive scope

The rule triggers different severity levels based on the combination of detected activities:

CaseSeverityRequired Components
eBPF Rootkit Loaded (Interactive)CriticalTampering Helpers + Suspicious Loading (interactive session)
eBPF Tampering (Interactive)CriticalTampering Helpers (interactive session)
eBPF Rootkit LoadedHighTampering Helpers + Suspicious Loading
eBPF TamperingHighTampering Helpers
Suspicious eBPF LoadingMediumSuspicious Loading

Triage & Response

  1. Isolate immediately: Isolate the affected host. To preserve memory evidence, DO NOT REBOOT.

  2. Enumerate loaded eBPF programs: Run bpftool prog show and bpftool map show and compare against a baseline. Capture the program bytecode and pinned maps for unfamiliar entries (bpftool prog dump xlated id <id>).

  3. Identify the loader: Review the process tree of the agent rule that triggered (process, container, image, command line, parent). For ebpf_load_from_world_writable_dir, fetch and hash the binary in /tmp, /var/tmp, /dev/shm, or /run/user/*.

  4. Map the helpers to behavior: bpf_override_return → look for hidden files/processes/sockets and silenced kills; bpf_probe_write_user → look for tampered ss/netstat/auth output; bpf_send_signal → look for EDR, auditd, osquery, or Datadog Agent processes terminated without a corresponding userspace kill.

  5. Check persistence: Inspect /etc/ld.so.preload (LinkPro fallback), systemd units that load BPF objects, cron jobs, and any pinned programs under /sys/fs/bpf/.

  6. Look for lateral indicators: Pivot on @process.variables.correlation_key to surface other rule hits inside the same shell or pod session (credential access, masquerading, network scanning).

  7. Perform memory forensics: Capture a memory dump before any remediation. eBPF programs are kernel-resident and disappear on reboot — preserve them first.

  8. Rebuild from a known-good image: After forensics, restore the host from a trusted image and rotate any credentials that were exposed on the compromised host.