阿里移動安全 · 2015/07/31 16:53html
做者: 迅迪 沒羽 軒夏 成淼 奮龍 逆巴android
StageFright是一個Android中的系統服務,可處理各類多媒體格式,由Natvie C++代碼實現,多媒體應用如何與Android Native多媒體進行交互可參考以下圖:c++
而Stagefright所涵蓋的模塊很是廣git
|-- stagefright
| |
| |-- codecs //提供解碼器實現
| |
| |-- colorconversion //顏色空間轉換
| |
| |-- foundation //基本數據結構的實現
| |
| |-- httplive //m3u8解析
| |
| |-- id3 // ID3 TAG解析(通常用於MP3格式的metadata容器)
| |
| |-- include //基本頭文件
| |
| |-- matroska //matroska文件解析
| |
| |-- mpeg2ts //mpeg2ts文件解析和數據獲取一些處理
| |
| |-- mp4
複製代碼
因爲多媒體處理的實時性特徵,該庫經過Native代碼實現,這也是的該庫存在內存破壞的問題遠遠多於Java實現的代碼。github
以色列移動信息安全公司Zimperium研究人員Joshua Drake在7月21號發佈的聲明,聲稱會在8月的BlackHat會議上發佈細節。瀏覽器
Android Stagefright框架中發現了多個整數溢出和下溢,不正確整數溢出檢查等漏洞,可致使任意代碼執行等問題。安全
攻擊者經過發送包含特製媒體文件的MMS或WEB頁來觸發該漏洞。因爲stagefright不僅是用來播放媒體文件的,還能自動產生縮略圖,或者從視頻或音頻文件中抽取元數據,如長度、高度、寬度、幀頻、頻道和其餘相似信息。所以接收到惡意彩信的用戶只要查看縮略圖就可觸發該漏洞。數據結構
「Stagefright」媒體播放引擎庫在Android 2.2中引入,至5.1的全部版本上均存在此漏洞,預計會有95%的Android設備,約有九億五千萬的安卓設備受該漏洞影響.app
使用Stagefright庫的應用程序以Media權限運行,成功利用漏洞,容許攻擊者瀏覽器媒體庫相應的文件,但經過權限提高攻擊,可徹底控制設備。框架
該Stagefright漏洞所對應的CVE ID以下:
CVE-2015-1538
CVE-2015-1539
CVE-2015-3824
CVE-2015-3826
CVE-2015-3827
CVE-2015-3828
CVE-2015-3829
複製代碼
根據https://github.com/CyanogenMod/android_frameworks_av/commits/cm-12.1
提供的補丁,進行了相關的分析:
4.1 Prevent reading past the end of the buffer in 3GPP
補丁連接:
https://github.com/CyanogenMod/android_frameworks_av/commit/57db9b42418b434751f609ac7e5539367e9f01a6
複製代碼
該漏洞產生在如下的chunk中:
這是一個堆內存讀越界漏洞,parse3GPPMetaData方法中調用mDataSource->readAt( offset, buffer, size)
讀取size大小的數據到申請的buffer中,而後下面會調用mFileMetaData->setCString()
方法進行內存拷貝:
咱們來看setCString()方法的最終會調用memcpy進行內在拷貝:
#!c++
void MetaData::typed_data::setData(uint32_t type, const void *data, size_t size) {
clear();
mType = type;
allocateStorage(size);
memcpy(storage(), data, size);
}
複製代碼
因爲對memcpy中size的處理不當,致使越界讀取了內存數據。
4.2 Prevent integer underflow if size is below 6
補丁連接:
https://github.com/CyanogenMod/android_frameworks_av/commit/9824bfd6eec1daa93cf76b6f4199602fe35f1d9d
複製代碼
該漏洞是一個integer underflow漏洞,對於構造的size來講,若是size<6,可致使len16的值變的很大:
致使接下來的內存越界操做:
4.3 Fix integer overflow when handling MPEG4 tx3g atom
補丁連接:
https://github.com/CyanogenMod/android_frameworks_av/commit/889ae4ad7227c395615d03b24a1667caa162c75f
複製代碼
該漏洞產生在「tx3g」的chunk中,chunk_size是uint,與size之和溢出,會致使實際分配比size小的內存。後面的memcpy函數將會發生堆溢出:
當mLastTrack->meta->findData(kKeyTextFormatData, &type, &data, &size)
函數調用返回爲真,size值將不會爲0,chunk_size與size都爲uint8_t,之和後發生整數溢出,這樣致使new一個比size更小的空間,在隨後的memcpy將發生堆溢出:
#!c++
bool MetaData::findData(uint32_t key, uint32_t *type,
const void **data, size_t *size) const {
ssize_t i = mItems.indexOfKey(key); //鍵值存在 i>0
if (i < 0) {
return false;
}
const typed_data &item = mItems.valueAt(i);
item.getData(type, data, size);
return true;
}
複製代碼
接下來new (std::nothrow) uint8_t[size + chunk_size]
,size與chunk_size之和發生整數溢出,值將小於size,此後的memcpy發生堆溢出:
4.4 Fix integer underflow in covr MPEG4 processing
補丁連接:
https://github.com/CyanogenMod/android_frameworks_av/commit/b1f29294f1a5831eb52a81d3ee082a9475f6e879
複製代碼
從patch代碼可知,因爲未檢測chunk_data_size的長度,致使後面的chunk_data_size – kSkipBytesOfDataBox爲負數,
向上追溯,chunk_data_size = offset + chunk_size - data_offset;off64_t data_offset = *offset + 8;其中chunk_size爲mpeg4格式中box的chunk_size,offset爲當前的box的起始位置。由patch代碼可知,有這樣的不等或成立才能避免該漏洞的出現:
chunk_data_size <= kSkipBytesOfDataBox
⇨ *offset + chunk_size - *offset - 8 <= 16
⇨ chunk_size - 8 <= 16
⇨ chunk_size <= 24(0x18)
複製代碼
因此當chunk_size的值<=24時會觸發漏洞。構造的一個樣本(0x08)截圖以下:
4.5 Prevent integer overflow when processing covr MPEG4 atoms
補丁連接:
https://github.com/CyanogenMod/android_frameworks_av/commit/7ff5505d36b1cfd8b03497e0fb5aa24b5b099e45
複製代碼
從patch代碼可知,因爲未對chunk_data_size的長度進行限制,當chunk_data_size>=SIZE_MAX-1時,chunk_data_size+1>=SIZE_MAX
,致使ABuffer分配0長度的內存,後續再進行內存操做就致使堆越界。
4.6 Fix integer overflow during MP4 atom processing
補丁連接:
https://github.com/CyanogenMod/android_frameworks_av/commit/3854030bf70cb78ec0afbf90d0e7d8e1cf8f9904
複製代碼
從代碼分析可知,要構造出知足條的POC樣本,須要chunk_size=1,而後unint64來存儲chunk_size。對於該漏洞POC的構造,咱們假設:mNumSampleToChunkOffsets = 0xFFFFFFFF/0xC
可得,mNumSampleToChunkOffsets = 0x15555555
咱們構造以下樣本:
其中chunk_size 爲1,large_chunk_size
爲0x100000007
, mNumSampleToChunkOffsets
爲0x15555555
。
加載該樣本,運行截圖以下:
4.7 Fix integer underflow in ESDS processing
補丁連接:
https://github.com/CyanogenMod/android_frameworks_av/commit/e586b3e891e7c598449d40a9c44c70fd6663d064
複製代碼
從patch代碼可知,因爲未對size的大小進行檢測,後續會進行屢次-2操做,致使size爲負數,致使堆下溢出。
要構造poc需進入ESDS.cpp查看詳細代碼:
首先獲取偏移的值,並進行一系列運算,當more=true時中止,並返回data_size,而後開始解析ESDS。
從代碼能夠看出來當3個標誌位都爲1時,纔會進行size-2操做,所以構造的poc必須知足3個標誌位,0xE0以上數值就知足要求。所以將size修改成5,標誌位修改成0xE3就能觸發漏洞的畸形樣本截圖以下:
4.8 Fix several ineffective integer overflow checks
補丁連接:
https://github.com/CyanogenMod/android_frameworks_av/commit/16c78bb6608dd5abbf3a1fc1cd98e8fc94cfb241
複製代碼
此漏洞有3處patch,涉及到3個chunk分別是「stts」、「ctts」、「stss」。是因爲幾個uint32型數據相乘,再賦值給uint64可能會致使溢出:
以「stts」chunk爲例來講一下poc的構造: 代碼分析,我可得「stts」chunk的結構頭以下:
第4個4字節的值即爲mTimeToSampleCount,咱們假設存在這樣一個等式:mTimeToSampleCount * 2 * 4 = 0xFFFFFFFF+0x1
可得,mTimeToSampleCount=0x20000000
咱們以mTimeToSampleCount=0x20000000構造的一個POC以下:
運行結果:
chunk「ctts」、「stss」也能夠經過相似的方法構造出POC。
Amazon Barnes and Noble
Google HTC
Huawei Technologies
Kyocera Communications
LG Electronics
Motorola, Inc.
Samsung Mobile
Sony Corporation
複製代碼
等
因爲Stagefright是一個底層的多媒體處理庫,所以調用該庫的應用都受此漏洞影響,咱們隨機檢測國內主流的幾個應用作,發現都存在此問題:
6.1 絕大多數視頻APP都受影響,以樂視視頻爲例
- 受影響版本:Android/5.9.3
- 點擊特製構建的視頻文件,選擇「樂視視頻」播放:
複製代碼
-查看日誌信息,能夠看到libstagefright.so的crash信息,在MPEG4Extractor::parseChunk(off64_t *offset, int depth)
方法中解析文件出錯,受影響代碼能夠參考:
https://android.googlesource.com/platform/frameworks/av/+/android-5.1.1_r8/media/libstagefright/MPEG4Extractor.cpp:
複製代碼
6.2 某手機瀏覽器
- 版本:
Android/6.0.1.1560
- 測試:
使用某手機瀏覽器的二維碼功能,掃描生成的視頻PoC文件,
在瀏覽器彈出的提示窗口中選擇「直接打開」:
複製代碼
-查看手機端,播放視頻文件出錯:
-查看日誌信息,能夠看到libstagefright.so的crash信息,在MPEG4Extractor::parseChunk(off64_t *offset, int depth)
方法中解析文件出錯。
6.3某SNS通信工具
- 版本:
Android/6.2.2
- 發送特殊構建的視頻文件時,點擊播放會彈出「播放失敗」窗口,如圖:
複製代碼
能夠看到解析視頻文件時發生崩潰,經過視頻發送或SNS形式傳播,可大範圍的影響用戶。
Google已經發布Android 5.1.1_r5修復該漏洞,注意不是全部Android 5.1.1 (Lollipop)手機應用了該補丁,須要安裝patchlevel r5補丁:
https://android.googlesource.com/platform/frameworks/av/+/0e4e5a8%5E!/
https://android.googlesource.com/platform/frameworks/av/+/5c134e6%5E!/
https://android.googlesource.com/platform/frameworks/av/+/030d8d0%5E!/
複製代碼
CyanogenMod中的cm12.1 branch已經修復該漏洞:
https://github.com/CyanogenMod/android_frameworks_av/commits/cm-12.1
複製代碼
積極聯繫經過廠商OTA進行更新
- http://blog.zimperium.com/experts-found-a-unicorn-in-the-heart-of-android/
- http://www.kb.cert.org/vuls/id/924951
- http://www.forbes.com/sites/thomasbrewster/2015/07/27/android-text-attacks/
- http://www.zdnet.com/article/stagefright-just-how-scary-is-it-for-android-users/
- http://arstechnica.com/security/2015/07/950-million-android-phones-can-be-hijacked-by-malicious-text-messages/
- https://android.googlesource.com/platform/frameworks/av/+/0e4e5a8%5E!/
- https://android.googlesource.com/platform/frameworks/av/+/5c134e6%5E!/
- https://android.googlesource.com/platform/frameworks/av/+/030d8d0%5E!/
- http://source.android.com/devices/media.html
- https://www.duosecurity.com/blog/exploit-mitigations-in-android-jelly-bean-4-1
複製代碼