Detection rules › Elastic
API Call from a Suspicious Stack
Identifies the call to some Windows APIs from an unusual call stack. This may be the result of an evasion attempt to hide the origin of the API call from the call stack such as unbacked memory region.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Rule body
[rule]
description = """
Identifies the call to some Windows APIs from an unusual call stack. This may be the result of an evasion attempt to
hide the origin of the API call from the call stack such as unbacked memory region.
"""
id = "1089f634-35bd-4877-a638-01e42cb47ae2"
license = "Elastic License v2"
name = "API Call from a Suspicious Stack"
os_list = ["windows"]
reference = ["https://www.elastic.co/security-labs/doubling-down-etw-callstacks"]
version = "1.0.1"
query = '''
api where process.Ext.api.name in ("VirtualAlloc", "VirtualProtect", "WriteProcessMemory", "ResumeThread") and
process.thread.Ext.call_stack_summary == "ntdll.dll|kernelbase.dll|kernel32.dll|ntdll.dll" and
not _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info like
("c:\\windows\\sys?????\\ntdll.dll!LdrLoadDll*",
"c:\\windows\\sys?????\\kernelbase.dll!LoadLibrary*",
"c:\\windows\\sys?????\\kernelbase.dll+0x*",
"c:\\windows\\sys?????\\ntdll.dll+0x*",
"c:\\windows\\sys?????\\kernelbase.dll!MsixIsSystemPackageByPackageFullName*"))
'''
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 in ("VirtualAlloc", "VirtualProtect", "WriteProcessMemory", "ResumeThread") and
process.thread.Ext.call_stack_summary == "ntdll.dll|kernelbase.dll|kernel32.dll|ntdll.dll" and
not _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info like
("c:\\windows\\sys?????\\ntdll.dll!LdrLoadDll*",
"c:\\windows\\sys?????\\kernelbase.dll!LoadLibrary*",
"c:\\windows\\sys?????\\kernelbase.dll+0x*",
"c:\\windows\\sys?????\\ntdll.dll+0x*",
"c:\\windows\\sys?????\\kernelbase.dll!MsixIsSystemPackageByPackageFullName*"))
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
process.thread.Ext.call_stack | array_any | excludes:process.thread.Ext.call_stack |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
process.Ext.api.name | in |
| field:"process.Ext.api.name" kind:in |
process.thread.Ext.call_stack_summary | eq |
| field:"process.thread.Ext.call_stack_summary" kind:eq value:"ntdll.dll|kernelbase.dll|kernel32.dll|ntdll.dll" |