Janus 二元神漏洞測試

img

同步發表於:http://blog.hacktons.cn/2017/12/25/janus-demo/android

背景

12月9號,Andorid對外曝光了一個名爲Janus的重量級系統漏洞CVE-2017-13156), 由安全研究公司Guard Square發現。
Janus原意是神話中的二元身,用於描述這個漏洞還真是貼切。git

Apk_Dex_Dual

整個漏洞其實創建在文件校驗規則之上:github

一個文件便是APK,又是DEX,在安裝APK和執行階段的校驗規則差別,致使能夠在APK頭部附加一個惡意DEX來欺騙系統web

下面咱們從市場上隨意下載一個apk來作測試。安全

測試APK

本文涉及的測試APK,只用於單擊研究之用,請勿惡意散播或上傳,由此引起的糾紛與做者無關app

能夠從豌豆莢,應用寶等市場下一個測試用的APK,爲了方便,咱們須要選用一些體積較小的apk,若是apk較大頗有可能通過了分包,替換工做會麻煩點。
快看漫畫less

這裏比較噁心的是,下載到的apk並非咱們選取的安裝包,而是豌豆莢市場,既然豌豆莢這麼強勢要入鏡,那麼姑且直接分析豌豆莢市場吧。ide

快看漫畫

MD5 (Wandoujia_224660_web_inner_referral_binded.apk) = d3c1d9b2a74a3f8fd9fce38d38423c58

簽名檢查

首先檢查下豌豆莢的這個apk是否是v2簽名的,由於咱們要測試的Janus只能在v1下驗證測試

檢查簽名信息能夠經過*.SF來確認,根據公開信息,若是v2簽名的話,會在SF文件內寫入一個字段X-Android-APK-Signed:2
豌豆莢的SF文件名字是META-INF/DEAMON2.SF, 比較幸運啊,能夠確認其使用的就是v1簽名。google

aven$ unzip -l Wandoujia_224660_web_inner_referral_binded.apk |grep META-INF
   120009  12-15-17 14:38   META-INF/MANIFEST.MF
   120130  12-15-17 14:38   META-INF/DEAMON2.SF
      891  12-15-17 14:38   META-INF/DEAMON2.RSA
aven$ unzip -p Wandoujia_224660_web_inner_referral_binded.apk META-INF/DEAMON2.SF|less
Signature-Version: 1.0
SHA1-Digest-Manifest-Main-Attributes: jq/6qzaCk3O+H4OBJsDhMXm+FvE=
Created-By: 1.6.0_30 (Sun Microsystems Inc.)
SHA1-Digest-Manifest: Dts4zfEM9pZstNDahVfVh4e4jGA=

Name: res/drawable-xhdpi-v4/il.png
SHA1-Digest: QCves3Cr/wm3X2w4PR4ESXGMBOw=

Name: res/layout/dh.xml
SHA1-Digest: DCuKb0PRLuNV6jTEbSDGMTEW174=

包名確認

接下來咱們須要構造一個新的dex,嫁接到豌豆莢的apk前面;這裏須要確認豌豆莢使用的包名:com.wandoujia.phoenix2

package: name='com.wandoujia.phoenix2' versionCode='16861' versionName='5.68.21'
sdkVersion:'14'
targetSdkVersion:'16'

另外值得一提的是,豌豆莢的權限仍是比較流氓的會要求大量敏感權限,所以在使用該市場的時候注意權限的問題,不然頗有可能裸奔了:

好比讀/寫短信,讀/寫通信錄等等,還有一些第三方權限

