Potential AMSI Bypass via RPC Runtime Hooking
editPotential AMSI Bypass via RPC Runtime Hooking
editIdentifies 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.
Rule type: query
Rule indices:
- winlogbeat-*
- logs-windows.powershell*
Severity: high
Risk score: 73
Runs every: 5m
Searches indices from: now-9m (Date Math format, see also Additional look-back time)
Maximum alerts per execution: 100
References:
Tags:
- Domain: Endpoint
- OS: Windows
- Use Case: Threat Detection
- Tactic: Defense Evasion
- Tactic: Execution
- Data Source: PowerShell Logs
- Resources: Investigation Guide
Version: 1
Rule authors:
- Elastic
Rule license: Elastic License v2
Investigation guide
editTriage 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.
Setup
editSetup
PowerShell Script Block Logging must be enabled to generate the events used by this rule (event ID 4104). The
Microsoft-Windows-PowerShell/Operational channel must be collected by the Windows integration or Winlogbeat.
Setup instructions: https://ela.st/powershell-logging-setup
Rule query
editevent.code: "4104" and host.os.type: "windows" and
powershell.file.script_block_text : (
"NdrClientCall" or
"NdrClientCall2" or
"NdrClientCall3"
) and
powershell.file.script_block_text : (
"GetProcAddress" or
"GetDelegateForFunctionPointer" or
"VirtualProtect"
)
Framework: MITRE ATT&CKTM
-
Tactic:
- Name: Defense Evasion
- ID: TA0005
- Reference URL: https://attack.mitre.org/tactics/TA0005/
-
Technique:
- Name: Impair Defenses
- ID: T1562
- Reference URL: https://attack.mitre.org/techniques/T1562/
-
Sub-technique:
- Name: Disable or Modify Tools
- ID: T1562.001
- Reference URL: https://attack.mitre.org/techniques/T1562/001/
-
Tactic:
- Name: Execution
- ID: TA0002
- Reference URL: https://attack.mitre.org/tactics/TA0002/
-
Technique:
- Name: Command and Scripting Interpreter
- ID: T1059
- Reference URL: https://attack.mitre.org/techniques/T1059/
-
Sub-technique:
- Name: PowerShell
- ID: T1059.001
- Reference URL: https://attack.mitre.org/techniques/T1059/001/