ETW-TI Fluctuation Monitor

repository·main·Indexed 41 days ago

https://github.com/jdu2600/etwti-fluctuationmonitor

A security tool that detects hidden shellcode by monitoring Microsoft-Windows-Threat-Intelligence ETW events for violations of memory immutability. It identifies suspicious memory protection transitions—such as executable memory becoming non-executable or non-writable memory becoming writable—using a frequency-based heuristic to flag potential 'Bad JIT' or shellcode activity.

Tokens
972
Snippets
1
Records
4
Agent score
2%

What's inside ETW-TI Fluctuation Monitor

  1. How etwti-fluctuationmonitor detects hidden shellcode

    main

    The monitor detects hidden shellcode by identifying violations of the 'immutable code page' principle. In secure environments, memory protection for code pages should only progress from Read/Write (RW) to Read/Execute (RX).

    While Windows enforces this for the kernel (via PatchGuard) and user-mode images (via Arbitrary Code Guard), it does not protect private user-mode executable code like JIT (Just-In-Time) compilers.

    The monitor watches for two specific suspicious transitions using Microsoft-Windows-Threat-Intelligence ETW events:

    1. Executable memory being changed to non-executable.
    2. Executable memory changing from non-writable to writable.

    To minimize false positives caused by legitimate JIT memory reuse or API hooking, the monitor uses a frequency-based heuristic: it only alerts if these transitions occur more than once for a given memory region.

  2. Detecting memory protection fluctuations via ETW-TI

    main

    The monitor uses the Microsoft-Windows-Threat-Intelligence ETW provider to intercept memory protection events. It specifically listens for Event ID 7 (related to VirtualProtect).

    Detection Logic:

    1. Identify Immutable Pages: A page is added to the g_ImmutableCodePages map if it undergoes a transition where:
      • It becomes executable (!IsExecutable(LastProtectionMask) && IsExecutable(ProtectionMask))
      • It becomes non-writable (IsWritable(LastProtectionMask) && !IsWritable(ProtectionMask))
    2. Detect Fluctuation: If an event occurs on a BaseAddress that is already present in g_ImmutableCodePages for a specific ProcessID, the monitor flags it as a fluctuation (potential shellcode activity).

    Parsed Event Fields: When processing the event via krabs::parser, the following fields are extracted:

    • CallingProcessId (DWORD)
    • BaseAddress (PVOID)
    • ProtectionMask (DWORD)
    • LastProtectionMask (DWORD)
  3. How the ETW-TI Fluctuation Monitor works

    main

    The monitor detects hidden shellcode by identifying violations of the immutable code page principle.

    In a secure JIT (Just-In-Time) compilation process, code pages follow a strict lifecycle: Allocate(RW) -> memcpy(code) -> Protect(RX) -> execute. Once a page transitions to an executable state or moves from a writable to a non-writable state, it is considered immutable and should never be modified again.

    Fluctuation occurs when a page that was previously marked as immutable undergoes further protection changes (e.g., Protect(RX) -> Protect(~X) -> Protect(RX)). This behavior is a strong indicator of malicious activity, such as a 'Bad JIT' or shellcode attempting to hide by toggling memory protections.

  4. Configure the ETW-TI provider for monitoring

    main

    To monitor memory protection changes, you must initialize the Microsoft-Windows-Threat-Intelligence provider and enable the specific keyword for local protection monitoring (0x10 / KERNEL_THREATINT_KEYWORD_PROTECTVM_LOCAL).

    krabs::provider<> ti_provider(L"Microsoft-Windows-Threat-Intelligence");
    ti_provider.any(0x10); // KERNEL_THREATINT_KEYWORD_PROTECTVM_LOCAL
    
    // Define a filter for Event ID 7
    krabs::event_filter protectvm_filter(krabs::predicates::id_is(7));
    
    // Add callback and enable trace
    ti_provider.add_filter(protectvm_filter);
    g_trace.enable(ti_provider);
    krabs::provider<> ti_provider(L"Microsoft-Windows-Threat-Intelligence");
    ti_provider.any(0x10); // KERNEL_THREATINT_KEYWORD_PROTECTVM_LOCAL
    
    krabs::event_filter protectvm_filter(krabs::predicates::id_is(7));
    // ... callback logic ...
    protectvm_filter.add_on_event_callback(protectvm_cb);
    ti_provider.add_filter(protectvm_filter);
    g_trace.enable(ti_provider);