uses-permission:'android.permission.READ_SMS'
uses-permission:'android.permission.RECEIVE_SMS'
uses-permission:'android.permission.MANAGE_ACCOUNTS'
uses-permission:'android.permission.AUTHENTICATE_ACCOUNTS'
uses-permission:'android.permission.USE_CREDENTIALS'
uses-permission:'android.permission.READ_SETTINGS'
uses-permission:'android.permission.READ_EXTERNAL_STORAGE'
uses-permission:'android.permission.SEND_SMS'
uses-permission:'android.permission.WRITE_EXTERNAL_STORAGE'
uses-permission:'android.permission.MOUNT_UNMOUNT_FILESYSTEMS'
uses-permission:'android.permission.INTERNET'
uses-permission:'android.permission.ACCESS_NETWORK_STATE'
uses-permission:'android.permission.ACCESS_WIFI_STATE'
uses-permission:'android.permission.CHANGE_WIFI_STATE'
uses-permission:'android.permission.CHANGE_WIFI_MULTICAST_STATE'
uses-permission:'android.permission.SET_WALLPAPER'
uses-permission:'android.permission.SET_WALLPAPER_HINTS'
uses-permission:'android.permission.WRITE_SETTINGS'
uses-permission:'android.permission.CAMERA'
uses-permission:'android.permission.FLASHLIGHT'
uses-permission:'com.android.launcher.permission.INSTALL_SHORTCUT'
uses-permission:'com.android.launcher.permission.UNINSTALL_SHORTCUT'
uses-permission:'android.permission.READ_PHONE_STATE'
uses-permission:'android.permission.MODIFY_AUDIO_SETTINGS'
uses-permission:'android.permission.SYSTEM_ALERT_WINDOW'
uses-permission:'android.permission.ACCESS_SUPPERUSER'
uses-permission:'android.permission.GET_PACKAGE_SIZE'
uses-permission:'android.permission.KILL_BACKGROUND_PROCESSES'
uses-permission:'android.permission.CLEAR_APP_CACHE'
uses-permission:'android.permission.DISABLE_KEYGUARD'
uses-permission:'com.android.launcher.permission.READ_SETTINGS'
uses-permission:'com.android.launcher.permission.WRITE_SETTINGS'
uses-permission:'com.android.launcher3.permission.READ_SETTINGS'
uses-permission:'com.android.launcher3.permission.WRITE_SETTINGS'
uses-permission:'com.meizu.flyme.launcher.permission.READ_SETTINGS'
uses-permission:'com.meizu.flyme.launcher.permission.WRITE_SETTINGS'
uses-permission:'org.adw.launcher.permission.READ_SETTINGS'
uses-permission:'org.adw.launcher.permission.WRITE_SETTINGS'
uses-permission:'com.qihoo360.launcher.permission.READ_SETTINGS'
uses-permission:'com.qihoo360.launcher.permission.WRITE_SETTINGS'
uses-permission:'com.lge.launcher.permission.READ_SETTINGS'
uses-permission:'com.lge.launcher.permission.WRITE_SETTINGS'
uses-permission:'net.qihoo.launcher.permission.READ_SETTINGS'
uses-permission:'net.qihoo.launcher.permission.WRITE_SETTINGS'
uses-permission:'org.adwfreak.launcher.permission.READ_SETTINGS'
uses-permission:'org.adwfreak.launcher.permission.WRITE_SETTINGS'
uses-permission:'com.huawei.launcher3.permission.READ_SETTINGS'
uses-permission:'com.huawei.launcher3.permission.WRITE_SETTINGS'
uses-permission:'com.fede.launcher.permission.READ_SETTINGS'
uses-permission:'com.fede.launcher.permission.WRITE_SETTINGS'
uses-permission:'com.sec.android.app.twlauncher.settings.READ_SETTINGS'
uses-permission:'com.sec.android.app.twlauncher.settings.WRITE_SETTINGS'
uses-permission:'com.anddoes.launcher.permission.READ_SETTINGS'
uses-permission:'com.anddoes.launcher.permission.WRITE_SETTINGS'
uses-permission:'com.lenovo.launcher.permission.READ_SETTINGS'
uses-permission:'com.lenovo.launcher.permission.WRITE_SETTINGS'
uses-permission:'com.google.android.launcher.permission.READ_SETTINGS'
uses-permission:'com.google.android.launcher.permission.WRITE_SETTINGS'
uses-permission:'com.oppo.launcher.permission.WRITE_SETTINGS'
uses-permission:'com.oppo.launcher.permission.READ_SETTINGS'
uses-permission:'com.yulong.android.launcher3.permission.WRITE_SETTINGS'
uses-permission:'com.yulong.android.launcher3.permission.READ_SETTINGS'
uses-permission:'com.huawei.android.launcher.permission.READ_SETTINGS'
uses-permission:'com.huawei.android.launcher.permission.WRITE_SETTINGS'
uses-permission:'com.htc.launcher.permission.READ_SETTINGS'
uses-permission:'com.htc.launcher.permission.WRITE_SETTINGS'
uses-permission:'com.bbk.launcher2.permission.READ_SETTINGS'
uses-permission:'com.bbk.launcher2.permission.WRITE_SETTINGS'
uses-permission:'android.permission.WAKE_LOCK'
uses-permission:'android.permission.BROADCAST_PACKAGE_ADDED'
uses-permission:'android.permission.BROADCAST_PACKAGE_CHANGED'
uses-permission:'android.permission.BROADCAST_PACKAGE_INSTALL'
uses-permission:'android.permission.BROADCAST_PACKAGE_REPLACED'
uses-permission:'android.permission.RESTART_PACKAGES'
uses-permission:'android.permission.GET_TASKS'
uses-permission:'android.permission.RECEIVE_BOOT_COMPLETED'
uses-permission:'android.permission.CHANGE_NETWORK_STATE'
uses-permission:'android.permission.GET_ACCOUNTS'
uses-permission:'android.permission.VIBRATE'
uses-permission:'android.permission.BIND_ACCESSIBILITY_SERVICE'
uses-permission:'android.permission.READ_CONTACTS'
uses-permission:'android.permission.WRITE_CONTACTS'
uses-permission:'android.permission.CALL_PHONE'
uses-permission:'android.permission.WRITE_SMS'
uses-permission:'android.permission.WRITE_CALL_LOG'
uses-permission:'android.permission.READ_CALL_LOG'
uses-permission:'android.permission.AUTHENTICATE_ACCOUNTS'
uses-permission:'android.permission.WRITE_SYNC_SETTINGS'
uses-permission:'android.permission.MANAGE_ACCOUNTS'
uses-permission:'android.permission.ACCESS_FINE_LOCATION'
uses-permission:'android.permission.ACCESS_COARSE_LOCATION'
uses-permission:'com.wandoujia.phoenix2.permission.MIPUSH_RECEIVE'
uses-permission:'android.permission.PACKAGE_USAGE_STATS'
uses-permission:'android.permission.PERSISTENT_ACTIVITY'
uses-permission:'android.permission.ACCESS_MTK_MMHW'

