Detection rules › Elastic

Potential ETW Bypass via VirtualProtect

Source
github.com/elastic/protections-artifacts

Identifies attempts to change the memory page permissions of Event Tracing for Windows (ETW) functions in ntdll.dll to make them writable from an unsigned or suspicious module. This is a precursor to patching those functions via a raw pointer write, which can disable ETW-based telemetry and evade security tooling that relies on it.

MITRE ATT&CK coverage

TacticTechniques
Defense Impairment

Rule body

[rule]
description = """
Identifies attempts to change the memory page permissions of Event Tracing for Windows (ETW) functions in ntdll.dll to
make them writable from an unsigned or suspicious module. This is a precursor to patching those functions via a raw
pointer write, which can disable ETW-based telemetry and evade security tooling that relies on it.
"""
id = "a26e8618-136d-4988-a8a7-eb45d5f1d468"
license = "Elastic License v2"
name = "Potential ETW Bypass via VirtualProtect"
os_list = ["windows"]
reference = [
    "https://blog.xpnsec.com/hiding-your-dotnet-etw/",
    "https://www.elastic.co/security-labs/doubling-down-etw-callstacks",
]
version = "1.0.3"

query = '''
api where process.Ext.api.name in ("VirtualProtect", "VirtualProtectEx") and
 process.Ext.api.metadata.target_address_name like ("ntdll.dll!Etw*", "ntdll.dll!NtTrace*") and
 process.Ext.api.parameters.protection like "?W*" and
 process.executable != null and
 process.thread.Ext.call_stack_final_user_module.hash.sha256 != null and 
 not process.thread.Ext.call_stack_final_user_module.name in ("Unknown", "Undetermined") and
 not (process.executable : "?:\\Program Files\\Microsoft Visual Studio\\*\\IDE\\devenv.exe" and 
      process.Ext.api.metadata.target_address_name like ("ntdll.dll!EtwUnregisterTraceGuid*", "ntdll.dll!EtwRegisterTraceGuids*")) and 
 not _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info like ("c:\\windows\\system32\\ntdll.dll!Ldr*", "c:\\program files\\microsoft sql server management studio*\\ide\\ssms.exe!SetOnAssertCallback*")) and 
 not _arraysearch(process.thread.Ext.call_stack_final_user_module.code_signature, $entry, $entry.trusted == true and
                  $entry.subject_name in ("Microsoft Windows Hardware Compatibility Publisher",
                                          "Microsoft Windows Software Compatibility Publisher",
                                          "Palo Alto Networks", "Sentinel Labs, Inc.",
                                          "Microsoft Corporation", 
                                          "Check Point Software Technologies Ltd.", 
                                          "ESET, spol. s r.o.",
                                          "Promon AS",
                                          "SAP",
                                          "NOVASYNC LABS PTE. LTD.",
                                          "Tonalio GmbH",
                                          "SentinelOne Inc.",
                                          "JetBrains s.r.o.",
                                          "Safetica a.s.",
                                          "ModuleWorks GmbH",
                                          "Star Finanz-Software Entwicklung und Vertriebs GmbH", 
                                          "TRACKER SOFTWARE PRODUCTS (CANADA) LIMITED, TRACKER SOFTWARE PRODUCTS (CANADA) LIMITED")) and 
  not (process.executable like "C:\\Program Files (x86)\\SFirmV*\\SFEbicsWorker.exe" and process.thread.Ext.call_stack_final_user_module.protection_provenance_path == "c:\\windows\\system32\\rundll32.exe") and 
  not (process.parent.executable like "C:\\Program Files (x86)\\StarMoney*\\app\\StarMoney.exe" and process.thread.Ext.call_stack_final_user_module.protection_provenance_path == "c:\\windows\\system32\\rundll32.exe") and 
  process.thread.Ext.call_stack_final_user_module.protection_provenance_path != "c:\\windows\\syswow64\\icu.dll" and 
  not (process.thread.Ext.call_stack_final_user_module.path == "c:\\windows\\syswow64\\combase.dll" and process.Ext.api.summary == "VirtualProtect( ntdll.dll!EtwEventRegister, 0x5, RWX, R-X )")
'''

min_endpoint_version = "8.16.3"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
tree = true

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1562"
name = "Impair Defenses"
reference = "https://attack.mitre.org/techniques/T1562/"
[[threat.technique.subtechnique]]
id = "T1562.001"
name = "Disable or Modify Tools"
reference = "https://attack.mitre.org/techniques/T1562/001/"



