標籤:

2017年度安全報告 — 平台漏洞

摘要

平台安全是計算機安全體系中重要的組成部分。平台對上層應用,服務,功能提供支持,主要體現在硬體,固件,協議及協議實現等。這方面有許多攻擊方法,比如邊信道攻擊,中間人攻擊,旁側降權攻擊等。這些高級攻擊方法,如果結合平台安全中的漏洞,將會十分危險。本文是360CERT對2017年平台安全的總結。

平台安全中的攻擊方法

側信道攻擊

邊信道最早的實踐是通過採集加密電子設備在運行過程中的時間消耗、功率消耗或者電磁輻射消耗等邊緣信息的差異性進行攻擊的手段。而隨著研究的深入,也逐漸從加密設備延伸到計算機內部CPU、內存等之間的信息傳遞等方面。

近年,這種攻擊方法最典型的案例莫過於Linux下TCP邊信道安全問題(CVE-2016-5696)。為了減少CPU和帶寬資源浪費,要限制challenge ACK發出的數量,所以引入了這裡的ACK Throttling機制。正是這個ACK Throttling機制,帶來了邊信道攻擊的可行性。

利用邊信道攻擊方式,攻擊者不需要處在「中間人」的位置,整個過程不需要與受害者進行互動,這種攻擊手法在平台安全中應用廣泛。

中間人攻擊

中間人攻擊(Man-in-the-MiddleAttack,簡稱「MITM攻擊」)是一種「間接」的入侵攻擊,這種攻擊模式是通過各種技術手段將受入侵者控制的一台計算機虛擬放置在網路連接中的兩台通信計算機之間,這台計算機就稱為「中間人」。這種攻擊方法通過攔截正常的網路通信數據,並進行數據篡改和嗅探,而通信的雙方卻毫不知情。MITM由來已久,但在今天仍然活躍,如SMB會話劫持、DNS欺騙等攻擊都是典型的MITM攻擊。

2017年披露了CVE-2017-0783和CVE-2017-8628,攻擊者利用這兩個漏洞,可以分別在Android設備和windows設備上進行MITM攻擊。

降級攻擊

降級攻擊主要應用在安全協議方面,比較典型的一個例子便是4G LTE攻擊。利用了3GPP的漏洞取得手機的IMSI碼,通過DoS攻擊迫使手機接入黑客控制的虛假GSM網路中。或者把手機導入一個與運營商網路連接的受黑客控制的合法基站上,從而能夠對手機通信進行竊聽以及對上網流量進行嗅探。這種攻擊方法的應用還有很多,比如HTTPS降級攻擊,TLS降級攻擊等

其他

其他情景的攻擊方法同樣適用於平台安全中,比如暴力猜解,重放,介面鑒權攻擊等。

還有許多不常用的攻擊方法,只能針對特定的環境。比如2017的WPA2密鑰重載攻擊,他讓我們意識到,消息可能丟失的協議可能會變得特別脆弱,畢竟這些協議用設計用來重傳幀時,就有可能密鑰重載。

下面就今年幾個比較典型的平台安全漏洞及攻擊方法進行詳細介紹。

Intel ME固件漏洞

今年五月份, Intel公司公布了一個嚴重高危級別安全漏洞,攻擊者可以在目標操作系統不可直接訪問的區域進行載入/執行任意代碼,具備極高的隱蔽性,常規方法無法檢測到。酷睿,至強,凌動等部分型號均受影響。

事件描述

Intel 晶元中有一個獨立於 CPU 和操作系統的微處理器,叫做英特爾管理引擎 Intel Management Engine,簡稱 ME。多種技術基於ME,例如代碼處理、媒體DRM、可信平台模塊TPM等。

ME 是一個有別於 CPU 的獨立系統,它可以在不受 CPU 管控下通過搭配 AMT(英特爾主動管理技術)來遠程管理企業計算機。AMT 技術能夠自動執行一個獨立於操作系統的子系統,使得在操作系統出現故障的時候,管理員能夠在遠程監視和管理客戶端、進行遠程管理和系統檢測、軟硬體檢查、遠端更新 BIOS 、病毒碼及操作系統,甚至在系統關機的時候,也可以通過網路對伺服器進行管理操作。

該漏洞主要存在英特爾管理引擎(ME ),英特爾伺服器平台服務(SPS),英特爾可信執行引擎(TXE)。攻擊者可以模擬ME/SPS/TXE,來影響本地安全認定的有效性,在目標操作系統不可直接訪問的區域進行載入/執行任意代碼,具備極高的隱蔽性,常規方法無法檢測到。

