Detection rules › Elastic

Parallel NTDLL Loaded from Unbacked Memory

Source
github.com/elastic/protections-artifacts

Identifies the load of NTDLL for the second time and from an unbacked call stack. This may indicate the use of direct system calls to evade endpoint security solutions hooking Windows APIs.

MITRE ATT&CK coverage

TacticTechniques
Stealth

Rule body

[rule]
description = """
Identifies the load of NTDLL for the second time and from an unbacked call stack. This may indicate the use of direct
system calls to evade endpoint security solutions hooking Windows APIs.
"""
id = "69267bb2-e2d9-4621-9bf6-064ac885e49c"
license = "Elastic License v2"
name = "Parallel NTDLL Loaded from Unbacked Memory"
os_list = ["windows"]
reference = [
    "https://www.elastic.co/security-labs/upping-the-ante-detecting-in-memory-threats-with-kernel-call-stacks",
    "https://www.ired.team/offensive-security/defense-evasion/using-syscalls-directly-from-visual-studio-to-bypass-avs-edrs",
]
version = "1.0.20"

query = '''
library where dll.name : "ntdll.dll" and
 dll.Ext.load_index >= 2 and
 process.thread.Ext.call_stack_summary :
                   ("*kernelbase.dll|Unbacked*",
                    "Unbacked*",
                    "ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|Unbacked",
                    "ntdll.dll|Unbacked",
                    "ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|Unbacked|kernel32.dll|ntdll.dll",
                    "ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|Unbacked|clr.dll|mscorlib.ni.dll|Unbacked|clr.dll|mscorlib.ni.dll|Unbacked|clr.dll|mscoreei.dll|mscoree.dll|ntdll.dll") and
 not (process.code_signature.subject_name == "Check Point Software Technologies Ltd." and
      process.code_signature.trusted == true and process.thread.Ext.call_stack_summary : "ntdll.dll|Unbacked") and
 not (process.executable : "?:\\Windows\\System32\\taskhostw.exe" and user.id : "S-1-5-18" and
      process.thread.Ext.call_stack_summary : "Unbacked") and
 not process.executable : "C:\\Program Files (x86)\\Steam\\steamapps\\common\\MonsterHunterWilds\\MonsterHunterWilds.exe"
'''

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

[[optional_actions]]
action = "rollback"
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.7.0"

Stages and Predicates

Stage 1: library

library where dll.name : "ntdll.dll" and
 dll.Ext.load_index >= 2 and
 process.thread.Ext.call_stack_summary :
                   ("*kernelbase.dll|Unbacked*",
                    "Unbacked*",
                    "ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|Unbacked",
                    "ntdll.dll|Unbacked",
                    "ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|Unbacked|kernel32.dll|ntdll.dll",
                    "ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|Unbacked|clr.dll|mscorlib.ni.dll|Unbacked|clr.dll|mscorlib.ni.dll|Unbacked|clr.dll|mscoreei.dll|mscoree.dll|ntdll.dll") and
 not (process.code_signature.subject_name == "Check Point Software Technologies Ltd." and
      process.code_signature.trusted == true and process.thread.Ext.call_stack_summary : "ntdll.dll|Unbacked") and
 not (process.executable : "?:\\Windows\\System32\\taskhostw.exe" and user.id : "S-1-5-18" and
      process.thread.Ext.call_stack_summary : "Unbacked") and
 not process.executable : "C:\\Program Files (x86)\\Steam\\steamapps\\common\\MonsterHunterWilds\\MonsterHunterWilds.exe"

Exclusions

The rule actively suppresses these predicates.

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
dll.Ext.load_indexge
  • 2 transforms: number corpus 3 (elastic 3)
field:"dll.Ext.load_index" kind:ge value:"2"
dll.namewildcard
  • ntdll.dll corpus 6 (elastic 6)
field:"dll.name" kind:wildcard value:"ntdll.dll"
process.thread.Ext.call_stack_summarywildcard
  • *kernelbase.dll|Unbacked*
  • Unbacked*
  • ntdll.dll|Unbacked corpus 6 (elastic 6)
  • ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|Unbacked corpus 4 (elastic 4)
  • ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|Unbacked|clr.dll|mscorlib.ni.dll|Unbacked|clr.dll|mscorlib.ni.dll|Unbacked|clr.dll|mscoreei.dll|mscoree.dll|ntdll.dll
  • ntdll.dll|wow64.dll|wow64cpu.dll|wow64.dll|ntdll.dll|Unbacked|kernel32.dll|ntdll.dll corpus 2 (elastic 2)
field:"process.thread.Ext.call_stack_summary" kind:wildcard