[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"

[internal]
min_endpoint_version = "8.16.3"

Stages and Predicates

Stage 1: api

api where process.Ext.api.name in ("VirtualProtect", "VirtualProtectEx") and
 process.Ext.api.metadata.target_address_name like ("ntdll.dll!Etw*", "ntdll.dll!NtTrace*") and
 process.Ext.api.parameters.protection like "?W*" and
 process.executable != null and
 process.thread.Ext.call_stack_final_user_module.hash.sha256 != null and 
 not process.thread.Ext.call_stack_final_user_module.name in ("Unknown", "Undetermined") and
 not (process.executable : "?:\\Program Files\\Microsoft Visual Studio\\*\\IDE\\devenv.exe" and 
      process.Ext.api.metadata.target_address_name like ("ntdll.dll!EtwUnregisterTraceGuid*", "ntdll.dll!EtwRegisterTraceGuids*")) and 
 not _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info like ("c:\\windows\\system32\\ntdll.dll!Ldr*", "c:\\program files\\microsoft sql server management studio*\\ide\\ssms.exe!SetOnAssertCallback*")) and 
 not _arraysearch(process.thread.Ext.call_stack_final_user_module.code_signature, $entry, $entry.trusted == true and
                  $entry.subject_name in ("Microsoft Windows Hardware Compatibility Publisher",
                                          "Microsoft Windows Software Compatibility Publisher",
                                          "Palo Alto Networks", "Sentinel Labs, Inc.",
                                          "Microsoft Corporation", 
                                          "Check Point Software Technologies Ltd.", 
                                          "ESET, spol. s r.o.",
                                          "Promon AS",
                                          "SAP",
                                          "NOVASYNC LABS PTE. LTD.",
                                          "Tonalio GmbH",
                                          "SentinelOne Inc.",
                                          "JetBrains s.r.o.",
                                          "Safetica a.s.",
                                          "ModuleWorks GmbH",
                                          "Star Finanz-Software Entwicklung und Vertriebs GmbH", 
                                          "TRACKER SOFTWARE PRODUCTS (CANADA) LIMITED, TRACKER SOFTWARE PRODUCTS (CANADA) LIMITED")) and 
  not (process.executable like "C:\\Program Files (x86)\\SFirmV*\\SFEbicsWorker.exe" and process.thread.Ext.call_stack_final_user_module.protection_provenance_path == "c:\\windows\\system32\\rundll32.exe") and 
  not (process.parent.executable like "C:\\Program Files (x86)\\StarMoney*\\app\\StarMoney.exe" and process.thread.Ext.call_stack_final_user_module.protection_provenance_path == "c:\\windows\\system32\\rundll32.exe") and 
  process.thread.Ext.call_stack_final_user_module.protection_provenance_path != "c:\\windows\\syswow64\\icu.dll" and 
  not (process.thread.Ext.call_stack_final_user_module.path == "c:\\windows\\syswow64\\combase.dll" and process.Ext.api.summary == "VirtualProtect( ntdll.dll!EtwEventRegister, 0x5, RWX, R-X )")

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.thread.Ext.call_stack_final_user_module.code_signaturearray_any(no value, null check)excludes:process.thread.Ext.call_stack_final_user_module.code_signature
process.Ext.api.metadata.target_address_namestarts_withntdll.dll!EtwUnregisterTraceGuid, ntdll.dll!EtwRegisterTraceGuidsexcludes:process.Ext.api.metadata.target_address_name field:"process.Ext.api.metadata.target_address_name" value:"ntdll.dll!EtwUnregisterTraceGuid" field:"process.Ext.api.metadata.target_address_name" value:"ntdll.dll!EtwRegisterTraceGuids"
process.executablewildcard?:\Program Files\Microsoft Visual Studio\*\IDE\devenv.exeexcludes:process.executable field:"process.executable" value:"?:\Program Files\Microsoft Visual Studio\*\IDE\devenv.exe"
process.Ext.api.summaryeqVirtualProtect( ntdll.dll!EtwEventRegister, 0x5, RWX, R-X )excludes:process.Ext.api.summary field:"process.Ext.api.summary" value:"VirtualProtect( ntdll.dll!EtwEventRegister, 0x5, RWX, R-X )"
process.thread.Ext.call_stack_final_user_module.patheqc:\windows\syswow64\combase.dllexcludes:process.thread.Ext.call_stack_final_user_module.path field:"process.thread.Ext.call_stack_final_user_module.path" value:"c:\windows\syswow64\combase.dll"
process.executablewildcardC:\Program Files (x86)\SFirmV*\SFEbicsWorker.exeexcludes:process.executable field:"process.executable" value:"C:\Program Files (x86)\SFirmV*\SFEbicsWorker.exe"
process.thread.Ext.call_stack_final_user_module.protection_provenance_patheqc:\windows\system32\rundll32.exeexcludes:process.thread.Ext.call_stack_final_user_module.protection_provenance_path field:"process.thread.Ext.call_stack_final_user_module.protection_provenance_path" value:"c:\windows\system32\rundll32.exe"
process.parent.executablewildcardC:\Program Files (x86)\StarMoney*\app\StarMoney.exeexcludes:process.parent.executable field:"process.parent.executable" value:"C:\Program Files (x86)\StarMoney*\app\StarMoney.exe"
process.thread.Ext.call_stackarray_any(no value, null check)excludes:process.thread.Ext.call_stack
process.thread.Ext.call_stack_final_user_module.nameinUndetermined, Unknownexcludes:process.thread.Ext.call_stack_final_user_module.name field:"process.thread.Ext.call_stack_final_user_module.name" value:"Undetermined" field:"process.thread.Ext.call_stack_final_user_module.name" value:"Unknown"

Indicators

These rows show field, operator, and value matches.