作者:
360安全衛士
·
2015/09/21 18:12
作者:LR、noirfate
0x00 前言
Qemu是一款處理器模擬軟體,可以提供使用者模式模擬和系統模式模擬。當處於使用者模式模擬狀態時,將使用動態翻譯技術,允許一個cpu構建的程式在另一個cpu上執行。
VNC [ Virtual Network Computing ]是一款優秀的遠端控制工具軟體。由於Qemu內建vnc功能模組,所以可透過vnc客戶端對遠端Qemu虛擬機器進行遠端訪問。
360安全團隊的 連一漢 在閱讀Qemu-VNC原始碼過程中,發現了功能模組中的一個遠端拒絕服務,漏洞危險等級為中,漏洞編號CVE-2015-5239。
相關資訊見 https://access.redhat.com/security/cve/CVE-2015-5239
0x01 VNC通訊協議介紹:
VNC採用RFB通訊協議。RFB ("remote 幀快取 ") 是一個遠端圖形使用者的簡單協議。透過這個協議,使用者可以遠端模擬滑鼠點選、鍵盤按鍵以及文字複製/剪下等功能。本文所講述漏洞就是在文字複製/剪下時觸發的。詳細協議格式如下圖:
舉例說明:
下面這段資料是真實傳送的用於文字複製/剪下的報文。
06 00 00 00 00 00 00 06 74 65 73 74 21 21
06 :表示協議型別message-type
00 00 00 :用於填充padding
00 00 00 06 :待剪下資料的長度length
74 65 73 74 21 21:待剪下資料內容text
協議格式相對簡單,就不再進一步描述。
0x02 漏洞分析:
QEMU在透過vnc讀取報文中儲存的剪下板中的資料時,由於其未對報文中用於描述資料長度的欄位進行嚴格限制,進而導致其出現邏輯錯誤進入死迴圈。下面就是程式處理的主體邏輯:
a) 讀取報文中用於描述待讀取資料長度的欄位
b) 判斷這個欄位是否超過整個報文的長度。
c) 如果為否,則進行資料複製;如果為是,則跳出迴圈
實現程式碼如下(ui/vnc.c):
從上述程式碼中可以發現:由於len的初始值為1,所以protocol_client_msg()
的返回值為8。Input.offset
的值始終為14大於8,所以此時不會跳出迴圈。在進入下次迴圈時8將作為protocol_client_msg()
的引數len傳入,用於讀取報文長度欄位的值。但是,如果此時讀取的報文中的長度欄位為0xFFFFFFF9
則protocol_client_msg()
的返回值又將為1,下次迴圈時len的值也就又恢復為初始值1。這樣,程式又進入開始時的狀態,再次呼叫protocol_client_msg()
並且返回值為8。然後又將8傳入protocol_client_msg()
,讀取報文中的長度欄位0xFFFFFFF9
,返回值又為1,迴圈往復。由於在這段迴圈過程中客戶端連線標誌vs->csock
始終未被更改,程式也將無法跳出迴圈,從而進入死迴圈狀態。Vnc拒絕服務也就由此產生。
0x03 漏洞危害:
攻擊者利用該漏洞可以導致虛擬機器拒絕服務,並且保持對cpu的高佔用率,繼而會影響宿主機以及其他虛擬機器的正常執行。 我們在測試環境中對該漏洞進行測試,觸發前後的截圖如下。可以看到,在漏洞觸發後qemu-kvm無法遠端訪問,並佔有極高的CPU使用率,嚴重影響其它程式的執行。 漏洞觸發前CPU的狀態:
漏洞觸發後CPU的狀態:
0x04 修補方案:
官方對該漏洞的修補方法如下:
具體見:http://git.qemu.org/?p=qemu.git;a=commit;h=f9a70e79391f6d7c2a912d785239ee8effc1922d
該補丁中,開發人員對關鍵資料dlen的大小進行嚴格的大小判斷,確保資料長度值不能超過1MB。這樣就完美修復此漏洞。在這裡建議所有使用qemu的廠商採用該補丁,防止攻擊者利用CVE-2015-5239漏洞對廠商和使用者攻擊造成損失。 建議廠商安排安全修復。
本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!