原文來自安全客,作者:Sniperhg&MissCoconut@360 Vulpecker Team
原文鏈接:https://www.anquanke.com/post/id/149286

前言

在去年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/general?packageName=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甚至只是特性),我們再來回顧一下:

參考鏈接

關于Vulpecker Team

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


本文經安全客授權發布,轉載請聯系安全客平臺。


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