password
status
date
icon
category
tags
slug
summary

0x00 混淆代码

对于 powershell 绕过 AMSI 来说,混淆代码是绕过 AMSI 最基础的步骤,因为大部分绕过方法还是要执行 AMSI 语句,这个用来绕过的语句本身也是要被 AMSI 检测的,所以要对这个绕过语句进行混淆处理。
这块严格来说不是绕过 AMSI,而是绕过 AMSI 对接的安全产品的规则,自带的 windows defender 的规则非常容易绕过。

攻击姿势

经过简单的分割测试,可以确定有如下规则
  • 字符串 'AmsiUtils'
  • 字符串'amsiInitFailed'
  • 同时出现 [Ref].Assembly.GetType GetField SetValue($null,$true)
powershell 语法极为灵活,下面简单列举几种绕过的方法。
使用 like 避免出现完整字符串 + 拆分成多条语句避免同时出现关键字
对方法名进行字符串拼接
拆分成变量
除了手动混淆,也可以使用专门的混淆工具,如:https://github.com/danielbohannon/Invoke-Obfuscation
不过要注意,一些混淆手法是对命令进行加密,再利用Invoke-Expression 执行解密的命令,这样是无法绕过 AMSI 的,因为Invoke-Expression 执行的命令将会被 AMSI 检测,效果如下:
notion image

检测方法

对于分割绕过,可以将同一 powershell 进程执行的多条命令合并后进行检测。
因为 AMSI 需要快速响应,所以很难使用高级检测方案,我的想法是阻断规则和告警规则可以分开,阻断规则就是高性能的正则表达式或者关键字,检测完成后直接返回给 AMSI,避免程序卡死,然后再进行相对耗时的高级检测,将检测结果发往服务端。
  • 使用语法树判断 powershell 代码是否混淆,正常业务一般不会混淆 powershell 代码,所以检测到混淆行为就可以直接告警个低危。(也许需要对一些业务混淆加白)
  • 静态反混淆
    • https://github.com/pan-unit42/public_tools/tree/master/powershellprofiler
  • 动态反混淆 - powershell 沙箱
    • 静态反混淆容易被一些动态特性击败,可以对 powershell 进行二开,做成 powershell 沙箱,真正的获取语句执行的操作。

0x01 降级攻击

降级PowerShell版本到 2.0 可以绕过 AMSI,因为这个版本的 powershell 还没有引入 AMSI 机制。
PowerShell 2.0 基于.NET CLR 2.0,对应的 .NET 版本是 2/3/3.5,这在现在的系统上预装的并不多,可以用以下命令查看安装的 .NET 版本。
早期的部分 win10 预装了 .NET 3.5

攻击姿势

使用 powershell.exe -version 2 改变版本。
在脚本开头加入 #requires -version 2 ,可以指定脚本使用 PowerShell 2.0 执行。

检测方法

检测进程启动事件是否有 -version 2 参数。
检测 powershell 脚本中是否有 #requires -version 2
感觉只要有这种行为,就可以给个中低危告警了,现在正常业务用 powershell 2 的情况太少了。

修改其他程序

0x02 修改注册表

对于 powershell、.NET 之外的 AMSI 检测,不少可以被注册表配置影响,比如 Jscript 对应的 Software\\Microsoft\\Windows Script\\Settings\\AmsiEnable ,wmi 对应的 Software\\Microsoft\\WBEM\\AmsiEnable
需要注意的是,这块微软做过多次修改,能不能生效要针对具体的windows版本来分析。
需要注意的是,在早期 win10 中,读取的是 HKEY_CURRENT_USER ,现在读取的是HKEY_LOCAL_MACHINE ,修改相关的注册表需要管理员权限。
此外,还可以直接删除注册表中注册的 Providers来影响 AMSI 正常运作。
HKLM:\SOFTWARE\Microsoft\AMSI\Providers

检测方法

监控修改相关注册表的行为。

0x03 反射

攻击姿势

PowerShell 将有关 AMSI 的信息存储在 System.Management.Automation.AmsiUtils 类内。通过反射与其进行交互。
前面几篇分析过,powershell 在进行 AMSI 扫描时会对 amsiInitFailed 进行判断,如果为 true 则直接跳过扫描。那么可以使用反射访问 AmsiUtils 类中的amsiInitFailed ,将其直接设置为 true
混淆后
前文还提到 AmsiOpenSession 的参数检查,如果 amsiSession 的指针或 amsiContext 为 NULL,或者 amsiContext 的第二和第三个 _QWORD 为0,则返回错误代码 -2147024809
那么就可以通过反射获取amsiContext 的地址进行修改,将第二_QWORD 修改为0。
在 win10上,还有个判断验证的是 amsiContext 的第一个 DWORD 值是否为 'AMSI',这个判断在 win11上被去除了。
在 win10 可以对amsiSession 赋值为 NULL 进行绕过, 在 win11 上并不可以,使用 dnspy 分析代码可以发现 win11 上每次的 amsiSession 都是从新从 amsiContext 中取出的。

