Detecting AMSI Bypasses: When Attackers Blind Your Script Scanner
AMSI is Windows' last line of defense against malicious scripts — and one of the first things attackers disable. Here's how the bypass works and how WinSentinel catches it.
Modern attackers rarely drop a compiled EXE anymore. They live in memory: a base64 PowerShell one-liner, an obfuscated JScript payload, a VBA macro that reflectively loads a .NET assembly. The one Windows component standing between that in-memory payload and execution is the Antimalware Scan Interface (AMSI). Understanding how AMSI works — and how attackers blind it — is essential for anyone defending Windows endpoints.
What AMSI actually does
AMSI is a Windows API introduced in Windows 10 that lets applications submit content to the installed antimalware provider (Defender by default) after it has been de-obfuscated but before it executes. When PowerShell decodes a -EncodedCommand blob, or a script decrypts a stage-two payload, the cleartext is handed to AmsiScanBuffer for a verdict. This is why AMSI is so powerful: it sees the real payload, not the wrapper.
PowerShell, the Windows Script Host (VBScript/JScript), Office VBA, and the .NET runtime are all AMSI providers. That coverage is exactly why bypassing AMSI is step zero of most modern offensive playbooks. If an attacker can neutralize AMSI in a process, everything downstream in that process runs unscanned.
How the bypass works
Because AMSI runs in-process — amsi.dll is loaded into the same PowerShell or Office process it protects — the attacker already controls the memory it lives in. There is no privilege boundary to cross. The three most common techniques are:
- Memory patching — locate
AmsiScanBufferinamsi.dlland overwrite its first bytes so it returnsAMSI_RESULT_CLEAN(orE_INVALIDARG) before scanning anything. - amsiInitFailed reflection — flip PowerShell's private
amsiInitFailedfield totrue, which makes the host skip scanning entirely. - Provider hijacking / DLL side-loading — register a rogue AMSI provider CLSID, or drop a malicious
amsi.dllnext to a vulnerable binary so it loads instead of the real one.
A textbook in-memory patch looks like this — note it never touches disk, which is the whole point:
$a = [Ref].Assembly.GetType('System.Management.Automation.'+'AmsiUtils')
$f = $a.GetField('amsiInitFailed','NonPublic,Static')
$f.SetValue($null,$true) # AMSI now no-ops for this session
The signature above is itself detected by Defender today — so real intrusions obfuscate every string and split the reflection across variables. Signature-matching the bypass is a losing game; you need behavioral and configuration evidence instead.
Why signatures alone don't cut it
Defender ships signatures for known bypass strings, but attackers mutate them faster than signatures ship. The durable detections are structural, not string-based:
- Event 1116/1117 from Defender when AMSI does catch something — but silence here can mean either "clean" or "blinded."
- PowerShell Script Block Logging (Event 4104) — because AMSI and script-block logging are fed from the same de-obfuscated buffer, 4104 records the cleartext even when AMSI is neutered downstream. This is your single best forensic artifact.
- amsi.dll load anomalies — an
amsi.dllloaded from a non-System32 path is almost always a side-loading attack. - Registry provider drift — new or altered CLSIDs under
HKLM\SOFTWARE\Microsoft\AMSI\Providers.
How WinSentinel catches it
WinSentinel treats AMSI health as a configuration and behavioral signal, not a one-time checkbox. On every machine, its audit modules verify the plumbing that makes AMSI trustworthy:
- Script Block Logging is enabled and centrally intact — so the cleartext buffer is captured even if AMSI is patched in a rogue process. WinSentinel flags when 4104 logging is off or has been quietly disabled via GPO.
- PowerShell v2 engine is removed — the legacy engine predates AMSI and is a trivial downgrade bypass. WinSentinel treats a present v2 engine as a finding.
- AMSI provider registration is baselined — the module records the registered providers and raises drift when a new CLSID appears or
amsi.dllis loaded from an unexpected path. - Constrained Language Mode and execution policy posture are scored, because they raise the cost of the reflection-based bypasses shown above.
Every one of these checks runs at full power on a single machine — all 33 modules, no gating, no limits — so an individual developer or admin gets the complete AMSI posture for free. What changes at scale is orchestration: on a fleet, WinSentinel Pro rolls these findings up to a central node, so a security lead managing 50 or 100 endpoints sees at a glance which machines have script-block logging disabled or an unexpected AMSI provider registered, and gets drift alerts the moment a bypass-enabling change lands anywhere in the estate.
The takeaway
AMSI is powerful precisely because it scans the real, de-obfuscated payload — and fragile precisely because it runs inside the process it protects. You cannot rely on AMSI to defend itself. Defend the evidence trail instead: keep script-block logging on, kill the PowerShell v2 downgrade path, baseline your AMSI providers, and alert on drift. Do that on one box with WinSentinel Free, or across a whole fleet with Pro, and a blinded scanner stops being a silent failure and becomes a loud, investigable event.