Introduction: The “God Mode” of Malware
In the hierarchy of malware, rootkits are stealthy, but bootkits are persistent. A Bootkit compromises the very first code that runs when you press the power button (UEFI/BIOS), surviving OS reinstalls. A Rootkit hides within the OS kernel, rendering itself invisible to task managers and antivirus.
BootKitty is a research prototype that combines both. It demonstrates how to break the “Chain of Trust” on Windows, Linux, and Android, subverting security mechanisms like Secure Boot, PatchGuard, and SELinux before they even initialize.
1. The Modern Boot Process Visualized
To understand the attack, we must first visualize the secure boot chain. Modern systems rely on a cryptographic chain of trust.
[ Power On ]
|
v
+------------------------+
| 1. FIRMWARE (UEFI) | <-- Verifies Digital Signatures
+------------------------+
|
v
+------------------------+
| 2. BOOTLOADER | <-- Windows Boot Manager / GRUB2 / LK
+------------------------+
|
v
+------------------------+
| 3. KERNEL INIT | <-- Initializes Hardware & Security (PatchGuard, SELinux)
+------------------------+
|
v
+------------------------+
| 4. USER SPACE | <-- OS is now fully operational
+------------------------+
The Problem: If an attacker compromises Stage 1 or 2, they control how Stage 3 is loaded. They can load a “poisoned” kernel that disables all security checks.
2. BootKitty Architecture
BootKitty operates in four distinct phases. It acts as a bridge between the firmware exploit (Bootkit) and the OS payload (Rootkit).
PHYSICAL ACCESS / REMOTE LPE
|
v
+--------------------------------+
| PHASE 1: INFECTION |
| (Exploit Firmware Vulns) |
+--------------------------------+
|
[ System Reboot Required ]
|
v
+--------------------------------+
| PHASE 2: BOOTKIT OPERATION |
| (Pre-OS Execution) |
| -> Bypass Secure Boot |
| -> Hook Boot Components |
+--------------------------------+
|
v
+--------------------------------+
| PHASE 3: ROOTKIT INSTALLATION |
| (Kernel Level) |
| -> Disable DSE/PatchGuard |
| -> Inject Malicious Driver |
+--------------------------------+
|
v
+--------------------------------+
| PHASE 4: ROOTKIT OPERATION |
| (Stealthy C&C) |
| -> Hide Processes/Files |
| -> Keylogging / Exfiltration |
+--------------------------------+
3. Case Study: BootKitty on Windows
Windows relies on a complex stack of security features: Secure Boot, VBS (Virtualization-Based Security), and PatchGuard. BootKitty tears them down one by one.
The Attack Chain
[ attacker runs bootkitty.exe ]
|
v
(1) DISABLE SECURITY
- Modifies BCD (Boot Configuration Data)
- Drops vulnerable, but *signed*, boot manager files
|
v
(2) REBOOT -> BYPASS SECURE BOOT
- Exploits CVE-2022-21894 (Baton Drop)
- Uses 'avoidlowmemory' trick to remove Secure Boot from memory
|
v
(3) BOOTKIT PAYLOAD
- Loads self-signed GRUB2 via MOK (Machine Owner Key)
- Hooks 'winload.efi' to reserve memory for rootkit
|
v
(4) KERNEL HIJACK
- Hooks 'ntoskrnl.exe'
- Disables DSE (Driver Signature Enforcement)
- Disables PatchGuard
|
v
(5) ROOTKIT LOADED
- Loads unsigned 'rootkit.sys'
- System Compromised
Technical Deep Dive: Disabling Protections
BootKitty uses kernel patching to disable core defenses. Here is a conceptualization of how it neutralizes DSE (Driver Signature Enforcement) and PatchGuard.
Note: The following is simplified pseudocode representing the logic described in the paper.
// Conceptual Kernel Patching Logic
void DisableSecurityMechanisms(KERNEL_STRUCTURES *kern) {
// 1. Disable DSE (Driver Signature Enforcement)
// DSE usually relies on a global variable or flag in the kernel (g_CiEnabled)
// BootKitty locates this flag and flips it to allow unsigned drivers.
ULONG_PTR *CiEnabled = FindPattern(kern->base, "DSE_FLAG_SIGNATURE");
if (CiEnabled) {
*CiEnabled = 0; // Allow unsigned drivers
}
// 2. Disable PatchGuard
// PatchGuard works by scheduling checks.
// BootKitty can intercept the initialization or remove the checks.
// Often this involves patching the function responsible for setting the timer.
PVOID PatchGuardInit = ResolveSymbol(kern, "KeInitializeGuardThread");
// Patch with RET instruction to prevent initialization
PatchMemory(PatchGuardInit, 0xC3);
// 3. Hook SSDT (System Service Descriptor Table)
// Allows intercepting system calls for hiding processes
kern->SSDT->NtQueryDirectoryFile = Hook_NtQueryDirectoryFile;
}
Rootkit Feature: Process Hiding
The Windows rootkit hides processes by unlinking them from the EPROCESS linked list in kernel memory.
[ Normal System View ]
+---------+ +---------+ +---------+
| Process |<-->| Process |<-->| Malware |
| A | | B | | .exe |
+---------+ +---------+ +---------+
|
v
[ Task Manager sees it ]
------------------------------------------------------
[ BootKitty View (EPROCESS Unlinking) ]
+---------+ +---------+
| Process |<-->| Process | (Malware is still running
| A | | B | but disconnected from list)
+---------+ +---------+ |
* | Hidden Link
v
+---------+
| Malware |
| .exe |
+---------+
|
v
[ Task Manager BLIND ]
Code Representation:
// Hiding a process via EPROCESS unlinking
void HideProcess(PEPROCESS Process) {
PLIST_ENTRY Prev = Process->ActiveProcessLinks.Blink;
PLIST_ENTRY Next = Process->ActiveProcessLinks.Flink;
// Link the previous process to the next, skipping current
Prev->Flink = Next;
Next->Blink = Prev;
// Point the hidden process to itself to avoid crashes
Process->ActiveProcessLinks.Flink = &Process->ActiveProcessLinks;
Process->ActiveProcessLinks.Blink = &Process->ActiveProcessLinks;
}
4. Case Study: BootKitty on Linux
Linux uses UEFI Secure Boot typically via a signed Shim bootloader. BootKitty exploits LogoFAIL (CVE-2023-40238) to break this trust.
The LogoFAIL Exploit
The UEFI firmware parses BMP images to display boot logos. BootKitty sends a malformed BMP image that triggers a buffer overflow in the firmware’s parser.
[ Normal Image Parsing ]
Header OK -> Width/Height -> Allocate Memory -> Display
[ Malicious Parsing (LogoFAIL) ]
Header:
Width: 0xFFFF
Height: 0xFFFF
Data: [ SHELLCODE ]
|
v
Parser Overflow: Allocates small buffer, writes huge SHELLCODE
|
v
Instruction Pointer (IP) hijacked -> Execution redirected to Shellcode
|
v
ACTION: Enroll Custom MOK (Machine Owner Key)
Bootkit Flow
User Space
|
+-> (1) LPE Exploit Chain (CVE-2024-35235 etc.)
| Gains Root Access
|
+-> (2) Write Malformed 'logo.bmp' to EFI Variables
|
+-> (3) Reboot
|
v
Firmware (DXE Phase)
|
+-> Parses 'logo.bmp'
+-> BOOM: Code Execution
+-> Enrolls Attacker's MOK Key
|
v
Bootloader (Shim)
|
+-> Verifies 'grubx64.efi' using NEW MOK
+-> Loads Bootkit (Modified GRUB2)
|
v
Kernel Load
|
+-> Hook 'decompress_kernel'
+-> Patch AppArmor to return 0 (Allow all)
+-> Disable Module Signature Verification
|
v
Rootkit
+-> Load 'rootkit.ko' (Kernel Module)
Kernel Patching Code (Conceptual)
To bypass Linux Kernel Module Signing and AppArmor, BootKitty patches the kernel image in memory during the decompression phase.
// Pseudo-code for Linux Kernel Patching
void patch_linux_kernel(unsigned char *kernel_base) {
// 1. Bypass AppArmor
// Find the function responsible for auditing file access.
// Force it to return success (0) immediately.
unsigned char *aa_audit_file = find_symbol(kernel_base, "aa_audit_file");
// Overwrite function start with: xor %eax, %eax; ret
// (Return 0)
unsigned char patch[] = { 0x31, 0xC0, 0xC3 };
memcpy(aa_audit_file, patch, sizeof(patch));
// 2. Bypass Kernel Module Signing
// Find the signature verification call in 'load_module'
unsigned char *verify_sig = find_pattern(kernel_base, "VERIFY_SIG_SIGNATURE");
// NOP out the check or force success
unsigned char bypass[] = { 0x90, 0x90, 0xB0, 0x01 }; // NOP, NOP, MOV AL, 1 (Success)
memcpy(verify_sig, bypass, sizeof(bypass));
}
5. Case Study: BootKitty on Android
Android security is rigid, relying on hardware-backed Verified Boot. BootKitty targets Samsung devices using Odin Mode and exploits in the Little Kernel (LK) bootloader.
ARM Exception Levels (EL)
To understand the Android attack, we look at privilege levels.
+-----------------------+
| EL0 (User Apps) | <--- Lowest Privilege
+-----------------------+
| EL1 (Kernel) | <--- Standard Rootkits operate here
+-----------------------+
| EL2 (Hypervisor) | <--- Virtualization
+-----------------------+
| EL3 (Secure Mon.) | <--- TrustZone, TEE (Fingerprint, Keys)
+-----------------------+
BootKitty aims for EL1 (Kernel) but needs to exploit the boot chain starting from EL3 (Boot ROM).
Android Attack Chain
- Physical Access: Force device into Odin Mode.
- GPT Exploit (CVE-2024-20865): Flash arbitrary partitions without signature checks.
- JPEG Parser Exploit (CVE-2024-20832): The
up_parampartition is processed by LK bootloader.
[ LK Bootloader Processing ]
|
v
Read 'secure_error.jpg' from up_param
|
v
Parse JPEG Header
|
v
[ Heap Overflow Triggered ]
|
v
Overwrite Function Pointer
|
v
Jump to SHELLCODE in Heap
|
v
ACTION: Disable RKP (Real-time Kernel Protection)
ACTION: Patch Ramdisk
Android Kernel Patching
BootKitty patches the kernel to disable SELinux and DEFEX.
// Conceptual patching in Android Kernel
void android_kernel_patch(void *kernel_base) {
// 1. Disable SELinux
// Usually a global integer variable 'selinux_enforcing'
int *selinux_enforcing = (int *)find_symbol(kernel_base, "selinux_enforcing");
*selinux_enforcing = 0; // Set to Permissive/Disabled
// 2. Bypass DEFEX (Samsung Security)
// Find the function checking process credentials
void *defex_verify = find_symbol(kernel_base, "defex_verify_creds");
// Patch to return success immediately
unsigned char ret_success[] = { 0x01, 0x20, 0x70, 0x47 }; // MOV R0, #1; BX LR (ARM Thumb)
memcpy(defex_verify, ret_success, sizeof(ret_success));
}
6. Impact & Defenses
Comparison of Rootkit Features
| Feature | Windows Implementation | Linux Implementation | Android Implementation |
|---|---|---|---|
| Process Hiding | Unlink EPROCESS |
Hook getdents64 |
Not primary focus (Kernel mod) |
| File Hiding | SSDT Hooks | Hook getdents64 |
Hook syscalls |
| Keylogging | Keyboard Driver Hook | Read /dev/input/eventX |
Input Event Hook |
| Persistence | Bootkit in UEFI | Bootkit in UEFI/GRUB | Partition Flashing |
| Defense Bypass | PatchGuard, DSE | AppArmor, Module Signing | SELinux, DEFEX, RKP |
Defensive Recommendations
- Firmware Updates: LogoFAIL and Baton Drop are patched, but users must update firmware/BIOS manually.
- Secure Boot Hardening: Manufacturers should enforce stricter verification of NVRAM variables and MOK enrollment (UI prompts).
- Hardware Attestation: Use TPM (Trusted Platform Module) to verify boot measurements (PCR values) before releasing encryption keys (BitLocker/FileVault).
- Kernel Integrity Monitoring: Systems like Linux IMA/EVM or Windows HVCI (if active) make these attacks significantly harder.
[ Defense Layers ]
Layer 0: Hardware (TPM/TrustZone) -> Attestation
Layer 1: Firmware (UEFI) -> Signature Verification
Layer 2: Bootloader -> Integrity Checks
Layer 3: Kernel -> Runtime Protection (PatchGuard)
BootKitty Breaks Layers 1, 2, and 3.
Layer 0 is the last line of defense.
Conclusion
BootKitty serves as a stark reminder: Security is only as strong as its weakest link. In modern computing, the boot chain is a critical attack surface. By chaining exploits from the firmware (LogoFAIL, Baton Drop) down to the kernel (Patching, Hooking), BootKitty proves that “low-level” access provides “God-level” control.
While complex to implement, these techniques are increasingly relevant as Advanced Persistent Threats (APTs) move lower into the stack to evade detection. Defenders must look upward from the hardware to ensure the software they see is the software they get.
References
- Lee, J., Kwon, J., et al. (2025). BootKitty: A Stealthy Bootkit-Rootkit Against Modern Operating Systems. Proceedings of the 19th USENIX WOOT Conference.
- USENIX Association. Open access to the Proceedings of the 19th USENIX WOOT Conference.
- CVE-2022-21894: “Baton Drop” Windows Boot Manager Security Feature Bypass.
- CVE-2023-40238: “LogoFAIL” UEFI Vulnerability.
- CVE-2024-20832 / CVE-2024-20865: Samsung Android Bootloader Vulnerabilities.
- BlackLotus UEFI Bootkit: Precursor research to Windows Bootkit techniques.
- Android Security: Verified Boot and TrustZone documentation.