Hack

接下來開始編碼工做,明確下咱們的目標:

  • 替換Application,而且在app進程啓動時彈出一個toast;
  • 替換啓動頁,顯示一個特殊文案;

所以首先安確認下豌豆莢的自定義application:com.pp.assistant.PPApplication

aven$ aapt dump xmltree Wandoujia_224660_web_inner_referral_binded.apk AndroidManifest.xml|less

    E: application (line=155)
      A: android:theme(0x01010000)=@0x7f0a0001
      A: android:label(0x01010001)=@0x7f0c038a
      A: android:icon(0x01010002)=@0x7f02009d
      A: android:name(0x01010003)="com.pp.assistant.PPApplication" (Raw: "com.pp.assistant.PPApplication")
      A: android:stateNotNeeded(0x01010016)=(type 0x12)0xffffffff
      A: android:windowSoftInputMode(0x0101022b)=(type 0x11)0x3
      A: android:allowBackup(0x01010280)=(type 0x12)0xffffffff

建立同名的PPApplication的,而後加上toast便可,接下來編譯獲得新的apk,並將其中的dex抽離出來備用。

插曲

在實際插入dex的時候,遇到了一些小插曲,好比插入完後,啓動崩潰,因此若是是插入全新的dex的話,須要確認和原有dex的關係,若是徹底摒棄原有邏輯,那麼須要手動補全manifest中聲明的ContentProviderBroadcastReceiver,Activity根據須要替換,Service可選替換

另外合併apk和dex不是簡單的字節疊加,須要修改最終apk的偏移量,確保zip的正確性。筆者使用的是一個Python腳本

https://github.com/V-E-O/PoC/tree/master/CVE-2017-13156

效果

搞定以後,能夠直接安裝apk,也能夠覆蓋升級安裝,接下來啓動app就能夠看到徹底不一樣的效果;

在這裏咱們出於實驗性質,將豌豆莢市場的application和啓動Activity作了總體替換,所以直接感覺就是原有邏輯所有沒有了,若是咱們經過反編譯後增量修改的方式來新增dex,納悶能夠實現和原app功能幾乎一致的串改,這樣能夠惡意插入代碼,同時不容易被用戶發現。

效果

修復

這個bug看起來挺嚴重的,不過實際上影響有限,若是用戶經過正規市場下載程序基本沒什麼問題,同時Android官方已經作fix,相信後續很快就會在新版本中生效。 對於開發者來講比較被動,最好升級簽名爲V2,別的就沒有屏蔽辦法了,比較問題出在系統校驗上面。

相關文章
相關標籤/搜索