透過AmsiOpenSession繞過AMSI

Powershell AMSI Bypass By AmsiOpenSession

前言

在現代 Windows 安全架構中,Antimalware Scan Interface(AMSI)扮演著至關重要的角色。作為 Microsoft 在 Windows 10 中引入的安全機制,AMSI 提供了一個標準化的介面,讓防毒軟體能夠在腳本執行前進行掃描,有效防止惡意腳本的執行。

本文將從資安防禦研究的角度,深入分析 AMSI 的運作原理與潛在的繞過技術。了解這些技術的目的是為了協助資安人員建立更完善的防禦機制,識別並阻止潛在的攻擊行為。

免責聲明:本文內容僅供教育與研究目的。未經授權對系統進行攻擊或繞過安全機制屬於違法行為。請僅在授權的測試環境中進行研究。


什麼是 AMSI?

AMSI 概述

AMSI(Antimalware Scan Interface)是 Microsoft 於 Windows 10(Build 1607)開始引入的安全機制,主要目的是提供一個統一的介面,讓應用程式能夠將內容傳送給系統中安裝的防惡意軟體產品進行掃描。

AMSI 特別針對以下情境設計:

  • 腳本引擎整合:PowerShell、JavaScript、VBScript 等腳本引擎在執行程式碼前會先透過 AMSI 進行掃描
  • 無檔案攻擊防護:即使惡意程式碼僅存在於記憶體中,AMSI 仍能進行掃描
  • 混淆程式碼偵測:AMSI 能夠掃描最終解碼/解混淆後的程式碼內容

AMSI 支援的應用程式

目前整合 AMSI 的 Windows 元件包括:

元件說明
PowerShell版本 3.0 以上的所有腳本執行
Windows Script Hostwscript.exe 和 cscript.exe
JavaScript/VBScript透過 Scripting Host 執行的腳本
Office VBA MacrosOffice 巨集程式碼
.NET Framework版本 4.8 以上的動態程式碼載入
Windows Management Instrumentation (WMI)WMI Script 執行

AMSI 架構與運作原理

整體架構

AMSI 的架構可分為三個主要層級:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
┌─────────────────────────────────────────────────────────────┐
│                    應用程式層 (Application Layer)              │
│  ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐   │
│  │PowerShell │ │  WSH      │ │  Office   │ │  .NET     │   │
│  └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘   │
│        │             │             │             │          │
│        └─────────────┴─────────────┴─────────────┘          │
│                              │                              │
├──────────────────────────────┼──────────────────────────────┤
│                    AMSI API 層                              │
│                    (amsi.dll)                               │
│  ┌──────────────────────────────────────────────────────┐   │
│  │ AmsiInitialize() │ AmsiOpenSession() │ AmsiScanBuffer()│ │
│  │ AmsiScanString() │ AmsiCloseSession() │ AmsiUninitialize│ │
│  └──────────────────────────────────────────────────────┘   │
│                              │                              │
├──────────────────────────────┼──────────────────────────────┤
│                    防毒引擎層 (AV Provider Layer)            │
│  ┌───────────┐ ┌───────────┐ ┌───────────┐                 │
│  │ Windows   │ │ Third-party│ │  Other    │                 │
│  │ Defender  │ │    AV      │ │ Providers │                 │
│  └───────────┘ └───────────┘ └───────────┘                 │
└─────────────────────────────────────────────────────────────┘

核心 API 函數

AMSI 提供以下核心 API 函數:

1. AmsiInitialize

1
2
3
4
HRESULT AmsiInitialize(
  LPCWSTR      appName,
  HAMSICONTEXT *amsiContext
);

初始化 AMSI API,建立應用程式與 AMSI 之間的連接。

2. AmsiOpenSession

1
2
3
4
HRESULT AmsiOpenSession(
  HAMSICONTEXT amsiContext,
  HAMSISESSION *amsiSession
);

開啟一個新的 AMSI Session,用於後續的掃描操作。此函數是本文分析的重點。

3. AmsiScanBuffer / AmsiScanString

1
2
3
4
5
6
7
8
HRESULT AmsiScanBuffer(
  HAMSICONTEXT amsiContext,
  PVOID        buffer,
  ULONG        length,
  LPCWSTR      contentName,
  HAMSISESSION amsiSession,
  AMSI_RESULT  *result
);

將緩衝區內容送交防毒引擎進行掃描。

4. AmsiCloseSession / AmsiUninitialize

用於關閉 Session 和釋放 AMSI 資源。

AMSI 掃描流程

