再探Stagefright漏洞——POC與EXP

wyzsk發表於2020-08-19
作者: 獵豹移動安全中心 · 2015/08/01 7:12

作者:Qever

0x00 前言


在之前的《拋磚引玉——Stagefright漏洞初探》中,我們確定了漏洞的產生位置,然後整篇文章就戛然而止了。此漏洞畢竟影響很深,有些細節不知當講不當講。本篇文章來簡單扒一扒漏洞利用的方案。只論思路,具體的Exp還是等漏洞具體細節公佈後再做討論。

0x01 手把手教你構造POC


在上篇文章裡面,給出了一個POC檔案,現在我們就來說說這個檔案是怎麼構造的。

首先,需要準備一個MP4檔案。這裡使用的是從網上隨意下載的一個檔案。

之後,需要為這個mp4檔案新增一個封面。筆者使用的工具是iTunes,在顯示簡介的插圖裡面可以為其新增封面圖片。

enter image description here

下一部,使用010Editor開啟新增封面的poc.mp4檔案。然後搜尋字串”covr”。

enter image description here

最後,把”covr”前面4個位元組改為00 00 00 01,後面8個位元組改為00 00 00 01 00 00 00 0F

enter image description here

儲存之後,扔到手機中開啟。由於mediaserver崩潰之後,會立刻重啟。所以我們需要系統Log來輔助驗證漏洞的觸發。

enter image description here

透過Log就能發現,mediaserver。其實這幅圖還包含了其他的資訊,後面再說。

0x02 知其所以然


要搞清楚,POC為什麼要這樣做,就必須要從原始碼下手。 我們在/frameworks/av/media/libstagefright/MPEG4Extractor.cpp中繼續看相關原始碼。

enter image description here

前面說過,這個漏洞的原因,在於chunk_data_size = 0xFFFFFFFF。使得chunk_data_size + 1 = 0,造成了申請記憶體的長度為0,然後往記憶體中複製資料時越界寫。

enter image description here

那麼我們就看看chunk_data_size如何才能等於0xFFFFFFFF。

enter image description here

從這裡就能看出來。*offset – data_offset = 8。也就是說,chunk_data_size要等於0xFFFFFFFF。Chunk_size就必須等於0xFFFFFFF + 8

enter image description here

但是,可以看到chunk_size是從*offset處讀取了4個位元組進行轉換的,最大值也就是0xFFFFFFFF了。 同時注意chunk_type,後面可以看到,chunk_type的值是FOURCC('c', 'o', 'v', 'r'),也就是(int)’covr’,這就是為什麼要用字串”covr”做定位的原因。

回來繼續看chunk_size,發現型別實際上是uint64_t,也就是說有可能會大於0xFFFFFFFF。繼續看程式碼。

enter image description here

這段就很清楚了。如果之前讀取到的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開始,逐漸增加檔案大小,然後一直測試,收集崩潰資訊。找尋利用點。

筆者還算是幸運,並沒有費多大的力氣,就找到了一個非常明顯的利用點。 還是回到之前的崩潰截圖,我們來看堆疊資訊。

enter image description here

根據堆疊,可以看到,是一個HTTPBase的智慧指標,在析構的時候崩潰了。

等等,android::RefBae::decStrongandroid_atomic_dec,之前研究過Android漏洞人,是不是覺得有點眼熟?這個東西實際上已經出現過一次了,是在CVE-2014-7911裡面。

我們來看看decStrong的實現。

enter image description here

可以看出,當android_atomic_dec返回值為1的時候。會觸發一句BLX R2。 這段通俗一點講,就是

#!c++
If(*(*(offset + 4)) == 1){
    r2 = *(*(*(offset + 4) + 8) + 0xC)
    blx r2;
}

程式碼執行!!資料可控!!!

我們隨後可以把mp4進行填充一下,得到以下的結果

enter image description here

也就是說,針對我的mp4檔案,檔案偏移在0x96a8-4處的值,就是上面所說的offset。

知道offset之後,就可以構造資料,達到程式碼執行的目的!!!!!

0x05 現實很骨感


到此,找到了一種利用漏洞的方案。雖然理論上可行,但是在實際操作中,並不是那麼如意。

最主要的一點,在於堆越界寫的地址上面,這個地址並不是固定的。好在經過測試,我們發現是在一定範圍內變化。在筆者的Nexus5手機上,這個範圍大概是0xb7000000~0xb9000000之間。如果透過大量的測試和調整,還是夠覆蓋準確的。

另外一個問題就是執行許可權。在堆上申請的記憶體本身是沒有執行許可權的。所以需要一個跳板才行,但是由於攻擊載體只是一個影片檔案,所以這並不是一件簡單的事情。

至於後續怎麼編寫shellcode,本身也存在一些問題。

當然,這些都不是本篇文章所考慮的內容 =。=

0x06 總結


還是那句話,本漏洞由於未修復。我們只能根據情況逐漸公開研究結果,以免造成不好的影響。

在廠商釋出更新補丁之前,我們來說說防禦。

對於該漏洞的防範,建議是關閉彩信自動下載。但是實際上透過任何渠道傳播的影片,都可能利用該漏洞。包括透過微信傳送影片,接收者根本無法分辨是否為mp4格式檔案,點選播放就可能被駭客攻擊。

目前大部分廠商都在嘗試主動查殺影片檔案的防禦方案。但是筆者認為這完全是事倍功半,而且由於無法監控所有途徑傳播的影片檔案,所以無法真正達到防禦的目的。

目前,獵豹移動安全中心正在嘗試一種被動式的防禦方案,可以有效降低攻擊危害。敬請關注獵豹移動相關資訊。

本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!

相關文章