Detection rules › Elastic

Potential Shellcode Injection via a WebShell

Source
github.com/elastic/protections-artifacts

Identifies the call of code injection related Windows API with suspicious parameters that align with shellcode execution and where the call stack is pointing to an IIS Web application as the source of the injection.

MITRE ATT&CK coverage

TacticTechniques
Stealth

Rule body

[rule]
description = """
Identifies the call of code injection related Windows API with suspicious parameters that align with shellcode execution
and where the call stack is pointing to an IIS Web application as the source of the injection.
"""
id = "38da66fc-171f-49f6-9144-bac4abb2f47b"
license = "Elastic License v2"
name = "Potential Shellcode Injection via a WebShell"
os_list = ["windows"]
version = "1.0.7"

query = '''
api where process.name : "w3wp.exe" and
(
 (process.Ext.api.name in ("MapViewOfFile", "MapViewOfFile2", "VirtualAlloc", "VirtualAllocEx", "VirtualProtect", "VirtualProtectEx", "WriteProcessMemory") and
  _arraysearch(process.thread.Ext.call_stack, $entry, $entry.protection_provenance like "app_web_*.dll" and $entry.symbol_info == "Unbacked")) or

 (process.Ext.api.behaviors in ("shellcode", "allocate_shellcode", "execute_shellcode") and
  process.thread.Ext.call_stack_final_user_module.name == "Unbacked" and process.Ext.api.metadata.target_address_name == "Unbacked" and
  process.parent.executable : "C:\\Windows\\System32\\svchost.exe" and
  process.Ext.api.name in ("MapViewOfFile", "MapViewOfFile2", "VirtualAlloc", "VirtualAllocEx", "VirtualProtect", "VirtualProtectEx", "WriteProcessMemory", "connect") and
  (process.thread.Ext.call_stack_final_user_module.protection_provenance_path like "c:\\windows\\microsoft.net\\framework*\\clr.dll" or
   process.thread.Ext.call_stack_final_user_module.protection_provenance == "clr.dll") and
   process.Ext.api.parameters.size != 5 and process.Ext.api.parameters.size != 10 and process.Ext.api.parameters.size != 40 and
   process.Ext.api.behaviors != "hook_api" and
   process.thread.Ext.call_stack_summary in
                ("ntdll.dll|kernelbase.dll|Unbacked",
                 "ntdll.dll|Unbacked",
                 "ntdll.dll|mswsock.dll|ws2_32.dll|Unbacked",
                 "ntdll.dll|kernelbase.dll|kernel32.dll|Unbacked"))
 ) and
 not _arraysearch(process.thread.Ext.call_stack, $entry,
                    $entry.callsite_trailing_bytes like "41c6470c01833d*88bc641c6470c01488b559049895710488d65c85b5e5f415c415d415e415f5dc3001910")
'''

