作者:「Tencent Blade Team」Leonwxqian & Xbalien & Nicky
公眾號:騰訊安全應急響應中心http://https://mp.weixin.qq.com/s/4kO3pU_tCDZmgj2CkROzMg
0x01 前言
智能音箱是近幾年最熱門的智能設備,在銷量的暴漲背后,各種智能音箱“偷聽”的新聞也讓人們非常擔心智能音箱會泄露自己的隱私,而在2018年初Tencent Blade Team把關注點放在了智能音箱自身的安全漏洞上,當時國外的蘋果,谷歌,亞馬遜,以及國內的阿里巴巴,百度,小米均已加入了這個戰場發布了各自的智能音箱產品,團隊選取當時全球用戶最多,破解難度最高的Amazon Echo,Google Home,小米AI音箱作為研究目標,耗時近一年時間完成了對這三款智能音箱的遠程無接觸式破解(靜默竊聽/RCE/ROOT)并協助廠商完成了漏洞修復。
0x02 概述
Google Home是Google在2017年發布的系列智能音箱產品,在全球擁有超過5000萬用戶,銷量僅次于Amazon Echo系列智能音箱。

在本文中,我們將分享Tencent Blade Team在2018年下半年利用多個漏洞遠程攻破Google Home音箱實現遠程代碼執行的研究成果。
Google Home音箱采用精簡版Chrome OS作為操作系統,這一系統之前普遍使用在Google Chromecast產品中,研究資料較少,同時系統特性相比市面上其它基于Linux和Android系統的智能音箱存在著不少差異,所以破解難度更高,Google Home與Amazon Echo都是這兩年Mobile Pwn2own的獎金最高的IoT比賽項目。

0x03 固件提取與分析
Google Home的系統固件并未公開下載,但Google遵循開源協議公開了Google Home音箱系統部分源代碼資料,如下圖,可以看到包含Google Home/Chromecast系列設備固件的信息,包括Bootloader、Kernel以及系統部分二進制程序等,甚至還包括帶符號的.o文件,這些文件能夠幫助我們快速了解Google Home/Chromecast系列的設備的概況。

此外Google Home在其OTA流程中雖然通過HTTPS請求檢測是否存在新版本,但使用了HTTP的方式下載固件,所以當云端有新版本固件推送,設備下載更新包時可以通過局域網嗅探抓包的方式拿到固件(最佳時機是新設備第一次聯網時)。

除了抓包獲取固件外,我們后期分析代碼發現也可以主動模擬設備更新請求,獲取不同設備最新的更新包。通過如下圖中的CURL命令就能夠獲取,需要在請求中填入合適的設備版本以及對應產品的代號。

以上三種方法使我們可以比較方便的獲得Google Home的部分系統文件,但如果我們需要獲得完整固件或者嘗試通過修改系統文件的方式搭建漏洞調試環境,最快速及暴力的方法的還是從硬件下手,由于整個Google Home系列產品硬件幾乎類似,我們以Google Home mini為例進行拆解,發現其使用了Marvell的Amada系列主控,以及東芝的NAND Flash芯片。

在簡單嘗試未發現主板存在燒錄/調試接口后,我們使用熱風槍將Flash芯片焊下,選擇直接使用編程器讀取Flash芯片中的固件。通過對比芯片的datasheet我們發現此芯片使用BGA67的封裝方式,BGA的芯片封裝方式在小型智能設備上很常見,不過由于我們沒有找到適合BGA67的轉接座將芯片測試座(如下圖)導出的接口直接連接到編程器,所以我們需要使用飛線連接或設計一個新的轉接座。

由于從測試座直接人工焊接飛線難度過高(焊點間距不到1mm),我們選擇了使用PCB設計軟件自己設計一個轉接座并轉由淘寶PCB制板廠商生產了一塊樣板。

此時我們可以將Flash轉接座與RT809H編程器連接,并直接提取整個Flash芯片原始數據。

不同自帶主控的EMMC芯片,我們從NAND Flash芯片中提取的是原始Flash數據,還需要對其中的OOB數據及ECC校驗位進行處理,最終才能解析出正確的文件系統與數據。

以下就是Google Home的完整系統目錄:

