作者:啟明星辰ADLab

一、概述

Android系統中,藍牙組件可以說是安全漏洞重災區,2017年ArmisSecurity安全團隊公布BlueBorne組合漏洞攻擊鏈可以通過藍牙對智能手機進行遠程攻擊,危害性極大。

今年三月份的Android安全公告中,系統層漏洞全部都是藍牙組件漏洞,總共10個。漏洞多分布在SDP(服務發現協議)和BNEP(藍牙網絡封裝協議)中,而且漏洞類型多是內存越界讀寫。四月份的安全公告中,總共有7個藍牙組件漏洞,多分布在AVRCP(音頻/視頻遠程控制配置文件)協議中。六月份和七月份Android 安全公告中依然披露了多個藍牙組件漏洞,涉及藍牙協議棧中多個協議,涉及的源碼版本為6.0、 6.0.1、 7.0、 7.1.1、 7.1.2、 8.0、 8.1,覆蓋范圍較廣。

本文將介紹藍牙協議棧中的L2CAP協議和SMP協議,并對CVE-2018-9359和CVE-2018-9365這兩個漏洞案例進行詳細分析。

二、協議簡介

2.1 L2CAP

L2CAP(Logical Link Control and Adaptation Protocol)稱為邏輯鏈路和適配協議,是藍牙系統中的核心協議,位于數據鏈路層。L2CAP通過協議多分復用、分段和重組,向高層提供面向連接和無連接的數據服務。

2.1.1 L2CAP數據包格式

L2CAP是基于分組的,但也遵循信道傳輸的通信模型。L2CAP支持的信道有兩種:面向連接的信道和面向無連接的信道。在面向連接的信道中,L2CAP數據包的格式如下圖所示。

數據包中每個字段的說明如下所示:

2.1.2 L2CAP信令

兩臺藍牙設備通過L2CAP協議通信時,所有的信令都被發送到CID為0x0001的信道中。L2CAP信令的格式如下所示。

L2CAP信令中每個字段的說明如下所示:

L2CAP協議共有12種信令類型,各信令的作用如下所示。

另外,多個信令可以在同一個幀中發送,如下圖所示。

2.2 SMP

SMP(Security Manage Protocol)是藍牙協議棧中的安全管理協議,負責藍牙設備之間的配對和密鑰分配。

SMP命令格式如下圖所示。

其中,Code字段為一個8bit,標識命令的類型。SMP命令的類型如下表所示。 Data字段在長度上是可變的,Code字段決定Data字段的格式。

三、漏洞原理分析

3.1 CVE-2018-9359

(以下分析基于android-8.0.0_r4版本源碼)

CVE-2018-9359漏洞位于L2CAP協議模塊,漏洞類型是越界讀。可以通過谷歌官方公告看到漏洞補丁。漏洞補丁代碼位于/stack/l2cap/l2c_main.cc文件中的process_l2cap_cmd函數中,該函數主要功能是處理接收的L2CAP協議的信令包。

從代碼291行開始,while循環解析L2CAP數據包中所有的COMMAND命令。首先看一下兩個宏定義:STREAM_TO_UINT8從p指向的數據包中讀取1個字節,p指針加1;STREAM_TO_UINT16每次從p指向的數據包中讀取2個字節,p指針加2。

程序調用宏依次從p指向的數據包中讀取cmd_code、id和cmd_len字段,此時p應該指向data數據域的開頭。

當Code=0x1,代表Command reject數據包,數據包定義如下所示。當Length不為0,data數據域中包含兩個字段:Reason字段(2字節)和Data字段。

處理Command reject數據包的分支代碼如下:

從代碼可以看出,程序沒有判斷該命令包是否存在data數據域,在334行中直接使用宏讀取2個字節的rej_reason。因此在內存堆中發生越界讀漏洞。

這里也只是發生了內存越界讀取,沒有將讀取的數據泄露到客戶端中。下面找到發送返回包的代碼,查看如何產生內存泄漏。

從378行代碼開始是解析L2CAP_CMD_CONN_REQ命令分支,379行代碼,先越界讀取兩個字節的con_info.psm,380行代碼越界讀取兩個字節的rcid。381行調用l2cu_find_rcb_by_psm函數通過con_info.psm去遍歷尋找注冊控制塊地址。這里簡單介紹一下PSM這個概念。