當 PowerShell 執行腳本時,AMSI 的運作流程如下:

  1. 初始化階段:PowerShell 啟動時呼叫 AmsiInitialize() 建立 AMSI Context
  2. Session 建立:執行腳本前呼叫 AmsiOpenSession() 建立掃描 Session
  3. 內容掃描:透過 AmsiScanBuffer()AmsiScanString() 將腳本內容送交掃描
  4. 結果判定:根據 AMSI_RESULT 決定是否允許執行
  5. Session 關閉:掃描完成後關閉 Session

AMSI_RESULT 回傳值

1
2
3
4
5
6
7
typedef 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   // 偵測到威脅
} AMSI_RESULT;

為什麼研究 AMSI 繞過對資安防禦很重要?

攻防對抗的本質

資訊安全是一場持續的攻防對抗。了解攻擊者可能使用的技術,是建立有效防禦機制的基礎。研究 AMSI 繞過技術的重要性在於:

  1. 威脅情報蒐集:了解最新的繞過技術,才能及時更新防禦策略
  2. 防禦機制強化:透過分析繞過原理,找出防禦機制的盲點並加以改善
  3. 入侵偵測改進:開發針對繞過行為的偵測規則
  4. 紅隊演練準備:在授權的滲透測試中模擬真實攻擊場景

常見的 AMSI 繞過類別

目前已知的 AMSI 繞過技術可分為以下幾類:

類別方法說明
記憶體修補Patching amsi.dll直接修改記憶體中的 AMSI 函數
強制錯誤AmsiInitFailed使 AMSI 初始化失敗
COM HijackingRegistry Modification劫持 AMSI COM 物件
反射載入Reflection透過反射修改 AMSI 相關欄位
CLR HookingHooking ScanContentHook CLR 中的掃描函數

AmsiOpenSession 技術分析

說明

AmsiOpenSession 是 amsi.dll 檔案中的一個功能,作為 Windows 中反惡意軟體掃描介面(AMSI)的一部分提供。AmsiOpenSession 功能用於為呼叫應用程式創建新的 AMSI Session。

AmsiOpenSession 功能可用於通過設置 Session 的內容和行為來配置 AMSI Session。例如,應用程式可以設定 Session 的內容,以指定正在掃描的資料的內容類型,例如 Script 或 Binary 資料。

反組譯分析

以下是 amsi.dll 中反組譯 AmsiOpenSession 功能的分析:

“AmsiOpenSession 反組譯”

組合語言層級分析

在 AmsiOpenSession 函數的開頭,有一段關鍵的驗證邏輯:

1
2
test rcx, rcx      ; 測試 amsiContext 參數是否為 NULL
je   0x180008244   ; 如果為零(NULL),跳轉至錯誤處理

指令說明

  1. TEST 指令test rcx, rcx 執行位元 AND 運算(rcx AND rcx),結果不儲存,僅更新旗標暫存器

    • 如果 RCX = 0,則 ZF(Zero Flag)= 1
    • 如果 RCX ≠ 0,則 ZF = 0
  2. JE 指令:Jump if Equal(當 ZF = 1 時跳轉)

    • 跳轉目標 0x180008244 是錯誤處理分支
    • 該分支會回傳錯誤碼 0x80070057(E_INVALIDARG)

記憶體結構說明

amsiContext 結構

AMSI Context 在記憶體中的大致結構:

1
2
3
4
5
6
typedef struct _AMSI_CONTEXT {
    DWORD       Signature;      // 0x00: 'AMSI' 簽章
    PWCHAR      AppName;        // 0x08: 應用程式名稱
    IAntimalware *Antimalware;  // 0x10: COM 介面指標
    DWORD       Version;        // 0x18: 版本資訊
} AMSI_CONTEXT, *HAMSICONTEXT;

amsiSession 結構

1
2
3
4
5
typedef struct _AMSI_SESSION {
    HAMSICONTEXT Context;       // 0x00: 關聯的 Context
    ULONGLONG    SessionId;     // 0x08: Session 識別碼
    // ... 其他欄位
} AMSI_SESSION, *HAMSISESSION;

繞過原理

如果將 JE(Jump if Equal)指令修改為 JNE(Jump if Not Equal),則邏輯將被反轉:

  • 原始邏輯:參數為 NULL 時跳轉至錯誤處理
  • 修改後邏輯:參數為 NULL 時繼續執行,有效參數時反而進入錯誤處理

由於大多數情況下參數不為 NULL,這將導致 AMSI Session 無法正常建立,進而使後續的掃描操作失敗。

指令修改對照

指令OpCode行為
JE (Jump if Equal)0x74ZF=1 時跳轉
JNE (Jump if Not Equal)0x75ZF=0 時跳轉