在對獲取的固件包以及公開資源進行分析后,我們發現在整個Google Home的啟動流程中,Bootloader、boot.img以及system.img,都是需要通過安全校驗才能加載的:
Bootloader和boot.img使用的簽名方式相同,采用SHA256+RSA簽名實現;在Bootloader正常流程中沒有提供解鎖的邏輯,只有簽名驗證通過才會加載boot.img;

除此之外,Google Home還對system.img進行驗證。主要通過內核啟用了Dm-verity驗證機制,極大增加了通過硬件方法修改system.img完成實現root的難度。

在少數的系統程序中,最核心的cast_shell可以認為就是一個Chrome瀏覽器,這個進程同時也受沙箱機制的保護。

在Chrome OS上,沙箱機制主要涵蓋setuid,user namespace 和seccomp-bpf。除此之外,在利用緩解措施方面,系統也啟用了ASLR機制,cast_shell程序也包含了NX和Stack Canary。
0x04 Google Home攻擊面

網絡通信上,Google Home開放了多個端口,其中包含端口8008。這是HTTP服務器,方便用戶在局域網內向Google Home進行基本命令操作。若路由器開啟了UPnP Forwarding,則有可能將局域網擴展到互聯網,之前在youtube的網站上熱傳的Cast Hack就是此原理進行批量遠程攻擊。8009端口主要是Google CAST 協議通信端口,采用TLS和protocol buffer封裝,我們發現CAST協議能夠遠程將任意頁面推送到Google Home的cast_shell中訪問,這得我們可以將攻擊Google Home轉換為攻擊Chrome瀏覽器;
無線協議上,Google Home使用的是Marvell的芯片,關于Marvell Wi-Fi , BLE固件攻擊的思路都可以進行嘗試。在去年的Zero Nights會議上,就有關于Marvell Wi-Fi固件的攻擊方法。
另外,效仿由HubCap(通過Bootloader Usb協議處理的漏洞完成Chromecast的root),挖掘Bootloader里的漏洞也是可以嘗試的思路。
0x05 Google Cast協議暗藏的風險
在上節我們提到了CAST協議,在架構上Google CAST協議包括Sender和Receiver。Sender可以是移動設備或者Chrome,而Receiver則是加載了CAST APP的接收設備,例如Google Home就是一個Receiver。

先來介紹CAST APP的加載流程,正如下圖所示:

當用戶通過Sender(移動設備或者Chrome)訪問了Sender Application時,便會通過CAST協議尋找局域網內的Receiver并與之通信,接著Receiver會去CAST APP市場拉取指定的APP鏈接并通過cast_shell加載訪問。
在這個過程中,我們發現CAST協議存在著以下安全風險,這些風險將是后續攻擊Google Home的關鍵所在:
-
CAST APP可以是任何網頁。若給定的CAST APP是惡意的網頁,Google Home仍會訪問它;
-
CAST應用商店中的應用可能是惡意的。當攻擊者注冊為CAST開發者后就可上傳CAST應用,并且看起來并未經過嚴格審核,很快就可以發布并上線;
-
局域網內,Sender可以直接發送CAST協議,甚至不需要用戶交互。
綜合以上幾點安全風險,可以巧妙的把攻擊Google Home轉換為對瀏覽器的攻擊。具體的攻擊過程大致為以下思路:
-
攻擊者欺騙用戶通過Chrome瀏覽器或移動設備訪問Sender Application。通過SENDER URL觸發CAST協議讓Google Home訪問CAST RECEIVER URL(CAST APP鏈接地址);
-
若攻擊者和Google Home位于同一個局域網,攻擊者還可以直接與端口8009進行CAST協議交互(例如發送LAUNCH APP請求),直接觸發Google Home訪問CAST RECEIVER URL。
-
更糟糕的是,若用戶家中的路由器打開UPnP Forwarding,攻擊者也可以在互聯網上完成遠程靜默攻擊。
下圖為CAST APP的發布界面與局域網觸發CAST協議交互的代碼:

0x06 Magellan漏洞詳情
在確定了利用CAST協議作為我們的遠程攻擊入口后,我們開始對Google Home中的核心程序cast_shell(Chrome瀏覽器)進行了漏洞審計,經過一段時間的研究我們在Chrome瀏覽器核心組件sqlite3中發現了多個高風險0day漏洞,我們把這組漏洞命名為Magellan。
Magellan漏洞對所有平臺(Android、Chrome OS、Windows、Linux、Mac)上的Chrome、Webview都會產生影響。包括使用Webview的產品,如Android App內嵌webview網頁瀏覽功能的APP,或使用sqlite3的客戶端與服務器軟件,如Apache+PHP等。
在下面的部分我們將介紹Magellan漏洞的相關細節。
6.1 CVE-2018-20346
fts3擴展中的merge操作可能允許攻擊者泄漏堆數據或導致堆緩沖區溢出。
-
表結構而言,fts3和fts4非常相似,在Chrome中關閉了fts4。
-
fts3和fts4都有一些表來存儲節點信息。
-
sqlite不禁止用戶修改(CREATE,INSERT,DELETE)這些表(%_SEGMENTS,%_SEGDIR,%_STAT)的數據。
-
fts4與fts3共享很多代碼分支,可以通過添加一些特殊的內置表(如%_stat)來激活。
-
sqlite3使用assert()進行條件檢查,但當Google構建Chrome時,assert變為void(),因為它不是debug版本。
因此,Google Chrome的發布版本中缺少許多關鍵條件檢查,sqlite3中也會發生同樣的事情。
- 當我們偽造一些關鍵的內置表和記錄,并調用
merge函數時,該函數會從攻擊者控制的內存區讀取數據,并執行memcpy操作,從而導致一些堆相關問題。
通過下面的代碼,我們可以觸發漏洞:

首先,我們嘗試通過nodeReaderInit→nodeReaderNext讀取錯誤的值nDoclist(由攻擊者控制)。
然后,將惡意的nDoclist值傳遞給fts3AppendToNode,我們可能會在這兩個地方導致堆緩沖區溢出:

在我們的攻擊中,我們選擇使用第二個點,因為它更穩定和易于使用。
nDoclist和aDoclist是可控制的,pNode->a和pNode->n也可以由我們調整,因此我們可以做堆風水。
6.2 CVE-2018-20505
fts3擴展中的fts3ScanInteriorNode(match)可能允許攻擊者泄漏堆數據或導致堆緩沖區溢出。
簡單介紹要利用的步驟:
-
將%_segdir中的節點設置為不是根節點。
-
修改節點的BLOB數據。
-
調用
match觸發攻擊。
有漏洞的函數如下:

1.函數fts3GetVariant32,該函數最多返回0x7fffffff的整數(輸入數據為Little-endian,輸入ff ff ff ff 07將產生輸出0x7fffffff)。
代碼將從BLOB(zNode)中提取nPrefix和nSuffix,BLOB可由攻擊者控制。

2.第一次檢查,將檢查zCsr+nSuffix-1是否超過zEnd。
但在32位機器(如Google Home)中,堆通常位于大于0x7fffffff的地址中,當加上另一個較大的數字(如0x7fffffff)時,必然存在整數溢出,結果可能非常小,此檢查將通過。

zCsr是表示BLOB中當前位置的指針,zEnd是指向BLOB的最后一個字符的指針。
如zCsr=0xe00000000,zEnd=0xe0002000,nSuffix=0x20000001,zCsr+nSuffix的結果為0x1,小于zEnd,可以通過此檢查。
總而言之,可能有2個條件:
a).nSuffix小于未處理的實際數據量。
b).nSuffix是一個巨大的數字,導致zCsr+nSuffix的整數溢出,我們認為b在Google Home中是可利用的。
選擇的值將對下一次驗證產生影響,我們將在此處將該值命名為“X”。
3、第二次檢查