總結

根據intel官方公告,相關產品漏洞一共有8個CVE:CVE-2017-5705、CVE-2017-5706、CVE-2017-5707、CVE-2017-5708、CVE-2017-5709、CVE-2017-5710、CVE-2017-5711、CVE-2017-5712。酷睿,至強,凌動?,賽揚?等部分型號產品受到該漏洞影響。

事實上,這並不是英特爾第一次被曝出產品存在嚴重漏洞。Intel ME固件漏洞相對於操作系統,用戶是完全透明的。操作系統的一切安全機制,漏洞緩解機制都是無用的。

Intel ME固件漏洞主要影響的是伺服器,個人PC平台。巧合的是,今年的一枚博通wifi晶元漏洞影響數十億台Android 和 IOS設備,移動設備在今年也被披露存在平台安全問題,未能倖免。

博通wifi晶元漏洞

今年披露的一枚名為BroadPwn遠程代碼執行漏洞, 影響Android 和 iOS 數十億台設備。7月初,谷歌,蘋果陸續發布了安全補丁。未進行安全更新的設備,一旦置身在惡意WiFi範圍內就會被黑客捕獲、入侵。當手機打開wifi時,無需任何操作,攻擊者便可在我們毫無察覺的情況下,完全控制手機,這是多麼恐怖的事情。

背景及相關知識

在過去的一段時間,Wi-Fi的使用再移動設備上已經普及。逐漸地,涉及物理層,數據鏈路層的Wi-Fi已經發展成為一套健全的規範。為了拓展和解決各種未知的複雜問題,供應商已經開始生產基於「FullMAC」的Wi-Fi SoC。這些是小的SoC執行所有PHY, MAC和MLME數據處理。FullMAC晶元容易集成,在固件中實現MLME處理,這種解決方案降低了主機端的複雜性,十分受廠商歡迎。但是引入這些新硬體,運行專有和複雜的代碼庫,可能會削弱設備的整體安全性,引入危及整個系統的漏洞。

技術分析

參考Google的Project Zero團隊對該漏洞的分析,問題出在內部通信渠道。

上圖是追蹤處理事件框架(dhd_wl_host_event)的入口點的控制流程,我們可以看到幾個事件接收,並被獨立處理。一旦初始完成,幀就被插入隊列。然後事件由內核線程出隊列,其唯一用處是從隊列中讀取事件並將其分派到相應的處理函數。這種關聯是通過使用事件的內部「event_type」欄位作為處理函數數組的索引來完成的,採用的evt_handler

該漏洞太過複雜,一些先決條件我們不進行探討,直接指出到漏洞關鍵點:處於dhd_handle_swc_evt 函數的total_count欄位。

漏洞的邏輯可歸結為:

  • 「 WLC_E_PFN_SWC 」 類型的事件處理SWC。
  • 通信中的每個SWC事件幀包含事件(wl_pfn_significant_net_t),總計數(total_count )和數組中的事件數(pkt_count )。
  • 當接收到SWC事件代碼時,觸發一個初始處理程序來處理事件。處理程序在內部調用「 dhd_handle_swc_evt 」函數來處理事件的數據。
  • dhd_handle_swc_evt處理函數無法驗證total_count 和pkt_count 之間的關係。

關鍵函數:

「event_data」是通信的事件中封裝的任意數據,函數首先初始化一個數組來保存事件的總數(如果之前沒有分配的話),然後在緩衝區中建立results_rxed_so_far與傳入數據的聯繫。但是,處理程序無法驗證total_count 和pkt_count 之間的關係!攻擊者可以指定一個小的total_count 和一個大的pkt_count ,觸發一個簡單的內核堆溢出。之後可以通過一些堆溢出利用方法,實現遠程代碼執行。

總結

該漏洞影響Android 和 iOS 數十億台設備。我們使用的智能機,平板電腦,都支持wifi功能,如果使用了博通受影響晶元的設備,均在危險之中。wi-fi晶元這種基本的元件存在的漏洞,如果被利用的話,那麼會有殺傷力會很驚人。我們都知道現在的智能機都支持熱點功能,如果將該漏洞做成蠕蟲勒索病毒,感染後,開啟免密熱點吸引其他手機連接,通過無線網路進行傳播,儼然一場低配版的Wannacry。