min_endpoint_version = "8.14.2"
[[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.14.2"

Stages and Predicates

Stage 1: api

api where process.name : "w3wp.exe" and
(
 (process.Ext.api.name in ("MapViewOfFile", "MapViewOfFile2", "VirtualAlloc", "VirtualAllocEx", "VirtualProtect", "VirtualProtectEx", "WriteProcessMemory") and
  _arraysearch(process.thread.Ext.call_stack, $entry, $entry.protection_provenance like "app_web_*.dll" and $entry.symbol_info == "Unbacked")) or

 (process.Ext.api.behaviors in ("shellcode", "allocate_shellcode", "execute_shellcode") and
  process.thread.Ext.call_stack_final_user_module.name == "Unbacked" and process.Ext.api.metadata.target_address_name == "Unbacked" and
  process.parent.executable : "C:\\Windows\\System32\\svchost.exe" and
  process.Ext.api.name in ("MapViewOfFile", "MapViewOfFile2", "VirtualAlloc", "VirtualAllocEx", "VirtualProtect", "VirtualProtectEx", "WriteProcessMemory", "connect") and
  (process.thread.Ext.call_stack_final_user_module.protection_provenance_path like "c:\\windows\\microsoft.net\\framework*\\clr.dll" or
   process.thread.Ext.call_stack_final_user_module.protection_provenance == "clr.dll") and
   process.Ext.api.parameters.size != 5 and process.Ext.api.parameters.size != 10 and process.Ext.api.parameters.size != 40 and
   process.Ext.api.behaviors != "hook_api" and
   process.thread.Ext.call_stack_summary in
                ("ntdll.dll|kernelbase.dll|Unbacked",
                 "ntdll.dll|Unbacked",
                 "ntdll.dll|mswsock.dll|ws2_32.dll|Unbacked",
                 "ntdll.dll|kernelbase.dll|kernel32.dll|Unbacked"))
 ) and
 not _arraysearch(process.thread.Ext.call_stack, $entry,
                    $entry.callsite_trailing_bytes like "41c6470c01833d*88bc641c6470c01488b559049895710488d65c85b5e5f415c415d415e415f5dc3001910")

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
process.thread.Ext.call_stackarray_any(no value, null check)excludes:process.thread.Ext.call_stack

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
process.Ext.api.behaviorsin
  • allocate_shellcode corpus 9 (elastic 9)
  • execute_shellcode corpus 3 (elastic 3)
  • shellcode corpus 2 (elastic 2)
field:"process.Ext.api.behaviors" kind:in
process.Ext.api.behaviorsne
  • hook_api
field:"process.Ext.api.behaviors" kind:ne value:"hook_api"
process.Ext.api.metadata.target_address_nameeq
  • Unbacked corpus 8 (elastic 8)
field:"process.Ext.api.metadata.target_address_name" kind:eq value:"Unbacked"
process.Ext.api.namein
  • MapViewOfFile
  • MapViewOfFile2
  • VirtualAlloc corpus 4 (elastic 4)
  • VirtualAllocEx
  • VirtualProtect corpus 19 (elastic 19)
  • VirtualProtectEx
  • WriteProcessMemory corpus 14 (elastic 14)
  • connect corpus 5 (elastic 5)
field:"process.Ext.api.name" kind:in
process.Ext.api.parameters.sizene
  • 10 transforms: number
  • 40 transforms: number
  • 5 transforms: number
field:"process.Ext.api.parameters.size" kind:ne
process.namewildcard
  • w3wp.exe corpus 3 (elastic 3)
field:"process_name" kind:wildcard value:"w3wp.exe"
process.parent.executablewildcard
  • C:\Windows\System32\svchost.exe corpus 5 (sigma 3, elastic 2)
field:"ParentImage" kind:wildcard value:"C:\Windows\System32\svchost.exe"
process.thread.Ext.call_stack_final_user_module.nameeq
  • Unbacked corpus 21 (elastic 21)
field:"process.thread.Ext.call_stack_final_user_module.name" kind:eq value:"Unbacked"
process.thread.Ext.call_stack_final_user_module.protection_provenanceeq
  • clr.dll corpus 4 (elastic 4)
field:"process.thread.Ext.call_stack_final_user_module.protection_provenance" kind:eq value:"clr.dll"
process.thread.Ext.call_stack_final_user_module.protection_provenance_pathwildcard
  • c:\windows\microsoft.net\framework*\clr.dll corpus 3 (elastic 3)
field:"process.thread.Ext.call_stack_final_user_module.protection_provenance_path" kind:wildcard value:"c:\windows\microsoft.net\framework*\clr.dll"
process.thread.Ext.call_stack_summaryin
  • ntdll.dll|Unbacked
  • ntdll.dll|kernelbase.dll|Unbacked corpus 3 (elastic 3)
  • ntdll.dll|kernelbase.dll|kernel32.dll|Unbacked
  • ntdll.dll|mswsock.dll|ws2_32.dll|Unbacked
field:"process.thread.Ext.call_stack_summary" kind:in