本文詳細分析了Phoenix Contact交換機中FL SWITCH 3xxx、FL SWITCH 4xxx和FL SWITCH 48xx系列設備的CVE-2018-10731漏洞。此漏洞存在於設備的 Web界面中,可以在不知道設備憑據的情況下執行任意代碼,CVSS3.0等級評分爲9分。 

漏洞分析

上面提到的Linux,可以使用web界面對其進行配置。與許多其他家用和工業IoT設備一樣,web界面由許多處理用戶HTTP請求的 CGI應用程序組成。在本文的案例中,CGI應用程序使用cgic 庫,這使得處理 HTTP請求更加容易,並且該庫的功能內置在設備文件系統中的 libipinfusionweb.so 共享庫中。

在處理HTTP請求時,web 服務器將用戶請求數據作爲一組環境變量傳遞給 CGI 應用程序。它們的初始處理由 libipinfusionweb 庫中的 main 函數執行。接下來, main 函數調用CGI應用程序的 cgiMain 函數,在其中對請求進行進一步處理。

圖1.    處理HTTP請求     

在其工作過程中, libipinfusionweb 庫的main函數調用 get_login_user 函數,該函數確定用戶是否已使用傳遞的Cookie值通過了系統身份驗證。     

圖2. main函數代碼片段

函數 get_login_user 使用 cookies_get_value 函數獲取 c_session 參數的cookie值,並將其存儲在 local_e0 變量中。變量 local_e0 是一個長度爲 0×80的單字節字符數組,並且位於距堆棧開頭0xE0的距離處。

圖3.  get_login_user 函數代碼片段     

但是,從 cookies_get_value 函數的代碼中可以看出,使用 cgiCookieString 函數獲取的cookie參數值的最大長度爲0×400字節。    

圖4.  cookies_get_value函數代碼片段

因此,當傳遞長度超過0xE0(224)個字符的cookie參數時, get_login_user 函數會將此參數的值保存到其棧中,結果 local_e0 變量後面的棧上的所有信息將被覆蓋,包括函數返回地址。 

注意:當一個函數調用另一個函數時,返回地址存儲在棧中。當被調用函數完成時,控制權將轉移到該返回地址。因此,如果重寫此地址,則可以控制程序執行流程。例如,攻擊者可以使用位於程序地址空間中的惡意shellcode的地址替換此地址。

請注意,返回地址的覆蓋是在身份驗證之前進行的,這使得不知道設備賬戶的攻擊者也可能利用此漏洞。

我們考慮了幾種方法來證明利用此漏洞的可能性。最簡單的方法是將有效負載代碼寫到堆棧上(0×400-0xE0 =剩下800 字節,對於代碼來說足夠了),然後用代碼地址覆蓋返回地址。從理論上講這是可行的,因爲存在該漏洞的交換機處理器不支持NX位功能(也就是說,它允許執行位於包括堆棧在內的任何位置的代碼),但實際上存在嚴重限制。

這些交換機處理器具有MIPS架構,此體系結構中的許多處理器指令均以包含零字節的字節序列進行編碼。寫入到緩衝區的內容在遇到第一個空字節時結束(由於使用了strcpy函數 ),因此僅能使用不包含空字節的操作碼,但這是不可能的,因爲任何有效載荷都至少使用幾個空字節。

同樣,在構建 ROP鏈 時,也將不得不面對空字節的限制:ROP gadgets的地址不應包含零,這會使地址的搜索大大複雜化。總的來說,我們只能使用由 strcpy函數複製的一個零,這限制了完整ROP鏈的創建。此外,我們所需的gadgets 也非常少。但是,在搜索libipinfusionweb庫的時候發現了以下代碼片段:             

圖5.  libipinfusionweb庫的可執行代碼片段

假設寄存器$s0的內容受到控制,此代碼段使用 mysystem 函數使你可以執行OS命令(該函數最初沒有名稱,但我們將其重命名,因爲它與Linux中的system 函數非常相似)。 

由於我們正在覆蓋get_login_user    函數的返回地址,因此該函數將執行到最後。從 get_login_user函數的末尾中,可以看到寄存器$s0的值是從棧上先前保存的值恢復的(從棧頂部偏移0xD8 )。不過此時,棧區域已經在我們的控制之下,也就是說,實際上,我們可以實現對寄存器$s0內容的控制,從而可以使用 mysystem 函數執行任意 OS命令。            

圖6.  get_login_user函數可執行代碼片段        

因此,爲了成功演示此漏洞利用,需要發送的 c_session cookie 參數字符串應包含以下內容:

OS命令字符串,該命令隨後將傳遞給mysystem函數;

OS命令在棧上的地址;

新的返回地址(圖5所示的代碼片段的地址)

最終的有效負載應如下所示:

圖7. 有效負載     

至此,我們已經利用漏洞獲取了設備上的shell,該 shell需要管理員權限。因此,我們能夠獲得有助於後續操作的更多其他信息:

ASLR在此研究設備上被禁用,因此,所使用的gadget和OS命令的地址將始終相同。

圖8. 被研究設備上的ASLR狀態

堆棧可能位於的內存地址範圍。爲了計算確切的地址,我們遍歷了該範圍內的所有地址。

作爲有效負載,我們實現了web shell—CGI應用程序的加載,其內容如下:

#!/bin/sh
eval $HTTP_CMD 2>&1

由於根據 CGI協議,HTTP標頭的內容以名稱爲HTTP_<Header Name> 的環境變量的形式傳輸到CGI 應用程序,因此該shell 將使用 eval 命令執行HTTP 標頭CMD的內容。下圖顯示了使用已加載的shell 成功運行和執行ls 命令的結果。                

圖9.  ls命令成功運行和執行的結果     

本文展示了利用此漏洞的能力,正如我們已經提到的,其操作不需要知道密碼,因此甚至可以由未經身份驗證的攻擊者執行。

入侵工業網絡交換機可能會破壞整個網絡環境,網絡交互中斷會對進程產生不利影響,直到它完全停止。

譯文,原文請參考: https://habr.com/ru/company/pt/blog/493944/

*本文作者:bey0nd,轉載請註明來自FreeBuf.COM

相關文章