緩衝區溢位漏洞(CVE-2018-4407)可導致核心崩潰,蘋果多款作業系統均受影響
前言
國外大神Kevin Backhouse剛剛放出了一篇博文,對蘋果作業系統核心中發現的堆緩衝區溢位漏洞(CVE-2018-4407)進行了一番解構。
該漏洞使得攻擊者只要接入同一Wi-Fi網路,即可向其他毫不知情的使用者傳送惡意資料包來觸發任何Mac或iOS裝置的崩潰和重啟。由於該漏洞存在於系統網路核心程式碼,因此任何反病毒軟體均無法防禦。
執行以下作業系統的裝置易受攻擊:
Apple iOS 11及更早版本:所有裝置(升級到iOS 12的部分裝置)
Apple macOS High Sierra(受影響的最高版本為10.13.6):所有裝置(通過 ofollow" rel="nofollow,noindex" target="_blank">安全更新2018-001 修復)
Apple macOS Sierra(受影響的最高版本為10.12.6):所有裝置(通過 安全更新2018-005中 修復)
Apple OS X El Capitan及更早版本:所有裝置
好在Kevin在發現這個漏洞後馬上就向蘋果報告了,蘋果在10月30日推出的iOS 12.1更新包中徹底修復了這個漏洞。
概述
該漏洞是蘋果 XNU 作業系統核心中網路程式碼的堆緩衝區溢位問題導致的,iOS和macOS都使用XNU,因此iPhone、iPad和的MacBook均受到影響。想要觸發該漏洞,攻擊者只需要連線到與目標裝置相同的網路,傳送惡意IP資料到目標裝置的IP地址即可,無需誘騙使用者進行任何互動操作。
舉個例子:
使用者在咖啡館使用免費Wi-Fi時,攻擊者可以加入相同的無線網路並向用戶的裝置傳送惡意資料包就可以讓裝置崩潰和重啟。(攻擊者只要使用 NMAP 工具就能很方便地獲得裝置IP地址。)
由於該漏洞的成因來源於系統的核心程式碼,反病毒軟體也無法防禦。 Kevin在執行 McAfee ® Endpoint Security for Mac 的Mac上成功測試了該漏洞。這和使用者在裝置上執行的軟體也沒有關係,即使沒有開啟任何埠,惡意資料包仍會觸發漏洞。
進一步推測的話,由於攻擊者可以控制堆緩衝區溢位的大小和內容,因此他們可能利用此漏洞在目標裝置執行遠端程式碼。
緩解措施
在未升級到最新版本作業系統的裝置上,目前已知的緩解措施只有以下兩個:
在macOS防火牆中啟用 隱藏模式 可防止攻擊。這個系統設定預設情況下不啟用,需要使用者手動開啟。iOS裝置不支援隱藏模式。
不接入公共無線網路。觸發該漏洞的唯一必要條件是處於同一Wi-Fi網路,該漏洞不支援通過網際網路傳送惡意資料包而觸發,Kevin測試過了。
漏洞分析
該漏洞來源於程式碼中的緩衝區溢位( bsd/netinet/ip_icmp.c:339 ):
m_copydata(n, 0, icmplen, (caddr_t)&icp->icmp_ip);
函式 icmp_error 使用該程式碼,目的是“生成包含錯誤資訊的資料包以響應發生錯誤的IP”。它使用 ICMP協議 傳送錯誤訊息,引發錯誤的資料報頭包含在ICMP訊息中,上述第339行程式碼呼叫m_copydata的目的是複製錯誤資料包的報頭到ICMP訊息。
問題在於報頭對於目標緩衝區來說可能太大了。目標緩衝區是mbuf,mbuf是一種資料型別,用於儲存傳入和傳出的網路資料包。在此程式碼中,n是一個傳入的資料包(包含不受信任的資料),而m是傳出的ICMP資料包。我們可以看到,icp是指向m的指標。m在 第294行或第296行 進行部署:
if (MHLEN > (sizeof(struct ip) + ICMP_MINLEN + icmplen)) m = m_gethdr(M_DONTWAIT, MT_HEADER);/* MAC-OK */ else m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
往下看 第314行 ,mtod用於獲取m的資料指標:
icp = mtod(m, struct icmp *);
mtod僅僅是個巨集,因此這行程式碼不會檢查mbuf是否足以容納icmp結構。此外,資料沒有複製到icp,而是複製到&icp->icmp_ip,存在+8位元組偏移。
由於沒有必要的工具,Kevin無法在偵錯程式中單步執行XNU核心,因此對於mbuf的分配大小沒有確切的數值。基於原始碼提供的資訊,這裡推測m_gethdr建立一個mbuf可以容納88個位元組,m_getcl無法確定。但是根據實驗結果,觸發該緩衝區溢位漏洞時滿足icmplen >= 84的條件即可。
漏洞的發現過程
使用QL查詢漏洞
Kevin是在分析 資料包管理程式 緩衝區溢位漏洞時發現的該漏洞。漏洞是由對於mbuf_copydata的呼叫(包含使用者控制的大小引數)引起的,因此只要寫一個簡單的查詢指令碼即可發現類似錯誤:
** * @name mbuf copydata with tainted size * @description Calling m_copydata with an untrusted size argument *could cause a buffer overflow. * @kind path-problem * @problem.severity warning * @id apple-xnu/cpp/mbuf-copydata-with-tainted-size */ import cpp import semmle.code.cpp.dataflow.TaintTracking import DataFlow::PathGraph class Config extends TaintTracking::Configuration { Config() { this = "tcphdr_flow" } override predicate isSource(DataFlow::Node source) { source.asExpr().(FunctionCall).getTarget().getName() = "m_mtod" } override predicate isSink(DataFlow::Node sink) { exists (FunctionCall call | call.getArgument(2) = sink.asExpr() and call.getTarget().getName().matches("%copydata")) } } from Config cfg, DataFlow::PathNode source, DataFlow::PathNode sink where cfg.hasFlowPath(source, sink) select sink, source, sink, "m_copydata with tainted size."
這是一個很簡單的問題跟蹤方法,它的查詢範圍涵蓋m_mtod到CopyData函式的引數大小的資料流。m_mtod函式返回一個mbuf的資料指標,它很可能會返回不受信任的資料,所以mtod巨集指令是根源所在。而m_mtod這只是XNU核心中不受信任資料的眾多來源之一。
使用上述方法進行查詢後返回9個結果,其中第一個是漏洞icmp_error,其他8個結果誤報的可能性較大。
在XNU上嘗試QL
與大多數其他開源專案不同,XNU無法通過查詢LGTM獲得有用的資訊。因為LGTM使用Linux流程構建專案,但XNU只能在蘋果電腦上構建。即使在蘋果電腦上,構建XNU也非常不容易。Kevin參考了Jeremy Andrus的 部落格文章 ,才得以為三個最新發布的XNU版本手動構建了快照(下載快照 10.13.4 , 10.13.5 , 10.13.6 )。由於蘋果尚未釋出10.14(Mojave/ iOS的12)的原始碼,因此無法建立QL快照來運行鍼對性的檢查。要在這些QL快照上執行查詢指令碼,需要下載 QL for Eclipse ,點選 此處 獲得有關如何使用QL for Eclipse的說明。
漏洞驗證視訊
為了讓蘋果使用者有充分的時間升級,Kevin不會立即放出PoC程式碼,而是製作了一個簡短的視訊來驗證漏洞。
*參考來源: lgtm ,Freddy編譯整理,轉載請註明來自 FreeBuf.COM。