<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

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

            0x00 背景


            Bluebox的CTO Jeff Forristal在其官?方blog爆出一個漏洞叫做UNCOVERING ANDROID MASTER KEY,大致是不篡改簽名修改android代碼。

            Link:http://bluebox.com/corporate-blog/bluebox-uncovers-android-master-key/

            blog:關于細節并沒有講太多,只有discrepancies in how Android applications are cryptographically verified & installed(安卓應?用簽名驗證和安裝的不?一致)essentially allowing a malicious author to trick Android into believing the app is unchanged even if it has been(讓andriod系統本?身認為應?用沒有修改)這兩條重要的信息。

            剩下就是放出來一張更改基帶字串的圖:

            enter image description here

            具體細節7月底的blackhat放出。

            沒多少天7月8號國外已經有人放出poc來。微博上看到rayh4c說已經搞定。就分析了一下。

            0x01 分析


            POC還沒出來之前,先是看了下android的簽名機制和安裝機制。

            簽名機制: 用簡單的話來講就是android把app應用的所有文件都做了sha1(不可逆)簽名,并對這簽名用RSA(非對稱加密算法)的私鑰進行了加密,客戶端安裝驗證時用公鑰進行解密。

            從邏輯上看,這簽名機制對完整性和唯一性的校驗是完全沒問題的。主流的很多加密都類似這樣。

            安裝機制:

            安裝機制則較為復雜。

            1.系統應用安裝――開機時完成,沒有安裝界面
            2.網絡下載應用安裝――通過market應用完成,沒有安裝界面
            3.ADB?工具安裝――沒有安裝界面。
            4.第三?方應用安裝――通過SD卡?里的APK?文件安裝,有安裝界面,由packageinstaller.apk應?用處理安裝及卸載過程的界面。
            

            安裝過程:復制APK安裝包到data/app目錄下,解壓并掃描安裝包,把dex?文件(Dalvik字節碼) 保存到dalvik-cache目錄,并data/data目錄下創建對應的應?用數據目錄。

            到這里看出在安裝機制上的問題可能性比較大。

            回頭看?老外的POC:https://gist.github.com/poliva/36b0795ab79ad6f14fd8

            enter image description here

            在linux執?行了一遍,出現錯誤。可能是apk的原因。

            索性把這poc移植到windows下,先是?用apktool 把要更改的apk給反編譯出來到一個目錄apk_test

            然后?又把apk_test打包成?一個新的apk

            把原先的apk解壓出來apk_old

            把apk_old所有?文件以zip壓縮的?方式加?入新的apk中。我本機以weibo.apk為例:

            enter image description here

            可見兩者大小發生了變化,apktool在反編譯過程不可避免的出現差異。并且重編譯的apk不含有簽名文件。

            按照poc的做法我用批處理導出目錄的文件名到1.txt修改了poc.py

            import zipfile
            import sys
            f=open('1.txt','r')
            line=f.readline()
            test=[]
            while line:
                test1=line.replace("\n","")
                test.append(test1)
                if not line:
                    break
                line=f.readline()
            f.close()
            z = zipfile.ZipFile("livers.apk", "a")
            for i in range(0,len(test)):
                print test[i]
                z.write(str(test[i]))
            z.close()
            

            enter image description here

            差不多增大了一倍,放在手機上安裝了一下,成功安裝。查看了下:

            enter image description here

            出現了多對同名文件。CRC校驗不同,查看了一下,基本上是兩個字節便產生不同。

            enter image description here

            這里我又測試了只添加簽名文件,或者dex文件等,均不能通過驗證。

            可證明其在scan list掃描目錄或者復制文件時候對同名文件處理不當。

            0x02 驗證


            證明是否可以進行更改源碼,并能使用原生簽名。我把apk圖標進行了更改。

            順便講下一般的反編譯修改:

            1. apktool或者其他工具進行反編譯包含smalijava字節碼匯編和xml圖片文件。 
            2. apkzip解壓。
            3. 反編譯dex成java文件。
            4. 查找對應修改的smali文件或者xml(一般廣告鏈接)
            5. Apktool打包成apk文件
            6. 用autosign進行簽名。
            這里沒有進行簽名直接借用原來的簽名。
            

            enter image description here

            enter image description here

            0x03 查找根源


            我這里下載的android 2.2的源碼,查找到獲取簽名信息安裝位于frameworks\base\core\java\android\content\pm\PackageParser.java這個文件,public?boolean?collectCertificates(Package?pkg,?int?flags)private?Certificate[]?loadCertificates(JarFile?jarFile,?JarEntry?je,?byte[]?readBuffer)這個方法是用來獲取簽名信息的。

             Enumeration entries = jarFile.entries();
                        while (entries.hasMoreElements()) {
                            JarEntry je = (JarEntry)entries.nextElement();
                            if (je.isDirectory()) continue;
                            if (je.getName().startsWith("META-INF/")) continue;
                            Certificate[] localCerts = loadCertificates(jarFile, je,
                                    readBuffer);
                        。。。。。。
                            } else {
                                // Ensure all certificates match.
                                for (int i=0; i<certs.length; i++) {
                                    boolean found = false;
                                    for (int j=0; j<localCerts.length; j++) {
                                        if (certs[i] != null &&
                                                certs[i].equals(localCerts[j])) {
                                            found = true;
                                            break;
                                        }
                                    }
                                  。。。。。
            

            前面通過黑盒方式,大致推斷出安裝機制就是把重命名文件同時處理了,沒有覆蓋而是:

            if (certs[i] != null &&certs[i].equals(localCerts[j])) {
                found = true;
                break;
            } 
            

            兩個重名文件都做了驗證,只要有一個通過驗證,就返回驗證通過。

            0x04 后繼


            我android研究不多,大多以前玩逆向的底子。大家可以多討論。 歡迎大家留言探討~!

            ======================================================================================================

            7月11日21點更新:

            沒看到看雪上已經討論的熱火朝天,讀下來來源于看雪的zmworm的原理分析應該是更準確的。

            原理簡述??

            由于ZIP格式允許存在兩個或以上完全相同的路徑,而安卓系統沒有考慮這種場景。

            在該情況下,android包管理器校驗簽名取的是最后一個文件的hash,而運行APK加載的dex文件卻是zip的第一個dex文件。??

            包管理器驗證簽名驗的是最后一個(名字相同情況下)文件。

            1.?解析zip的所有Entry,結果存到HashMap(key為路徑,value為Entry)。

            enter image description here

            2.?由于HashMap.put在相同key的情況下,會把value更新,導致上述的HashMap在相同路徑下,存儲的一定是最后一個文件的Entry。

            enter image description here

            ?系統加載dex文件,加載的是第一個dex。???

            ??1.?查找dex的Entry用的是dexZipFindEntry。?

            enter image description here

            2.?dexZipFindEntry的實現是只要match就返回,所以返回的都是第一個文件。

            enter image description here

            Zip 可以包含兩個同名文件或者路徑,而其自身的unzip 默認方式是后一個覆蓋前一個。

            HashMap.put 的寫法應該文件也直接覆蓋(hash表的沖突處理不當果真出大問題)才算是算是符合zip 的標準。

            就是加載dex的方式則是先加載第一個,這樣確實信息不一致。

            而我之前黑盒測出來認為android 默認把兩個都加載在簽名驗證順序上出現問題的,未分析到上一層的類。

            看雪上也是討論很多帖子得到準確的原理分析,大家共同討論,集思廣益。Hack it, know it too.

            持續跟新中。

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线