PowerShell PSReflect Script
Detects PowerShell scripts that implements PSReflect-style helpers (for example, Add-Win32Type, New-InMemoryModule, or DllImport patterns) for dynamic Win32 API invocation. Attackers use PSReflect to call native APIs from PowerShell for execution, injection, or privilege manipulation.
Elastic rule (View on GitHub)
1[metadata]
2creation_date = "2021/10/15"
3integration = ["windows"]
4maturity = "production"
5updated_date = "2026/02/09"
6
7[rule]
8author = ["Elastic"]
9description = """
10Detects PowerShell scripts that implements PSReflect-style helpers (for example, Add-Win32Type, New-InMemoryModule, or
11DllImport patterns) for dynamic Win32 API invocation. Attackers use PSReflect to call native APIs from PowerShell for
12execution, injection, or privilege manipulation.
13"""
14false_positives = ["Legitimate PowerShell scripts that make use of PSReflect to access the win32 API"]
15from = "now-9m"
16index = ["winlogbeat-*", "logs-windows.powershell*"]
17language = "kuery"
18license = "Elastic License v2"
19name = "PowerShell PSReflect Script"
20note = """## Triage and analysis
21
22> **Disclaimer**:
23> This guide was created by humans with the assistance of generative AI. While its contents have been manually curated to include the most valuable information, always validate assumptions and adjust procedures to match your internal runbooks and incident triage and response policies.
24
25### Investigating PowerShell PSReflect Script
26
27This rule detects PowerShell scripts consistent with PSReflect-style helpers used to dynamically define in-memory .NET types and invoke Win32 APIs via interop (for example, Add-Win32Type, New-InMemoryModule, and DllImport patterns). This technique can be used for legitimate administration and development, but it is also commonly used by adversaries to access native capabilities from PowerShell.
28
29#### Key alert fields to review
30
31- `user.name`, `user.domain`, `user.id`: Account execution context for correlation, prioritization, and scoping.
32- `host.name`, `host.id`: Host execution context for correlation, prioritization, and scoping.
33- `powershell.file.script_block_text`: Script block content that matched the detection logic.
34- `powershell.file.script_block_id`, `powershell.sequence`, `powershell.total`: Script block metadata to pivot to other fragments or reconstruct full script content when split across multiple events.
35- `file.path`, `file.directory`, `file.name`: File-origin context when the script block is sourced from an on-disk file.
36- `powershell.file.script_block_length`: Script block length (size) context.
37
38#### Possible investigation steps
39
40- Review the alert context to prioritize the investigation:
41 - Identify the affected host (`host.name`, `host.id`) and the execution context (`user.name`, `user.domain`, `user.id`).
42 - Use `@timestamp` to scope a short timeline around the activity and identify related alerts on the same host or user.
43 - Treat activity as higher risk when the executing account is unexpected for PowerShell development/administration or when the host is not typically used for scripting.
44
45- Reconstruct the complete script block content before assessing intent:
46 - Pivot on `powershell.file.script_block_id` to locate all related events.
47 - Order events by `powershell.sequence` and confirm whether the observed sequence aligns with `powershell.total`.
48 - Combine the fragments into a single script view to avoid misinterpreting partial content.
49
50- Analyze `powershell.file.script_block_text` to understand capability and likely intent:
51 - Identify which PSReflect artifacts are present (for example, `Add-Win32Type`, `New-InMemoryModule`, `psenum`, `DefineDynamicAssembly`, `DefineDynamicModule`, and `Runtime.InteropServices.DllImportAttribute`).
52 - Determine whether the content is primarily a helper library (type/struct/enum definitions and import scaffolding) or includes immediate API calls or operational logic.
53 - If `DllImportAttribute` is used, extract the referenced DLLs and imported function names from the script text and map them to likely objectives (for example, process/memory operations, token and privilege manipulation, registry or service interaction, or networking).
54 - Capture distinctive identifiers from the script (function names, type names, imported API names, unique strings) to support scoping and hunting.
55
56- Establish script origin and distribution:
57 - If `file.path`/`file.name` are present, treat the script as file-backed and assess whether the location and filename align with approved tooling and change control.
58 - If `file.path` is not present, consider that the script may have been executed interactively or delivered in-memory, and prioritize correlation with surrounding activity for the same `user.id` and `host.id`.
59
60- Scope the activity across time, hosts, and users:
61 - Search for additional script blocks on the same `host.id` and `user.id` around `@timestamp` to identify preceding staging activity and follow-on behavior.
62 - Hunt across the environment for the same `file.path`/`file.name` and for distinctive strings extracted from `powershell.file.script_block_text` to identify other impacted hosts.
63 - Pivot on `user.id` to determine whether the same account executed similar PSReflect content on other endpoints.
64
65- Correlate with adjacent telemetry (if available) to confirm execution chain and impact:
66 - Process telemetry: identify the PowerShell host process and its parent process to understand how the script was initiated (interactive, automated, or remote execution context).
67 - Network telemetry: review DNS lookups and outbound connections near the alert time for evidence of staging, command-and-control, or lateral movement.
68 - Endpoint changes: review file, service, scheduled task, and registry activity after the script execution to identify persistence, payload delivery, or privilege changes that align with the capabilities implied by the script text.
69 - If Elastic Osquery response actions are available, collect DNS cache and service inventory to support scoping and to identify suspicious services or unsigned service binaries.
70
71### False positive analysis
72
73- False positives are possible in environments where administrators, developers, or internal tooling use PSReflect-style code to access native APIs from PowerShell.
74- Validate legitimacy by confirming that:
75 - The executing account and host are expected to run advanced PowerShell code (`user.id`, `user.name`, `host.id`, `host.name`).
76 - The script source is known and controlled when `file.path`/`file.name` are present (for example, approved repositories, deployment paths, or administrative script locations).
77 - The script content and its imported APIs are consistent with a documented operational need and do not align with common attacker objectives (for example, credential access, injection, or persistence).
78- If the activity is recurring, baseline expected frequency and approved users/hosts to distinguish routine usage from anomalous execution.
79
80### Response and remediation
81
82- If malicious activity is confirmed or suspected:
83 - Contain the affected host to prevent further execution and lateral movement, following your incident response procedures.
84 - Preserve evidence: the fully reconstructed script (`powershell.file.script_block_id` with `powershell.sequence`/`powershell.total`), the raw script content (`powershell.file.script_block_text`), and any referenced file path details (`file.path`, `file.name`).
85 - Use extracted identifiers (imported API names, helper function names, unique strings) to hunt for related activity across other hosts and users.
86 - Investigate and remediate follow-on activity identified during correlation (persistence mechanisms, suspicious services, unexpected outbound connections, and any dropped or modified files).
87 - If account compromise is suspected, reset credentials for the impacted user and review recent authentication activity to identify additional compromised assets.
88
89- If the activity is confirmed benign:
90 - Document the legitimate script/tool, expected hosts/users, and the operational purpose to speed up future triage.
91 - Where appropriate, improve controls around advanced PowerShell usage (least privilege for scripting accounts, controlled script distribution, code review, and continued logging coverage).
92"""
93references = [
94 "https://github.com/mattifestation/PSReflect/blob/master/PSReflect.psm1",
95 "https://github.com/atc-project/atc-data/blob/master/docs/Logging_Policies/LP_0109_windows_powershell_script_block_log.md",
96]
97risk_score = 73
98rule_id = "56f2e9b5-4803-4e44-a0a4-a52dc79d57fe"
99setup = """## Setup
100
101PowerShell Script Block Logging must be enabled to generate the events used by this rule (e.g., 4104).
102Setup instructions: https://ela.st/powershell-logging-setup
103"""
104severity = "high"
105tags = [
106 "Domain: Endpoint",
107 "OS: Windows",
108 "Use Case: Threat Detection",
109 "Tactic: Execution",
110 "Resources: Investigation Guide",
111 "Data Source: PowerShell Logs",
112]
113timestamp_override = "event.ingested"
114type = "query"
115
116query = '''
117event.category:process and host.os.type:windows and
118 powershell.file.script_block_text:(
119 "New-InMemoryModule" or
120 "Add-Win32Type" or
121 psenum or
122 DefineDynamicAssembly or
123 DefineDynamicModule or
124 "Reflection.TypeAttributes" or
125 "Reflection.Emit.OpCodes" or
126 "Reflection.Emit.CustomAttributeBuilder" or
127 "Runtime.InteropServices.DllImportAttribute"
128 ) and
129 not user.id : "S-1-5-18"
130'''
131
132
133[[rule.filters]]
134
135[rule.filters.meta]
136negate = true
137[rule.filters.query.wildcard."file.path"]
138case_insensitive = true
139value = "?:\\\\ProgramData\\\\MaaS360\\\\Cloud Extender\\\\AR\\\\Scripts\\\\ASModuleCommon.ps1"
140[[rule.threat]]
141framework = "MITRE ATT&CK"
142[[rule.threat.technique]]
143id = "T1059"
144name = "Command and Scripting Interpreter"
145reference = "https://attack.mitre.org/techniques/T1059/"
146[[rule.threat.technique.subtechnique]]
147id = "T1059.001"
148name = "PowerShell"
149reference = "https://attack.mitre.org/techniques/T1059/001/"
150
151
152[[rule.threat.technique]]
153id = "T1106"
154name = "Native API"
155reference = "https://attack.mitre.org/techniques/T1106/"
156
157
158[rule.threat.tactic]
159id = "TA0002"
160name = "Execution"
161reference = "https://attack.mitre.org/tactics/TA0002/"
162
163[rule.investigation_fields]
164field_names = [
165 "@timestamp",
166 "user.name",
167 "user.id",
168 "user.domain",
169 "powershell.file.script_block_text",
170 "powershell.file.script_block_id",
171 "powershell.sequence",
172 "powershell.total",
173 "file.path",
174 "file.directory",
175 "file.name",
176 "process.pid",
177 "host.name",
178 "host.id",
179 "powershell.file.script_block_length"
180]
Triage and analysis
Disclaimer: This guide was created by humans with the assistance of generative AI. While its contents have been manually curated to include the most valuable information, always validate assumptions and adjust procedures to match your internal runbooks and incident triage and response policies.
Investigating PowerShell PSReflect Script
This rule detects PowerShell scripts consistent with PSReflect-style helpers used to dynamically define in-memory .NET types and invoke Win32 APIs via interop (for example, Add-Win32Type, New-InMemoryModule, and DllImport patterns). This technique can be used for legitimate administration and development, but it is also commonly used by adversaries to access native capabilities from PowerShell.
Key alert fields to review
user.name,user.domain,user.id: Account execution context for correlation, prioritization, and scoping.host.name,host.id: Host execution context for correlation, prioritization, and scoping.powershell.file.script_block_text: Script block content that matched the detection logic.powershell.file.script_block_id,powershell.sequence,powershell.total: Script block metadata to pivot to other fragments or reconstruct full script content when split across multiple events.file.path,file.directory,file.name: File-origin context when the script block is sourced from an on-disk file.powershell.file.script_block_length: Script block length (size) context.
Possible investigation steps
-
Review the alert context to prioritize the investigation:
- Identify the affected host (
host.name,host.id) and the execution context (user.name,user.domain,user.id). - Use
@timestampto scope a short timeline around the activity and identify related alerts on the same host or user. - Treat activity as higher risk when the executing account is unexpected for PowerShell development/administration or when the host is not typically used for scripting.
- Identify the affected host (
-
Reconstruct the complete script block content before assessing intent:
- Pivot on
powershell.file.script_block_idto locate all related events. - Order events by
powershell.sequenceand confirm whether the observed sequence aligns withpowershell.total. - Combine the fragments into a single script view to avoid misinterpreting partial content.
- Pivot on
-
Analyze
powershell.file.script_block_textto understand capability and likely intent:- Identify which PSReflect artifacts are present (for example,
Add-Win32Type,New-InMemoryModule,psenum,DefineDynamicAssembly,DefineDynamicModule, andRuntime.InteropServices.DllImportAttribute). - Determine whether the content is primarily a helper library (type/struct/enum definitions and import scaffolding) or includes immediate API calls or operational logic.
- If
DllImportAttributeis used, extract the referenced DLLs and imported function names from the script text and map them to likely objectives (for example, process/memory operations, token and privilege manipulation, registry or service interaction, or networking). - Capture distinctive identifiers from the script (function names, type names, imported API names, unique strings) to support scoping and hunting.
- Identify which PSReflect artifacts are present (for example,
-
Establish script origin and distribution:
- If
file.path/file.nameare present, treat the script as file-backed and assess whether the location and filename align with approved tooling and change control. - If
file.pathis not present, consider that the script may have been executed interactively or delivered in-memory, and prioritize correlation with surrounding activity for the sameuser.idandhost.id.
- If
-
Scope the activity across time, hosts, and users:
- Search for additional script blocks on the same
host.idanduser.idaround@timestampto identify preceding staging activity and follow-on behavior. - Hunt across the environment for the same
file.path/file.nameand for distinctive strings extracted frompowershell.file.script_block_textto identify other impacted hosts. - Pivot on
user.idto determine whether the same account executed similar PSReflect content on other endpoints.
- Search for additional script blocks on the same
-
Correlate with adjacent telemetry (if available) to confirm execution chain and impact:
- Process telemetry: identify the PowerShell host process and its parent process to understand how the script was initiated (interactive, automated, or remote execution context).
- Network telemetry: review DNS lookups and outbound connections near the alert time for evidence of staging, command-and-control, or lateral movement.
- Endpoint changes: review file, service, scheduled task, and registry activity after the script execution to identify persistence, payload delivery, or privilege changes that align with the capabilities implied by the script text.
- If Elastic Osquery response actions are available, collect DNS cache and service inventory to support scoping and to identify suspicious services or unsigned service binaries.
False positive analysis
- False positives are possible in environments where administrators, developers, or internal tooling use PSReflect-style code to access native APIs from PowerShell.
- Validate legitimacy by confirming that:
- The executing account and host are expected to run advanced PowerShell code (
user.id,user.name,host.id,host.name). - The script source is known and controlled when
file.path/file.nameare present (for example, approved repositories, deployment paths, or administrative script locations). - The script content and its imported APIs are consistent with a documented operational need and do not align with common attacker objectives (for example, credential access, injection, or persistence).
- The executing account and host are expected to run advanced PowerShell code (
- If the activity is recurring, baseline expected frequency and approved users/hosts to distinguish routine usage from anomalous execution.
Response and remediation
-
If malicious activity is confirmed or suspected:
- Contain the affected host to prevent further execution and lateral movement, following your incident response procedures.
- Preserve evidence: the fully reconstructed script (
powershell.file.script_block_idwithpowershell.sequence/powershell.total), the raw script content (powershell.file.script_block_text), and any referenced file path details (file.path,file.name). - Use extracted identifiers (imported API names, helper function names, unique strings) to hunt for related activity across other hosts and users.
- Investigate and remediate follow-on activity identified during correlation (persistence mechanisms, suspicious services, unexpected outbound connections, and any dropped or modified files).
- If account compromise is suspected, reset credentials for the impacted user and review recent authentication activity to identify additional compromised assets.
-
If the activity is confirmed benign:
- Document the legitimate script/tool, expected hosts/users, and the operational purpose to speed up future triage.
- Where appropriate, improve controls around advanced PowerShell usage (least privilege for scripting accounts, controlled script distribution, code review, and continued logging coverage).
References
Related rules
- Potential PowerShell HackTool Script by Function Names
- Suspicious Portable Executable Encoded in Powershell Script
- Potential PowerShell HackTool Script by Author
- Potential Process Injection via PowerShell
- PowerShell Share Enumeration Script