InsecurePowerShell:不用類庫System.Management.Automation
長期以來,大家可能認為PowerShell實際上就是System.Management.Automation.dll,但我們在這裡將介紹不使用該類庫前提下的PowerShell腳本執行方法,具體而言就是藉助InsecurePowerShell。
不依賴powershell.exe的PowerShell腳本執行
首先,我們要對本文的標題進行一下解釋。本文中的內容源自於大量有關「不依賴powershell.exe的PowerShell腳本執行」的相關研究。我們在研究中發現,powershell.exe進程只是為System.Management.Automation.dll的實現提供了一個DLL Host。而它的核心,實際上就是System.Management.Automation.dll,這也是PowerShell的真實身份。此外,還有其他本地Windows進程同樣也作為PowerShell的Host,比如powershell_ise.exe。
然而,我們也可以創建自己的進程來為System.Management.Automation.dll提供Host。目前已經有一些開源項目實現了這一點,例如UnmanagedPowerShell,(https://github.com/leechristensen/UnmanagedPowerShell)、SharpPick(https://github.com/PowerShellEmpire/PowerTools/tree/master/PowerPick/SharpPick)、PSAttack(https://github.com/jaredhaight/PSAttack)以及nps(https://github.com/Ben0xA/nps)。
當然,使用PowerShell的優勢之一在於,PowerShell.exe是經過微軟簽名的二進位文件,會被應用程序加入白名單,方便我們的使用。而自己創建的進程則不會被應用程序所信任,但是通過這樣的方式,可以在powershell.exe被禁用的情況下執行PowerShell。
不使用System.Management.Automation.dll的PowerShell
在這裡,我們要重點介紹另一個開源項目InsecurePowerShell(https://github.com/cobbr/InsecurePowerShell)。既然我們想要創建一個新的進程作為PowerShell的Host,就不一定再繼續使用System.Management.Automation.dll,我們可以對其進行修改,並為修改後的版本提供Host。另外,希望大家了解的是,PowerShell目前新加入了很多安全特性,特別是在v5版本中,其中包括:腳本塊日誌(ScriptBlock Logging)、模塊日誌(Module Logging)、轉錄日誌(Transcription Logging)、反惡意軟體掃描介面(AMSI)、受限語言模式(Constrained Language Mode)等。而上述所有這些安全功能,都是在System.Management.Automation.dll中實現的。
我們理想的System.Management.Automation.dll,最好是帶有最新版本的PowerShell支持的全部功能,同時沒有任何安全防護功能。我們如何得到這樣的修改後版本呢?事實上,InsecurePowerShell就可以做到這一點。所以到現在,大家應該已經理解了我們標題的含義,所謂的「不使用」 System.Management.Automation.dll,實際上是不使用默認的System.Management.Automation.dll。
InsecurePowerShell是開源項目PowerShell Core v6.0.0的一個分支,僅對其進行了一些修改。InsecurePowerShell從PowerShell中刪除了下列安全功能:
AMSI:InsecurePowerShell不會將任何PowerShell代碼提交給AMSI,即使是在有主動監聽的反惡意軟體產品(AntiMalware Provider)的情況下。
PowerShell日誌記錄:InsecurePowerShell將禁用腳本塊日誌、模塊日誌和轉錄日誌。即使已經在組策略中啟用這些日誌記錄,也會在InsecurePowerShell中被忽略。
語言模式:InsecurePowerShell始終以全語言(Full Language)模式運行PowerShell代碼。如果嘗試將InsecurePowerShell設置為約束語言(Constrained Language)、限制語言(Restricted Language)等備選語言模式,實際上將不會產生任何作用。
ETW:InsecurePowerShell不使用ETW(Windows的事件跟蹤)。
使用方法
InsecurePowerShell的編譯方式與PowerShell Core版本完全相同,所以我們可以通過完全一樣的方式使用。InsecurePowerShell的發行版本中包含一個名為pwsh.exe的二進位文件,該文件就是PowerShell.exe的替代,和標準PowerShell和新版本的用法相同。我們可以以交互的方式使用,也可以非互動式地藉助-Command或者-EncodedComand參數使用。
以下是如何使用pwsh.exe的示例:
PSnC:InsecurePowerShell> .pwsh.exennPowerShellnv6.0.0-rc.2-67-g642a8fe0eb0b49f4046e434dc16748ea5c963d51nnCopyrightn(c) Microsoft Corporation. All rights reserved.nnhttps://aka.ms/pscore6-docsnnTypenhelp to get help.nnPSnC:InsecurePowerShell> $Execution.SessionState.LanguageMode =nConstrainedLanguagennPSnC:InsecurePowerShell> $Execution.SessionState.LanguageModennFullLanguagennPSnC:InsecurePowerShell> Get-WinEvent -FilterHashtablen@{ProviderName="Microsoft-Windows-PowerShell"; Id=4104} | % MessagennCreatingnScriptblock text (1 of 1):nn.pwsh.exennScriptBlocknID: 877d94f3-4bb5-4a26-88e3-58bb8091e1d8nnPath:nnCreatingnScriptblock text (1 of 1):nnpromptnnScriptBlocknID: 72983606-2c4d-4266-808c-280c718550c4nnPath:n
InsecurePowerShellHost
除了這個與powershell.exe非常相似的複製版本pwsh.exe之外,我還創建了一個名為InsecurePowerShellHost的.NET Core應用。正如大家看到的那樣,InsecurePowerShellHost是在InsecurePowerShell創建的應用,用於為修改後的System.Management.Automation.dll提供Host。InsecurePowerShellHost只能藉助–Command和–EncodedCommand參數非交互使用。在InsecurePowerShell上,使用InsecurePowerShellHost的主要優勢是,相比於InsecurePowerShell的完整構建,它是一個更為輕量級的工具。
以下是如何使用InsecurePowerShellHost的示例:
PSnC:InsecurePowerShellHost> .InsecurePowerShellHost.exennusage:nInsecurePowerShellHost.exe [--EncodedCommand encoded_command | --Commandncommand]nnPSnC:InsecurePowerShellHost> .InsecurePowerShellHost.exe --Commandn"`$Execution.SessionState.LanguageMode = ConstrainedLanguage;n`$Execution.SessionState.LanguageMode"nnFullLanguagen
總結
InsecurePowerShell和InsecurePowerShellHost是非常簡單的概念,並沒有太多突破性的技術。同時,它還存在著一些缺點,應該不會被廣泛應用於實際攻防場景之中。然而,我想要證明的一點是,我們可以創建一個定製版本的PowerShell,在無法將自己的應用程序加入白名單的情況下,轉換一種思路,使用不包含安全特性的應用程序。我認為,InsecurePowerShell很好地證明了這一觀點。
在這種思路的引導下,讓我們來談談使用InsecurePowerShell的優缺點。
InsecurePowerShell的優點
1. 不包含安全功能的PowerShell:這是目前它最大的優勢所在,InsecurePowerShell能夠運行不具有安全功能的PowerShell,沒有AMSI、腳本塊記錄、模塊記錄和轉錄記錄。
2. 具有良好的兼容性:作為.NET Core應用程序,我們可以在Windows 7 SP1、Windows 8.1、Windows 10、Windows Server 2008 R2 SP1、Windows Server 2012和Windows Server 2016上運行InsecurePowerShell。
3. 具有PowerShell Core 6.0版本的全部功能:作為攻防人員,我們為了避免PowerShell的安全特性,最常使用的是PowerShell的2.0版本。但藉助於InsecurePowerShell,我們就不再受到版本的限制,可以暢通無阻地使用6.0版本的所有功能。
InsecurePowerShell的缺點
1. 需要接觸到磁碟:作為.NET Core應用程序,我們不僅需要將二進位文件放到磁碟上,同時還需要放置支持.NET Core所需的DLL文件。儘管這些文件大多是經過微軟簽名的,但我們還是更傾向於盡量減少對磁碟的接觸。事實上,InsecurePowerShell完全不符合攻擊過程中的「離地原則」。
2. 不使用應用程序白名單:InsecurePowerShell不會使用一個強大的應用程序白名單作為解決方案,因此我們也失去了powershell.exe的一個巨大優勢。
3. PowerShell Core並不是Windows PowerShell:我們要知道,InsecurePowerShell是PowerShell Core的一個分支,並不是Windows PowerShell。而Windows PowerShell和PowerShell Core之間,並不會進行功能校驗。因此,可能會在使用InsecurePowerShell的過程中出現一些實際問題,預先準備的PowerShell工具可能無法在PowerShell Core中正常工作。
防護方式
InsecurePowerShell和InsecurePowerShellHost都需要將二進位和DLL文件放入磁碟。因此,只需要將修改後的System.Management.Automation.dll加入黑名單,就能夠實現防護。並且,你也可以同時將舊版本的System.Management.Automation.dll加入黑名單,特別是攻擊者經常使用的2.0版本,這樣就多了一份保障。
儘管,黑名單是一個快速、簡單的防護方式。但如果想要徹底進行防護,我們還需要一個應用程序白名單的解決方案。事實上,攻擊者只需要重新編譯一下InsecurePowerShell和InsecurePowerShellHost,就能不再受到黑名單的限制,這個過程也非常簡單。
後續計劃
InsecurePowershell的原理非常簡單,因此我並不打算做太多的後續維護工作。但是,有一些有意思的內容可以增強我們的InsecurePowerShell,因此我可能會在以後對其展開深入研究。
1. 動態載入程序集:我將研究過程中的絕大部分精力都放在嘗試在InsecurePowershell上創建一個能動態載入修改後System.Management.Automation.dll和.NET Core DLL的二進位文件,希望藉此,能讓InsecurePowershell作為單獨的二進位文件進行分發。然而,這個過程比我預期的更為困難。目前來說,InsecurePowerShell作為一個ZIP文件存在,必須將其解壓縮成多個文件後再運行。在以後,我將會繼續這方面的研究,目標是讓其變成只有一個文件。
2. PowerShell Core代理:假如我們擁有一個完整的PowerShell C2代理,可以與PowerShell Core兼容,會讓我們的實際使用過程非常方便。然而,由於Windows PowerShell和PowerShell Core之間沒有功能校驗機制,會導致大多數已有的PowerShell C2代理出現問題。 我打算對該問題進行研究,並嘗試解決。
InsecurePowerShell的源代碼請參見:https://github.com/cobbr/InsecurePowerShell ,InsecurePowerShellHost的源代碼請參見:https://github.com/cobbr/InsecurePowerShellHost 。
登錄安全客 - 有思想的安全新媒體www.anquanke.com/,或下載安全客APP來獲取更多最新資訊吧~
推薦閱讀: