Potential AMSI Bypass via RPC Runtime Hooking
Identifies PowerShell script block content associated with an Antimalware Scan Interface (AMSI) bypass that hooks the RPC runtime marshaling stub NdrClientCall3 (or NdrClientCall2) in rpcrt4.dll. Unlike bypasses that patch AmsiScanBuffer or set amsiInitFailed, this technique operates at the RPC layer used by AMSI to delegate scan requests to the antivirus provider, tampering with the request before it reaches the engine and leaving AMSI itself unmodified. The loader allocates an executable trampoline and marshals a delegate to the native stub; these primitives appear in PowerShell Script Block Logging before the hook takes effect.
Elastic rule (View on GitHub)
1[metadata]
2creation_date = "2026/06/22"
3integration = ["windows"]
4maturity = "production"
5updated_date = "2026/06/22"
6
7[rule]
8author = ["Elastic"]
9description = """
10Identifies PowerShell script block content associated with an Antimalware Scan Interface (AMSI) bypass that hooks the
11RPC runtime marshaling stub NdrClientCall3 (or NdrClientCall2) in rpcrt4.dll. Unlike bypasses that patch AmsiScanBuffer
12or set amsiInitFailed, this technique operates at the RPC layer used by AMSI to delegate scan requests to the
13antivirus provider, tampering with the request before it reaches the engine and leaving AMSI itself unmodified. The
14loader allocates an executable trampoline and marshals a delegate to the native stub; these primitives appear in
15PowerShell Script Block Logging before the hook takes effect.
16"""
17from = "now-9m"
18index = ["winlogbeat-*", "logs-windows.powershell*"]
19language = "kuery"
20license = "Elastic License v2"
21name = "Potential AMSI Bypass via RPC Runtime Hooking"
22note = """## Triage and analysis
23
24### Investigating Potential AMSI Bypass via RPC Runtime Hooking
25
26The Antimalware Scan Interface (AMSI) delegates scan requests to the registered antivirus provider over RPC. By hooking
27the RPC runtime marshaling stub `NdrClientCall3`/`NdrClientCall2` in `rpcrt4.dll`, an adversary can tamper with these
28requests so that malicious content is reported as clean, without modifying `amsi.dll` or patching `AmsiScanBuffer`.
29This makes the bypass harder to catch via AMSI buffer or memory-write telemetry; the most reliable host artifact is the
30loader's own PowerShell script content, captured by Script Block Logging.
31
32#### Possible investigation steps
33
34- Review `powershell.file.script_block_text` for references to `NdrClientCall3`/`NdrClientCall2`, resolution of
35 functions in `rpcrt4.dll`, allocation of executable (`PAGE_EXECUTE_READWRITE`) memory, and delegate marshaling via
36 `GetDelegateForFunctionPointer`.
37- PowerShell logs each statement as a separate event; pivot on `host.id` and the PowerShell process id to reconstruct
38 the full loader sequence and confirm intent.
39- Identify how PowerShell was launched (interactive, encoded command, remote session) and review the parent process
40 tree for download or staging activity.
41- Correlate with Elastic Defend endpoint telemetry on the same host around the same time. Note that this RPC-layer hook
42 may not surface as a memory modification of `rpcrt4.dll`, which is expected for this technique.
43- Hunt for the same script content, user, or host pattern across the environment.
44
45### False positive analysis
46
47- Security research, detection engineering, and red-team development that legitimately references the RPC runtime
48 marshaling functions or allocates executable memory from PowerShell can match. Validate the user, host, parent
49 process, and surrounding script blocks against authorized testing before closing as benign, and add exceptions for
50 known testing identities or hosts.
51
52### Response and remediation
53
54- Isolate the host if the activity is confirmed malicious and review for follow-on payload execution that the bypass
55 was intended to conceal.
56- Terminate the offending PowerShell session and preserve the Script Block Logging events for analysis.
57- Restrict PowerShell usage outside of IT and engineering business units using GPOs, AppLocker, or WDAC.
58- Reset credentials for accounts active on the host during the session if follow-on activity is observed.
59
60### Limitations
61
62This rule detects the technique only when it is delivered as logged PowerShell script-block text. In-memory delivery, a
63PowerShell v2 downgrade, or implementing the hook outside PowerShell (compiled binary) can evade Script Block Logging
64and therefore this rule. For customers running Elastic Defend, prefer the companion Endpoint Rule which detects the
65VirtualProtect call targeting rpcrt4.dll!NdrClientCall* directly via API telemetry and is not dependent on Script
66Block Logging."""
67references = [
68 "https://github.com/andreisss/Ghosting-AMSI",
69]
70risk_score = 73
71rule_id = "4027f24e-b02f-4605-872f-7bafd8fe1b33"
72setup = """## Setup
73
74PowerShell Script Block Logging must be enabled to generate the events used by this rule (event ID 4104). The
75`Microsoft-Windows-PowerShell/Operational` channel must be collected by the Windows integration or Winlogbeat.
76
77Setup instructions: https://ela.st/powershell-logging-setup"""
78severity = "high"
79tags = [
80 "Domain: Endpoint",
81 "OS: Windows",
82 "Use Case: Threat Detection",
83 "Tactic: Defense Evasion",
84 "Tactic: Execution",
85 "Data Source: PowerShell Logs",
86 "Resources: Investigation Guide",
87]
88timestamp_override = "event.ingested"
89type = "query"
90
91query = '''
92event.code: "4104" and host.os.type: "windows" and
93 powershell.file.script_block_text : (
94 "NdrClientCall" or
95 "NdrClientCall2" or
96 "NdrClientCall3"
97 ) and
98 powershell.file.script_block_text : (
99 "GetProcAddress" or
100 "GetDelegateForFunctionPointer" or
101 "VirtualProtect"
102 )
103'''
104
105[rule.investigation_fields]
106field_names = [
107 "@timestamp",
108 "host.id",
109 "host.name",
110 "user.id",
111 "user.name",
112 "user.domain",
113 "process.pid",
114 "powershell.file.script_block_text",
115 "powershell.file.script_block_id",
116 "powershell.sequence",
117 "powershell.total",
118 "file.path",
119]
120
121[[rule.threat]]
122framework = "MITRE ATT&CK"
123
124[[rule.threat.technique]]
125id = "T1562"
126name = "Impair Defenses"
127reference = "https://attack.mitre.org/techniques/T1562/"
128
129[[rule.threat.technique.subtechnique]]
130id = "T1562.001"
131name = "Disable or Modify Tools"
132reference = "https://attack.mitre.org/techniques/T1562/001/"
133
134[rule.threat.tactic]
135id = "TA0005"
136name = "Defense Evasion"
137reference = "https://attack.mitre.org/tactics/TA0005/"
138
139[[rule.threat]]
140framework = "MITRE ATT&CK"
141
142[[rule.threat.technique]]
143id = "T1059"
144name = "Command and Scripting Interpreter"
145reference = "https://attack.mitre.org/techniques/T1059/"
146
147[[rule.threat.technique.subtechnique]]
148id = "T1059.001"
149name = "PowerShell"
150reference = "https://attack.mitre.org/techniques/T1059/001/"
151
152[rule.threat.tactic]
153id = "TA0002"
154name = "Execution"
155reference = "https://attack.mitre.org/tactics/TA0002/"
Triage and analysis
Investigating Potential AMSI Bypass via RPC Runtime Hooking
The Antimalware Scan Interface (AMSI) delegates scan requests to the registered antivirus provider over RPC. By hooking
the RPC runtime marshaling stub NdrClientCall3/NdrClientCall2 in rpcrt4.dll, an adversary can tamper with these
requests so that malicious content is reported as clean, without modifying amsi.dll or patching AmsiScanBuffer.
This makes the bypass harder to catch via AMSI buffer or memory-write telemetry; the most reliable host artifact is the
loader's own PowerShell script content, captured by Script Block Logging.
Possible investigation steps
- Review
powershell.file.script_block_textfor references toNdrClientCall3/NdrClientCall2, resolution of functions inrpcrt4.dll, allocation of executable (PAGE_EXECUTE_READWRITE) memory, and delegate marshaling viaGetDelegateForFunctionPointer. - PowerShell logs each statement as a separate event; pivot on
host.idand the PowerShell process id to reconstruct the full loader sequence and confirm intent. - Identify how PowerShell was launched (interactive, encoded command, remote session) and review the parent process tree for download or staging activity.
- Correlate with Elastic Defend endpoint telemetry on the same host around the same time. Note that this RPC-layer hook
may not surface as a memory modification of
rpcrt4.dll, which is expected for this technique. - Hunt for the same script content, user, or host pattern across the environment.
False positive analysis
- Security research, detection engineering, and red-team development that legitimately references the RPC runtime marshaling functions or allocates executable memory from PowerShell can match. Validate the user, host, parent process, and surrounding script blocks against authorized testing before closing as benign, and add exceptions for known testing identities or hosts.
Response and remediation
- Isolate the host if the activity is confirmed malicious and review for follow-on payload execution that the bypass was intended to conceal.
- Terminate the offending PowerShell session and preserve the Script Block Logging events for analysis.
- Restrict PowerShell usage outside of IT and engineering business units using GPOs, AppLocker, or WDAC.
- Reset credentials for accounts active on the host during the session if follow-on activity is observed.
Limitations
This rule detects the technique only when it is delivered as logged PowerShell script-block text. In-memory delivery, a PowerShell v2 downgrade, or implementing the hook outside PowerShell (compiled binary) can evade Script Block Logging and therefore this rule. For customers running Elastic Defend, prefer the companion Endpoint Rule which detects the VirtualProtect call targeting rpcrt4.dll!NdrClientCall* directly via API telemetry and is not dependent on Script Block Logging.
References
Related rules
- Potential Process Injection via PowerShell
- Suspicious .NET Reflection via PowerShell
- Suspicious Portable Executable Encoded in Powershell Script
- Potential PowerShell HackTool Script by Author
- PowerShell PSReflect Script