<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/mobile/16382

            作者:[email protected]

            0x00 Content Provider組件簡介


            Content Provider組件是Android應用的重要組件之一,管理對數據的訪問,主要用于不同的應用程序之間實現數據共享的功能。Content Provider的數據源不止包括SQLite數據庫,還可以是文件數據。通過將數據儲存層和應用層分離,Content Provider為各種數據源提供了一個通用的接口。

            創建一個自己的Content Provider需要繼承自ContentProvider抽象類,需要重寫其中的onCreate()query()insert()update()delete()getType()六個抽象方法,這些方法實現對底層數據源的增刪改查等操作。還需在AndroidManifest文件注冊Content Provider,注冊時指定訪問權限、exported屬性、authority屬性值等。

            其它APP使用ContentResolver對象來查詢和操作Content Provider,此對象具有Content Provider中同名的方法名。這樣其他APP接就可以訪問Content Provider對應的數據源的底層數據,而無須知道數據的結構或實現。?

            如何定位到具體的數據??

            采用Content Uri,一個Content Uri如下所示:

            content://com.jaq.providertest.friendsprovider/friends
            

            它的組成一般分為三部分:

            1. content://:作為 content Uri的特殊標識(必須);

            2. 權(authority):用于唯一標識這個Content Provider,外部訪問者可以根據這個標識找到它;在AndroidManifest中也配置的有;

            3. 路徑(path): 所需要訪問數據的路徑,根據業務而定。

            這些內容就不具體展開詳談了,詳見參考【1】【4】。

            0x01 風險簡介


            如果在AndroidManifest文件中將某個Content Provider的exported屬性設置為true,則多了一個攻擊該APP的攻擊點。如果此Content Provider的實現有問題,則可能產生任意數據訪問、SQL注入、目錄遍歷等風險。

            1.1 私有權限定義錯誤導致數據被任意訪問

            私有權限定義經常發生的風險是:定義了私有權限,但是卻根本沒有定義私有權限的級別,或者定義的權限級別不夠,導致惡意應用只要聲明這個權限就能夠訪問到相應的Content Provider提供的數據,造成數據泄露。

            以公開的烏云漏洞WooYun-2014-57590為例:

            某網盤客戶端使用了自己的私有權限,但是在AndroidManifest中卻沒有定義私有權限,其它APP只要聲明這個權限就能訪問此網盤客戶端提供的Provider,從而訪問到用戶數據。

            在網盤客戶端的AndroidManifest中注冊Provider時,聲明了訪問時需要的讀寫權限,并且權限為客戶端自定義的私有權限:

            但是在AndroidManifest中卻沒有見到私有權限“com.huawei.dbank.v7.provider.DBank.READ_DATABASE”和“com.huawei.dbank.v7.provider.DBank.WRITE_DATABASE”的定義:

            反編譯客戶端后查看到的URI,根據這些可以構造訪問到Provider的URI:

            編寫POC

            以查看網盤下載的文件列表為例,?

            在POC的AndroidManifest中聲明私有權限,權限的保護級別定義為最低級“normal”:

            主要代碼為:

            拿到數據庫中保存的下載列表數據:

            對應的數據庫:

            這樣任意的惡意應用程序就可以訪問到用戶網盤的上傳、下載記錄,網盤里面存的文件列表等隱私信息。

            再以公開的烏云漏洞wooyun-2013-039697為例:

            定義了私有權限,但是保護等級設置成為了dangerous或者normal,這樣的保護等級對于一些應用的Provide重要性相比保護級低了。?

            Provider為:

            私有權限“com.renren.mobile.android.permission.PERMISSION_ADD_ACCOUNT”的定義為:

            反編譯客戶端,看到AcountProvider對應的實現:

            編寫POC:?

            AndroidManifest中定義和聲明權限:

            主要代碼為:

            可看到用戶的賬戶信息,包括uid,手機號,加密后的密碼等:

            1.2 本地SQL注入

            當Content Provider的數據源是SQLite數據庫時,如果實現不當,而Provider又是暴露的話,則可能會引發本地SQL注入漏洞。

            Content Provider的query( )的方法定義為:

            其中參數:

            query() 與 SQL 查詢對比如下:

            如果query( )中使用的是拼接字符串組成SQL語句的形式去查詢底層的SQLite數據庫時,容易發生SQL注入。

            以烏云公開漏洞wooyun-2016-0175294為例:

            客戶端的com.sohu.sohuvideo.provider.PlayHistoryProviderexported屬性為“true”:

            反編譯客戶端,追蹤PlayHistoryProvider的實現,發現是用拼接字符串形式構造原始的SQL查詢語句:

            使用drozer工具,證明漏洞:

            對外暴露的Content Provider實現了openFile()接口,因此其他有相應調用該Content Provider權限的應用即可調用Content Provider的openFile()接口進行文件數據訪問。但是如果沒有進行Content Provider訪問權限控制和對訪問的目標文件的Uri進行有效判斷,攻擊者利用文件目錄遍歷可訪問任意可讀文件,更有甚者可以往手機設備可寫目錄中寫入任意數據。

            例子1?

            以烏云公開漏洞wooyun-2013-044407為例:?

            此APP實現中定義了一個可以訪問本地文件的Content Provider組件,為com.ganji.android.jobs.html5.LocalFileContentProvider,因為使用了minSdkServison=“8”targetSdkVersion=”13”,即此Content Provider采用默認的導出配置,即android:exported=”true”

            該Provider實現了openFile()接口:

            通過此接口可以訪問內部存儲app_webview目錄下的數據,由于后臺未能對目標文件地址進行有效判斷,可以通過”../”實現目錄遍歷,實現對任意私有數據的訪問。

            例子2

            某社交應用客戶端,使用了的minSDKVersion為8,定義了私有權限,并且android:protectionLevel設為了signature

            有一個對外暴露的Content Provider,即com.facebook.lite.photo.MediaContentProvider,此Provider沒有設置訪問權限,而另外一個Provider是設置了訪問權限的:

            MediaContentProvider中實現了openFile()接口,沒有對傳入的URI進行限制和過濾:

            此接口本來只想讓用戶訪問照片信息的,但是卻可以突破限制,讀取其他文件:?

            POC:

            讀取到其他文件的內容為:

            另外看到Openfile()接口的實現中,如果要訪問的文件不存在,就會創建此文件,還有可能的風險就是在應用的目錄中寫入任意文件。

            0x02 阿里聚安全開發者建議


            在進行APP設計時,要清楚哪些Provider的數據是用戶隱私數據或者其他重要數據,考慮是否要提供給外部應用使用,如果不需要提供,則在AndroidManifes文件中將其exported屬性顯式的設為“false”,這樣就會減少了很大一部分的攻擊面。

            人工排查肯定比較麻煩,建議開發者使用阿里聚安全提供的安全掃描服務,在APP上線前進行自動化的安全掃描,盡早發現并規避這樣的風險。

            注意:

            由于Android組件Content Provider無法在Android 2.2(即API Level 8)系統上設為不導出,因此建議聲明最低SDK版本為8以上版本(這已經是好幾年前的SDK了,現在一般都會大于此版本);?

            由于API level 在17以下的所有應用的“android:exported”屬性默認值都為true,因此如果應用的Content Provider不必要導出,建議顯式設置注冊的Content Provider組件的“android:exported”屬性為false;?

            如果必須要有數據提供給外部應用使用,則做好設計,做好權限控制,明確什么樣的外部應用可以使用,如對于本公司的應用在權限定義時用相同簽名即可,合作方的應用檢查其簽名;不過還是盡量不提供用戶隱私敏感信息。

            對于必須暴露的Provider,如第二部分遇到的風險解決辦法如下:

            2.1 正確的定義私有權限

            在AndroidManifest中定義私有權限的語法為:

            其中android:protectionLevel的可選值分別表示:

            大部分開放的Provider,是提供給本公司的其他應用使用的,一般的話一個公司打包簽名APP的簽名證書都應該是一致的,這種情況下,Provider的android:protectionLevel應為設為“signature”。

            2.2 防止本地SQL注入

            注意:一定不要使用拼接來組裝SQL語句。?

            如果Content Provider的數據源是SQLite數據庫,如果使用拼接字符串的形式組成原始SQL語句執行,則會導致SQL注入。?

            如下的選擇子句:

            如果執行此操作,則會允許用戶將惡意 SQL 串連到 SQL 語句上。?

            例如,用戶可以為 mUserInput 輸入“nothing; DROP TABLE ** ;”,這會生成選擇子句

            #!sql
            var = nothing; DROP TABLE **;
            

            由于選擇子句是作為SQL語句處理,因此這可能會導致提供程序擦除基礎 SQLite 數據庫中的所有表(除非提供程序設置為可捕獲 SQL 注入嘗試)。

            使用參數化查詢:

            要避免此問題,可使用一個“ ? ” 作為可替換參數的選擇子句以及一個單獨的選擇參數數組。?

            執行此操作時,用戶輸入直接受查詢約束,而不解釋為 SQL 語句的一部分。?

            由于用戶輸入未作為 SQL 處理,因此無法注入惡意 SQL。

            請使用此選擇子句,而不要使用串連來包括用戶輸入:

            #!java
            String mSelectionClause = “var = ?”;
            

            按如下所示設置選擇參數數組:

            #!java
            String[] selectionArgs = {“”};
            

            按如下所示將值置于選擇參數數組中:

            #!java
            selectionArgs[0] = mUserInput;
            

            還可調用SQLiteDatabase類中的參數化查詢query()方法:

            3.3 防止目錄遍歷

            1、去除Content Provider中沒有必要的openFile()接口。?

            2、過濾限制跨域訪問,對訪問的目標文件的路徑進行有效判斷:?

            使用Uri.decode()先對Content Query Uri進行解碼后,再過濾如可通過“../”實現任意可讀文件的訪問的Uri字符串,如:

            2.4 通過檢測簽名來授權合作方應用訪問

            如果必須給合作方的APP提供Provider的訪問權限,而合作方的APP簽名證書又于自己公司的不同,可將合作方的APP的簽名哈希值預埋在提供Provider的APP中,提供Provider的APP要檢查請求訪問此Provider的APP的簽名,簽名匹配通過才讓訪問。

            0x03 參考


            【1】《內容提供程序基礎知識》https://developer.android.com/guide/topics/providers/content-provider-basics.html ?

            【2】《Android app端的sql注入》http://zone.wooyun.org/content/15097

            【3】《Android - Content Providers》?http://www.tutorialspoint.com/android/android_content_providers.htm ?

            【4】?http://www.compiletimeerror.com/2013/12/content-provider-in-android.html

            【5】?https://developer.android.com/guide/topics/manifest/permission-element.html?hl=zh-cn

            【6】?https://developer.android.com/guide/topics/manifest/permission-element.html

            【7】? WooYun: 人人客戶端權限問題導致隱私泄露 ?

            【8】? WooYun: 華為網盤content provider組件可能泄漏用戶信息 ?

            【9】 《Android Content Provider Security》http://drops.wooyun.org/tips/4314

            【10】? WooYun: 搜狐app注入泄露觀看歷史 ?

            【11】《Android Content Provider Security》http://drops.wooyun.org/tips/4314

            【12】? WooYun: 趕集網Android客戶端Content Provider組件任意文件讀取漏洞 ?

            【13】? WooYun: 58同城Android客戶端遠程文件寫入漏洞 ?

            【14】 《Content Provider文件目錄遍歷漏洞淺析》,https://jaq.alibaba.com/blog.htm?id=61?

            【15】?https://github.com/programa-stic/security-advisories/tree/master/FacebookLite

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

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

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

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

                      亚洲欧美在线