作者:
獵豹移動安全中心
·
2015/08/01 7:12
作者:Qever
0x00 前言
在之前的《拋磚引玉——Stagefright漏洞初探》中,我們確定了漏洞的產生位置,然後整篇文章就戛然而止了。此漏洞畢竟影響很深,有些細節不知當講不當講。本篇文章來簡單扒一扒漏洞利用的方案。只論思路,具體的Exp還是等漏洞具體細節公佈後再做討論。
0x01 手把手教你構造POC
在上篇文章裡面,給出了一個POC檔案,現在我們就來說說這個檔案是怎麼構造的。
首先,需要準備一個MP4檔案。這裡使用的是從網上隨意下載的一個檔案。
之後,需要為這個mp4檔案新增一個封面。筆者使用的工具是iTunes,在顯示簡介的插圖裡面可以為其新增封面圖片。
下一部,使用010Editor開啟新增封面的poc.mp4檔案。然後搜尋字串”covr”。
最後,把”covr”前面4個位元組改為00 00 00 01
,後面8個位元組改為00 00 00 01 00 00 00 0F
儲存之後,扔到手機中開啟。由於mediaserver崩潰之後,會立刻重啟。所以我們需要系統Log來輔助驗證漏洞的觸發。
透過Log就能發現,mediaserver。其實這幅圖還包含了其他的資訊,後面再說。
0x02 知其所以然
要搞清楚,POC為什麼要這樣做,就必須要從原始碼下手。 我們在/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
中繼續看相關原始碼。
前面說過,這個漏洞的原因,在於chunk_data_size = 0xFFFFFFFF
。使得chunk_data_size + 1 = 0
,造成了申請記憶體的長度為0,然後往記憶體中複製資料時越界寫。
那麼我們就看看chunk_data_size
如何才能等於0xFFFFFFFF。
從這裡就能看出來。*offset – data_offset = 8
。也就是說,chunk_data_size
要等於0xFFFFFFFF
。Chunk_size就必須等於0xFFFFFFF + 8
。
但是,可以看到chunk_size是從*offset處讀取了4個位元組進行轉換的,最大值也就是0xFFFFFFFF了。 同時注意chunk_type,後面可以看到,chunk_type的值是FOURCC('c', 'o', 'v', 'r')
,也就是(int)’covr’
,這就是為什麼要用字串”covr”做定位的原因。
回來繼續看chunk_size,發現型別實際上是uint64_t,也就是說有可能會大於0xFFFFFFFF。繼續看程式碼。
這段就很清楚了。如果之前讀取到的chunk_size == 1
,那麼就讀取*offset + 8處的8個位元組,作為chunk_size的值,同時data_offset會加8。
由此可以確定。當*offset處記憶體值設定為
00 00 00 01 ‘c’ ‘o’ ‘v’ ‘r’ 00 00 00 01 00 00 00 0F
可以使chunk_data_size的值成為0xFFFFFFFF達到攻擊的目的!
0x03 沒Exp你說個剷剷
看過上面的內容,相信大家也該瞭解到,POC還是非常簡單的,實際上就是沒啥技術含量。相信大多數人關心的還是Exp。不過因為是未修復的漏洞,所以想伸手要Exp的就不要想了。下面只是來講講利用的思路。沒興趣的就可以直接跳過了。
根據之前的分析,可以確定該漏洞是堆的越界寫引起的。那麼利用思路就只有一個,就是越界修改其他物件的值,造成在使用或者析構的時候出錯,跳入shellcode執行。
但是這個漏洞的難點在於,攻擊載體是一個影片檔案,本身沒有執行程式碼的能力,也就沒辦法干涉到記憶體佈局,也沒辦法獲取記憶體佈局資訊。由此使得基本無法穩定利用。由於記憶體地址問題,反正筆者目前尚未發現能比較穩定的利用方法,如果哪位大牛有,歡迎分享!
0x04 如何尋找Exp
事實上,要尋找Exp的思路還是比較簡單的。從前面00 00 00 01 00 00 00 0F
開始,逐漸增加檔案大小,然後一直測試,收集崩潰資訊。找尋利用點。
筆者還算是幸運,並沒有費多大的力氣,就找到了一個非常明顯的利用點。 還是回到之前的崩潰截圖,我們來看堆疊資訊。
根據堆疊,可以看到,是一個HTTPBase的智慧指標,在析構的時候崩潰了。
等等,android::RefBae::decStrong
和android_atomic_dec
,之前研究過Android漏洞人,是不是覺得有點眼熟?這個東西實際上已經出現過一次了,是在CVE-2014-7911裡面。
我們來看看decStrong的實現。
可以看出,當android_atomic_dec
返回值為1的時候。會觸發一句BLX R2。 這段通俗一點講,就是
#!c++
If(*(*(offset + 4)) == 1){
r2 = *(*(*(offset + 4) + 8) + 0xC)
blx r2;
}
程式碼執行!!資料可控!!!
我們隨後可以把mp4進行填充一下,得到以下的結果
也就是說,針對我的mp4檔案,檔案偏移在0x96a8-4
處的值,就是上面所說的offset。
知道offset之後,就可以構造資料,達到程式碼執行的目的!!!!!
0x05 現實很骨感
到此,找到了一種利用漏洞的方案。雖然理論上可行,但是在實際操作中,並不是那麼如意。
最主要的一點,在於堆越界寫的地址上面,這個地址並不是固定的。好在經過測試,我們發現是在一定範圍內變化。在筆者的Nexus5手機上,這個範圍大概是0xb7000000~0xb9000000
之間。如果透過大量的測試和調整,還是夠覆蓋準確的。
另外一個問題就是執行許可權。在堆上申請的記憶體本身是沒有執行許可權的。所以需要一個跳板才行,但是由於攻擊載體只是一個影片檔案,所以這並不是一件簡單的事情。
至於後續怎麼編寫shellcode,本身也存在一些問題。
當然,這些都不是本篇文章所考慮的內容 =。=
0x06 總結
還是那句話,本漏洞由於未修復。我們只能根據情況逐漸公開研究結果,以免造成不好的影響。
在廠商釋出更新補丁之前,我們來說說防禦。
對於該漏洞的防範,建議是關閉彩信自動下載。但是實際上透過任何渠道傳播的影片,都可能利用該漏洞。包括透過微信傳送影片,接收者根本無法分辨是否為mp4格式檔案,點選播放就可能被駭客攻擊。
目前大部分廠商都在嘗試主動查殺影片檔案的防禦方案。但是筆者認為這完全是事倍功半,而且由於無法監控所有途徑傳播的影片檔案,所以無法真正達到防禦的目的。
目前,獵豹移動安全中心正在嘗試一種被動式的防禦方案,可以有效降低攻擊危害。敬請關注獵豹移動相關資訊。
本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!