時間:2018-09-28 來源:互聯網 瀏覽量:
根據微軟官網對CVE-2017-11885的描述,該漏洞幾乎可以通殺微軟的全版本操作係統,有關該漏洞的POC在exploit-db上於2018年5月份被披露,該POC僅僅針對windows server 2003進行了測試。
由於在相關描述中並沒有獲取到觸發該漏洞的原因,因此在獲取POC後,嚐試對該漏洞進行複現並分析。
POC的關鍵代碼如下:
作者已經對該POC做了較為詳細的注釋,從stub的布局以及注釋來看,第41行的stub數據可能會被傳入到CALL off_64389048[ECX*4]的ecx中,ecx如果是被控製的值,那麼基本上可以直接在目標係統執行任意代碼了。接下來搭建一個windows server2003係統,並嚐試通過該POC觸發漏洞。
該漏洞僅當操作係統開啟了RRAS服務才會存在,在windows server2003中,通過管理工具->路由和遠程訪問進行配置,結果如下:
開啟了RRAS服務後,在另一台主機執行POC,並抓包。發現使用了SMB協議進行數據傳輸,pcap包數據如下圖:
隨便打開一個包,發現是SMB協議並且通過445端口發送的數據,SMB協議後緊跟著DCERPC協議,對該協議的解釋如下:
還是相對古老的協議,而微軟的操作係統中的MSRPC協議是對DCERPC的一種實現,也算是第一代RPC協議。在這裏簡單介紹下RPC協議以及關鍵內容。
RPC 是指計算機 A 上的進程,調用另外一台計算機 B 上的進程,其中 A 上的調用進程被掛起,而 B 上的被調用進程開始執行,當值返回給 A 時,A 進程繼續執行。A、B進程的交互過程如下圖:
RPC應用程序的開發基於C/S模式,在windows環境下開發RPC所要實現的內容有:
1.IDL文件
2.ACF文件(可選)
3.客戶端程序
4.服務端程序
IDL文件是接口描述文件,編寫該文件所需的關鍵信息包含程序注冊的uuid、函數調用接口以及參數的數據結構定義等。ACF文件可用來創建一些相對複雜的數據結構,這裏不多關注。利用MIDL程序對IDL文件進行編譯生成對應的客戶端和服務端所需的頭文件。客戶端程序和服務端程序包含著關鍵調用函數的主體程序。其整個模式類似於我們通常的WINAPI調用,如我們調用ReadFile函數時,通常需要傳遞一部分參數,並得到一個返回值,在RPC編程中客戶端程序負責參數的傳遞,服務端程序負責接收參數並執行相應的功能,隨後將數據返回,整個過程對於開發人員是透明的,隻不過是跨計算機的調用。RPC開發具體可參考微軟的官方文檔。
鏈接如下:https://docs.microsoft.com/en-us/windows/desktop/rpc/rpc-start-page。
這裏我們主要關注的內容包含RPC的協議傳輸方式、端點名稱、以及具體的程序接口調用。該POC利用到了impacket這個庫進行SMB以及rce協議的傳輸,POC中通過transport.DCERPCTransportFactory('ncacn_np:%s[\\pipe\\browser]' % target)進行遠程命名管道的鏈接,其中使用到的rpc協議為ncacn_np,通用的rpc協議如下:
而且,SMB作為rpc的底層通信協議,一般都會同135、445這兩個端口進行通信,一般的RPC 漏洞挖掘工具如spike等會通過特定端口查詢rpc服務的名稱數據庫來獲取一些關鍵信息,如下:
但是本次漏洞中的服務端程序無法通過客戶端查詢來獲取信息,原因可能是因為服務端在綁定端點時采用了動態綁定的方式,並且沒有將自身的相關信息綁定到名稱服務中,將自身的信息導出到名稱服務一般需要調用如下函數:
這樣隻有特定的程序才能夠訪問對應的服務端程序,一般的msrpc fuzz工具在獲取不到指定信息,也不會對遠程服務進行fuzz,所以此類fuzz工具也難以挖掘到該類型的漏洞。
除了協議外,比較重要的一點就是遠程的端點了,該POC中用到了/pipe/browser這個遠程的命名管道,其實這個和RRAS協議中所規定的有點出入,在微軟的官方文檔[MS-RRASM]中指出,如果需要同RRAS服務進行交互,應該使用/pipe/ROUTER這個命名管道。
當然漏洞的發現者之所以用這個命名管道當然有他的用意,這涉及到了另一方麵的操作係統缺陷即MSRPC NULL sessions,在很早以前有人做過研究,可能在滲透中會用的多一些。還有一個相對重要的就是uuid,這代表著唯一的遠程服務端程序的標識,本次POC中對應的uuid為8f09f000-b7ed-11ce-bbd2-00001a181cad,同樣在官方文檔中也有說明,該uuid對應著RRAS服務的應用程序。
接下來就開始對漏洞的調試分析,通過在win7、winserver2003、winserver2008上進行測試,發現僅能在win server2003上觸發漏洞,win7尚沒有找到配置遠程路由的功能,盡管開啟了RRAS服務,但是無法觸發漏洞。
由於微軟不再維護win server2003的符號表,因此在調試起來很難確定函數的關鍵的信息,同時,由於使用的win server2003可能打了補丁,導致在發送攻擊報文後,並沒有反彈shell,同時操作係統也沒有產生異常,當時懷疑該漏洞是否需要其它條件才能觸發,隨後查看了win server的事件日誌記錄,發現了一個appcrash記錄,點擊進去查看詳細信息如下:
從圖中看出svchost.exe發生了崩潰,而svchost具有是管理、開啟服務的功能,因此猜測可能是RRAS服務在接收到攻擊報文後發生了異常,異常的模塊是iptrmgr.dll,利用ida打開該dll,同時跳轉到偏移為0x17436的地方查看代碼如下:
此處的代碼和POC中提供的相對應,接下來利用調試工具對RRAS服務進行調試。由於在win server2003進行調試,很多工具都無法使用,連最基本的windbg都無法使用,隻能用最原始的OD來調試,還有一個問題就是如何找到RRAS對應的svchost程序,因為係統會開啟多個svchost程序,在不考慮使用其他監控程序的情況下,可以使用tasklist /M iprtrmgr.dll來顯示當前加載了iprtrmgr.dll這個模塊的svchost,基本可以確定該svchost同RRAS服務相對應,結果顯示如下:
接下來直接附加該程序,並在出現崩潰處的函數下斷點,觀察程序的狀態如下:
可以看出ecx的值來源於eax,而eax來自於第三個參數,在內存dump中可以看到這些是POC中構造的NDR(網絡數據表示)數據,在MSRPC中,通過NDR引擎對參數格式進行編碼、解碼,比如客戶端希望傳遞一個結構體指針類型的參數,該參數在IDL文件中被定義,在MIDL對IDL進行編譯的時候,會將該參數通過NDR引擎編碼轉換成為可以通過網絡傳輸的數據格式,在服務端由NDR引擎進行解碼,並將解碼後的參數傳遞給服務端程序,整個過程對程序員是透明的。在POC中,作者通過構造特定的NDR數據作為服務端的參數進行漏洞利用,觀察0x64127058處的數據,發現該處保存著函數列表,如下:
一共有0x23個函數,可以猜測服務端根據客戶端的調用號ecx值來確定下一步的函數調用,但是當傳入的ecx可以被控製時,那麼通過ROP技術可以控製整個程序的流程。
漏洞發現者通過在內存中找到包含著jmp eax這樣的gadgets來實現漏洞利用,但是由於應用程序的版本問題導致特定地址的代碼並非預期,指向了一個不可讀的地址,因此這裏會產生一個訪問異常,使應用程序崩潰。
程序的調用棧當前無法正常顯示,但是查看棧指針不難發現如下的函數調用:
這裏比較關鍵的是mprdim.dll,該dll存放著服務端的代碼存根stub,利用ida的mIDA工具可以將RPC的IDL數據結構分析出來,通過對比發現win7和winserver上的代碼基本類似,win7上也存在著本次的漏洞,由於win7上的dll可以獲取到符號,因此下麵的所有代碼都是對應的win7版本的,將win7下的mprdim.dll利用mIDA工具進行分析的結果如下:
可以看到觸發漏洞的函數為RMIBEntryGetFirst,該函數對應的調用號為0x1e(30),通過wireshark查看RRAS協議的包格式也可以得到驗證:
接下來查看該函數的一些關鍵RPC數據結構,如下:
該函數以及對應數據結構在微軟的官方文檔有定義,如下:
從第二個參數開始,分別對應著我們構造的三個參數,第三個關鍵的參數為DIM_MIB_ENTRY_CONTAINER結構,當dwPid=10000時,該結構體指向 MIB_OPAQUE_QUERY,該結構體聲明如下:
在觸發漏洞的函數中,ecx代表著dwVarID,而dwVarID對應著函數的編號,微軟的解釋如下:
在ida中體現如下:
通過ida查看該函數的整個實現發現,僅僅在開始對傳入數據中的dwPid進行檢測,而並沒有對參數範圍進行嚴格校驗,導致其最終指向了rop gadgets的地址。
在漏洞觸發的地方查看關鍵的上下文信息,發現eax指向了用戶傳入的參數的緩衝區,而該內存的屬性是RWE(可讀可寫可執行),簡直為漏洞利用提供了完美的環境,不需要通過ROP來繞過DEP等防護技術,該漏洞更像是一個後門。
當然存在漏洞的也不隻這一處函數,查看對函數表的引用可以發現共有三處,其執行邏輯基本類似,隻要更改下函數調用號,同樣可以觸發。
前麵提到過漏洞使用了/pipe/browser這個命名管道進行通信,該命名管道在winxp 、win server2003默認開啟,並且是空會話格式的,意味著匿名的用戶也可以進行訪問,無需用戶名、密碼,但是在win server2008上,微軟關閉了大部分的命名管道,因此即便開啟了RRAS服務,前期的通信尚無法建立,該漏洞自然無法成功利用,返回結果如下:
利用pipelist程序查看當前開啟的命名管道,結果如下:
但是全部無法通過遠程訪問,結果如下:
所以,如果需要成功利用該漏洞,必須開啟一個空會話的命名管道,啟用方式如下:
這樣就可以通過POC對win server 2008進行攻擊了,而且最重要的是調試起來相對更方便點,可以使用windbg並且加載符號進行調試。
微軟目前已經對該程序打了補丁,打補丁的方式是在對參數的範圍作了校驗,如下:
到此漏洞基本分析完畢。