0x1 防御者视角的逆向思考
在谈AMS绕过之前,我们需要从防御者的视角进行逆向思考。AMSI,全称为Anti-Malware Scan Interface,是Windows 10引入的一项安全功能。它的设计初衷是为了解决恶意软件检测的短板,通过提供统一的接口供各类反病毒软件扫描脚本等内容。然而,任何防御措施都存在被绕过的可能。作为一名攻防专业人士,我们要思考,如果我想绕过AMSI,我会怎么做?
防御机制分析
AMSI的核心是通过拦截脚本执行过程中的代码片段,将其传递给注册的杀毒软件进行扫描。一般来说,AMSI在PowerShell及其他支持脚本的环境下表现得尤为活跃。其具体工作机制如下:

- 拦截执行:在脚本执行之前,AMSI会提取内容。
- 调用接口:通过公开的AMSI API将脚本内容发送给反病毒软件。
- 扫描与响应:反病毒软件分析脚本内容,返回执行或阻止的指令。
从攻击者的角度,我们可以识别出几个关键点:拦截点、接口调用以及扫描内容。这也是我们需要集中火力绕过的地方。
0x2 AMSI绕过的武器库
对防御机制有了基本了解后,我们可以构建一个“武器库”,从中选取合适的工具和技术来进行AMS绕过。我们将在下面介绍几种可行的绕过技巧,并结合Ruby和Shell来进行实战演示。
技巧一:老旧方法依然有效
利用AMS初始化时机:一些攻击者发现,AMSI在某些情况下的初始化并不完全可靠,利用这一点进行脚本混淆或分段执行可能避开初次扫描。
<pre><code class="language-ruby"># 伪装成无害的Ruby代码 safe_code = "puts 'Hello World'"
将恶意代码嵌入进来
malicious_code = "File.write('C:\\\\Windows\\\\System32\\\\drivers\\\\etc\\\\hosts', '127.0.0.1 example.com')"
拼接并执行
eval(safe_code + malicious_code)</code></pre>
这种方法的关键在于利用脚本的动态特性,将恶意代码与无害代码混淆,拦截工具可能会因为初步的脚本内容无害而放行。
技巧二:利用Shell的特性
重大劣势:许多情况下,脚本甚至不需要完全绕过AMSI,只需在特定环境中执行一段可疑代码。
<pre><code class="language-shell">#!/bin/bash
基于bash的简单脚本示例
echo "执行看似无害的命令"
混淆的恶意命令
eval $(echo "bHMgLWE=" | base64 --decode)</code></pre>

这个技巧利用了脚本语言的特性和AMSI接口依赖的劣势,通过在执行过程中动态解码恶意代码,使其绕过初步的静态扫描。
0x3 环境准备和攻击演练
为了在实战中应用这些技巧,我们需要搭建一个测试环境。以下是一个可能的环境配置清单:
- Windows 10 虚拟机:启用最新补丁和Windows Defender。
- Ruby 2.x 环境:用于执行我们的混淆代码。
- Bash for Windows:利用Windows Subsystem for Linux (WSL) 或者Git Bash。
实验步骤
部署环境后,我们可以通过以下步骤进行实验:
- 脚本准备:将上述Ruby和Shell脚本保存并准备好执行。
- 防御策略分析:观察每一步操作Windows Defender的反应。
- 日志分析与调整:检查事件查看器的安全日志,调整脚本以尽量减少触发。
通过在这样的环境中反复演练,我们可以找到更可靠的AMSI绕过方法,并不断改进我们的攻击链。
0x4 绕过AMS的深度解析

动态加载与内存注入
AMSI主要通过静态扫描来检测恶意代码,因此动态加载和内存注入成为常见的绕过手段。攻击者可以利用以下方法来隐藏真实意图:
动态加载模块:
<pre><code class="language-ruby">require 'fiddle'
动态加载AMSI模块
amsi = Fiddle.dlopen('amsi.dll')
获取AMSI初始化函数指针
AmsiInitialize = Fiddle::Function.new(amsi['AmsiInitialize'], [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT)
动态调用
AmsiInitialize.call('AMSI Bypass', nil)</code></pre>
这种策略通过绕过静态扫描,将恶意代码搬运到内存中执行,极大提高了绕过成功率。
内存注入技术
利用Ruby Fiddle模块或Shell脚本,直接将代码片段注入到目标进程的内存中,从而避开了文件系统及常规的调用路径。
<pre><code class="language-shell">#!/bin/bash
使用dd命令模拟内存注入
dd if=/dev/zero of=/proc/self/mem bs=1 count=0 seek=$((0x$(printf %x $(date +%s))))</code></pre>
这种内存注入方法要求攻击者对系统内存结构有较好的了解,但一旦成功,几乎可以免受AMSI的干扰。
0x5 攻击者的智慧:经验分享
在实际操作中,绕过AMSI的方法并不是千篇一律的,需要根据目标环境不断调试。以下是一些个人经验分享:

- 环境摸底:在攻击之前,务必对目标环境进行详细的信息收集,确定防御软件版本及配置。
- 代码混淆:使用多层次的代码混淆技术,不仅仅局限于字符替换,还可以尝试逻辑层次的混淆。
- 动态分析:利用动态分析工具,在攻击过程中实时调整策略,避免触发安全机制。
- 测试与改进:在虚拟环境中反复测试,确保攻击链的每一步都经过验证,才能在实战中发挥最大效果。
通过这些技巧和经验的分享,我们不仅可以绕过AMSI的防御,还可以为自己的攻击链增添更多的不可预见性。记住,攻击的艺术在于掌握变化并适应它。
合法声明:本文中提到的技术和方法仅限于合法的渗透测试和安全研究,读者需在遵守法律的前提下学习和使用。