PSM全稱為Protocol/ServiceMultiplexer,PSM的長度最少是2字節,它的值應當是奇數,就是最低的byte的最低位必須為1。另外,PSM的最高byte的最低位應當為0。它可以比2字節長,PSM由兩個范圍段組成,第一個范圍段是SIG用來表示對應protocol的,第二個范圍段是動態申請的和SDP結合使用。這個值用來支持特定protocol的不同實現。所以,在申請PSM的時候都是從0x1001開始申請的。原因就是0x0001~0x0eff都是被SIG保留的。那么這些保留的值都各自對應了哪些protocol呢?具體見下圖。

代碼382行判斷p_rcb是否為NULL,如果為空就調用l2cu_reject_connection函數,具體看一下該函數代碼。

從代碼520行到523行,通過宏UINT6_TO_STREAM將數據寫入p指向的內存中。

其中remote_cid就是之前越界讀取的兩個字節數據。構造好響應數據包后,代碼525行調用l2c_link_check_send_pkts將響應包發送到客戶端。

在六月份android安全公告中,CVE-2018-9359、CVE-2018-9360、CVE-2018-9361三個漏洞的補丁是一樣的。部分補丁代碼如下。

可以看出,補丁中添加了長度判斷。如果p+2>p_next_cmd不為真,說明存在data數據域,然后才開始讀取字節。

3.2 CVE-2018-9365

(以下分析基于android-8.0.0_r4版本源碼)

CVE-2018-9365是SMP(security manager protocol)協議中一個數組越界漏洞。該漏洞出現在smp_sm_event函數中,代碼路徑為:\smp\smp_main.cc。谷歌官方補丁代碼如下。

從補丁中可以看到,這里判斷了p_cb->role是否大于1,如果大于1報錯返回,補丁代碼下一行就是以p_cb->role為下標在smp_entry_table數組中查找。Smp_entry_table數組定義如下。

可以看到,smp_entry_table數組中只有兩項,一個是針對主設備,一個是針對從設備。當有數據包通過L2CAP在SMP信道中接收到時,會調用smp_data_received函數進行處理。Smp_data_received函數代碼如下。

代碼146行定位到內存中SMP數據包位置。代碼150行通過STREAM_TO_UINT8宏取出cmd。

第160行代碼判斷cmd的類型是否為配對請求指令或者安全請求指令。如果是,第164行開始對p_cb->role進行復制。通過名稱判斷,L2CA_GetBleConnRole函數應該是通過藍牙地址獲取藍牙設備的角色信息。對于藍牙設備來說,只有兩種角色,一是主設備角色,二是從設備角色。L2CA_GetBleConnRole函數代碼如下。

第201行定義了role,同時給role賦值為HCI_ROLE_UNKNOWN。宏定義如下所示。

Role先被復制為0xff,代碼205行是通過藍牙地址遍歷尋找p_lcb,如果p_lcb為空,則直接返回HCI_ROLE_UNKNOWN。P_cb->role被賦值為0xff后,后續代碼直接調用了smp_sm_event函數。代碼如下所示。

調用smp_sm_event函數,補丁前的代碼在957行由于沒有判斷p_cb->role的大小,導致數組越界訪問。

四、總結

通過對多個藍牙漏洞的分析,發現Android藍牙組件中的漏洞多是較為低級的代碼bug導致的,而且漏洞多出現在對數據包的解析代碼邏輯中。針對披露的這么多藍牙漏洞,安卓手機用戶還需及時更新官方推送的補丁,將安全隱患降低到最低。

相關鏈接

  1. https://android.googlesource.com/platform/system/bt/+/b66fc16410ff96e9119f8eb282e67960e79075c8%5E%21/#F0
  2. https://android.googlesource.com/platform/system/bt/+/ae94a4c333417a1829030c4d87a58ab7f1401308%5E%21/#F0
  3. https://blog.quarkslab.com/a-story-about-three-bluetooth-vulnerabilities-in-android.html

啟明星辰積極防御實驗室(ADLab)

ADLab成立于1999年,是中國安全行業最早成立的攻防技術研究實驗室之一,微軟MAPP計劃核心成員。截止目前,ADLab通過CVE發布Windows、Linux、Unix等操作系統安全或軟件漏洞近400個,持續保持國際網絡安全領域一流水準。實驗室研究方向涵蓋操作系統與應用系統安全研究、移動智能終端安全研究、物聯網智能設備安全研究、Web安全研究、工控系統安全研究、云安全研究。研究成果應用于產品核心技術研究、國家重點科技項目攻關、專業安全服務等。


Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/666/