您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關如何深入分析MikroTik RouterOS CVE-2018-14847 ,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
MikroTik路由器在4月份被發現存在目錄遍歷漏洞CVE-2018-14847,危險程度為中。Tenable Research的專家于10月7日在DerbyCon上發表了題為“Bug Hunting inRouterOS”的演講,介紹了這項新技術,就是利用該漏洞。目前結合該漏洞的黑客工具已放出,運行RouterOS的MikroTik設備成為惡意代碼的目標。
本文從MikroTik RouterOS與客戶端的通信協議入手,輔以逆向分析,深入解讀了CVE-2018-14847以及內置開發者后門的漏洞原理,最后進行完整的組合拳進階利用,達到Get bash shell的目的。整體流程圖如下:
MikroTik RouterOS是一款基于Linux核心開發,兼容Arm,mips,x86 PC等多種架構網絡設備操作系統。通過安裝該操作系統可以將標準的PC電腦變成專業路由器,也就是平時常說的軟路由。同時,RouterOS提供了豐富的管理配置接口:1)winbox:GUI軟件管理; 2)cli:命令配置;3)webfig :網頁圖形化管理。而Winbox for MikroTikRouterOS是一個用于管理MikroTik RouterOS系統的 GUI客戶端應用程序。
RouterOS官方提供了相應的ISO系統鏡像包,所以可以像安裝正常操作系統一樣安裝RouterOS,直接在vm中安裝一個虛擬機。
通過CliTelnet的方式對RouterOS進行配置,但是要知道以下兩點:
?這不是一個osbash shell,不能訪問到底層的linux的操作系統
?只能利用內置的一些命令集對RouterOS進行配置和管理
從下圖的nmap掃描結果可以看可以看到RouterOS專門提供了8291端口跟winbox通信。
漏洞原理是怎么的呢?要理解漏洞的原理,首先得需要理解Routeros與winbox的通信過程,本文先從webfig和Routeros的通信過程入手。
訪問webfig,首先請求的一個js文件,下載來美化后看看代碼:
代碼很多,17000行左右。大致瀏覽了一下,可以看到webfig與RouterOS之間所有的通信消息都是由這個js文件產生和處理。 初始化相關代碼:
登錄、認證相關功能,相關的POST數據包都發送到RouterOS的jsproxy處理, 這里的jsproxy就相當于jsp中servlet一樣。
但當查看這些數據包的時候,發現POST是加密的,同樣返回的數據也是。
而其中的加密算法在js文件中可以找到:
其中的產生56位key的算法采用的是RFC 3079 MS-CHAP-2 。
這是一個很老的PPP協議(存在離線碰撞破解漏洞)
從js代碼和數據包可以看到采用的身份認證方式是:提問/應答(Challenge/Response)方式。
至此,筆者來完整地梳理一下整個認證的流程:
客戶端首先發送一個空的POST請求給服務器。
服務器收到后發出Challenge(提問):
客戶端利用輸入的賬號密碼采用MS-CHAP-2算法生成通信key,再利用這個key使用RC4加密生成Reponse(應答),發給服務器。
服務器將客戶端的應答利用自己計算的出的key解密,能解出來則認證成功。接下的通信數據包就是全是用這個認證成功的key加密的Content-type為msg的POST數據包。
理清楚認證過程,就可以來考慮下數據包怎么解密?
思路總結成兩步:
1. 離線暴力從登錄數據包中碰撞出賬號密碼。
2. 利用碰撞出的賬號密碼生成key解密其余通信數據包。
至此我們已經拿到解密之后的數據包了,可以看到是json格式的。但是這些數據的含義還是一臉懵逼的。雖然js文件存在一些映射關系,但是要理解這些數據的含義還得加上逆向+仔細看代碼+可能存在的文檔:
這里筆者直接就把Tenable的分析報告當文檔,可以到每一個key-value鍵值對都是由如下幾部分組成:
而其中type可以取如下值:
而其中一些常見變量名的含義如下:
OK,結合上面的文檔繼續分析,發現Uff0001 system_to這個變量的值是一個數組[13, 7],當RouterOS接到這條消息后jsproxy會做一次映射,最終找到/nova/bin/下的對應可執行程序來處理這條消息。
具體怎么映射的呢? 在RouterOS中有一個叫/nova/etc/loader/system.x3的二進制文件,我們直接cat查看下:
雖然找不到具體的映射關系,但是可以知道映射關系就存儲在這個文件中。Tenable通過分析對應的文件格式和內容,得到了對應的映射方式:
并開發了一個提取數字到可執行文件對應關系的程序,筆者利用該程序得到對應的映射結果:
也就是說數組[13,7]中的13最終調用的是/nova/bin/user,那么剩下的7代表什么?繼續往下看:
因為沒有用livecd的方式將RouterOS的文件系統掛載出來,所以只有利用binwalk把官網的iso鏡像包中的文件系統提取出來:
用ida打開nova/bin/user,通過逆向分析,發現calls to nv::Looper::addHandler是調用handler的關鍵代碼,總共有八處這樣的調用:
并且其傳入的參數可為3,2,1,4,5,6,7,8,數組第二項的值正好在其中:
部分匯編代碼:
也就是說[13,7]中兩項分別對應:[/nove/bin/下的一個二進制程序,二進制程序中對應的handler]。 繼續跟進,發現7對應的handler中有如下具體的方法:
至此,{Uff0001:[13,7],uff0007:16646157,s1:'admin'} 這條json消息中第一個鍵值對的值就搞清楚了,接著看第二個uff0007:16646157。通過前面的變量名對應關系,可以知道uff0007代表的是命令,也就是對應上面handler中具體的分支。
這里Tenable也給出了一份具體的映射關系:
16646157對應著Get命令,跟進看看Get command:
其中進了很多函數,這里就不一一細致分析了,但可以看到此函數實現的最主要功能點就是:獲取json消息中傳入的用戶名字符串admin的對應用戶信息。
理清楚整個通信過程以及json消息的含義之后,正式開始漏洞分析。 漏洞發生在winbox和RouterOS的通信中,經過分析發現其數據包的本質還是與webfig與RouterOS之間的通信一樣,采用的是json消息的形式,對應的參數含義都是一致的,甚至winbox的數據包沒有加密,只是將json按照一定規則轉化成了二進制形式利用TCP進行傳輸。
所以同樣可以將winbox的二進制數據包轉化成JSON形式:
轉化出來的第一條json消息就對應著exp中list a 中的二進制payload:
ok,這下就是熟悉的json格式了,重點關注以下幾個變量的值:
找到Uff0001:[2,2]對應的二進制程序和對應的handler:
繼續跟進uff0007:7, 由前面可知這鍵值對的含義是command變量值為7。ok,繼續找handler 2中的怎么處理7命令的,首先先找到handler 2,其中箭頭所指函數就是處理command 7的函數:
跟進這個函數,是一個switch分支,找到case 7,可以看到當變量值為7時打開了一個/home/web/webfig下的文件,并將這個文件的大小和一個session id作為返回值(由于代碼太長了筆者只截取了關鍵部分):
對應著RouterOS回應的第一條json消息:
就按這樣的思路繼續逆向分析,發現commoad可以取以下七個值,分別實現了不同的功能(由于篇幅原因就只截取了部分功能的關鍵代碼):
1. Opens a file in /var/pckg/ for writing.
2. Writes to the open file.
3. Opens a file in /var/pckg/ for reading.
4. Reads the open file.
5. Cancel transfer (and deletes the file).
6. Creates a directory in /var/pckg/.
7. Opens a file in /home/web/webfig/ for reading.
這樣exp中發送的第二條二進制payload就好理解了,含義就是:帶上RouterOS返回的SessionID和文件大小(PS: 至于為啥要帶上這兩個,上面的代碼已經很清楚,RouterOS對這兩個值做了驗證),發給mproxyhandler 2中的command4:
此外,在handler 2調用前可以看到對這七個command做了策略限制的:
同樣,RouterOS提供了一個叫Get Policies的命令,可以用來獲取system_to數組對應command的權限策略,也就是能獲取某個command的執行是否需要認證,利Tenable的自動化工具獲取看下:
結果和上面的匯編代碼一致,可以看到command 4 和 7的policy值為0,是不需要認證的,也就是說網上一些關于該漏洞是基于權限繞過的描述是不完全正確的,這里不存在權限認證bypass,上面已經提到了,第二條利用代碼中替換Session id是為了通過Command 5中的IF條件,讓exp繼續執行下去。
至此漏洞原理就理清楚了,整個漏洞總結來其實就是一個未授權的任意文件讀取漏洞。來看看具體的利用過程:
1. 構造數據包去讀取/flash/rw/store/user.dat文件,該文件中存儲RouterOS的用戶名密碼。
2. 由于存儲的是:password xormd5(user+"283i4jfkai3389"), 所以可逆,得到密碼明文。
3. 登錄RouterOS,控制路由器。
以上就是CVE-2018-14847的漏洞分析和利用。這時雖然進入到了RouterOS,但還是不能訪問底層linux那部分,所以就有了更進階的利用。
在Tenable的報告中,發現在6.42 stable版本以前很多版本存在開發者后門。筆者以6.41 statle版本為例分析。
定位到后門關鍵點:
可以看到除了管理員admin用戶,還有一個內置用戶devel。要滿足if條件,不僅需要用戶為devel以及后面函數的返回值為真。跟進nv::hasOptionPackage()函數,發現其是/lib/libumsg.so動態庫中的函數:
繼續跟進nv::hasPackage()函數:
此函數只對/pckg/option這個文件做了存在與否的簡單判斷,存在的話,返回為真,加上用戶為devel就滿足了關鍵點處的if條件,byte_8053D15變量的值就被置為1。
當byte_8053D15變量值為1,且/pckg/option文件存在時,RouterOS直接調用了/bin/bash,此時獲得的就是一個 Root shell,到達了linux系統層。
至此,整個后門原理梳理清楚了,但這些后門文件默認是不存在,要想利用需要先寫入,此時不妨回頭看看mproxy handler 2的幾個command。command 1執行了創建文件的操作,似乎剛好切合需求,但是需要認證,也就是說要想寫入后門文件,必須得先登錄成功。筆者思考這個設定也確實合理,要進開發者模式,首先得獲得認證,一般情況下賬號密碼也只有開發者或者用戶自己知道,只是恰好有了上面的未授權的任意文件讀取,來了一個組合拳。
這樣整體思路就很明確了:
1. 先通過command4,7任意文件讀取獲得用戶名密碼。
2. 登錄后再通過command1寫入后門文件。
3. 利用內置用戶devel+admin用戶密碼登錄獲取Rootshell。
整個利用過程如果用python通過socket直接發二進制數據跟winbox通信,是可行,但是數據包的構造很復雜麻煩。所以這里可以直接利用RouterOS官方提供的 c++的winboxapi庫大大簡化了代碼(具體exp來自Tenable):
利用結果:
1、正常登錄,返回登錄失敗:
2、執行BTW后,再次登錄,返回登錄成功。
關于如何深入分析MikroTik RouterOS CVE-2018-14847 就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。