Detection rules › Elastic

Windows System Module Remote Hooking

Source
github.com/elastic/protections-artifacts

Identifies attempts to write to a remote process memory to modify NTDLL or Kernelbase modules. This may indicate an attempt to evade endpoint security solutions or perform code injection.

MITRE ATT&CK coverage

TacticTechniques
Stealth

Rule body

[rule]
description = """
Identifies attempts to write to a remote process memory to modify NTDLL or Kernelbase modules. This may indicate an
attempt to evade endpoint security solutions or perform code injection.
"""
id = "4c10ee1d-8373-4450-bf5c-81ce138739a1"
license = "Elastic License v2"
name = "Windows System Module Remote Hooking"
os_list = ["windows"]
reference = ["https://www.elastic.co/security-labs/doubling-down-etw-callstacks"]
version = "1.0.12"

query = '''
api where process.Ext.api.name == "WriteProcessMemory" and process.executable != null and
  process.thread.Ext.call_stack_final_user_module.name != null and 
  process.Ext.api.behaviors == "cross-process" and process.Ext.api.summary like ("*ntdll.dll*", "*kernelbase.dll*") and
   process.thread.Ext.call_stack_summary like
             ("Unbacked", "*kernelbase.dll|Unbacked*", "ntdll.dll|Unknown", "*kernel32.dll|Unbacked*", "*ntdll.dll|Unbacked*") and 
   not stringcontains~(process.Ext.api.summary, process.name) and 
   (process.code_signature.trusted == false or process.code_signature.exists == false or process.name : "rundll32.exe") and 
   not (process.name : "rundll32.exe" and process.command_line : "\"?:\\WINDOWS\\System32\\RUNDLL32\" tsworkspace,WorkspaceStatusNotify2" and 
        process.parent.executable : "?:\\Windows\\System32\\svchost.exe") and 
   not process.thread.Ext.call_stack_final_user_module.name == "kernel" and
   not process.parent.executable : ("C:\\Program Files (x86)\\Xoreax\\IncrediBuild\\BuildSystem.exe", "C:\\Program Files (x86)\\Incredibuild\\BuildSystem.exe") and
   not process.thread.Ext.call_stack_final_user_module.path like
                               ("?:\\program files\\*",
                                "?:\\program files (x86)\\*",
                                "?:\\windows\\system32\\*.dll",
                                "?:\\windows\\syswow64\\*.dll",
                                "\\program files\\*",
                                "\\program files (x86)\\*",
                                "\\windows\\system32\\*.dll",
                                "\\windows\\syswow64\\*.dll",
                                "?:\\windows\\apppatch\\appPatch64\\exploitblocker.dll",
                                "?:\\windows\\FireEye\\AppMonitorDll.dll") and
   not (process.thread.Ext.call_stack_final_user_module.protection_provenance  in ("clr.dll", "mscorwks.dll", "coreclr.dll", "teams.exe") and
      _arraysearch(process.thread.Ext.call_stack_final_user_module.code_signature, $entry, $entry.trusted == true and $entry.subject_name in ("Microsoft Corporation", "Microsoft Corporation", ".NET"))) 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"))
'''

min_endpoint_version = "8.10.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1055"
name = "Process Injection"
reference = "https://attack.mitre.org/techniques/T1055/"


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

[internal]
min_endpoint_version = "8.10.0"

Stages and Predicates

Stage 1: api

