Name:PowerShell PInvoke Process Injection API Chain id:3f1a2b4c-d5e6-7890-abcd-ef1234567890 version:1 date:2026-04-22 author:Teoderick Contreras, Splunk status:production type:TTP Description:The following analytic detects PowerShell Script Block Logging (Event ID 4104) evidence of a complete P/Invoke process-injection API chain at either the compile phase or the execution phase.
Compile phase:
Detects inline .NET class definitions created via `Add-Type -TypeDefinition` where the embedded C# source includes `[DllImport]` declarations and full P/Invoke signatures such as `extern <ReturnType> <FunctionName>`. This reduces false positives from comments, string literals, and arbitrary text references.
Execution phase:
Detects PowerShell static method invocation patterns using `::MethodName(` syntax, anchored with execution-context indicators such as `[IntPtr]::Zero` or `Marshal]::Copy`.
Injection technique coverage:
1. Self-injection shellcode runner
- VirtualAlloc + VirtualProtect + CreateThread
2. Remote thread injection
- OpenProcess + VirtualAllocEx/VirtualAlloc + WriteProcessMemory + CreateRemoteThread
3. APC injection
- OpenProcess + VirtualAllocEx/VirtualAlloc + WriteProcessMemory + QueueUserAPC
4. Thread-context hijacking
- OpenThread + SuspendThread + GetThreadContext + WriteProcessMemory + SetThreadContext + ResumeThread
5. Process hollowing
- CreateProcess + VirtualAllocEx/VirtualAlloc + WriteProcessMemory + SetThreadContext + ResumeThread
6. Section-map injection
- NtCreateSection + NtMapViewOfSection (+ CreateRemoteThread in this analytic)
7. Reflective DLL loading
- VirtualAlloc + GetProcAddress + GetModuleHandle + VirtualProtect + CreateThread
8. DLL injection
- OpenProcess + VirtualAllocEx/VirtualAlloc + WriteProcessMemory + GetModuleHandle + GetProcAddress + CreateRemoteThread
Including the execution phase ensures coverage when an adversary loads a pre-compiled assembly from memory or disk and bypasses Add-Type entirely, since the static method call pattern is still captured in the script block regardless of how the class was originally compiled.
Data_source:
how_to_implement:The following analytic requires PowerShell operational logs to be imported. Modify the powershell macro as needed to match the sourcetype or add index. This analytic is specific to 4104, or PowerShell Script Block Logging. known_false_positives:No false positives have been identified at this time. References: -https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.dllimportattribute -https://www.ired.team/offensive-security/code-injection-process-injection -https://www.broadcom.com/support/security-center/protection-bulletin/vip-keylogger-spreads-via-multi-org-impersonation-campaign -https://attack.mitre.org/techniques/T1055/ -https://attack.mitre.org/techniques/T1620/ drilldown_searches: name:'View the detection results for - "$dest$"' search:'%original_detection_search% | search dest = "$dest$"' earliest_offset:'$info_min_time$' latest_offset:'$info_max_time$' name:'View risk events for the last 7 days for - "$dest$"' search:'| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$dest$") | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' earliest_offset:'7d' latest_offset:'0' tags: analytic_story: - 'VIP Keylogger' asset_type:Endpoint mitre_attack_id: - 'T1055.001' - 'T1055.003' - 'T1055.004' - 'T1055.012' - 'T1055.013' - 'T1059.001' - 'T1620' product: - 'Splunk Enterprise' - 'Splunk Enterprise Security' - 'Splunk Cloud' security_domain:endpoint