【漏洞分析】如何用11個exp攻破三星S8

FLy_鵬程萬里發表於2018-06-25

Author:  Sniperhg@Vulpecker Team 、MissCoconut@Vulpecker Team

前言

在去年Mobile Pwn2Own上MWR Labs成功攻破了三星S8,據官方報導整個攻擊鏈總共由11個exp構成,是目前Pwn2Own歷史上最長利用鏈。上週MWR Labs公開了他們的Slide,在本次攻擊中,其高深之處並不在於使用了多少個0day,而是使用的都是系統自帶App層面的邏輯漏洞甚至是App特性的一連串的精巧組合而形成的攻擊鏈。本文根據這個slide來對其攻擊思路和步驟進行簡要分析。

初探


縱觀整個利用鏈,攻擊者的程式碼得以成功執行以及敏感資訊得以成功獲取,其中最關鍵的漏洞出現在三星手機自帶的應用商店Galaxy Apps中。

由於開發者疏忽,release版本的Galaxy Apps中存在如下遺留的除錯程式碼:


這段程式碼的作用是為了除錯Galaxy Apps與升級伺服器之間的連通性而去載入SD卡上的配置檔案(/sdcard/saconfig.ini),為方便本地除錯,配置檔案中可以手動指定升級伺服器地址,配置檔案格式如下所示:


攻擊者通過指定升級伺服器地址,再加上中間人轉發請求,可以讓Galaxy Apps安裝攻擊者指定的任意App。一般我們在平時的審計中,可以寫一個App去釋放這個配置檔案或是直接adb push配置檔案到/sdcard中,但在Pwn2Own比賽環境下,是無法連線USB進行adb install的,有限的物理接觸也僅能進行點選瀏覽器,開啟url等操作。那麼這裡是如何生成或是釋放這個關鍵的saconfig.ini檔案的,以及如何通過瀏覽器發動這個遠端攻擊的,筆者就來根據slide大膽猜測一下攻擊思路,一步步進行逆向探究。

在探究之前我們先要明確一點:起點入口是三星自帶的瀏覽器SBrowser,最終目標是在Galaxy S8上執行攻擊者的程式碼並竊取隱私檔案。我們從整個利用鏈的最後一環入手來倒序分析,假定此時Galaxy Apps已經等著配置檔案來進行下一步攻擊了。


Step 1 如何釋放saconfig.ini配置檔案?

由於程式碼中硬編碼了配置檔案路徑(/sdcard/saconfig.ini),我們必須在指定目錄下生成配置檔案,那麼該如何生成到指定目錄?通過瀏覽器強制下載?顯然不可,下載的檔案位於Download目錄內。這裡利用了Samsung Notes中的一處Zip解壓縮目錄穿越漏洞。Samsung Notes中存在一處匯出元件,可載入memo型別的檔案,memo型別檔案本質上是個zip壓縮包,在Samsung Notes載入memo檔案時會呼叫一個方法去解壓這個memo檔案,通過解壓惡意構造的memo檔案來準確釋放檔案到/sdcard下:


存在漏洞的元件:com.samsung.android.app.notes.composer.ConvertToSdocActivity


這裡我們可以猜想memo檔案的構成,其中有個檔案的路徑應該是這樣的:”../../../../../../sdcard/saconfig.ini”,組合上面程式碼會產生路徑“/data/data/com.samsung.android.app.notes/cache/unzip_1529565489/../../../../../../sdcard/saconfig.ini”,這樣最終的路徑就變成“/sdcard/saconfig.ini”了。

Step 2 如何讓Samsung Notes開啟memo檔案?

如何開啟特定App的特定activity?我們知道平時開發過程中直接使用Context.startActivity()即可,但在比賽環境下,並不能這樣方便的執行程式碼,而且Samsumg Nots中存在問題的元件,並沒有響應“android.intent.category.BROWSABLE”action,也無法通過瀏覽器開啟。

所以安全人員這裡找了一個跳板——Android Vending,也就是Google Play應用商店。在這個App中存在一個匯出的Activity——LaunchUrlHandlerActivity,可接收外部傳入的引數,並開啟指定的應用,具體程式碼如下所示:


並且這個Activity是響應“android.intent.category.BROWSABLE”的,意味著我們能通過瀏覽器利用其自定義協議進行呼叫。安全人員隨後測試了http協議、file協議以及content協議,發現這裡只能使用content協議,隨後嘗試了Chrome的Content Provider和系統Media Provider,最終確定了可行的URI:
market://details?url=content://media/external/file/350&id=com.samsung.android.app.notes