检测方法

  • 使用反混淆分析语句
  • hook SetValue,检测设置 amsiInitFailed 值的行为。

0x04 修补

从内存中修补 Amsi.dll 也是常用的绕过的手法。

AmsiInitialize

AmsiInitialize 在执行命令前就已经执行,但可以修补后执行 AmsiUninitialize 重新触发 AmsiInitialize
AmsiInitialize 较为复杂且版本差异大,攻击者一般不会考虑修补这个函数的逻辑来绕过,以下仅为研究使用。 (实战要修补的话应该也是修补为强制失败,见后文)
AmsiInitialize 存在如下汇编,可以通过修补满足两个跳转条件,强制跳转返回 80070057h
以下脚本内容为获取内存地址、修改内存权限、修补对应内存
触发重新初始化,完成绕过
更通用的绕过脚本,强制返回错误代码

AmsiOpenSession

这是一个比较好的修补对象,在win10和win11上的变化很小,且逻辑较为简单,只要满足第一个跳转条件就可以直接返回报错。
test rdx,rdx 修补为 xor rax,rax
脚本如下

AmsiScanBuffer

逻辑比较复杂,可以将函数开头修补为以下内容,以强制其返回错误代码,稍微混淆了下避免特征被匹配。
 

检测方法

  • 去混淆后识别攻击代码特征
  • 扫描 Amsi.dll 中特定地址
    • 性能比扫描整个 Amsi.dll 好点,不过攻击者能修改的位置是非常多的,比较容易被绕过。
  • 内存完整性检查
    • 对 Amsi.dll 的代码部分进行哈希处理,而不是对整个Amsi.dll模块进行哈希处理,与硬盘上 Amsi.dll 的代码部分进行比较。
    • 考虑到性能问题,扫描频率不可能太高,攻击者有可能在完成攻击后将 amsi 修改回去(仅对短时间就能完成目的的攻击有效)。
    • 瞬间修改 Amsi.dll 造成永久失效 (在win10上修改后再改回来可以永久失效,但 win11上不行,win11 每次执行时发现AMSI失败会重新初始化。
      • 经过研究,只要修补AmsiInitialize保证初始化成功但没有执行加载杀毒软件的dll,还是可以在win11瞬间修改造成永久失效的,但这样修补不仅复杂且很容易受 amsi.dll 版本影响。
  • api监控,检测修改 Amsi.dll 内存权限、内存内容的调用。

0x05 ScriptBlock Shaulling

攻击姿势

简单来说,就是 PowerShell 中的所有的安全功能都只传递 ScriptBlockExtent ,但实际上还可以通过 BeginBlockEndBlock 执行代码。
可以用以下方法来创建 BeginBlockEndBlockExtent 不一致的代码块
利用方式
可以看到 AMSI 接收的结果和实际执行的命令并不一致
notion image
虽然这样也需要传入恶意命令,但与混淆那里的绕过不同的是,这里传入的恶意命令是字符串,不需要基于 powershell 语法混淆,可以随意进行混淆,解密后的代码不是通过 Invoke-Expression 执行的,也就不用担心

检测方法

检测操控 ScriptBlockAst 的行为,正常业务程序几乎不可能用到这个特性。

0x06 硬件断点(待学习)

攻击姿势

参考文章:

检测方法

参考文章:

0x07 修补其他程序

因为对 amsi.dll 的修改检测比较严格,所以出现了这种绕过思路。
修补杀毒软件的 amsi 提供程序对应的 dll。
修补调用 amsi.dll 的程序。

参考文章

300hero战场节奏榜AMSI研究(2) - 检测
公告
password
status
date
icon
category
tags
slug
summary
年轻时,你的潜力是无限的。说实在的,任何事都有可能做成。你可以成为爱因斯坦,也可以成为迪马吉奥。直到某一天,你身上的可能性消失殆尽,你没能成为爱因斯坦,你只是一个无名之辈。那真是糟糕的时刻。
🔮
所谓魔法不过是我们尚未了解的科学。
📚
潜心学习,低调发展。