說到wifi晶元漏洞,不得不提今年披露的WPA2 KRACK(密鑰重載攻擊),不止我們使用的設備不安全,我們wifi使用的WPA2加密協議也存在問題。

WPA2 KRACK(密鑰重載攻擊)

2017年10月16日,針對WiFi+WPA2網路,名為KRACK的漏洞攻擊方式被披露。KRACK主要是利用802.11i ,4次握手中的漏洞來最終實現解密和偽造加密的WiFi流量,該漏洞由來自imec-DistriNet的Mathy Vanhoef和 KU Leuven發現。本次漏洞事件有多種攻擊型態,AP熱點端,中繼端,和客戶端均受到影響。根據krackattacks.com和部分廠商發布的安全公告綜合分析,包括Linux,Android, Cisco wireless products, OpenBSD, MacOS, Windows, iOS等產品或平台受到影響。

相關知識

當客戶端要連接 WiFi 網路,自動開始(互相)身份驗證和連接。圖 2 描述了連接階段的握手。但是當第一次連接到網路時,是沒有實際的身份驗證。相反,使用了開放系統身份驗證,對客戶端進行身份驗證。實際身份驗證在四次握手中使用。但真正的身份認證僅在兩個採用 fast BSS transition 握手協議的相同網路 AP 之間漫遊時使用。在開放式身份驗證之後,客戶端連接到網路中。通過客戶端向 AP 發送一個連接請求完成。這條消息包含客戶端希望使用的成對的密碼組。AP 回復一個連接響應,通知客戶端連接是否被成功建立。

圖1

四次握手提供相互身份驗證,基於共享密鑰技術,這種技術稱為成對的主密鑰 PairwiseMaster Key(PMK),並協商一個新的會話秘鑰 PairWise Transient Key(PTK)。在這次握手中,客戶端稱為 supplicant,而 AP 稱為 authenticator,PMK 由個人網路中的預共享密碼生成,在企業網路中使用 802.1x 身份驗證來進行協商。PTK 由 PMK,Authenticator Nonce (ANonce),Supplicant Nonce (SNonce)和 supplicant 和 authenticator 使用的 MAC 地址派生而來。一旦生成,PTK 被分割成確認 key(KCK), 加密 Key(KEK),和臨時 Key(TK),確認 Key 和加密 Key 使用來保護握手消息,TK 和數據機密性協議是用來保護正常數據幀,如果使用了 WPA2,四次握手協議也傳輸現在的 Group Temporal Key 組臨時密鑰(GTK)到 supplicant。

四次握手中的每一條消息都是使用 EAPOL 幀格式(如圖 1)。對欄位進行介紹首先,消息的頭部定義了所代表的消息類型,我們將使用 message n 和 MsgN 來代表四次握手中第 n 段消息。Replay count(重放計數器)欄位用於檢測重放的數據幀:authenticator 在發送一個幀之後會自增長,當 supplicant 對 authenticator 發送的 EAPOL 幀做出應答時,它使用相同的 replaycount。Nonce 欄位是一個隨機的 nones 值,這個隨機值是 supplicant 和 authenticator 在生成新的會話秘鑰這一步驟產生的。接下來,如果 EAPOL 幀傳輸一個組密鑰,RSC(接受序列)包含了 key 起始包號。組密鑰是存儲在 Key Data 欄位,使用加密 Key(KEK)加密。最後,使用消息確認 Key(KCK)來進行完整性校驗. MIC(Message Integrity Check)。

圖2

四次握手中的第 N 條消息,重放計數器 replay count 為 r, 給定的 nonce,在』;』之後的參數都存儲在數據域中,也就是說會使用 KEK 加密。

  • Authenticator 通過發送 message 1 來初始化四次握手。包含 ANonce,是唯一一個沒有MIC(完整性校驗) EAPOL 格式消息。
  • 當收到消息時,suplicant 生成一個 SNonce 而且導出 PTK,suplicant 發送 message2 給authenticator,message2 包含了(SNonce)。
  • authenticator 收到 SNonce,也會導出 PTK。並且發送組密鑰 GTK 給 supplicant。
  • supplicant 在安裝 PTK 和 GTK 之後回復 message4
  • authenticator 收到 message4 之後也會安裝 PTK,其中 GTK 在 AP 啟動時就已經安裝。

1,2 條消息使用來傳輸 nonces,最後兩條消息是用來傳輸組密鑰 而且使用抵禦降級攻擊注意:在已經存在的連接中,PTK 可以被刷新初始化新的四次握手。在密鑰重載的過程中,所有的四次握手

