Detection rules › Elastic
Stack Spoofing via ROP Gadget for Memory API
Detects potential stack spoofing via ROP gadget in the context of memory or execution API calls. Flags invocations where the call stack exhibits patterns associated with return-oriented programming used to alter call stack appearance.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Stealth |
Rule body
[rule]
description = """
Detects potential stack spoofing via ROP gadget in the context of memory or execution API calls. Flags invocations where
the call stack exhibits patterns associated with return-oriented programming used to alter call stack appearance.
"""
id = "c5e0a2f9-7d1b-3f6c-e4a8-0b9d5e2c1a3f"
license = "Elastic License v2"
name = "Stack Spoofing via ROP Gadget for Memory API"
os_list = ["windows"]
reference = [
"https://www.elastic.co/security-labs/doubling-down-etw-callstacks",
"https://attack.mitre.org/techniques/T1036/",
]
version = "1.0.1"
query = '''
api where process.Ext.token.integrity_level_name != "low" and
process.Ext.api.name in (
"VirtualProtect",
"VirtualAlloc",
"VirtualProtectEx",
"VirtualAllocEx",
"WriteProcessMemory",
"ReadProcessMemory",
"MapViewOfFile",
"MapViewOfFile2",
"SetThreadContext",
"SuspendThread"
) and
process.thread.Ext.call_stack_summary in (
"ntdll.dll|kernelbase.dll|dfshim.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|dfshim.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|archiveint.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|archiveint.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|authfwsnapin.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|authfwsnapin.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|fluenceds.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|fluenceds.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|hostnetsvc.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|hostnetsvc.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|bingmaps.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|bingmaps.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|maprouter.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|maprouter.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|mshtml.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|mshtml.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|printui.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|printui.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|shell32.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|shell32.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|urlmon.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|urlmon.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|winipcsecproc.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|winipcsecproc.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|windows.networking.backgroundtransfer.contentprefetchtask.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|windows.networking.backgroundtransfer.contentprefetchtask.dll|kernel32.dll|ntdll.dll"
) and
not (process.Ext.api.name == "VirtualProtect" and
_arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info like ("c:\\windows\\system32\\ntdll.dll!LdrLoadDll*", "c:\\windows\\system32\\kernelbase.dll!LoadLibrary*"))) and
not (process.Ext.api.name == "SuspendThread" and process.thread.Ext.call_stack_summary == "ntdll.dll|shell32.dll|kernel32.dll|ntdll.dll")
'''
min_endpoint_version = "8.10.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
tree = true
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1036"
name = "Masquerading"
reference = "https://attack.mitre.org/techniques/T1036/"
[[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.token.integrity_level_name != "low" and
process.Ext.api.name in (
"VirtualProtect",
"VirtualAlloc",
"VirtualProtectEx",
"VirtualAllocEx",
"WriteProcessMemory",
"ReadProcessMemory",
"MapViewOfFile",
"MapViewOfFile2",
"SetThreadContext",
"SuspendThread"
) and
process.thread.Ext.call_stack_summary in (
"ntdll.dll|kernelbase.dll|dfshim.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|dfshim.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|archiveint.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|archiveint.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|authfwsnapin.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|authfwsnapin.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|fluenceds.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|fluenceds.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|hostnetsvc.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|hostnetsvc.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|bingmaps.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|bingmaps.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|maprouter.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|maprouter.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|mshtml.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|mshtml.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|printui.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|printui.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|shell32.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|shell32.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|urlmon.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|urlmon.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|winipcsecproc.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|winipcsecproc.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|kernelbase.dll|windows.networking.backgroundtransfer.contentprefetchtask.dll|kernel32.dll|ntdll.dll",
"ntdll.dll|windows.networking.backgroundtransfer.contentprefetchtask.dll|kernel32.dll|ntdll.dll"
) and
not (process.Ext.api.name == "VirtualProtect" and
_arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info like ("c:\\windows\\system32\\ntdll.dll!LdrLoadDll*", "c:\\windows\\system32\\kernelbase.dll!LoadLibrary*"))) and
not (process.Ext.api.name == "SuspendThread" and process.thread.Ext.call_stack_summary == "ntdll.dll|shell32.dll|kernel32.dll|ntdll.dll")
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 | |
process.Ext.api.name | eq | VirtualProtect | excludes:process.Ext.api.name field:"process.Ext.api.name" value:"VirtualProtect" |
process.Ext.api.name | eq | SuspendThread | excludes:process.Ext.api.name field:"process.Ext.api.name" value:"SuspendThread" |
process.thread.Ext.call_stack_summary | eq | ntdll.dll|shell32.dll|kernel32.dll|ntdll.dll | excludes:process.thread.Ext.call_stack_summary field:"process.thread.Ext.call_stack_summary" value:"ntdll.dll|shell32.dll|kernel32.dll|ntdll.dll" |
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.Ext.token.integrity_level_name | ne |
| field:"process.Ext.token.integrity_level_name" kind:ne value:"low" |
process.thread.Ext.call_stack_summary | in |
| field:"process.thread.Ext.call_stack_summary" kind:in |