Android系統存在一些漏洞可導致系統重啟,當然讓系統重啟只是一種現象,這些漏洞有的還可以權限提升、執行代碼等。本文以重啟這個現象為分類依據,牽強的把這些漏洞放在一塊來看。下面對這些漏洞的成因和本質進行簡單的分析,并盡量附上編譯好的poc和漏洞利用演示視頻。
https://labs.mwrinfosecurity.com/advisories/2014/11/05/nexus-5-4-4-2-local-dos/ 漏洞概述:
Nexus 5預裝了一個隱藏的用來測試網絡連通性的系統應用。在4.4.3之前的版本里,這個應用里有大量導出的activity,這些 activity不需要任何權限就可以被外部調用。其中一個導出的activity可以使手機遭受DOS攻擊,外部調用就可以讓手機直接重啟。
除了調用這個組件使系統重啟外,如果一個惡意應用注冊響應BOOT_COMPLETED廣播,并且發送合適的intent給漏洞activity組件,那么手機將會循環重啟。
存在漏洞的應用包:com.lge.SprintHiddenMenu
存在漏洞的組件:?com.lge.SprintHiddenMenu.sprintspec.SCRTN,該組件是導出的,并且沒有做任何權限限制。 通過如下命令即可使Nexus 5手機重啟:
#!bash
adb shell am start –n com.lge.SprintHiddenMenu/com.lge.SprintHiddenMenu.sprintspec.SCRTN
4.4.3及以上系統中對這個組件做了權限限制,只有應用申請了com.lge.permission.SPRINTHIDDEN這個權限才能調起com.lge.SprintHiddenMenu.sprintspec.SCRTN組件。
http://blog.trendmicro.com/trendlabs-security-intelligence/malformed-androidmanifest-xml-in-apps-can-crash-mobile-devices/
兩種方法:
strings.xml文件中一些tag(如permission name,label,activity name)如果包含超長字符串,當Package Parser去解析這個.XML文件時需要申請大量內存,導致內存溢出,PackageParser crash。所有依賴PackageParser運行的服務都會停止,導致系統也會重啟一次。
下面是編譯好的一個poc應用,這個應用沒有申請任何權限,也無惡意代碼,只是在strings.xml的label tag中使用了超長字符串。裝上之后運行就可使系統重啟。
云盤下載地址:
http://yunpan.cn/cZK5pQRasVrAr (提取碼:f256)
如果一個apk文件里大量activity或者service包含下面特定的intent-filter,那么應用安裝后會生成相同數量的icon.如果這樣的activity或service的數量超過10000,系統就會重啟,如果超過100000,設備會循環重啟。
#!html
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
運行如下命令即可導致nexus6異常重啟。
#!bash
$ adb shell cat /d/pc_debug_counter
具體原因不詳,Twitter上有人講是因為arch/arm/mach-msm/msm-pm.c內核驅動文件里msm_pc_debug_counters_copy()里調用的scnprintf()函數引起的。
scnprintf() API說明見1。作用是格式化一個字符串并把它放在buffer里,返回值是寫進buffer的字符數量。
在網上找到這個文件的兩個版本,舊版本2如下:
漏洞可能是因為MSM_PC_NUM_COUNTERS 值等于4,而counter_name長度為3,循環中j最大取值為3,數組下標越界,counter_name[j]取不到值導致的。
新的版本3如下,發現新文件在循環中做了處理。
http://seclists.org/fulldisclosure/2014/Nov/51
Android < 5.0, java.io.ObjectInputStream 沒有校驗被反序列化的對象是否合法.
java.io.ObjectInputStream不校驗被反序列化的對象的真實性,這就意味著攻擊者可以構造一個任意的序列化對象,這個對象的屬性值可以由攻擊者指定。然而這個惡意對象是無用的,最終會被GC回收,GC會調用對象的finalize方法。
Android里system_service是以root權限運行的,其他應用都可以通過Intent的方式和其通信,可以傳遞一個Bundle對象給Intent,而Bundle里可以放一個序列化對象,其他應用都可以以這種方式攻擊system_service。
android.os.BinderProxy類包含一個finalize方法,這個方法最終會調用native層的android_os_BinderProxy_destroy()4這個方法,可以看到這個方法里會使用序列化對象里的兩個字段值,并把這兩個值傳給了指針。
如果攻擊者可以在system_server 的已知內存地址插入數據,那么就可以執行任意代碼。 Android有做地址空間隨機化ASLR,但是所有的app都是fork自zygote進程,他們都有相同的基本內存布局,因此是可以繞過system_server的ASLR.
poc偽造了一個AAdroid.os.BinderProxy類對象,傳遞給system_server的jvm后觸發了GC回收,但是把其當成了android.os.BinderProxy,觸發了android_os_BinderProxy_destroy函數,獲得代碼執行。
編譯好的poc:http://yunpan.cn/cZK5NuMJspXAc(提取碼:5962)
漏洞演示視頻:http://v.youku.com/v_show/id_XOTE0MDgxODE2.html
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1474
Google Android platform/frameworks/native/libs/ui/GraphicBuffer.cpp中的GraphicBuffer::unflatten函數存在整數溢出錯誤,攻擊者通過傳遞超長文件描述符或整數值,可使應用程序崩潰或執行任意代碼。?
Google Android 5.0
遠程攻擊者利用漏洞可使應用程序拒絕服務或執行任意代碼。
利用和CVE-2014-7911一樣,攻擊system_service。
Google已經發布patch,對numFds 和numInts的最大值進行了判斷和限制。
https://android.googlesource.com/platform/frameworks/native/+/4aaa39358f538d8e06e026385bb8be8088d78c35/libs/ui/GraphicBuffer.cpp
修復后:
https://android.googlesource.com/platform/frameworks/native/+/38803268570f90e97452cd9a30ac831661829091/libs/ui/GraphicBuffer.cpp
如果有興趣,讀者也可以自行編譯AOSP代碼進行patch,可以使用下面這個教程。 https://gist.github.com/Fuzion24/068fe36bb5b762367921
一些Android設備,通過Wifi直連功能搜索可直連的設備過程,可以被DOS攻擊。攻擊者發送一個精心構造的802.11協議的探測響應幀,存在漏洞的設備在收到這個響應幀后不能正確處理畸形數據,導致系統重啟。
漏洞影響的設備:
Nexus 5 - Android 4.4.4
Nexus 4 - Android 4.4.4
LG D806 - Android 4.2.2
Samsung SM-T310 - Android 4.2.2
Motorola RAZR HD-Android4.1.2
其他設備也可能受影響。
Android使用了修改過的wpa_supplicant來提供無線驅動和Android platform framework之間的通訊接口。關于wpa_supplicant請參考:http://w1.fi/wpa_supplicant/
下面的函數用來處理wpa_supplicant events。這個函數最后通過調用NewStringUTF方法來返回一個jstring。 https://gitorious.org/android-eeepc/base/source/a0332f171e7413f79f156e8685d1147d89bfc5ca:core/jni/android_net_wifi_Wifi.cpp#L127
WiFi_Direct 規范里定義了P2P的發現過程,使得P2P設備間可以互相交換設備信息,device name是設備信息的一部分。 WifiP2pDevice類位于/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java5文件,它的對象可以表示一個Wi-Fi p2p設備。代碼如下,可以看到它的構造函數是通過wpa_supplicant返回的string來初始化的,也就是剛才提到的android_net_wifi_waitForEvent()返回的值。如果這個值,也就是wpa_supplicant event是個異常值,那么就會拋出IllegalArgumentException。
一些Android設備在處理探測響應幀時,如果WiFi-Direct(p2p)信息元素里包含device name屬性和一些特定的字節生成的異常的supplicant event字符串,那么就會拋出IllegalArgumentException。然而WiFiMonitor這個系統進程并沒有處理這個異常,導致設備重啟。
Nexus 5上的部分logcat內容如下:
Poc:
文件地址:http://downloads.securityfocus.com/vulnerabilities/exploits/72311.py
這個poc里使用了兩個開源庫Lorcon6和PyLorcon27,其中PyLorcon2是對Lorcon的封裝。
這兩個庫可以獲取到無線網卡的信息,并且可以開啟monitor模式。通過指定無線信道、源和目標信息來構造探測響應幀,最后響應給被攻擊設備。被攻擊設備收到畸形的響應數據,沒有處理異常,導致系統重啟。
下面是我們錄制的漏洞演示視頻:
http://v.youku.com/v_show/id_XODgwNzk2Nzk2.html
0x07.總結: 以上漏洞成因總結大致如下: (1)沒有判斷數據類型的邊界值,導致溢出攻擊 (2)傳遞惡意payload (3)數組下標越界 (4)權限限制不嚴 (5)攻擊system_service
1 http://oss.org.cn/ossdocs/gnu_linux/kernel-api/r1980.html
2https://bot.bricked.de/showp1984/zarboz_m8wlv/raw/621cf6bec9f2b2fed94374c8cd949985a740dbbf/arch/arm/mach-msm/msm-pm.c
3https://github.com/dtsinc/DTS-Eagle-Integration_CAF-Android-kernel/blob/master/drivers/power/qcom/msm-pm.c
4https://code.google.com/p/android-source-browsing/source/browse/core/jni/android_util_Binder.cpp?repo=platform--frameworks--base&name=android-cts-4.2_r2
5https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
6 https://code.google.com/p/lorcon/
7https://code.google.com/p/pylorcon2/