消息都是使用 PTK 完成數據機密性加密的。

技術細節

802.11i協議(即:WPA2協議)通過兩種獨立的機制來保證數據傳輸的機密性。

第一個是在記錄層通過加密WiFi幀的方式,保證明文無法被讀取或嗅探。該加密機制通常是通過AES-CCM的方式,當然也有部分啟動GCM模式,還有部分老的RC4-TKIP方式。需要認真考慮的是AES-CCM(還包括GCM, TKIP)是一種流加密,這意味著在重用加密參數key和nonce(即:初始向量)的情況下是可以被攻擊的。802.11i是基於包計數(packet number number)的方式,其在會話建立後的初始值為0,且會不停遞增(當然到了2^48的時候,會觸發更新key操作)。這樣一來,假設在包計數不被重置的情況下,就可以成功防範key+nonce的重用攻擊。第二個機制是AP和客戶端(supplicant)之間的4次握手流程,主要用於協商加密key。KRACK漏洞會直接利用到4次握手中的#3包,#3包可作用於客戶端新key安裝使用。

KRACK的主要漏洞在於 #3包可以被惡意阻斷。當這個情況發生時,AP端會重發這個消息,會導致同樣的一個key在客戶端中被重裝。帶來的副作用是也會導致包計數會被重置為0(部分客戶端,如Android6,會把key重置為0),最終,就會觸發key+nonce的重用攻擊了。攻擊者可以利用它來全流量解密,TCP劫持等。

此外,還有如下2種攻擊:

  • 包括針對客戶端的基於GTK的攻擊;
  • 針對AP端的11 RFT握手攻擊;

github.com/vanhoefm/kra

目前公開poc都是只針對客戶端,和伺服器進行安全檢測,但不排除已經有一鍵傻瓜式工具利用。

總結

針對客戶端的攻擊類似中間人的形式,需要迫使無線客戶端從AP連接到攻擊者偽造的AP上,所以漏洞利用需要在一個有限地域範圍內進行攻擊,漏洞利用需要有針對性;不需要與被攻擊者產生任何交互,漏洞利用觸發難度小,對於針對性的實戰利用是很有意義的。

漏洞存在於linux,Android到windows各種終端,可以對一些明文傳輸或者不正確配置的https網站進行嗅探,數據捕獲,考慮到現階段安全狀況,利用效果較好。同時,WPA2 KRACK(密鑰重載攻擊)並沒有從根本上打破WPA系列密鑰體系基本的安全特性,暫時不存在更換加密方式,只需要針對特定客戶端和AP進行修復。考慮到無線設備更新修復難度,建議在需要高安全性環境時,進行無線連接時採取vpn等方式加密進行連接。

360CERT建議廣大用戶:

  • 及時更新無線路由器、手機,智能硬體等所有使用WPA2無線認證客戶端的軟體版本。
  • 合理部署WIPS(無線入侵防禦系統),及時監測合法WiFi區域內的惡意釣魚WiFi,並加以阻斷干擾,使其惡意WiFi無法正常工作。
  • 無線通信連接使用VPN加密隧道及強制SSL規避流量劫持與中間人攻擊造成的信息泄漏。
  • 在不使用WiFi時關閉手機WiFi功能,公共WiFi下不要登錄有關支付、財產等賬號、密碼。如需登錄、支付,將手機切換至數據流量網路。
  • 及時更新官方補丁:

Linux的hostapd和wpa_supplicant 補丁地址:w1.fi/security/2017-1/微軟在Windows 10 操作系統中發布補丁 KB4041676蘋果在最新的 beta 版本iOS、macOS、 tvOS和 watchOS中修復了無線網路安全漏洞。

BlueBorne藍牙漏洞

上述的三個漏洞和攻擊方法分別分別屬於引擎,固件,協議三個方面平台安全。此外,今年還有另外一些值得我們注意漏洞。

9月12日,armis披露了一系列藍牙的漏洞,手機開啟了藍牙,就可能被遠程控制。無接觸無感知接管系統的能力有點可怕,而且基本上影響所有的藍牙設備,危害不可估量。

所有Android智能機,平板,可穿戴設備均受到4個高危漏洞的影響,其中有兩個是遠程代碼執行漏洞(CVE-2017-0781 和 CVE-2017-0782),有一個可被利用來進行MITM攻擊(CVE-2017-0783),還有一個會導致信息泄露(CVE-2017-0785)。

