一個(gè)漏洞泄露你的郵箱的所有秘密
谷歌近期對(duì)外公布了2016年10月的Nexus Security Bulletin ,這其中包含一個(gè)由360手機(jī)衛(wèi)士阿爾法團(tuán)隊(duì)(Alpha Team)提交的電子郵件信息泄露漏洞(CVE-2016-3918 ),谷歌對(duì)此漏洞的評(píng)級(jí)為高危險(xiǎn)等級(jí)。該漏洞可導(dǎo)致惡意應(yīng)用獲取到電子郵件內(nèi)的數(shù)據(jù),可能是電子郵件內(nèi)容、電子郵件附件甚至賬號(hào)密碼。目前谷歌已經(jīng)修復(fù)該漏洞并向OEM廠商推送了補(bǔ)丁,本文將對(duì)此漏洞進(jìn)行分析。
本文的測(cè)試環(huán)境和代碼版本如下:
- SDK Version: 23,
- Android 6.0.1 Build: MOB30Y
- Branch: android-6.0.1_r60
漏洞成因
在Android AOSP的Email應(yīng)用程序的源碼中,我們可以看到在AndroidManifest.xml 文件中存在名為AttachmentProvider的ContentProvider。
- <provider
- android:name=".provider.AttachmentProvider"
- android:authorities="com.android.email.attachmentprovider"
- android:grantUriPermissions="true"
- android:exported="true"
- android:readPermission="com.android.email.permission.READ_ATTACHMENT"
- />
其主要屬性如下:
- exported true即對(duì)外開放
- authorities com.android.email.attachmentprovider 即URI唯一標(biāo)識(shí)
- readPermission com.android.email.permission.READ_ATTACHMENT 即讀取需要此權(quán)限
通過(guò)查詢我們可以了解到com.android.email.permission.READ_ATTACHMENT權(quán)限的protectionLevel為 dangerous,即可被第三方應(yīng)用獲取到。
- <permission
- android:name="com.android.email.permission.READ_ATTACHMENT"
- android:permissionGroup="android.permission-group.MESSAGES"
- android:protectionLevel="dangerous"
- android:label="@string/permission_read_attachment_label"
- android:description="@string/permission_read_attachment_desc"/>
在確定此ContentProvider可以被第三方應(yīng)用接觸到之后,我們定位AttachmentProvider的源碼。 源碼路徑如下:
- /packages/apps/Email/provider_src/com/android/email/provider/AttachmentProvider.java
通過(guò)閱讀源碼我們可以發(fā)現(xiàn)AttachmentProvider中實(shí)現(xiàn)了一個(gè)public的openFile 接口,該接口會(huì)返回一個(gè)ParcelFileDescriptor類型的對(duì)象供調(diào)用者打開文件。
- public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
進(jìn)入openFile接口立刻就會(huì)判斷mode值是否為 "w" ,如果為w則會(huì)返回一個(gè)可寫的文件描述符。但在返回之前,函數(shù)的實(shí)現(xiàn)代碼進(jìn)行了權(quán)限檢查,如果調(diào)用者沒有com.android.email.permission.ACCESS_PROVIDER 權(quán)限的話是會(huì)拋異常的。而該權(quán)限的聲明如下:
- <permission
- android:name="com.android.email.permission.ACCESS_PROVIDER"
- android:protectionLevel="signature"
- android:label="@string/permission_access_provider_label"
- android:description="@string/permission_access_provider_desc"/>
可以看到該權(quán)限是無(wú)法被第三方應(yīng)用獲取到的,所以獲取可寫的權(quán)限是不可行的。 繼續(xù)往下分析代碼。
- List<String> segments = uri.getPathSegments();
- String accountId = segments.get(0);
- String id = segments.get(1);
- String format = segments.get(2);
- if (AttachmentUtilities.FORMAT_THUMBNAIL.equals(format)) {
- int width = Integer.parseInt(segments.get(3));
- int height = Integer.parseInt(segments.get(4));
- ...
- }
- else {
- return ParcelFileDescriptor.open(
- new File(getContext().getDatabasePath(accountId + ".db_att"), id),
- ParcelFileDescriptor.MODE_READ_ONLY);
- }
接下來(lái)一系列代碼會(huì)從uri.getPathSegments()中分割開不同的字段,并從中讀取相應(yīng)的配置參數(shù)。 當(dāng) format參數(shù)不等于"THUMBNAIL"時(shí),該代碼將會(huì)直接返回一個(gè)getDatabasePath()該目錄下名為id 的文件的文件描述符。 而id參數(shù)是上面從uri.getPathSegments().get(1) 得到的,獲取之后則沒有任何處理。 uri.getPathSegments()方法的作用是將字符串以"/"進(jìn)行分割,但由于其沒有對(duì)經(jīng)過(guò)url 編碼的字符串進(jìn)行解碼,導(dǎo)致在處理過(guò)程中,對(duì)于/編碼之后的%2f則將不做處理,從而繞過(guò)getPathSegments的分割。
漏洞利用
根據(jù)上面我們對(duì)于代碼的分析,可以得出AttachmentProvider的uri如下:
- content://accountId/id/format/width/height
我們?nèi)绻肜么寺┒醋x取數(shù)據(jù),為使程序流能夠成功運(yùn)行至目標(biāo)位置,需要構(gòu)造如下uri
- content://com.android.email.attachmentprovider/1/file_position/1/1/1
而且,getDatabasePath()的目錄是/data/user/0/com.android.email/databases/,如果我們要讀取Email 郵件的數(shù)據(jù),則需要跳轉(zhuǎn)至目標(biāo)目錄/data/data/com.android.email/來(lái)讀取Email應(yīng)用的sqlite數(shù)據(jù)庫(kù)文件,我們需要構(gòu)造如下 uri:
- content://com.android.email.attachmentprovider/1/..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fdata%2Fdata%2Fcom.android.email%2Fdatabases%2FEmailProvider.db/1/1/1
而EmailProvider.db中存儲(chǔ)了我們已登陸賬戶的賬戶名和密碼,對(duì)應(yīng)的結(jié)構(gòu)為HostAuth表的login和password 字段。 我們構(gòu)造的PoC截圖如下:
總結(jié)
至此,CVE-2016-3918漏洞的分析和利用已經(jīng)完成。 經(jīng)過(guò)我們的測(cè)試,目前多款主流手機(jī)機(jī)型的自帶電子郵件客戶端都存在該問(wèn)題,如小米 NOTE、華為P9、三星S5等機(jī)型,為了賬戶的安全,請(qǐng)使用存在漏洞手機(jī)的用戶暫停使用電子郵件客戶端并清除賬戶信息,換至其他郵件客戶端。