這樣Android Vending會喚起com.samsung.android.app.notes並把content://media/external/file/{file_id}作為data傳遞給Samsung Notes。

Step 3 如何確定file_id?

Step 2中,我們看到URI中有一個content://media/external/file/{file_id},這個file_id是不確定的數字,代表的是memo檔案在系統 Media Provider裡對應的ID,至於如何確定,下面是MWR給出的一段JS程式碼:


這段JS的意思是從id=300開始向下列舉Meida Provider中的檔案,如果檔案不存在的話就一直遞減,直到出現一個存在的檔案正確顯示在頁面上。

如下圖示是上一個下載的檔案payload.html: 

先取得memo檔案將佔位的ID(這個時候memo檔案還沒下載呢),然後保證這個時候手機的外部儲存裡不會多出任何檔案,因為任何檔案的出現都會讓ID變化。如果發現i=100的時候出現了payload.html頁面,那麼101就是memo檔案將會存在的ID值。

Step 4 這段JS由誰執行?

MWR Labs安全人員指出:


由於三星自帶的瀏覽器不支援content協議,所以這裡需要用Chrome來載入payload.html,那麼如何喚起Chrome?這裡利用Chrome的特性即可:

googlechrome://navigate?url=content://com.android.chrome.FileProvider/downloads/payload.html

Step 5 payload.html從何而來?

三星瀏覽器SBrowser支援Content-Type: application/force-download; ,通過配置攻擊者的Web伺服器使其強制下載payload.html:


經過強制下載後,payload.html是儲存在/sdcard/Download下的。巧合的是Chrome中的一個Content Provider指向路徑即為/sdcard/Download,所以這裡通過傳入:
googlechrome://navigate?url=content://com.android.chrome.FileProvider/downloads/payload.html即可引導Chrome開啟payload.html。


小結

到這裡暫時休息整理一下,我們從後往前看,就是從瀏覽器訪問一個頁面到釋放配置檔案的過程了。

結合官方給出的圖示:



順序就是:

  1. SBrowser訪問index.html,index.html頁面裡也許使用<iframe>嵌入了一個payload.html,這個時候利用force-download特性將payload.html下載到手機裡再利用googlechrome://navigate?url=content://com.android.chrome.FileProvider/downloads/payload.html喚起Chrome並載入payload.html;
  2. 在payload.html中我們列舉出memo檔案佔位ID,接著請求下載了memo檔案,再跳轉market://details?url=content://media/external/file/350&id=com.samsung.android.app.notes喚起了Android Vending;
  3. Android Vending被喚起後傳送Intent繼而喚醒Samsung Notes訪問memo檔案進行解壓縮釋放了配置檔案saconfig.ini。

進一步利用

Step 6 如何突破比賽時間限制?

進行到這裡我們已經有了這個配置檔案,雖然配置檔案能控制Galaxy Apps的行為去劫持下載,但是由於其使用的是Android Job Scheduler,Scheduler的執行間隔是15分鐘,而比賽的規則是每次嘗試只有5分鐘時間,所以這裡碰到了一個限制需要突破:如何讓Scheduler快速執行?

由於Galaxy Apps在啟動時會去載入這個配置檔案,這裡想到了讓Galaxy Apps重啟。由於Galaxy Apps是系統應用,會在系統啟動時自啟動,那麼這裡面臨著兩個選擇,是選擇crash掉一個App還是crash system引起手機重啟?MWR Labs選擇了後者。

Step 7 如何重啟系統?

在這一步的攻擊中,利用了系統程式“com.android.server.telecom”中的元件“com.android.server.telecom.components.UserCallActivity”中存在一處隱藏的空指標異常未捕獲的問題:


如果外部直接啟動這個Activity不帶任何data進來,URI將會為null,null傳給getScheme()方法時就會產生空指標異常,系統程式的崩潰意味著系統的崩潰,這個時候手機就會重啟,由於Galaxy Apps會在系統啟動時自啟動,那麼重啟手機之後,Galaxy App也會重新啟動並載入我們的配置檔案。

Step 8 如何傳送特定Intent?

如何能傳送這樣一個Intent呢,一個只帶包名和元件名,不會填充data資料的Intent?這裡利用了另外一個跳板——Samsung Members:



Samsung Members中的匯出元件LauncherActivity可在瀏覽器中使用其自定義協議voc://喚起,並且可傳入特定的包名和元件名。


Step 9 如何喚醒Samsung Members?

