緩衝區溢出漏洞可導致內核崩潰,蘋果多款操作系統均受影響

前言

國外大神Kevin Backhouse剛剛放出了一篇博文,對蘋果操作系統內核中發現的堆緩衝區溢出漏洞(CVE-2018-4407)進行了一番解構。

該漏洞使得攻擊者只要接入同一Wi-Fi網絡,即可向其他毫不知情的用戶發送惡意數據包來觸發任何Mac或iOS設備的崩潰和重啓。由於該漏洞存在於系統網絡核心代碼,因此任何反病毒軟件均無法防禦。

運行以下操作系統的設備易受攻擊:

Apple iOS 11及更早版本:所有設備(升級到iOS 12的部分設備) Apple macOS High Sierra(受影響的最高版本爲10.13.6):所有設備(通過安全更新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的分配大小沒有確切的數值。基於源代碼提供的信息,這裏推測mgethdr創建一個mbuf可以容納88個字節,mgetcl無法確定。但是根據實驗結果,觸發該緩衝區溢出漏洞時滿足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."

這是一個很簡單的問題跟蹤方法,它的查找範圍涵蓋mmtod到CopyData函數的參數大小的數據流。mmtod函數返回一個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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章