變量nAlloc是分配的緩沖區數量,通常每次值增加兩倍。
請注意,nAlloc可以大于實際數據,并且不能保證重新分配的內存區內的數據是從原始BLOB獲得的,因此我們可以在這里泄漏一些堆信息。
d)如果nSuffix滿足上述條件(a),但nPrefix大于buf持有的實際數據,則下一步可能存在信息泄漏問題。
(因為sqlite3_realloc調用libc的realloc,這不會將內存初始化為零)。
e)如果(nPrefix+nSuffix)*2大于0x1`0000 0000(僅保留低32位),則在realloc之后,buf將被設置為非常小的緩沖區,這可能使緩沖區溢出。
攻擊者可以將nPrefix設置為較大的值,而將nSuffix設置為較小的值,這將導致越界寫。
f)如果我們選擇利用a)或b),將nSuffix(我們稱其為“Y”)設置為Y=0x80000000-X(你可能不想將Y設置為80000000-X,你可以這么做,但如果這樣做,則很可能會在memcpy期間崩潰)。
例如,
-
我們有zCsr=0xa0000000,nPrefix=7ffff001來觸發zCsr+nPrefix-1,結果是0x1 1FFF000,較高的0x1被截斷,因此它實際上是0x1ffff000。
-
我們將nSuffix設置為0xfff,因此nPrefix+nSuffix整數溢出,結果是0x0,0x0小于nalloc,因此我們不會進入realloc部分。(if( nPrefix+nSuffix>nAlloc ) {realloc…})
-
因此,最后,將會有一個寫大小為0xfff的對0x1ffff000的越界寫入。
4、觸發緩沖區相關漏洞的代碼h)
memcpy(&zBuffer[nPrefix],zCsr,nSuffix);
這將復制數據,并且nPrefix、zCsr、nSuffix是可控制的。nPrefix,nSuffix的最大值為0x7fffffff。
5、信息泄漏i )

我們可以使用SELECT來獲取匹配的數據,以獲取泄漏的數據。
(我們現在沒有足夠的時間來編寫PoC,但我們認為這是可利用的。)
6.3 CVE-2018-20506
fts3擴展中的fts3SegReaderNext可能允許攻擊者泄漏堆數據或導致堆緩沖區溢出。
有漏洞的函數
此代碼位于fts3SegReaderNext中,此漏洞原理與6.2相同。

0x07 遠程攻破Google Home
本節將會介紹如何結合Google CAST協議安全風險與Magellan漏洞,對Google Home發起攻擊并最終實現遠程代碼執行。第一部分主要是編寫與調試CVE-2018-20346的漏洞利用代碼,這包含了尋找劫持控制流的函數指針,尋求觸發函數指針的調用路徑,堆內存布局及RCE。第二部分是通過CAST協議在局域網及互聯網遠程環境下推送payload到Google Home中實現惡意代碼執行。
7.1可利用函數指針
首先,需要找到在堆上使用的函數指針用于劫持控制流。在創建fts3表時,默認情況下會創建tokenizer其默認值為simple_tokenizer。具體結構如下圖所示:

simple_tokenizer是堆上分配的結構,其成員base指向sqlite3_tokenizer結構,sqlite3_tokenizer結構的成員pModule指向tokenizer_module,而tokenizer_module包含了許多回調函數,例如xCreate / xOpen。分析調用流程后,我們了解到在對fts3表進行插入操作時將觸發xOpen回調函數,若將xOpen的地址修改為任意地址,則可以劫持PC。
7.2 劫持PC
在漏洞觸發后的路徑上,若要完成前述的PC劫持需要滿足兩個條件。第一,在堆溢出后能夠操作fts3表;另外,還需要在內存釋放前完成劫持,否則就會導致crash從而中斷利用過程。通過分析memcpy到free代碼路徑,存在函數fts3TruncateSegment,該函數會執行一次SQL update操作,正如下圖藍色標記的代碼。既然能夠執行SQL語句,那么就可以利用SQL Trigger在執行該update操作前執行fts3表的操作

最終,我們通過Trigger在SQL update操作和free內存之前執行了fts3 表的插入操作,進而觸發xOpen回調完成劫持PC。
7.3 堆內存布局
完成了前述兩步后,接下來將會介紹進行內存布局的思路。具體思路如下圖:

-
通過創建多個fts3表,即可在堆上創建多個simple_tokenizer結構;
-
選擇適當的時機刪除之前創建的fts3表,對應simple_tokenizer結構也會隨之釋放;
-
由于simple_tokenizer結構體在堆上會連續存儲且分配與simple_tokenizer相同大小的內存將會重用已經釋放的simple_tokenizer結構。因此,通過調整payload大小,可以將fts3表的simple_tokenizer結構覆蓋掉;
-
最后,利用SQL Trigger執行fts3表的操作,觸發被覆蓋的回調函數來劫持PC。
7.4繞過ASLR
當具備劫持PC和控制寄存器的能力后,我們還需要信息泄露漏洞繞過ASLR。同樣還是利用漏洞CVE-2018-20346,通過調節nDoclist和pNode->a,就能夠泄露以下兩類地址:
-
泄露cast_shell加載基址,根據該地址和偏移計算出需要的ROP gadgets;
-
泄露最后堆的基址,根據這個地址和偏移,較大概率能計算出堆噴地址。
7.5 cast_shell渲染進程RCE
cast_shell是一個很大的二進制程序,包含了很多可用的ROP gadget。結合堆噴和ROP技術,便可以在cast_shell的renderer中遠程執行代碼,下圖為ROP和堆噴內存狀況:

一個堆噴單元里面包含偽造的sqlite3_tokenizer_module和ROP gadgets。偽造的sqlite3_tokenizer_module結構體里的xCreate/xOpen地址將會被賦值為stack pivot地址。堆噴的過程就是把多個這樣的單元插入到數據庫的表中。經過多次嘗試,可以把其放置在和最后堆基址相對固定的偏移上;而溢出后覆蓋的simple_tokenizer結構里包含了stack pivot所需的寄存器數據。一切順利的話,將能在cast_shell的renderer里實現遠程代碼執行,效果如下圖所示:

左圖表示可以完成了PC劫持和控制的寄存器。右圖則是ShellCode的運行結果(正常情況下,navigator.appName是只讀數據,為”Netscape”,Shellcode代碼執行后將其改成了”AAAAcape”。
7.6 局域網內與遠程攻擊鏈

局域網攻擊鏈
局域網內,攻擊者可以直接發送CAST協議完成攻擊。
-
通過"Launch APPID=1"的指令,Google Home會根據APPID拉取應用市場上的Leak.html并加載,可利用該惡意網頁用于泄露內存數據;
-
接著,發送"Launch APPID=2"的指令,Google Home就會加載Exp.html,從而遠程代碼執行,整個過程不需要用戶交互。
互聯網遠程攻擊鏈
-
攻擊者誘導用戶通過Chrome瀏覽器訪問Sender Application的url,這時Chrome瀏覽器會提示用戶選擇設備,用戶確認后將會開始攻擊流程;
-
參考Cast Hack的攻擊思路,通過掃描網絡上存在UPnP Forwarding的路由器,嘗試發起遠程攻擊;
0x08 后記
在向Google報告漏洞后,Google在2018年12月的Chrome安全補丁中修復了我們提交的所有漏洞。

本文是Tencent Blade Team物聯網安全系列的第一篇,主要內容整理自團隊在BlackHat USA 2019及DEFCON27的演講,由于篇幅限制部分內容無法詳細敘述,大家可以參考附錄中的whitepaper,同時也歡迎大家同我們進行技術交流,聯系方式參見Blade Team官網: (https://blade.tencent.com)
參考:
- https://drive.google.com/drive/folders/0B3j4zj2IQp7MZkplRzRvcERtaU0
- https://2018.zeronights.ru/wp-content/uploads/materials/19-Researching-Marvell-Avastar-Wi-Fi.pdf
- https://github.com/axoltl/HubCap
- https://developers.google.com/cast/docs/developers
- https://blade.tencent.com/magellan/
- https://chromereleases.googleblog.com/2018/12/stable-channel-update-for-desktop.html
- https://media.defcon.org/DEF%20CON%2027/DEF%20CON%2027%20presentations/DEFCON-27-Wenxiang-Qian-Yuxiang-Li-Huiyu-Wu-Breaking-Google-Home-Exploit-It-with-SQLite-Magellan.pdf
- http://i.blackhat.com/USA-19/Thursday/us-19-Qian-Exploring-The-New-World-Remote-Exploitation-Of-SQLite-And-Curl.pdf
- https://i.blackhat.com/USA-19/Thursday/us-19-Qian-Exploring-The-New-World-Remote-Exploitation-Of-SQLite-And-Curl-wp.pdf
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1111/
暫無評論