修改只需將單一位元組從 0x74 改為 0x75


防禦建議

如何偵測 AMSI 繞過嘗試

1. 事件日誌監控

監控 Windows 事件日誌中的可疑活動:

1
2
3
事件來源:Microsoft-Windows-PowerShell
事件 ID:4104(腳本區塊記錄)
事件 ID:4103(模組記錄)

建議啟用 PowerShell 腳本區塊記錄:

1
2
3
4
# 透過群組原則設定
Computer Configuration > Administrative Templates >
Windows Components > Windows PowerShell >
Turn on PowerShell Script Block Logging

2. 記憶體完整性監控

使用 Endpoint Detection and Response(EDR)解決方案監控:

  • amsi.dll 的記憶體完整性
  • 可疑的記憶體寫入操作
  • 程序對 amsi.dll 的非預期存取

3. ETW(Event Tracing for Windows)監控

監控 AMSI 相關的 ETW Provider:

1
2
Provider GUID: {2A576B87-09A7-520E-C21A-4942F0271D67}
Provider Name: Microsoft-Antimalware-Scan-Interface

4. 行為分析指標

可疑的行為模式包括:

  • 程序嘗試取得 amsi.dll 的記憶體位址
  • 使用 VirtualProtect 修改 amsi.dll 的記憶體保護屬性
  • 對 amsi.dll 函數進行 inline hooking

YARA 規則範例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
rule AMSI_Bypass_Attempt
{
    meta:
        description = "偵測可能的 AMSI 繞過嘗試"
        author = "Security Research"

    strings:
        $amsi1 = "AmsiScanBuffer" ascii wide
        $amsi2 = "AmsiOpenSession" ascii wide
        $amsi3 = "AmsiInitialize" ascii wide
        $patch1 = { 48 85 C9 74 }  // test rcx, rcx; je
        $patch2 = { C3 }            // ret
        $vp = "VirtualProtect" ascii wide

    condition:
        any of ($amsi*) and $vp and any of ($patch*)
}

相關防護措施建議

組織層級

  1. 強化 PowerShell 安全設定

    • 啟用 Constrained Language Mode
    • 實施 AppLocker 或 WDAC 原則
    • 限制 PowerShell 執行原則
  2. 實施最小權限原則

    • 限制本機管理員權限
    • 使用 JIT(Just-In-Time)管理存取
  3. 部署進階威脅防護

    • 使用支援 AMSI 的防毒解決方案
    • 部署 EDR 解決方案
    • 啟用 Microsoft Defender Credential Guard

技術控制

  1. 啟用 Windows Defender Exploit Guard

    1
    2
    
    # 啟用記憶體完整性保護
    Set-ProcessMitigation -System -Enable DEP,SEHOP
    
  2. 設定 PowerShell 記錄

    1
    2
    3
    4
    5
    6
    
    # 啟用模組記錄
    $basePath = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell'
    Set-ItemProperty -Path "$basePath\ModuleLogging" -Name EnableModuleLogging -Value 1
    
    # 啟用腳本區塊記錄
    Set-ItemProperty -Path "$basePath\ScriptBlockLogging" -Name EnableScriptBlockLogging -Value 1
    
  3. 監控可疑的 DLL 載入

    • 使用 Sysmon 監控 ImageLoad 事件
    • 特別關注對 amsi.dll 的操作

Sysmon 設定範例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<Sysmon schemaversion="4.90">
    <EventFiltering>
        <!-- 監控 AMSI 相關的 DLL 載入 -->
        <ImageLoad onmatch="include">
            <ImageLoaded condition="contains">amsi.dll</ImageLoaded>
        </ImageLoad>

        <!-- 監控可疑的記憶體操作 -->
        <ProcessAccess onmatch="include">
            <TargetImage condition="contains">amsi.dll</TargetImage>
        </ProcessAccess>
    </EventFiltering>
</Sysmon>

結論

AMSI 作為 Windows 的重要防禦機制,在阻止腳本類型的惡意程式方面發揮著關鍵作用。然而,如同所有的安全機制,AMSI 並非無懈可擊。透過深入了解其運作原理和潛在的繞過技術,資安防禦人員能夠:

  1. 更好地理解攻擊者的技術手段
  2. 建立更全面的防禦策略
  3. 開發更有效的偵測機制
  4. 及時應對新型態的威脅

防禦不僅僅是部署工具,更重要的是理解威脅本質並建立縱深防禦體系。


參考資料

官方文件

研究文章

防禦資源

工具


本文最後更新:2023-06-14

本文僅供教育與研究目的,請遵守相關法律法規。

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy