Potential Antimalware Scan Interface Bypass via PowerShell

Detects PowerShell scripts that reference Antimalware Scan Interface (AMSI) bypass classes, methods, or known bypass strings. Attackers attempt AMSI bypass to disable scanning and run malicious PowerShell content undetected.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2023/01/17"
  3integration = ["windows"]
  4maturity = "production"
  5updated_date = "2026/04/27"
  6
  7[rule]
  8author = ["Elastic"]
  9description = """
 10Detects PowerShell scripts that reference Antimalware Scan Interface (AMSI) bypass classes, methods, or known bypass
 11strings. Attackers attempt AMSI bypass to disable scanning and run malicious PowerShell content undetected.
 12"""
 13from = "now-9m"
 14index = ["logs-windows.powershell*", "winlogbeat-*"]
 15language = "kuery"
 16license = "Elastic License v2"
 17name = "Potential Antimalware Scan Interface Bypass via PowerShell"
 18references = ["https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell"]
 19risk_score = 73
 20rule_id = "1f0a69c0-3392-4adf-b7d5-6012fd292da8"
 21severity = "high"
 22tags = [
 23    "Domain: Endpoint",
 24    "OS: Windows",
 25    "Use Case: Threat Detection",
 26    "Tactic: Defense Evasion",
 27    "Data Source: PowerShell Logs",
 28    "Resources: Investigation Guide",
 29]
 30timestamp_override = "event.ingested"
 31type = "query"
 32
 33query = '''
 34event.category:"process" and host.os.type:windows and
 35  (
 36    powershell.file.script_block_text : (
 37      "System.Management.Automation.AmsiUtils" or
 38      amsiInitFailed or
 39      "Invoke-AmsiBypass" or
 40      "Bypass.AMSI" or
 41      "amsi.dll" or
 42      AntimalwareProvider or
 43      amsiSession or
 44      amsiContext or
 45      AmsiInitialize or
 46      unloadobfuscated or
 47      unloadsilent or
 48      AmsiX64 or
 49      AmsiX32 or
 50      FindAmsiFun or
 51      "AllocHGlobal((9076" or
 52      "[cHAr](65)+[cHaR]([byTe]0x6d)+[ChaR]([ByTe]0x73)+[CHaR]([BYte]0x69"
 53    ) or
 54    powershell.file.script_block_text:("[Ref].Assembly.GetType(('System.Management.Automation" and ".SetValue(") or
 55    powershell.file.script_block_text:("::AllocHGlobal((" and ".SetValue(" and "-replace" and ".NoRMALiZe(")
 56  ) and
 57  not powershell.file.script_block_text : (
 58    "sentinelbreakpoints" and "Set-PSBreakpoint"
 59  )
 60'''
 61
 62note = """## Triage and analysis
 63
 64### Investigating Potential Antimalware Scan Interface Bypass via PowerShell
 65#### Possible investigation steps
 66
 67- Does the preserved script block show active AMSI bypass behavior or reference-only content?
 68  - Focus: `powershell.file.script_block_text`, source in `file.path` or `file.name`, and whether bypass helpers execute or are only mentioned.
 69  - Hint: treat AmsiUtils, amsiInitFailed, AmsiScanBuffer/AmsiOpenSession patching, ScriptBlockAst smuggling, VirtualProtect/Marshal.Copy, and logging suppression as active-behavior anchors.
 70  - Implication: escalate when content flips AMSI state, patches scan routines, smuggles script blocks, or invokes decoded content; lower suspicion only for inert research text or bounded training with no execution path.
 71
 72- Does reconstruction add payload execution, download logic, or extra evasion?
 73  - Why: Script Block Logging can split helper functions, decoded strings, and later stages across multiple fragments.
 74  - Focus: reconstruct fragments scoped by `host.id` and `powershell.file.script_block_id`; order with `powershell.sequence`, confirm `powershell.total`, then read `powershell.file.script_block_text`. $investigate_2
 75  - Hint: review surrounding 4104 blocks for the same `host.id` and `process.pid` with different `powershell.file.script_block_id`; keep timestamp comparison tight to avoid PID reuse. $investigate_3
 76  - Hint: if fragments are missing, score visible bypass logic and record the missing sequence range as unresolved, not benign.
 77  - Implication: escalate when reconstruction adds download, decode, in-memory execution, credential access, persistence, Disable Script Logging, or unloadobfuscated/unloadsilent evasion; lower suspicion only when complete fragments remain bounded to authorized lab or training content.
 78
 79- Can endpoint process telemetry recover how PowerShell was launched?
 80  - Focus: if available, recover the process via `host.id` and `process.pid` before interpreting `process.*` or `process.parent.*`; read `process.command_line`, `process.parent.command_line`, and `process.Ext.session_info.logon_type`, expanding the window if PowerShell started earlier. $investigate_4
 81  - Implication: escalate for encoded commands, PowerShell v2 downgrade, Office/browser parents, remote-administration launchers, or service/network logon that does not fit the user; missing endpoint telemetry leaves launch context unresolved, not benign.
 82
 83- Do the user, host, and source context fit an authorized test workflow?
 84  - Focus: `user.id`, `host.id`, `host.name`, preserved `file.path` or `file.name`, and recovered launch context.
 85  - Hint: if no source path is preserved, treat the block as interactive, pasted, in-memory, or remotely delivered and require stronger corroboration before benign closure.
 86  - Implication: escalate when standard-user, shared-workstation, production-server, user-writable-source, or fileless-delivery context cannot be tied to one authorized lab, red-team, detection-engineering, or training case; lower suspicion only when all context supports that exact workflow.
 87
 88- If local evidence remains suspicious or unresolved, does the pattern recur for the same user or host?
 89  - Focus: last-48h related alerts for the same `user.id`, looking for repeated AMSI bypass, delivery, credential access, persistence, or defense evasion. $investigate_0
 90  - Hint: check the same `host.id` before expanding beyond the affected host or user. $investigate_1
 91  - Implication: broaden scope when related alerts show repeated evasion or follow-on abuse; quiet pivots lower scope only and never close active bypass without local evidence proving one exact authorized workflow.
 92
 93- Escalate on active bypass logic, suspicious provenance, launch abuse, operational follow-on evidence, or partial/mixed visibility; close only when script content, reconstruction, launch, source, and related-alert evidence bind activity to one exact authorized lab, training, or red-team workflow; preserve artifacts and escalate when outside confirmation is needed.
 94
 95### False positive analysis
 96
 97- Authorized detection-engineering, red-team, malware-analysis, training, or reference-only course/research use can trigger this rule. Confirm that `powershell.file.script_block_text`, reconstruction, `user.id`, `host.id`, source/session context, and recovered launch context all stay inside the same test case and add no second stage. If records are unavailable, recurrence supports assessment only when the same telemetry pattern proves the exact exercise; do not close on recurrence alone.
 98- Before creating an exception, validate that the same `user.id`, `host.id`, stable source path, launch context, and reconstructed fragment pattern recur across prior alerts from this rule. Build the exception from that confirmed workflow pattern. Avoid exceptions on AMSI strings alone, on `user.name` alone, or on a host alone.
 99
100### Response and remediation
101
102- If confirmed benign, reverse temporary containment and document which evidence proved the authorized workflow: script content, reconstruction, `user.id`, `host.id`, preserved source path, and recovered launch context. Create an exception only if the same workflow pattern recurs and the telemetry still proves the exact exercise.
103- If suspicious but unconfirmed, preserve the script block content, fragment IDs and sequence numbers, `process.pid`, recovered launch details, script-named URLs or paths, source files, and related-alert exports before containment. Apply reversible containment first, such as tighter monitoring on the affected `host.id` or `user.id`, temporary restrictions for script-named URLs, or suspend-process actions when the host role can tolerate them. Escalate to isolation only if reconstructed content or recovered launch evidence confirms operational follow-on activity.
104- If confirmed malicious, contain the host or account based on the script content, recovered launch chain, source path, script-named indicators, or related-alert evidence that established unauthorized operational use. Record the recovered PowerShell process details, parent chain, script content, downstream commands, and affected `user.id` / `host.id` before terminating processes, deleting files, or purging sessions.
105- Block confirmed malicious script-named URLs or hashes, collect referenced source files, and eradicate only the unauthorized scripts, payloads, startup artifacts, scheduled tasks, and security-control changes expressed in reconstruction or recovered launch context.
106- Before destructive cleanup, review related hosts and users for the same script fragments, launch chain, downgrade pattern, script-named indicators, or already-running PowerShell reuse so scope is understood before evidence is removed.
107- After the incident, retain Script Block Logging plus required endpoint process telemetry, and document PowerShell version 2 downgrade, logging-suppression, or script-block smuggling variants in the case record.
108"""
109
110setup = """## Setup
111
112PowerShell Script Block Logging must be enabled to generate the events used by this rule (e.g., 4104).
113Setup instructions: https://ela.st/powershell-logging-setup
114"""
115
116[rule.investigation_fields]
117field_names = [
118    "@timestamp",
119    "user.name",
120    "user.id",
121    "user.domain",
122    "powershell.file.script_block_text",
123    "powershell.file.script_block_id",
124    "powershell.sequence",
125    "powershell.total",
126    "file.path",
127    "file.directory",
128    "file.name",
129    "process.pid",
130    "host.name",
131    "host.id",
132    "powershell.file.script_block_length"
133]
134
135[transform]
136
137[[transform.investigate]]
138label = "Alerts associated with the user"
139description = ""
140providers = [
141  [
142    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
143    { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
144  ]
145]
146relativeFrom = "now-48h/h"
147relativeTo = "now"
148
149[[transform.investigate]]
150label = "Alerts associated with the host"
151description = ""
152providers = [
153  [
154    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
155    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
156  ]
157]
158relativeFrom = "now-48h/h"
159relativeTo = "now"
160
161[[transform.investigate]]
162label = "Script block fragments for the same script"
163description = ""
164providers = [
165  [
166    { excluded = false, field = "powershell.file.script_block_id", queryType = "phrase", value = "{{powershell.file.script_block_id}}", valueType = "string" },
167    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
168  ]
169]
170relativeFrom = "now-1h"
171relativeTo = "now"
172
173[[transform.investigate]]
174label = "PowerShell script blocks for the same process"
175description = ""
176providers = [
177  [
178    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
179    { excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" },
180    { excluded = false, field = "event.code", queryType = "phrase", value = "4104", valueType = "string" }
181  ]
182]
183relativeFrom = "now-1h"
184relativeTo = "now"
185
186[[transform.investigate]]
187label = "Process events for the PowerShell instance"
188description = ""
189providers = [
190  [
191    { excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" },
192    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
193    { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }
194  ]
195]
196relativeFrom = "now-1h"
197relativeTo = "now"
198
199[[rule.threat]]
200framework = "MITRE ATT&CK"
201
202[[rule.threat.technique]]
203id = "T1027"
204name = "Obfuscated Files or Information"
205reference = "https://attack.mitre.org/techniques/T1027/"
206
207[[rule.threat.technique.subtechnique]]
208id = "T1027.010"
209name = "Command Obfuscation"
210reference = "https://attack.mitre.org/techniques/T1027/010/"
211
212[[rule.threat.technique]]
213id = "T1562"
214name = "Impair Defenses"
215reference = "https://attack.mitre.org/techniques/T1562/"
216
217[[rule.threat.technique.subtechnique]]
218id = "T1562.001"
219name = "Disable or Modify Tools"
220reference = "https://attack.mitre.org/techniques/T1562/001/"
221
222[rule.threat.tactic]
223id = "TA0005"
224name = "Defense Evasion"
225reference = "https://attack.mitre.org/tactics/TA0005/"
226
227[[rule.threat]]
228framework = "MITRE ATT&CK"
229
230[[rule.threat.technique]]
231id = "T1059"
232name = "Command and Scripting Interpreter"
233reference = "https://attack.mitre.org/techniques/T1059/"
234
235[[rule.threat.technique.subtechnique]]
236id = "T1059.001"
237name = "PowerShell"
238reference = "https://attack.mitre.org/techniques/T1059/001/"
239
240[rule.threat.tactic]
241id = "TA0002"
242name = "Execution"
243reference = "https://attack.mitre.org/tactics/TA0002/"

Triage and analysis

Investigating Potential Antimalware Scan Interface Bypass via PowerShell

Possible investigation steps

  • Does the preserved script block show active AMSI bypass behavior or reference-only content?

    • Focus: powershell.file.script_block_text, source in file.path or file.name, and whether bypass helpers execute or are only mentioned.
    • Hint: treat AmsiUtils, amsiInitFailed, AmsiScanBuffer/AmsiOpenSession patching, ScriptBlockAst smuggling, VirtualProtect/Marshal.Copy, and logging suppression as active-behavior anchors.
    • Implication: escalate when content flips AMSI state, patches scan routines, smuggles script blocks, or invokes decoded content; lower suspicion only for inert research text or bounded training with no execution path.
  • Does reconstruction add payload execution, download logic, or extra evasion?

    • Why: Script Block Logging can split helper functions, decoded strings, and later stages across multiple fragments.
    • Focus: reconstruct fragments scoped by host.id and powershell.file.script_block_id; order with powershell.sequence, confirm powershell.total, then read powershell.file.script_block_text. $investigate_2
    • Hint: review surrounding 4104 blocks for the same host.id and process.pid with different powershell.file.script_block_id; keep timestamp comparison tight to avoid PID reuse. $investigate_3
    • Hint: if fragments are missing, score visible bypass logic and record the missing sequence range as unresolved, not benign.
    • Implication: escalate when reconstruction adds download, decode, in-memory execution, credential access, persistence, Disable Script Logging, or unloadobfuscated/unloadsilent evasion; lower suspicion only when complete fragments remain bounded to authorized lab or training content.
  • Can endpoint process telemetry recover how PowerShell was launched?

    • Focus: if available, recover the process via host.id and process.pid before interpreting process.* or process.parent.*; read process.command_line, process.parent.command_line, and process.Ext.session_info.logon_type, expanding the window if PowerShell started earlier. $investigate_4
    • Implication: escalate for encoded commands, PowerShell v2 downgrade, Office/browser parents, remote-administration launchers, or service/network logon that does not fit the user; missing endpoint telemetry leaves launch context unresolved, not benign.
  • Do the user, host, and source context fit an authorized test workflow?

    • Focus: user.id, host.id, host.name, preserved file.path or file.name, and recovered launch context.
    • Hint: if no source path is preserved, treat the block as interactive, pasted, in-memory, or remotely delivered and require stronger corroboration before benign closure.
    • Implication: escalate when standard-user, shared-workstation, production-server, user-writable-source, or fileless-delivery context cannot be tied to one authorized lab, red-team, detection-engineering, or training case; lower suspicion only when all context supports that exact workflow.
  • If local evidence remains suspicious or unresolved, does the pattern recur for the same user or host?

    • Focus: last-48h related alerts for the same user.id, looking for repeated AMSI bypass, delivery, credential access, persistence, or defense evasion. $investigate_0
    • Hint: check the same host.id before expanding beyond the affected host or user. $investigate_1
    • Implication: broaden scope when related alerts show repeated evasion or follow-on abuse; quiet pivots lower scope only and never close active bypass without local evidence proving one exact authorized workflow.
  • Escalate on active bypass logic, suspicious provenance, launch abuse, operational follow-on evidence, or partial/mixed visibility; close only when script content, reconstruction, launch, source, and related-alert evidence bind activity to one exact authorized lab, training, or red-team workflow; preserve artifacts and escalate when outside confirmation is needed.

False positive analysis

  • Authorized detection-engineering, red-team, malware-analysis, training, or reference-only course/research use can trigger this rule. Confirm that powershell.file.script_block_text, reconstruction, user.id, host.id, source/session context, and recovered launch context all stay inside the same test case and add no second stage. If records are unavailable, recurrence supports assessment only when the same telemetry pattern proves the exact exercise; do not close on recurrence alone.
  • Before creating an exception, validate that the same user.id, host.id, stable source path, launch context, and reconstructed fragment pattern recur across prior alerts from this rule. Build the exception from that confirmed workflow pattern. Avoid exceptions on AMSI strings alone, on user.name alone, or on a host alone.

Response and remediation

  • If confirmed benign, reverse temporary containment and document which evidence proved the authorized workflow: script content, reconstruction, user.id, host.id, preserved source path, and recovered launch context. Create an exception only if the same workflow pattern recurs and the telemetry still proves the exact exercise.
  • If suspicious but unconfirmed, preserve the script block content, fragment IDs and sequence numbers, process.pid, recovered launch details, script-named URLs or paths, source files, and related-alert exports before containment. Apply reversible containment first, such as tighter monitoring on the affected host.id or user.id, temporary restrictions for script-named URLs, or suspend-process actions when the host role can tolerate them. Escalate to isolation only if reconstructed content or recovered launch evidence confirms operational follow-on activity.
  • If confirmed malicious, contain the host or account based on the script content, recovered launch chain, source path, script-named indicators, or related-alert evidence that established unauthorized operational use. Record the recovered PowerShell process details, parent chain, script content, downstream commands, and affected user.id / host.id before terminating processes, deleting files, or purging sessions.
  • Block confirmed malicious script-named URLs or hashes, collect referenced source files, and eradicate only the unauthorized scripts, payloads, startup artifacts, scheduled tasks, and security-control changes expressed in reconstruction or recovered launch context.
  • Before destructive cleanup, review related hosts and users for the same script fragments, launch chain, downgrade pattern, script-named indicators, or already-running PowerShell reuse so scope is understood before evidence is removed.
  • After the incident, retain Script Block Logging plus required endpoint process telemetry, and document PowerShell version 2 downgrade, logging-suppression, or script-block smuggling variants in the case record.

References

Related rules

to-top