作者:Qever
在之前的《拋磚引玉——Stagefright漏洞初探》中,我們確定了漏洞的產生位置,然后整篇文章就戛然而止了。此漏洞畢竟影響很深,有些細節不知當講不當講。本篇文章來簡單扒一扒漏洞利用的方案。只論思路,具體的Exp還是等漏洞具體細節公布后再做討論。
在上篇文章里面,給出了一個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。其實這幅圖還包含了其他的信息,后面再說。
要搞清楚,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達到攻擊的目的!
看過上面的內容,相信大家也該了解到,POC還是非常簡單的,實際上就是沒啥技術含量。相信大多數人關心的還是Exp。不過因為是未修復的漏洞,所以想伸手要Exp的就不要想了。下面只是來講講利用的思路。沒興趣的就可以直接跳過了。
根據之前的分析,可以確定該漏洞是堆的越界寫引起的。那么利用思路就只有一個,就是越界修改其他對象的值,造成在使用或者析構的時候出錯,跳入shellcode執行。
但是這個漏洞的難點在于,攻擊載體是一個視頻文件,本身沒有執行代碼的能力,也就沒辦法干涉到內存布局,也沒辦法獲取內存布局信息。由此使得基本無法穩定利用。由于內存地址問題,反正筆者目前尚未發現能比較穩定的利用方法,如果哪位大牛有,歡迎分享!
事實上,要尋找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之后,就可以構造數據,達到代碼執行的目的!!!!!
到此,找到了一種利用漏洞的方案。雖然理論上可行,但是在實際操作中,并不是那么如意。
最主要的一點,在于堆越界寫的地址上面,這個地址并不是固定的。好在經過測試,我們發現是在一定范圍內變化。在筆者的Nexus5手機上,這個范圍大概是0xb7000000~0xb9000000
之間。如果通過大量的測試和調整,還是夠覆蓋準確的。
另外一個問題就是執行權限。在堆上申請的內存本身是沒有執行權限的。所以需要一個跳板才行,但是由于攻擊載體只是一個視頻文件,所以這并不是一件簡單的事情。
至于后續怎么編寫shellcode,本身也存在一些問題。
當然,這些都不是本篇文章所考慮的內容 =。=
還是那句話,本漏洞由于未修復。我們只能根據情況逐漸公開研究結果,以免造成不好的影響。
在廠商發布更新補丁之前,我們來說說防御。
對于該漏洞的防范,建議是關閉彩信自動下載。但是實際上通過任何渠道傳播的視頻,都可能利用該漏洞。包括通過微信發送視頻,接收者根本無法分辨是否為mp4格式文件,點擊播放就可能被黑客攻擊。
目前大部分廠商都在嘗試主動查殺視頻文件的防御方案。但是筆者認為這完全是事倍功半,而且由于無法監控所有途徑傳播的視頻文件,所以無法真正達到防御的目的。
目前,獵豹移動安全中心正在嘗試一種被動式的防御方案,可以有效降低攻擊危害。敬請關注獵豹移動相關資訊。