在這一步中,依舊利用Chrome來進行跳轉,
“voc://activity/generalpackageName=com.android.server.telecom&className=com.android.server.telecom.components.UserCallActivity”,這個URI會被Samsung Members所接收到。所以Chrome在整個攻擊鏈中要執行2次開啟其他應用的任務,一次是為了喚起Android Vending跳板,另外一次是為了喚醒Samsung Members跳板。這裡我們能注意到被當作跳板的元件的一個共同點:都響應了“android.intent.category.browsable”Action,導致攻擊者可以通過瀏覽器開啟進行遠端利用,這裡對我們來說算是一個小Tips吧,今後的漏洞挖掘工作中,對可通過瀏覽器開啟的元件需要格外關注。

後續利用

Step 10 中間人劫持App更新

Galaxy Apps啟動後載入配置檔案,這個時候就會去請求這個攻擊者的中間地址,攻擊者再將所有的請求轉發給真正的升級伺服器https://uk-odc.samsungapps.com/,同時也會將伺服器的響應返回給手機。

Galaxy Apps進行更新請求時會與伺服器產生三次互動:

  1. 客戶端傳送當前所有的App列表給伺服器/服務端做出響應告知客戶端所有App的最新版本
  2. 客戶端如果發現版本比自己高的App則請求這個App的最新資訊/服務端返回App的包名版本等資訊
  3. 客戶端請求最新App的下載地址等/伺服器返回下載地址以及App大小簽名等資訊

中間人在這裡修改了1次請求和3次返回的包,讓Galaxy Apps誤以為自己手機上的某個App是舊版本的,然後下載了攻擊者執行的App進行了安裝。

Step 11 如何繞過許可權申請彈窗?

在Android 6.0及後續版本中,App申請危險許可權時,系統會彈出對話方塊詢問使用者是否授予其特定許可權,這裡繞過的方式也很簡單,編譯apk時將targetSdkVersion設定為18及以下即可。

Step 12 如何啟動惡意App?

根據slide中的描述,MWR的研究人員也以為到這裡就夠了,惡意App已經成功安裝,還有什麼不能做的呢?但是ZDI卻要求現場就能執行App並進行敏感資料的竊取等操作。所以這裡就涉及到一個問題:Android 3.1以後,新安裝的App預設都是停止狀態的。

接著研究人員發現,三星對Android Contacts Provider進行了重度修改,在一個App的狀態發生改變時,會有一個方法去做一次query查詢:


所以在惡意App裡建立一個provider,meta-data中寫上android.content.ContactDirectory屬性為true,則可以在安裝上之後,執行provider中的query方法。


到此為止,惡意App成功安裝並啟動。

總結

經過對整個攻擊鏈的分析,將這麼多“不起眼”的邏輯漏洞(或bug)利用起來,居然能從瀏覽器到程式碼執行做遠端攻擊。在這個攻擊鏈中,總共涉及到了6個App、3個系統元件以及系統的總共11個邏輯漏洞(或bug甚至只是特性),我們再來回顧一下:

元件作用
三星SBrowser支援強制下載,儲存了payload.html
Chrome支援googlechrome://協議,載入payload.html檔案
Android Vending

(Play Store)

跳板1,可被瀏覽器用scheme喚醒併傳送Intent
Android Media Provider系統特性,通過id能訪問到相應的檔案
Samsung Notes解壓縮目錄穿越漏洞,為釋放配置檔案提供了便利
Samsung Members跳板2,同樣可被瀏覽器用scheme喚醒併傳送Intent
Android Telecom空指標異常,可被利用來重啟系統
Galaxy Apps遺留除錯程式碼,可指定任意伺服器除錯App的升級更新過程;且存在中間人攻擊風險
三星定製Android Contacts ProviderApp更新時會去執行query方法導致惡意App自啟動
系統特性通過設定targetSdkVersion繞過許可權彈框

參考連結

  1. https://labs.mwrinfosecurity.com/publications/chainspotting-building-exploit-chains-with-logic-bugs/
  2. https://www.zerodayinitiative.com/advisories/ZDI-18-562/
  3. https://www.zerodayinitiative.com/advisories/ZDI-18-561/
  4. https://www.zerodayinitiative.com/advisories/ZDI-18-560/

關於Vulpecker Team


360威派克團隊(Vulpecker Team)隸屬於360資訊保安部,負責集團內部移動APP和OS類產品安全攻防, 制定了公司內部安卓產品安全開發規範,自主開發並維護了線上安卓應用安全審計系統-360顯危鏡。同時團隊高度活躍在谷歌、三星、華為等各大手機廠商的致謝名單中,截止2018年,累計獲得近百個CVE編號和官方致謝,多次在國內外各大安全會議上分享研究成果。


相關文章