api where process.Ext.api.name == "WriteProcessMemory" and process.executable != null and
  process.thread.Ext.call_stack_final_user_module.name != null and 
  process.Ext.api.behaviors == "cross-process" and process.Ext.api.summary like ("*ntdll.dll*", "*kernelbase.dll*") and
   process.thread.Ext.call_stack_summary like
             ("Unbacked", "*kernelbase.dll|Unbacked*", "ntdll.dll|Unknown", "*kernel32.dll|Unbacked*", "*ntdll.dll|Unbacked*") and 
   not stringcontains~(process.Ext.api.summary, process.name) and 
   (process.code_signature.trusted == false or process.code_signature.exists == false or process.name : "rundll32.exe") and 
   not (process.name : "rundll32.exe" and process.command_line : "\"?:\\WINDOWS\\System32\\RUNDLL32\" tsworkspace,WorkspaceStatusNotify2" and 
        process.parent.executable : "?:\\Windows\\System32\\svchost.exe") and 
   not process.thread.Ext.call_stack_final_user_module.name == "kernel" and
   not process.parent.executable : ("C:\\Program Files (x86)\\Xoreax\\IncrediBuild\\BuildSystem.exe", "C:\\Program Files (x86)\\Incredibuild\\BuildSystem.exe") and
   not process.thread.Ext.call_stack_final_user_module.path like
                               ("?:\\program files\\*",
                                "?:\\program files (x86)\\*",
                                "?:\\windows\\system32\\*.dll",
                                "?:\\windows\\syswow64\\*.dll",
                                "\\program files\\*",
                                "\\program files (x86)\\*",
                                "\\windows\\system32\\*.dll",
                                "\\windows\\syswow64\\*.dll",
                                "?:\\windows\\apppatch\\appPatch64\\exploitblocker.dll",
                                "?:\\windows\\FireEye\\AppMonitorDll.dll") and
   not (process.thread.Ext.call_stack_final_user_module.protection_provenance  in ("clr.dll", "mscorwks.dll", "coreclr.dll", "teams.exe") and
      _arraysearch(process.thread.Ext.call_stack_final_user_module.code_signature, $entry, $entry.trusted == true and $entry.subject_name in ("Microsoft Corporation", "Microsoft Corporation", ".NET"))) 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"))

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.thread.Ext.call_stack_final_user_module.protection_provenanceinclr.dll, coreclr.dll, mscorwks.dll, teams.exeexcludes:process.thread.Ext.call_stack_final_user_module.protection_provenance
process.command_lineeq"?:\WINDOWS\System32\RUNDLL32" tsworkspace,WorkspaceStatusNotify2excludes:process.command_line
process.nameeqrundll32.exeexcludes:process.name field:"process.name" value:"rundll32.exe"
process.parent.executableeq?:\Windows\System32\svchost.exeexcludes:process.parent.executable field:"process.parent.executable" value:"?:\Windows\System32\svchost.exe"
process.Ext.api.summarycontainsprocess.nameexcludes:process.Ext.api.summary field:"process.Ext.api.summary" value:"process.name"
process.parent.executableeqC:\Program Files (x86)\Xoreax\IncrediBuild\BuildSystem.exe, C:\Program Files (x86)\Incredibuild\BuildSystem.exeexcludes:process.parent.executable field:"process.parent.executable" value:"C:\Program Files (x86)\Xoreax\IncrediBuild\BuildSystem.exe" field:"process.parent.executable" value:"C:\Program Files (x86)\Incredibuild\BuildSystem.exe"
process.thread.Ext.call_stack_final_user_module.nameeqkernelexcludes:process.thread.Ext.call_stack_final_user_module.name field:"process.thread.Ext.call_stack_final_user_module.name" value:"kernel"
process.thread.Ext.call_stack_final_user_module.pathwildcard?:\program files\*, ?:\program files (x86)\*, ?:\windows\system32\*.dll, ?:\windows\syswow64\*.dll, \program files\*, \program files (x86)\*, \windows\system32\*.dll, \windows\syswow64\*.dll, ?:\windows\apppatch\appPatch64\exploitblocker.dll, ?:\windows\FireEye\AppMonitorDll.dllexcludes:process.thread.Ext.call_stack_final_user_module.path

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
process.Ext.api.behaviorseq
  • cross-process corpus 20 (elastic 20)
field:"process.Ext.api.behaviors" kind:eq value:"cross-process"
process.Ext.api.nameeq
  • WriteProcessMemory corpus 14 (elastic 14)
field:"process.Ext.api.name" kind:eq value:"WriteProcessMemory"
process.Ext.api.summarywildcard
  • *kernelbase.dll*
  • *ntdll.dll* corpus 2 (elastic 2)
field:"process.Ext.api.summary" kind:wildcard
process.code_signature.existseq
  • false transforms: boolean corpus 119 (elastic 119)
field:"process.code_signature.exists" kind:eq value:"false"
process.code_signature.trustedeq
  • false transforms: boolean corpus 115 (elastic 115)
field:"process.code_signature.trusted" kind:eq value:"false"
process.executableis_not_null
  • (no value, null check)
field:"Image" kind:is_not_null
process.namewildcard
  • rundll32.exe corpus 126 (elastic 100, splunk 26)
field:"process_name" kind:wildcard value:"rundll32.exe"
process.thread.Ext.call_stack_final_user_module.nameis_not_null
  • (no value, null check)
field:"process.thread.Ext.call_stack_final_user_module.name" kind:is_not_null
process.thread.Ext.call_stack_summarywildcard
  • *kernel32.dll|Unbacked*
  • *kernelbase.dll|Unbacked*
  • *ntdll.dll|Unbacked*
  • Unbacked
  • ntdll.dll|Unknown corpus 2 (elastic 2)
field:"process.thread.Ext.call_stack_summary" kind:wildcard