Kernel-Level Shadow Play: Hiding Root Detection with eBPF Syscall Interception + Video

Listen to this Post

Featured Image

Introduction:

Modern Runtime Application Self-Protection (RASP) and root detection tools increasingly audit the kernel’s process execution chain directly, making userspace hooks like Zygisk ineffective. eBPF (Extended Berkeley Packet Filter) allows security researchers and red teamers to intercept system calls at the kernel level, rewriting arguments in userspace memory before the kernel ever sees them—effectively hiding “su” executions from even the most vigilant root checkers.

Learning Objectives:

  • Understand how eBPF and BCC can hook `execve()` syscalls to alter path arguments transparently.
  • Implement a kernel-level bypass that rewrites “su” to a nonexistent binary to avoid root detection.
  • Recognize the limitations of syscall interception and required complementary stealth techniques.

You Should Know:

1. Reconnaissance: Mapping Syscalls with bpftrace

Before writing any payload, observe live syscall behavior to identify the target application’s UID and the exact memory addresses being queried by RASP.

Step‑by‑step guide:

  • Install bpftrace on your eBPF‑enabled Linux kernel (e.g., Ubuntu 22.04+).
  • Run a live trace on `execve` and `execveat` syscalls, filtering by your target app’s UID (found via `ps -u` or id).
  • Extract and print the user‑space memory address of the executed path.

Linux commands:

 Install bpftrace
sudo apt install bpftrace -y

Trace execve with UID filter (replace 10128 with actual UID)
sudo bpftrace -e 'kprobe:__x64_sys_execve /uid == 10128/ { printf("execve called with path: %s\n", str(arg1)); }'

Trace execveat similarly
sudo bpftrace -e 'kprobe:__x64_sys_execveat /uid == 10128/ { printf("execveat called with path: %s, dirfd: %d\n", str(arg2), arg1); }'

This reveals exactly what path strings RASP is auditing, confirming that “/system/bin/su” is a key indicator.

2. Writing the eBPF Hook with Python BCC

Use the BCC toolkit (BPF Compiler Collection) to attach kprobes and modify the filename argument in kernel‑space before the syscall executes.

Step‑by‑step guide:

  • Create a Python script that loads an eBPF C program.
  • Attach to `__x64_sys_execve` and __x64_sys_execveat.
  • Read the calling UID with `bpf_get_current_uid_gid()` and filter to your target app.
  • Use `bpf_probe_read_user_str()` to read the original path.
  • If the path contains “s”, “u”, “\0”, overwrite it with “xx” using bpf_probe_write_user().

Example BCC script (hide_su.py):

from bcc import BPF

bpf_code = """
include <uapi/linux/ptrace.h>
include <linux/sched.h>

int hook_execve(struct pt_regs ctx, const char __user filename, const char __user const __user argv, const char __user const __user envp) {
u32 uid = bpf_get_current_uid_gid() & 0xffffffff;
if (uid != 10128) return 0; // target UID

char path[bash];
bpf_probe_read_user_str(path, sizeof(path), filename);
// Check for "su" binary (simple pattern)
if (path[bash] == 's' && path[bash] == 'u' && path[bash] == '\0') {
char fake[] = "xx";
bpf_probe_write_user((void )filename, fake, sizeof(fake));
}
return 0;
}
"""

b = BPF(text=bpf_code)
b.attach_kprobe(event="__x64_sys_execve", fn_name="hook_execve")
b.attach_kprobe(event="__x64_sys_execveat", fn_name="hook_execve")
print("eBPF root-hiding hook active. Press Ctrl+C to exit...")
b.trace_print()

Run with sudo python3 hide_su.py. The root checker’s `execve(“/system/bin/su”)` becomes execve(“xx”), failing silently and never triggering an alert.

3. Bypassing Additional Syscalls: execveat and openat

Modern RASP may also use `execveat` or even `openat` to detect su binary presence. Extend the hook to cover these.

Step‑by‑step guide:

  • Hook `__x64_sys_execveat` – the argument order differs (dirfd, pathname, etc.).
  • For openat, similarly overwrite the path when the target attempts to read /system/bin/su.
  • Use the same `bpf_probe_write_user()` technique, but be cautious: corrupting `openat` for critical system files could crash the OS.

Additional hook for execveat:

int hook_execveat(struct pt_regs ctx, int dfd, const char __user filename, ...) {
u32 uid = bpf_get_current_uid_gid() & 0xffffffff;
if (uid != 10128) return 0;
char path[bash];
bpf_probe_read_user_str(path, sizeof(path), filename);
if (path[bash] == 's' && path[bash] == 'u' && path[bash] == '\0') {
char fake[] = "xx";
bpf_probe_write_user((void )filename, fake, sizeof(fake));
}
return 0;
}

4. Limitations and Complementary Stealth Measures