Windos設備中Windows Vista以外所有版本系統均受「Bluetooth Pineapple」 攻擊(CVE-2017-8628)影響,可使攻擊者進行MITM攻擊。微軟已在今年7月11日發布安全更新,並在9月12日發布了相應的通知。iOS設備中iPhone, iPad, iPod在iOS 9.3.5及以下版本,AppleTV7.2.2及以下版本均受RCE(遠程代碼執行漏洞)影響。

背景及相關知識

首先給出armis的披露漏洞時,整理的藍牙架構圖:

圖上把藍牙的各個層次關係描述得很詳盡,不過我們這裡暫時只需要關心這麼幾層:HCI,L2CAP,BNEP,SDP。BNEP和SDP是比較上層的服務,HCI在最底層,直接和藍牙設備打交道,而承載在藍牙服務和底層設備之間的橋樑,也就是L2CAP層了。每一層都有它協議規定的數據組織結構,所有層的數據包組合在一起,就是一個完整的藍牙包(一個SDP包為例):

雖然協議在各個平台的架構一樣,但具體實現方式有所不同,Linux用的BlueZ,而Android用的BlueDroid。

  • 在Linux里,用的是BlueZ架構,c 通過註冊sock協議的方式提供了針對userspace的介面。

L2CAP的數據是由HCI層傳過來的,在hci_core.c的hci_rx_work函數里處理,當L2CAP層有SDP數據後,通過sdp-server.c中的io_session_event來獲取這個數據包,遞交給sdp-request.c的handle_request。

  • 在Android里用的時BlueDroid架構。這個和BlueZ架構很大不同的一點是:BlueDroid將L2CAP層放在了userspace。

SDP連接建立起來後,在收到SDP數據包之後呢,會觸發回調函數sdp_data_ind,這個函數會把數據包交個sdp-server.c的sdp_server_handle_client_req函數進行處理。BNEP連接建立起來後,再收到BNEP的包,和SDP類似,會觸發回調函數bnep_data_ind,這個函數包含了所有對BNEP請求的處理。

漏洞分析

Armis披露漏洞時,介紹了細節。360VulpeckerTeam對這幾個漏洞進行了深入分析,這裡引用借鑒下。

CVE-2017-1000251

這個漏洞觸發的思路如下:

  • 建立和目標機器的L2CAP 連接,這裡sock_type的選擇應該是SOCK_RAW,如果不是,內核會自動幫我們完成sent_infomation_request , send_connection_request, send_configure_request這些操作,也就無法觸發目標機器的漏洞了。
  • 建立SOCK_RAW連接,connect的時候,會自動完成sent_infomation_request的操作,不過這個不影響。
  • 接下來我們需要完成send_connection_request操作,來確定SCID,DCID。完成這個操作的過程是發送合法的 L2CAP_CONN_REQ數據包。
  • 接下來需要發送包含有L2CAP_CONF_EFS類型的數據,而且L2CAP_CONF_EFS數據的stype == L2CAP_SERV_NOTRAFIC的L2CAP_CONF_REQ包,這一步是為了讓目標機器的conf_state變成CONF_LOC_CONF_PEND。
  • 這裡就到了發送cmd_len很長的L2CAP_CONN_RSP包了。這個包的result欄位需要是L2CAP_CONF_PENDING。這個包發過去之後,目標機器內核就會棧溢出,要麼重啟了,要麼死機了。

我們的漏洞發生在對L2CAP_CONFIG_RSP(config response)的處理上。那麼來看l2cap_config_rsp:

staticinline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) { struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data; ... scid = __le16_to_cpu(rsp->scid); //從包中剝離出scid flags = __le16_to_cpu(rsp->flags); //從包中剝離出flag result = __le16_to_cpu(rsp->result); //從包中剝離出resultswitch(result) { caseL2CAP_CONF_SUCCESS: l2cap_conf_rfc_get(chan, rsp->data, len); clear_bit(CONF_REM_CONF_PEND, &chan->conf_state); break; caseL2CAP_CONF_PENDING: set_bit(CONF_REM_CONF_PEND, &chan->conf_state); if(test_bit(CONF_LOC_CONF_PEND, &chan->conf_state)) { charbuf[64]; //buf數組大小64位元組 len = l2cap_parse_conf_rsp(chan, rsp->data, len, buf, &result); ... } gotodone; ...

當收到的數據包里,滿足result == L2CAP_CONF_PENDING,且自身的連接狀態conf_state == CONF_LOC_CONF_PEND的時候,會走到 l2cap_parse_conf_rsp函數里,而且傳過去的buf是個長度為64的數據,參數len ,參數rsp->data都是由包中的內容來任意確定。那麼在l2cap_parse_conf_rsp函數里:

仔細閱讀這個函數的代碼可以知道,這個函數的功能就是根據傳進來的包,來構造將要發出去的包。而數據的出口就是傳進去的64位元組大小的buf。但是對傳入的包的數據的長度並沒有做檢驗,那麼當len很大時,就會一直往出口buf里寫數據,比如有64個L2CAP_CONF_MTU類型的opt,那麼就會往buf里寫上64*(L2CAP_CONF_OPT_SIZE + 2)個位元組,那麼顯然這裡就發生了溢出。由於buf是棧上定義的數據結構,那麼這裡就是一個棧溢出。

CVE-2017-1000250

這個漏洞是BlueZ的SDP服務里的信息泄露漏洞。這個不像L2CAP層的連接那麼複雜,主要就是上層服務,收到數據就 進行處理。那麼我們也只需要關注處理的函數。BlueZ的SDP收到數據是從io_session_event開始。之後,數據的流向是:

io_session_event–>handle_request–>process_request。

SDP協議它有一個sdp_pud_hdr的頭部,頭部數據里定義了PUD命令的類型,tid,以及pdu parameter的長度,然後就是具體的parameter。最後一個欄位是continuation state,當一個包發不完所要發送的數據的時候,這個欄位就會有效。對於這個欄位,BlueZ給了它一個定義:

typedefstruct { uint32_t timestamp; union { uint16_t maxBytesSent; uint16_t lastIndexSent; } cStateValue; } sdp_cont_state_t;

對於遠程的連接,PDU命令類型只能是這三個:SDP_SVC_SEARCH_REQ, SDP_SVC_ATTR_REQ, SDP_SVC_SEARCH_ATTR_REQ。這個漏洞出現在對SDP_SVC_SEARCH_ATTR_REQ命令的處理函數service_search_attr_req裡面 ,其功能有這幾點:

  • extract_des(pdata, data_left, &pattern, &dtd, SDP_TYPE_UUID); 解析service search pattern(對應SDP協議數據結構圖)
  • max = get_be16(pdata); 獲得Maximu Attribute Byte
  • scanned = extract_des(pdata, data_left, &seq, &dtd, SDP_TYPE_ATTRID);解析Attribute ID list
  • if (sdp_cstate_get(pdata, data_left, &cstate) < 0) ;獲取continuation state狀態cstate,如果不為0,則將包里的continuation state數據複製給

漏洞發生在對cstate狀態不為0的時候,這部分代碼:

sdp_buf_t *pCache = sdp_get_cached_rsp(cstate); if (pCache) { uint16_t sent = MIN(max, pCache->data_size - cstate->cStateValue.maxBytesSent); pResponse = pCache->data; memcpy(buf->data, pResponse + cstate->cStateValue.maxBytesSent, sent); buf->data_size += sent; cstate->cStateValue.maxBytesSent += sent; if (cstate->cStateValue.maxBytesSent == pCache->data_size) cstate_size = sdp_set_cstate_pdu(buf, NULL); elsecstate_size = sdp_set_cstate_pdu(buf, cstate);

sdp_get_cached_rsp函數其實是對cstate的timestamp值的檢驗,如何過這個檢驗之後再說。當代碼走到第五行處的memcpy時,由於cstate->maxBytesSent就是由數據包里的數據所控制,而且沒有做任何檢驗,所以這裡可以為任意的uint16_t值。那麼很明顯,這裡就出現了一個對pResponse的越界讀的操作。而越界讀的數據還會通過SDP RESPONSE發送給攻擊方,那麼一個信息泄露就發生了。

CVE-2017-0785

這個漏洞也是SDP的信息泄露漏洞,不過是BlueDroid的。與BlueZ的那個是有些類似的。我們也從對SDP數據包的處理函數說起。 SDP數據包會通過sdp_data_ind函數送給sdp_server_handle_client_req。與BlueZ一樣,這個函數也會根據包中的pud_id來確定具體的處理函數。這個漏洞發生在對SDP_PDU_SERVICE_SEARCH_REQ命令的處理,對包內數據的解析與上文BlueZ中的大同小異,不過注意在BlueDroid中,cstate結構與BlueZ中有些不同:

typedefstruct { uint16_t cont_offset; } sdp_cont_state_t;

關注漏洞處的代碼:

Ⅰ,Ⅱ中代碼可以看出,變數num_rsp_handles的值,一定程度上可以由包中的Maximu Attribute Byte欄位控制。

Ⅲ中代碼是對帶cstate的包的處理,第一步是對大小的檢查,第二步是獲得cont_offset,然後對cont_offset進行檢查,第三步就到了

rem_handles = num_rsp_handles – cont_offset

可以思考一種情況,如果num_rsp_handles < cont_offset,那麼這個代碼就會發生整數的下溢,而num_rsp_handles在一定程度上我們可以控制,而且是可以控制它變成0,那麼只要cont_offset不為0,這裡就會發生整數下溢。發生下溢的結果給了rem_handles,而這個變數代表的是還需要發送的數據數。

在④中,如果rem_handles是發生了下溢的結果,由於它是uint16_t類型,它將變成一個很大的數,所以會走到 p_ccb->cont_offset += cur_handles;,cur_handles是一個固定的值,如果這個下溢的過程,發生很多次,p_ccb->cont_offset就會變得很大,那麼在5處,就會有一個對rsp_handles數組的越界讀的產生。

下面的操作可以讓這個越界讀發生:

  • 發送一個不帶cstate的包, 而且Maximu Attribute Byte欄位設置的比較大。那麼結果就是rem_handles = num_rsp_handles,而由於max_replies比較大,所以num_rsp_handles會成為一個比較大的值。只要在Ⅳ中保證rem_handles > cur_handles,那麼p_ccb->cont_offset就會成為一個非0值cur_handles。這一步是為了使得p_ccb->cont_offset成為一個非0值。
  • 接收服務端的回應包,這個回應包里的cstate欄位將會含有剛剛的p_ccb->cont_offset值,我們取得這個值。
  • 發送一個帶cstate的包,cont_offset指定為剛剛提取的值,而且設置Maximu Attribute Byte欄位為0。那麼服務端收到這個包後,就會走到rem_handles = num_rsp_handles – cont_offset 從而發生整數下溢,同時p_ccb->cont_offset又遞增一個cur_handles大小。
  • 重複2和3的過程,那麼p_ccb->cont_offset將越來越大,從而在⑤出發生越界讀,我們提取服務端返回的數據,就可以獲得泄露的信息的內容。

CVE-2017-0781

BlueDroid中BNEP服務對於接受到的數據包的處理也不複雜:

  • 解析得到BNEP_TYPE,得到extension位。
  • 檢查連接狀態,如果已經連接則後續可以處理非BNEP_FRAME_CONTROL的包,如果沒有建立連接,則後續只處理BNEP_FRAME_CONTROL的包。
  • 去BNEP_TYPE對應的處理函數進行處理。
  • 對於BNEP_TYPE不是BNEP_FRAME_CONTROL而且有extension位的,還需要對extension的數據進行處理。
  • 調用pan層的回調函數。

值得注意的是,BNEP連接真正建立起來,需要先處理一個合法的BNEP_FRAME_CONTROL數據包。CVE-2017-0781正是連接還沒建立起來,在處理BNEP_FRAME_CONTROL時所發生的問題:

caseBNEP_FRAME_CONTROL: ctrl_type = *p; p = bnep_process_control_packet (p_bcb, p, &rem_len, FALSE); if (ctrl_type == BNEP_SETUP_CONNECTION_REQUEST_MSG && p_bcb->con_state != BNEP_STATE_CONNECTED && extension_present && p && rem_len) { p_bcb->p_pending_data = (BT_HDR *)osi_malloc(rem_len); memcpy((UINT8 *)(p_bcb->p_pending_data + 1), p, rem_len); p_bcb->p_pending_data->len = rem_len; p_bcb->p_pending_data->offset = 0; }

上述代碼中,malloc了一個rem_len的大小,這個是和收到的數據包的長度相關的。可是memcpy的時候,卻是從p_bcb->p_pending_data+1開始拷貝數據,那麼這裡會直接溢出一個sizeof(*(p_bcb->p_pending_data))大小的內容。這個大小是8.所以只要代碼走到這,就會有一個8位元組大小的堆溢出。而要走到這,只需要過那個if的判斷條件,而這個if其實是對BNEP_SETUP_CONNECTION_REQUEST_MSG命令處理失敗後的錯誤處理函數。那麼只要發送一個錯誤的BNEP_SETUP_CONNECTION_REQUEST_MSG命令包,就可以進入到這段代碼了觸發堆溢出了。

CVE-2017-0782

這個也是由於BNEP協議引起的漏洞,首先它是個整數溢出,整數溢出導致的後果是堆溢出。

問題出在BNEP對extension欄位的處理上:

上述代碼中,ext_len = *p++的ext_len從數據包中獲得,沒有長度的檢查,可為任意值。而當control_type為一個非法值的時候,會走到*rem_len -= (ext_len – 1),那麼這裡就很有說法了,我們如果設置ext_len比較大,那麼這裡就會發生一個整數下溢。從而使得rem_len變成一個很大的uint16_t的值。這個值將會影響後續的處理:

上面的代碼中,bnep_process_control_packet()處將發生整數下溢出,使得rem_len成為一個很大的值(比如0xfffd),p_buf->len=rem_len處會將這個值賦值給p_buf->len。If()中,是回調函數處理這個p_buf,在BlueDroid中這個函數是pan_data_buf_ind_cb,這個函數會有一條路徑調到bta_pan_data_buf_ind_cback,而在這個函數中:

memcpy用到了我們傳進來的p_buf,而p_buf->len是剛剛下溢之後的很大的值,所以主要保證sizeof(tBTA_PAN_DATA_PARAMS) > p_buf->offset,這裡就會發生一次很大位元組的堆溢出。

CVE-2017-0781和CVE-2017-0782導致了堆溢出,一般會使得com.android.bluetooth崩潰,但是這個進程崩潰系統不會有提醒,需要去logcat來找崩潰的日誌。這是兩個很有價值的堆溢出漏洞,結合前面的信息泄露漏洞,是完全可以進行遠程代碼執行的。

總結

現在關於這五個漏洞的PoC,github有很多,安裝上pybluez和pwntools,嗅探到藍牙地址,便可進行攻擊,簡單的演示如下:

我們使用的智能機,平板電腦,可穿戴設備大多都支持藍牙功能。這些設備均受前面提到的幾個漏洞的影響。當手機打開藍牙時,無需任何操作,攻擊者便可在我們毫無察覺的狀態下,完全控制手機。Wifi晶元可能被黑,wpa2協議進行加密會被監聽,現在藍牙也不安全。普通用戶,最主要的還是提高安全意識,及時更新設備的安全補丁。

總結

電腦CPU不安全,手機WIFI晶元有問題,無線上網有可能被竊聽,用藍牙也可能被攻擊。用戶需要警惕但也不必過度恐慌,這些都屬於高級攻擊方法,利用技術門檻比較高,不容易造成廣泛性攻擊事件。

平台安全中核心的兩個問題:

  • 固件安全

硬體對固件進行支持,固件對操作系統提供服務。這個「承上啟下「的位置說明了他的重要性。固件中運行專有和複雜的代碼庫,不安全的固件會削弱設備的整體安全性,引入危及整個系統的漏洞。

  • 規範的制定以及實現

規範,包括但不限於協議,格式,處理模型。這方面例如WPA2 KRACK密鑰重載攻擊是協議制定時,沒有處理好重傳幀的情況;又例如BlueBorne藍牙漏洞是在各個平台中,規範實現時的出現的問題。

文中所講的問題,僅僅影響到信息的安全。IoT,IoE,人工智慧……一場又一場革命將我們帶入智能時代。智能家居和自動駕駛這些科技產物已經融入了我們生活,如果不注意這方面的平台安全,危及的可是用戶的生命和財產。所以,這些新興科技的平台安全問題,將是我們之後關注的重點。

參考鏈接

intel.com/content/www/u

googleprojectzero.blogspot.jp

cert.360.cn/static/file

https://www.krackattacks.com

papers.mathyvanhoef.com

github.com/kristate/kra

blog.cryptographyengineering.com

git.archlinux.org/svnto

git.archlinux.org/svnto

svn.dd-wrt.com/changese

bobao.360.cn/learning/d

armis.com/blueborne/

anquanke.com/post/id/86

blog.csdn.net/rain0993/

people.csail.mit.edu/al


推薦閱讀:

2018網路安全行業全景圖,幾維安全名列前茅
幾維安全提醒勒索病毒又來襲 網路安全行業或迎機遇
「安全開發教學」github泄露掃描系統開發
網友發布違法文檔被拘留
安全數據科學是什麼?

TAG:網路安全 |