blackpill: A stealthy Linux rootkit made in Rust
blackpill
A Linux kernel rootkit in Rust using a custom made type-2 hypervisor, eBPF XDP and TC programs
Features
The rootkit is composed of multiple modules (talking about Rust modules, not kernel modules):
- defense evasion: hide files, processes, network connections, etc.
- hooking: hook syscalls and IDT
- hypervisor: create a virtual machine to execute malicious code
- persistence: make the rootkit persistent after reboot and resilient to supression
- utils: various utilities
The architecture looks as the following:
And here is how malicious code is executed from C2 to VM guest:
C2 sends crafted assembled x86_64 mnemonics to the rootkit, which then sends it to the VM guest to execute it. The VM guest is isolated from the host and can be used to execute malicious code.
Kernel do not see incoming malicous packets as they are filtered by the eBPF XDP program and sent to the LKM module, and outgoing packets are modified by the eBPF TC program.
Hooking
Hooking is a fundamental capability of the rootkit, implemented using kprobes
in the Linux kernel. This technique intercepts and redirects the execution of system functions to monitor or modify their behavior. In the context of this rootkit, kprobes
provides a powerful mechanism to interact with kernel functions without altering the source code directly.
Defense Evasion
To ensure stealth, the rootkit employs two primary anti-detection mechanisms:
-
Removing the Module from the Kernel Module List
When a kernel module is loaded, it is added to the kernel’s module list, visible via tools likelsmod
or/proc/modules
. To prevent detection:- The rootkit manually removes itself from this list.
- Despite being removed from the list, the module remains operational, enabling continued execution of its functionality.
-
Hooking the
filldir64
Function to Hide a Specific Directory
To conceal files used by the rootkit, a hook is implemented on thefilldir64
function. This function is invoked when a process reads directory contents (e.g., viagetdents
orreaddir
system calls).- Hooking Process:
- The rootkit intercepts the
filldir64
function usingkprobes
. - During execution, the handler inspects directory entries returned to the user.
- If an entry matches the
/BLACKPILL-BLACKPILL
directory (used to store critical rootkit files), it is filtered out and not returned to the user. - All other directory entries are returned normally, ensuring transparency for user-space tools.
- The rootkit intercepts the
- Hooking Process:
-
Using eBPF XDP and TC Programs to Modify Ingress and Egress network traffic To normalize our malicious network communications, we use eBPF XDP (eXpress Data Path) and TC (Traffic Control) programs. As such, we can:
- Intercept specific incoming (ingress) packets with the XDP program at the lowest network level by matching the crafted TCP payload signature from our C2, which we then redirect to a custom BPF map for VM/LKM processing.
- Intercept specific outgoing (egress) packets with the TC program by matching TCP packets generated by VM/LKM, which we then modify by overwriting their payload with our C2 response data. The original packets are automatically retransmitted by TCP, maintaining the appearance of legitimate traffic.
Hypervisor
Our simple hypervisor was implemented following this :
-
Initial system configuration
- Enable hardware virtualization extensions (Intel VT-x or AMD-V) in the BIOS/UEFI (the rootkit doesn’t do that, is must be enabled before).
- Configure the control registers (CR0, CR4, and IA32_EFER) to switch into VMX (Virtual Machine Extensions (Intel)) or SVM (Secure Virtual Machine (AMD)) mode.
-
Entering VMX or SVM Mode
- Initialize the virtualization-specific data structures (VMCS for Intel or VMCB for AMD).
- Program the processor features, such as VM exits, to handle interactions between the guest and the host.
-
Managing Transitions Between Host and Guest
- Configure the entry and exit points for virtual machines (VM entry/exit).
- Implement logic to intercept sensitive system calls made by the guest and analyze their effects.
-
Guest System Creation
- Allocate memory for the guest and initialize its resources (registers, stack, etc.).
-
Communication
- Use communication channels between the rootkit and the hypervisor to transmit commands or data.
Persistence
Persistence is a critical capability of any rootkit, enabling it to maintain control over the target system even after a reboot.
In its current implementation, the persistence mechanism demonstrates its functionality by creating a test file in the file system using the /bin/touch
command. This placeholder action showcases the rootkit’s ability to execute privileged operations and can be extended to implement more advanced persistence strategies.
It is now useless as it is not our priority to create an APT-tier rootkit, but more research around less seen concepts.