<dd id="sga4y"><optgroup id="sga4y"></optgroup></dd>
<nav id="sga4y"><code id="sga4y"></code></nav>
  • <optgroup id="sga4y"></optgroup>

    原文地址:http://drops.wooyun.org/papers/7558

    作者: 迅迪 沒羽 軒夏 成淼 奮龍 逆巴

    0x00 什么是Stagefright


    StageFright是一個Android中的系統服務,可處理各種多媒體格式,由Natvie C++代碼實現,多媒體應用如何與Android Native多媒體進行交互可參考如下圖:

    enter image description here

    而Stagefright所涵蓋的模塊非常廣

    |-- stagefright  
    |   |  
    |   |-- codecs   //提供解碼器實現  
    |   |  
    |   |-- colorconversion   //顏色空間轉換  
    |   |  
    |   |-- foundation   //基本數據結構的實現  
    |   |  
    |   |-- httplive   //m3u8解析  
    |   |  
    |   |-- id3        // ID3 TAG解析(一般用于MP3格式的metadata容器)  
    |   |  
    |   |-- include    //基本頭文件  
    |   |   
    |   |-- matroska   //matroska文件解析  
    |   |  
    |   |-- mpeg2ts    //mpeg2ts文件解析和數據獲取一些處理  
    |   |  
    |   |-- mp4     
    

    由于多媒體處理的實時性特征,該庫通過Native代碼實現,這也是的該庫存在內存破壞的問題遠遠多于Java實現的代碼。

    0x01 誰發現了Stagefright


    以色列移動信息安全公司Zimperium研究人員Joshua Drake在7月21號發布的聲明,聲稱會在8月的BlackHat會議上發布細節。

    0x02 漏洞概要


    Android Stagefright框架中發現了多個整數溢出和下溢,不正確整數溢出檢查等漏洞,可導致任意代碼執行等問題。

    攻擊者通過發送包含特制媒體文件的MMS或WEB頁來觸發該漏洞。由于stagefright不只是用來播放媒體文件的,還能自動產生縮略圖,或者從視頻或音頻文件中抽取元數據,如長度、高度、寬度、幀頻、頻道和其他類似信息。因此接收到惡意彩信的用戶只要查看縮略圖就可觸發該漏洞。

    “Stagefright”媒體播放引擎庫在Android 2.2中引入,至5.1的所有版本上均存在此漏洞,預計會有95%的Android設備,約有九億五千萬的安卓設備受該漏洞影響.

    使用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  
    

    0x03 漏洞分析


    根據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中:

    enter image description here

    這是一個堆內存讀越界漏洞,parse3GPPMetaData方法中調用mDataSource->readAt( offset, buffer, size)讀取size大小的數據到申請的buffer中,然后下面會調用mFileMetaData->setCString()方法進行內存拷貝:

    enter image description here

    我們來看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的值變的很大:

    enter image description here

    導致接下來的內存越界操作:

    enter image description here

    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函數將會發生堆溢出:

    enter image description here

    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發生堆溢出:

    enter image description here

    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為負數,

    enter image description here

    向上追溯,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)截圖如下:

    enter image description here

    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長度的內存,后續再進行內存操作就導致堆越界。

    enter image description here

    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

    我們構造如下樣本:

    enter image description here

    其中chunk_size 為1,large_chunk_size0x100000007, mNumSampleToChunkOffsets0x15555555

    加載該樣本,運行截圖如下:

    enter image description here

    4.7 Fix integer underflow in ESDS processing

    補丁鏈接:

    https://github.com/CyanogenMod/android_frameworks_av/commit/e586b3e891e7c598449d40a9c44c70fd6663d064
    

    從patch代碼可知,由于未對size的大小進行檢測,后續會進行多次-2操作,導致size為負數,導致堆下溢出。

    enter image description here

    要構造poc需進入ESDS.cpp查看詳細代碼:

    enter image description here

    首先獲取偏移的值,并進行一系列運算,當more=true時停止,并返回data_size,然后開始解析ESDS。

    enter image description here

    從代碼可以看出來當3個標志位都為1時,才會進行size-2操作,因此構造的poc必須滿足3個標志位,0xE0以上數值就滿足要求。因此將size修改為5,標志位修改為0xE3就能觸發漏洞的畸形樣本截圖如下:

    enter image description here

    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可能會導致溢出:

    enter image description here

    以“stts”chunk為例來說一下poc的構造: 代碼分析,我可得“stts”chunk的結構頭如下:

    enter image description here

    第4個4字節的值即為mTimeToSampleCount,我們假設存在這樣一個等式:mTimeToSampleCount * 2 * 4 = 0xFFFFFFFF+0x1可得,mTimeToSampleCount=0x20000000 我們以mTimeToSampleCount=0x20000000構造的一個POC如下:

    enter image description here

    運行結果:

    enter image description here

    chunk“ctts”、“stss”也可以通過類似的方法構造出POC。

    0x04 觸發途徑


    0x05 受影響廠商


    Amazon   Barnes and Noble    
    Google   HTC     
    Huawei Technologies  
    Kyocera Communications   
    LG Electronics   
    Motorola, Inc.  
    Samsung Mobile   
    Sony Corporation
    

    0x06 受影響應用:


    由于Stagefright是一個底層的多媒體處理庫,因此調用該庫的應用都受此漏洞影響,我們隨機檢測國內主流的幾個應用做,發現都存在此問題:

    6.1 絕大多數視頻APP都受影響,以樂視視頻為例

    - 受影響版本:Android/5.9.3
    - 點擊特制構建的視頻文件,選擇“樂視視頻”播放:
    

    enter image description here

    enter image description here

    -查看日志信息,可以看到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:
    

    enter image description here

    6.2 某手機瀏覽器

    - 版本:
      Android/6.0.1.1560
    - 測試:
      使用某手機瀏覽器的二維碼功能,掃描生成的視頻PoC文件,
      在瀏覽器彈出的提示窗口中選擇“直接打開”:
    

    enter image description here

    -查看手機端,播放視頻文件出錯:

    enter image description here

    -查看日志信息,可以看到libstagefright.so的crash信息,在MPEG4Extractor::parseChunk(off64_t *offset, int depth) 方法中解析文件出錯。

    enter image description here

    6.3某SNS通訊工具

    -   版本:
    Android/6.2.2
    -  發送特殊構建的視頻文件時,點擊播放會彈出“播放失敗”窗口,如圖:
    

    enter image description here

    enter image description here

    可以看到解析視頻文件時發生崩潰,通過視頻發送或SNS形式傳播,可大范圍的影響用戶。

    0x07,緩解方案


    0x08 廠商解決方案


    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進行更新

    0x09 參考鏈接


    -   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
    

    97av