Kernel‑level syscall interception defeats execution‑based detection but leaves numerous artifacts. To achieve full stealth, you must also address:

Step‑by‑step guide for residual risk mitigation:

  • Filesystem artifacts: Use mount namespaces or overlayfs to hide /system/bin/su.
    sudo mount --bind /dev/null /system/bin/su
    
  • Root packages (Magisk/SuperSU): Remove or rename package directories in /data/app.
  • Build properties: Patch `ro.debuggable` and `ro.secure` via Magisk modules or kernel cmdline.
  • Hardware attestation: Use MagiskHide Props Config or custom kernels to spoof SafetyNet/Play Integrity responses.
  • Writable environment checks: Hook additional syscalls like `access()` and `stat()` via eBPF to return `ENOENT` for su paths.
  1. Setting Up an eBPF Development Environment on Linux
    For testing and development, you need a kernel with eBPF support and BCC tools.

Step‑by‑step guide:

  • Verify kernel version (5.4+ recommended) with uname -r.
  • Install build essentials and LLVM.
  • Clone and install BCC from source or via package manager.

Commands:

 Check eBPF support
grep CONFIG_BPF /boot/config-$(uname -r)

Install BCC on Ubuntu/Debian
sudo apt install bpfcc-tools linux-headers-$(uname -r) libbpfcc-dev

Test with a simple eBPF program
sudo execsnoop-bpfcc

For Waydroid (recommended testbed), ensure the container runs a kernel with `CONFIG_BPF=y` and CONFIG_BPF_SYSCALL=y.

  1. Detecting and Mitigating eBPF-Based Syscall Hooks (Blue Team Perspective)
    Defenders can detect this technique by monitoring for unexpected `bpf()` syscalls or verifying syscall arguments after eBPF modifications.

Step‑by‑step guide for detection:

  • Audit loaded eBPF programs via bpftool prog list.
  • Hook the `bpf_probe_write_user` helper to detect memory writes to syscall arguments.
  • Use Kernel Runtime Security Instrumentation (KRSI) with LSM hooks to validate path arguments after eBPF processing.

Detection commands:

 List all loaded eBPF programs
sudo bpftool prog list

Dump eBPF bytecode for suspicious programs
sudo bpftool prog dump xlated id <prog_id>

Monitor bpf syscalls with auditd
sudo auditctl -a always,exit -S bpf -k ebpf_load

Blue teams should enforce signed eBPF programs (e.g., with `BPF_F_KPROBE_MULTI_RETURN` restrictions) and disable `bpf_probe_write_user` via kernel lockdown mode.

7. Testing Your eBPF Root Hider on Waydroid

Waydroid provides an Android container on Linux, making it ideal for safe testing without physical devices.

Step‑by‑step guide:

  • Install Waydroid on an eBPF‑enabled host.
  • Deploy a test root checker app that calls Runtime.getRuntime().exec("su").
  • Run your BCC script from the host (outside the container) – eBPF hooks affect the entire kernel, including Waydroid’s namespaces.
  • Verify that the app fails to detect root because `execve(“su”)` never reaches the kernel as “su”.

Waydroid setup:

sudo apt install waydroid -y
sudo waydroid init
sudo waydroid container start
adb shell  Inside Waydroid, install test app

What Undercode Say:

  • Kernel-level interception is a game-changer: eBPF’s `bpf_probe_write_user` allows live modification of syscall arguments, bypassing userspace RASP without modifying binaries or libraries.
  • Defense is not dead, but it must go deeper: Blue teams need to monitor eBPF program loading and restrict dangerous helpers like `bpf_probe_write_user` via LSM or kernel lockdown.
  • Stealth requires layers: No single technique hides all artifacts. Combine eBPF syscall hooks with filesystem hiding, property spoofing, and hardware attestation bypasses for comprehensive concealment.

Prediction:

As eBPF adoption grows in both offensive and defensive tooling, we will see a new class of “eBPF rootkits” that are nearly invisible to conventional antivirus and EDR. In response, cloud providers and mobile OS vendors will harden eBPF by enforcing strict capability models, signature verification, and runtime auditing of helper functions. The cat-and-mouse game will shift toward securing the eBPF verifier itself and deploying kernel‑level integrity monitors that can detect unauthorized `bpf_probe_write_user` invocations. Within two years, expect eBPF-based detection evasion to become a standard chapter in red team manuals – and a critical alert condition in next‑gen security stacks.

▶️ Related Video (88% Match):

🎯Let’s Practice For Free:

IT/Security Reporter URL:

Reported By: Zlatanh %F0%9D%97%9B%F0%9D%97%B6%F0%9D%97%B1%F0%9D%97%B6%F0%9D%97%BB%F0%9D%97%B4 – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow UndercodeTesting & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin | 🦋BlueSky