不可阻擋的PowerShell :Red Teamer告訴你如何突破簡單的AppLocker策略

從目前的攻擊發展趨勢來看,攻擊者已經比大多數防禦者或系統管理員更喜歡使用PowerShell。像Powersploit,Veil Power *和Nishang這樣的工具的一些常規功能已經被Red Team,Pentesters,惡意攻擊者們所使用。隨著這種演變以及將技術整合成一種單一的腳本語言,防禦者能否發現一種方法來成功的阻止PowerShell的執行?當然,軟體限制策略(SRP)或AppLocker確定能起到作用嗎?不要肯定那麼早哦…

經過實踐評估後,我發現在我們拿到一個域用戶,本地提權,竊取憑據,注入payloads,並繼續在域中滲透時幾乎每一步都在使用PowerShell。可是,我們總有惡夢的一天,會有人能夠有效地限制PowerShell的執行並且那些老技巧肯定會失效。從我與防禦者或信息安全愛好者的交流中,他們防禦PowerShell的意識和技術正在上升,人們終於開始注意到PowerShell攻擊工具的常規發布,以幫助發動攻擊。這就是說,直到在不需要的系統上禁用PowerShell成為企業的常規做法之前,攻擊者仍然可能會取得勝利。從這一點上來說,在防禦者考慮將實現的防禦方案所需的時間/成本最小化到一個點前,PowerShell的限制不太可能發生。

下面是一些之前關於使用 PowerShell 進行攻擊的研究︰

1. FireEye在黑帽大會發布的白皮書 —— 包括與PowerShell攻擊有關的事件響應和討論。這份paper寫的非常好!在與演講者關於一些防禦方案的談話討論中我獲益匪淺。我希望以後能再參與這樣的活動。

2. Crowdstrike 發布的關於DeepPanda的報告 —— 這是一份APT攻擊者使用 PowerShell 進行攻擊的報告。

3. PowerShell武器化 —— PowerShell武器化是 harmj0ys 發表的一篇很好的關於繞過執行限制的博文。

4. PowerShell 基礎知識 —— Carlos Perez的PowerShell教基礎程。絕對值得一讀。

5. Powersploit Github —— 攻擊 PowerShell 用戶的必需工具。

防禦者的方法 — 「使用Applocker限制PowerShell」

免責聲明:本文不是AppLocker的使用指南。後面你會看到,這是一個指導你什麼事情不可以做的文章! 此外,我不是微軟認證系統工程師(MSCE)也不是什麼微軟專家。下文會有正確配置AppLocker以防止PowerShell運行的方法…但是如果有人已經公開過了,我就不會再做過多的說明了! 畢竟我Google的平均次數和其他網路防禦者一樣多。

AppLocker是Microsoft提供的用於「企業應用程序控制」的解決方案。它的目的是限制不必要的軟體的運行,並提供了各種方法來實現這一點。它允許你通過指定路徑,文件哈希或應用程序發布者來限制可執行文件,DLL,安裝程序或腳本等策略以限制程序正常運行。生成的策略由組策略推送並進行集中管理。

顯然,在可用性和安全性之間需要一直強調「平衡」,但是我發現在這裡有必要提到一點,那就是使用AppLocker的最佳設置可能是利用白名單的方式。企業組織可以分析他們的標準構想方案和構建策略來匹配此構想方案。也就是說,CEO不可以安裝他們想要的P2P軟體,用戶將無法運行魔獸世界,技術支持會增加3000%的電話求助量(這很嚴重,希望他們永遠都不工作…但我肯定讚賞他們所做的工作!)。基於這個原因,企業組織仍然依靠基於黑名單的策略來防止使用net * .exe,cmd.exe和powershell.exe等程序的運行。

為了演示的目的,我打算模擬一個企業組織使用AppLocker的黑名單方式限制程序運行。我的目標是使用AppLocker來儘可能多的阻止PowerShell並測試適當的措施來繞過黑名單限制。

我用Windows 7系統進行測試。我將執行以下操作嘗試設置和保護我的測試機:

1. 啟動應用程序身份驗證服務

2. 通過哈希拒絕以下可執行文件並添加相應的可執行文件規則:

C:windowssystem32WindowsPowerShellv1.0powershell.exenC:windowssystem32WindowsPowerShellv1.0powershell_ise.exenC:windowsSyswow64WindowsPowerShellv1.0powershell.exenC:windowsSyswow64WindowsPowerShellv1.0powershell_ise.exen

3. 添加通過路徑拒絕:* .ps1 *的腳本規則

4. 在DLL規則中啟用「強制」(AppLocker->屬性)

5. 添加通過哈希拒絕以下DLL的DLL規則:

· C:Program FilesReference AssembliesMicrosoftWindowsPowerShellv1.0Microsoft.PowerShell.Commands.Management.dlln· C:Program FilesReference AssembliesMicrosoftWindowsPowerShellv1.0Microsoft.PowerShell.Commands.Utility.dlln· C:Program FilesReference AssembliesMicrosoftWindowsPowerShellv1.0Microsoft.PowerShell.ConsoleHost.dlln· C:Program FilesReference AssembliesMicrosoftWindowsPowerShellv1.0Microsoft.PowerShell.Security.dlln· C:Program FilesReference AssembliesMicrosoftWindowsPowerShellv1.0System.Management.Automation.dlln

6. 測試並確保以上配置工作已經生效!

繞過AppLocker鎖定應用程序的解決辦法

我最近了解了PowerShell攻擊的世界,所以只會在這一方面提示一些東西。 我之前聽到有人討論如何繞過關於PowerShell的AppLocker規則的方法。 就我個人而言,我感謝harmj0y給予的支持並提示給我正確的研究方向。 我也知道許多想法和一些來自「darkoperator」的初步的研究發現以及其他幾個討論PowerShell攻擊的社區。 感謝那些分享相關技術的人,為我鋪平了道路。 如果你有更好的方法我非樂意聽到!

PowerShell可以通過.NET框架和Windows公共語言介面(CLI)提供後端訪問功能。開發人員非常喜歡這種可擴展性,網上存在著許多如何使用這些功能來創建實用程序來做有趣的系統廣告之類的事情的示例代碼。不過,很少有人意識到,相同的代碼可以用於將PowerShell打包並作為繞過AppLocker限制的解決方法。

閱讀這篇文章,了解如何在C#中調用PS腳本。

首先,我必須配置我的項目並添加引用自動化程序集:

1. RC引用 – >添加引用

2. 瀏覽並選擇下面的文件路徑:

C:Program FilesReference AssembliesMicrosoft Windows PowerShellv1.0System.Management.Automation.dlln

為了從資源載入PowerShell代碼,我必須首先創建一個資源:

1. 打開Resources.resx

2. 添加字元串資源

3. 將字元串命名為「Script」

4. 將值設置為「Get-Process」或任何你想要執行的腳本

創建完項目後,我實例化我的Runspace並創建了將用於執行命令的管道(Pipeline)。

//Init stuff Runspace runspace = RunspaceFactory.CreateRunspace();nrunspace.Open();nRunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);nPipeline pipeline = runspace.CreatePipeline();n

接下來,從資源區段提取PowerShell腳本,並將其添加到管道中。 你也可以改變為從互聯網讀取PowerShell腳本或者加密的字元串等。在目標環境中,重要的是混淆或加密腳本以防止AV或HIPS查殺原始的腳本。 在磁碟上的腳本每時每刻都會被Read Teamer捕獲…

//Add commands string script = Properties.Resources.ResourceManager.GetString("Script"); pipeline.Commands.AddScript(script);n

要檢索腳本中的輸出,我將「Out-String」命令添加到管道中並抓取了返回對象。 使用string對象對這些對象進行迭代遍歷以返回最終輸出的字元串。

//Prep PS for string output and invokenpipeline.Commands.Add("Out-String");nCollection results = pipeline.Invoke();nrunspace.Close();n//Convert records to stringsnStringBuilder stringBuilder = new StringBuilder();nforeach (PSObject obj in results) {n stringBuilder.AppendLine(obj.ToString());n}nConsole.Write(stringBuilder.ToString());n

編譯這個可執行文件並把它放到測試環境中,將會帶來驚人的結果,它運行成功了。 儘管運行著針對限制PowerShell執行的所有預防措施,可是我們的可執行文件依舊能夠訪問API並運行我們選擇的任何腳本。 我主要將它與Veil-PowerView進行了測試。 20行的C#代碼展示了一個相當基本的POC。 不過這個繞過方式有一些明顯的缺點…

1. 在磁碟上寫入了攻擊腳本(儘管腳本可以從互聯網獲取)

2. 託管代碼,.NET代碼很容易被反編譯

3. 如果環境配置的是白名單方式這種繞過方式將會失效

阻止惡意程序執行的解決方法

這太簡單了…對.NET的嚴重依賴使我有信心有一個簡單的方法來阻止惡意程序運行。 在我的測試環境中,我在Process Explorer和Process Monitor中花了一些時間挖掘我的惡意應用程序。 我確認自定義可執行文件正在載入.NET程序集以完成PowerShell執行。 用Microsoft的話來說,「程序集是.NET Framework的構建的一部分」。 本質上,程序集是構成CLI的庫的一部分。 在大多數情況下,程序集存儲在C:WindowsAssembly的全局程序集緩存(GAC)中。 事實上,.NET會在運行時載入程序集,而不是在初始化應用程序時執行。 當我執行代碼時,就可以觀察到載入程序集的時機。 下面是我觀察到的文件句柄示例:

·C:WindowsassemblyGAC_MSILMicrosoft.PowerShell.Commands.Diagnostics1.0.0.0__31bf3856ad364e35Microsoft.PowerShell.Commands.Diagnostics.dlln·C:WindowsassemblyGAC_MSILSystem.Management.Automation1.0.0.0__31bf3856ad364e35System.Management.Automation.dlln

快速切回到AppLocker,我將所有來自GAC的PowerShell特定的程序集添加到了拒絕策略列表中,然後通過驗證文件哈希進行載入阻斷。 為了獲得在AppLocker中被阻止的程序集DLL文件並允許explorer進程訪問後端程序集庫,我需要禁用「緩存查看器」功能。 如果你想使用拖拽式安裝程序集,記得一定要確保重新啟用這個功能。 註冊表命令如下:

reg add HKLMSoftwareMicrosoftFusion /v DisableCacheViewer /t REG_DWORD /d 1n

由於某種原因,程序集拒絕策略仍然無法有效的阻斷我的惡意應用程序的執行。 起初我想這可能是因為DLL被隱藏在程序集中所導致的,但是在測試之後,結果證明並不是這樣。 我想可能是其他程序集DLL被阻止了。 有關更多信息,請參閱後續部分! 我可以找到的唯一一個可以成功阻止.NET程序內嵌PS代碼執行的DLL,對應的AppLocker DLL規則是:

C:WindowsMicrosoft.NETassemblyGAC_32System.Transactionsv4.0_4.0.0.0__b77a5c561934e089System.Transactions.dlln

這個規則阻止了我的惡意腳本的執行,但是被阻止的DLL是負責所有事務類(也就是提供創建資源管理器的功能)的庫。 這是一個不合理的阻止方式,因為許多合法的.NET應用程序都需要資源。 最後的結論就是:重命名或移動 PowerShell 程序集。

mkdir c:windowsassemblydisabled move c:windowsassemblyGAC_MSILMicrosoft.PowerShell.Commands.Management1.0.0.0__31bf3856ad364e35Microsoft.PowerShell.Commands.Management.dll c:windowsassemblydisabledn

顯然,這起作用了,它阻止了我的惡意應用程序的執行。不過在我看來,這是一個有限的解決方案,因為它不夠靈活,配置時需要安裝/卸載程序集。理想的方案是具有可配置的策略以允許某些用戶使用該程序集或在某些情況下阻止標準用戶的使用。

*關注一下*(下面的內容是本文發表後才添加的)

本文發表之後,最初,幾個人通過twitter參與了討論。 在進一步深入之前,我必須聲明,最好的方案是基於白名單的策略。黑名單往往考慮的不夠周全,而且很可能會被專門研究繞過方法的攻擊者繞過。 這篇文章只是為了演示。 也就是說,我很少發現有公司使用任何類型的AppLocker策略。

非常感謝Lee Holmes(@Lee_Holmes)和Carlos Perez(@Carlos_Perez)後續在Twitter上的討論。Lee Holmes深挖了一下,為什麼我在DLL黑名單模式下無法成功獲得PowerShell程序集。他測試了我的黑名單策略並結合使用AppLocker審計模式和Windows事件日誌來檢測哪些DLL被載入和阻止了。這肯定有助於縮小你的阻止列表範圍。在測試了這個方法後,我可以保證它的確很有用。

要將.NET程序集(特別是PowerShell程序)列入黑名單,必須阻止與該程序集相關的所有DLL。這包括GAC_MSIL和NativeImages中的DLL(如果它們都存在的話)。要發現與PowerShell程序集相關的的DLL,可以在PowerShell中運行如下命令:

[PSObject] .Assembly.Locationn

在.NET程序集中還有幾種不同的PowerShell依賴,所以請自己檢查一下。使用這種方法,我就能夠阻止.NET導入的程序集DLL的執行。

本文參考來源於sixdub,如若轉載,請註明來源於嘶吼: 不可阻擋的PowerShell :Red Teamer告訴你如何突破簡單的AppLocker策略 更多內容請關注「嘶吼專業版——Pro4hou」

推薦閱讀:

PowerShell指令為什麼都要採用 Verb-XXXX 的格式?
乾貨 || Windows Shellcode學習筆記——棧溢出中對jmp esp的利用與優化
PowerShell 與 cmd 有什麼不同?
AppDomainManager後門的實現思路

TAG:PowerShell | 技术分析 |