Detection rules › Elastic

Shellcode Injection via PowerShell

Source
github.com/elastic/protections-artifacts

Identifies shellcode execution behavior from a powershell script interpreter. This may indicate the execution of a malicious powershell script or the result of a cross process injection targeting powershell.

MITRE ATT&CK coverage

Rule body

[rule]
description = """
Identifies shellcode execution behavior from a powershell script interpreter. This may indicate the execution of a
malicious powershell script or the result of a cross process injection targeting powershell.
"""
id = "98fffa16-53e1-4db9-9126-2d0441cac417"
license = "Elastic License v2"
name = "Shellcode Injection via PowerShell"
os_list = ["windows"]
version = "1.0.9"

query = '''
api where process.Ext.api.name in ("VirtualAlloc", "VirtualAllocEx", "VirtualProtect", "VirtualProtectEx", "WriteProcessMemory", "connect") and
    process.name : ("powershell.exe", "pwsh.exe", "powershell_ise.exe") and
    process.Ext.api.behaviors in ("shellcode", "allocate_shellcode") and
    process.thread.Ext.call_stack_final_user_module.name == "Unbacked" and
    process.thread.Ext.call_stack_final_user_module.protection_provenance == "Unbacked" and
    (process.Ext.api.name == "connect" or process.Ext.api.parameters.size >= 10000) and
    process.thread.Ext.call_stack_summary like "?*" and
    _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info : "Unbacked*" and $entry.callsite_trailing_bytes : "?*") and

    /* noisy patterns */
    not _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info like "Unbacked*" and
                     $entry.callsite_trailing_bytes like
                                   ("*85f60f95c10fb6c9894dac488bcce82f000000908b45ac0fb6c0488b55a0c6420c01*",
                                    "488dac24d00000004c8bb424a8000000*4c8b45f84d8d4e08*",
                                    "*85f60f95c10fb6c9894dac488bcce82f000000908b45*", 
                                    "*7f00004883c42848ffe000190401000442000040000*", 
                                    "488986200f0000488d8fe00d000048894*", 
                                    "*8bc6488d65f85e5dc355564883ec28488b6920*")) and
    not (process.thread.Ext.call_stack_summary  == "ntdll.dll|Unbacked" and
         _arraysearch(process.thread.Ext.call_stack, $entry, $entry.protection_provenance == "Unknown")) and
    not process.thread.Ext.call_stack_summary like ("Unbacked", "*Unknown*") and
    not _arraysearch(process.thread.Ext.call_stack, $entry,
                     $entry.protection_provenance like ("Kernel", "clr.dll", "coreclr.dll", "fships.dll*", "Kernel|*", "tmmon.dll",
                                                     "mfehcthe.dll", "mfehcs.exe|mfehcs.exe", "conemuhk64.dll", "tmmon64.dll", "dwadv.dll", "bdhkm32.dll")) and
    not _arraysearch(process.thread.Ext.call_stack, $entry,
                     $entry.symbol_info : ("?:\\Program Files\\*.dll*",
                                           "?:\\Program Files (x86)\\*.dll*",
                                           "?:\\windows\\system32\\*\\tmmon*.dll*",
                                           "c:\\windows\\syswow64\\ntdll.dll!RtlInitializeExceptionChain*",
                                           "c:\\windows\\syswow64\\ntdll.dll!RtlGetFullPathName*",
                                           "c:\\windows\\syswow64\\ntdll.dll!RtlGetAppContainerNamedObjectPath*")) and
    not (process.Ext.api.name == "connect" and process.parent.executable : "C:\\Program Files\\Tychon\\TychonEngine.exe") and
    not (user.id in ("S-1-5-18", "S-1-5-19", "S-1-5-20") and
         process.parent.executable : ("?:\\Windows\\System32\\svchost.exe", "?:\\Windows\\System32\\services.exe") and
         _arraysearch(process.thread.Ext.call_stack, $entry, $entry.protection_provenance == "Unbacked")) and
    not (process.thread.Ext.call_stack_final_user_module.name == "Unbacked" and
         process.thread.Ext.call_stack_final_user_module.protection_provenance_path == "c:\\windows\\syswow64\\sppc.dll") and
    not process.parent.executable : "C:\\Program Files (x86)\\Msp Agent\\components\\generic-asset-interrogator\\0.2.10\\generic-asset-interrogator.exe" and
    not (process.Ext.api.name == "VirtualProtect" and
         _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info like ("c:\\windows\\sys?????\\ntdll.dll!LdrLoadDll*", "c:\\windows\\sys?????\\kernelbase.dll!LoadLibrary*"))) 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", "SentinelOne Inc.")) and
    not process.thread.Ext.call_stack_final_user_module.protection_provenance_path like "c:\\windows\\assembly\\nativeimages_*\\microsoft.powershell.commands.diagnostics.ni.dll"
'''

min_endpoint_version = "8.14.2"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
tree = true

[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 0

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1059"
name = "Command and Scripting Interpreter"
reference = "https://attack.mitre.org/techniques/T1059/"
[[threat.technique.subtechnique]]
id = "T1059.001"
name = "PowerShell"
reference = "https://attack.mitre.org/techniques/T1059/001/"



[threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[[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.Ext.api.name in ("VirtualAlloc", "VirtualAllocEx", "VirtualProtect", "VirtualProtectEx", "WriteProcessMemory", "connect") and
    process.name : ("powershell.exe", "pwsh.exe", "powershell_ise.exe") and
    process.Ext.api.behaviors in ("shellcode", "allocate_shellcode") and
    process.thread.Ext.call_stack_final_user_module.name == "Unbacked" and
    process.thread.Ext.call_stack_final_user_module.protection_provenance == "Unbacked" and
    (process.Ext.api.name == "connect" or process.Ext.api.parameters.size >= 10000) and
    process.thread.Ext.call_stack_summary like "?*" and
    _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info : "Unbacked*" and $entry.callsite_trailing_bytes : "?*") and
    not _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info like "Unbacked*" and
                     $entry.callsite_trailing_bytes like
                                   ("*85f60f95c10fb6c9894dac488bcce82f000000908b45ac0fb6c0488b55a0c6420c01*",
                                    "488dac24d00000004c8bb424a8000000*4c8b45f84d8d4e08*",
                                    "*85f60f95c10fb6c9894dac488bcce82f000000908b45*",
                                    "*7f00004883c42848ffe000190401000442000040000*",
                                    "488986200f0000488d8fe00d000048894*",
                                    "*8bc6488d65f85e5dc355564883ec28488b6920*")) and
    not (process.thread.Ext.call_stack_summary  == "ntdll.dll|Unbacked" and
         _arraysearch(process.thread.Ext.call_stack, $entry, $entry.protection_provenance == "Unknown")) and
    not process.thread.Ext.call_stack_summary like ("Unbacked", "*Unknown*") and
    not _arraysearch(process.thread.Ext.call_stack, $entry,
                     $entry.protection_provenance like ("Kernel", "clr.dll", "coreclr.dll", "fships.dll*", "Kernel|*", "tmmon.dll",
                                                     "mfehcthe.dll", "mfehcs.exe|mfehcs.exe", "conemuhk64.dll", "tmmon64.dll", "dwadv.dll", "bdhkm32.dll")) and
    not _arraysearch(process.thread.Ext.call_stack, $entry,
                     $entry.symbol_info : ("?:\\Program Files\\*.dll*",
                                           "?:\\Program Files (x86)\\*.dll*",
                                           "?:\\windows\\system32\\*\\tmmon*.dll*",
                                           "c:\\windows\\syswow64\\ntdll.dll!RtlInitializeExceptionChain*",
                                           "c:\\windows\\syswow64\\ntdll.dll!RtlGetFullPathName*",
                                           "c:\\windows\\syswow64\\ntdll.dll!RtlGetAppContainerNamedObjectPath*")) and
    not (process.Ext.api.name == "connect" and process.parent.executable : "C:\\Program Files\\Tychon\\TychonEngine.exe") and
    not (user.id in ("S-1-5-18", "S-1-5-19", "S-1-5-20") and
         process.parent.executable : ("?:\\Windows\\System32\\svchost.exe", "?:\\Windows\\System32\\services.exe") and
         _arraysearch(process.thread.Ext.call_stack, $entry, $entry.protection_provenance == "Unbacked")) and
    not (process.thread.Ext.call_stack_final_user_module.name == "Unbacked" and
         process.thread.Ext.call_stack_final_user_module.protection_provenance_path == "c:\\windows\\syswow64\\sppc.dll") and
    not process.parent.executable : "C:\\Program Files (x86)\\Msp Agent\\components\\generic-asset-interrogator\\0.2.10\\generic-asset-interrogator.exe" and
    not (process.Ext.api.name == "VirtualProtect" and
         _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info like ("c:\\windows\\sys?????\\ntdll.dll!LdrLoadDll*", "c:\\windows\\sys?????\\kernelbase.dll!LoadLibrary*"))) 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", "SentinelOne Inc.")) and
    not process.thread.Ext.call_stack_final_user_module.protection_provenance_path like "c:\\windows\\assembly\\nativeimages_*\\microsoft.powershell.commands.diagnostics.ni.dll"

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
process.parent.executableeq?:\Windows\System32\svchost.exe, ?:\Windows\System32\services.exeexcludes:process.parent.executable field:"process.parent.executable" value:"?:\Windows\System32\svchost.exe" field:"process.parent.executable" value:"?:\Windows\System32\services.exe"
user.idinS-1-5-18, S-1-5-19, S-1-5-20excludes:user.id field:"user.id" value:"S-1-5-18" field:"user.id" value:"S-1-5-19" field:"user.id" value:"S-1-5-20"
process.thread.Ext.call_stack_summaryeqntdll.dll|Unbackedexcludes:process.thread.Ext.call_stack_summary field:"process.thread.Ext.call_stack_summary" value:"ntdll.dll|Unbacked"
process.Ext.api.nameeqVirtualProtectexcludes:process.Ext.api.name field:"process.Ext.api.name" value:"VirtualProtect"
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.Ext.api.nameeqconnectexcludes:process.Ext.api.name field:"process.Ext.api.name" value:"connect"
process.parent.executableeqC:\Program Files\Tychon\TychonEngine.exeexcludes:process.parent.executable field:"process.parent.executable" value:"C:\Program Files\Tychon\TychonEngine.exe"
process.thread.Ext.call_stack_final_user_module.nameeqUnbackedexcludes:process.thread.Ext.call_stack_final_user_module.name field:"process.thread.Ext.call_stack_final_user_module.name" value:"Unbacked"
process.thread.Ext.call_stack_final_user_module.protection_provenance_patheqc:\windows\syswow64\sppc.dllexcludes:process.thread.Ext.call_stack_final_user_module.protection_provenance_path field:"process.thread.Ext.call_stack_final_user_module.protection_provenance_path" value:"c:\windows\syswow64\sppc.dll"
process.parent.executableeqC:\Program Files (x86)\Msp Agent\components\generic-asset-interrogator\0.2.10\generic-asset-interrogator.exeexcludes:process.parent.executable field:"process.parent.executable" value:"C:\Program Files (x86)\Msp Agent\components\generic-asset-interrogator\0.2.10\generic-asset-interrogator.exe"
process.thread.Ext.call_stack_final_user_module.protection_provenance_pathwildcardc:\windows\assembly\nativeimages_*\microsoft.powershell.commands.diagnostics.ni.dllexcludes:process.thread.Ext.call_stack_final_user_module.protection_provenance_path field:"process.thread.Ext.call_stack_final_user_module.protection_provenance_path" value:"c:\windows\assembly\nativeimages_*\microsoft.powershell.commands.diagnostics.ni.dll"
process.thread.Ext.call_stack_summarywildcardUnbacked, *Unknown*excludes:process.thread.Ext.call_stack_summary field:"process.thread.Ext.call_stack_summary" value:"Unbacked" field:"process.thread.Ext.call_stack_summary" value:"*Unknown*"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
process.Ext.api.behaviorsin
  • allocate_shellcode corpus 9 (elastic 9)
  • shellcode corpus 2 (elastic 2)
field:"process.Ext.api.behaviors" kind:in
process.Ext.api.nameeq
  • connect corpus 5 (elastic 5)
field:"process.Ext.api.name" kind:eq value:"connect"
process.Ext.api.namein
  • 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.sizege
  • 10000 transforms: number corpus 11 (elastic 11)
field:"process.Ext.api.parameters.size" kind:ge value:"10000"
process.namewildcard
  • powershell.exe corpus 184 (elastic 140, splunk 44)
  • powershell_ise.exe corpus 52 (splunk 29, elastic 23)
  • pwsh.exe corpus 77 (elastic 48, splunk 29)
field:"process_name" kind:wildcard
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
  • Unbacked
field:"process.thread.Ext.call_stack_final_user_module.protection_provenance" kind:eq value:"Unbacked"
process.thread.Ext.call_stack_summarywildcard
  • ?* corpus 14 (elastic 14)
field:"process.thread.Ext.call_stack_summary" kind:wildcard value:"?*"