关于android设备管理器的一些分析
生活随笔
收集整理的這篇文章主要介紹了
关于android设备管理器的一些分析
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
想必很多人都知道轟動(dòng)一時(shí)android木馬OBAD,該木馬利用android設(shè)備管理器的漏洞,當(dāng)用戶激活設(shè)備管理器后,該程序會(huì)在setting設(shè)備管理器列表隱藏,應(yīng)用程序激活成設(shè)備管理器后,可以實(shí)現(xiàn)鎖屏、擦除用戶數(shù)據(jù)等功能,并且無(wú)法使用常規(guī)的卸載方式對(duì)其卸載,本文主要和介紹漏洞原理和漏洞補(bǔ)丁分享個(gè)人在分析過(guò)程中遇到的一些事情。
Android?在實(shí)現(xiàn)設(shè)備管理器時(shí),需要再manifest.xml中注冊(cè)一個(gè)廣播接收者,代碼如下
??<receiver
????????????android:name=".MyDeviceAdmin"
?????????????????????android:permission="android.permission.BIND_DEVICE_ADMIN"?>?
?????????????<meta-data
????????????????android:name="android.app.device_admin"
????????????????android:resource="@xml/device_admin"?/>?
?????????????<intent-filter>
???????????????<action?android:name="android.app.action.DEVICE_ADMIN_ENABLED"?/>
????????????</intent-filter>??
????????</receiver>?
OBAD如何在setting的管理器列表隱藏呢,我們可以通過(guò)setting的源碼找到答案。相關(guān)代碼:packages\apps\Settings\src\com\android\settings\DeviceAdminSettings.java
??主要方法:
void?updateList()?{
????????mActiveAdmins.clear();
????????List<ComponentName>?cur?=?mDPM.getActiveAdmins();
????????if?(cur?!=?null)?{
????????????for?(int?i=0;?i<cur.size();?i++)?{
????????????????mActiveAdmins.add(cur.get(i));
????????????}
????????}
//獲得已經(jīng)激活設(shè)備管理器列表mActiveAdmins
????????mAvailableAdmins.clear();
//?mAvailableAdmins?setting的設(shè)備管理器列表
????????List<ResolveInfo>?avail?=?getActivity().getPackageManager().queryBroadcastReceivers(
????????????????new?Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED),
????????????????PackageManager.GET_META_DATA);
//獲取所有注冊(cè)了DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED即android.app.action.DEVICE_ADMIN_ENABLED?action的廣播接收者列表avail
????????int?count?=?avail?==?null???0?:?avail.size();
????????for?(int?i=0;?i<count;?i++)?{
????????????ResolveInfo?ri?=?avail.get(i);
????????????try?{
????????????????DeviceAdminInfo?dpi?=?new?DeviceAdminInfo(getActivity(),?ri);
???????????????
????????????????if?(dpi.isVisible()?||?mActiveAdmins.contains(dpi.getComponent()))?{
????????????????????mAvailableAdmins.add(dpi);
??????????//如果應(yīng)用注冊(cè)了包含該action的廣播接受者并且激活了設(shè)備管理器,就會(huì)在setting的設(shè)備管理器列表中顯示
????????????????}
????????????}?catch?(XmlPullParserException?e)?{
????????????????Log.w(TAG,?"Skipping?"?+?ri.activityInfo,?e);
????????????}?catch?(IOException?e)?{
????????????????Log.w(TAG,?"Skipping?"?+?ri.activityInfo,?e);
????????????}
????????}
???????????????getListView().setAdapter(new?PolicyListAdapter());
????}
但是沒(méi)有注冊(cè)android.app.action.DEVICE_ADMIN_ENABLED?action的應(yīng)用也可以激活為設(shè)備管理器。這就導(dǎo)致了激活后的設(shè)備管理器無(wú)法在setting的設(shè)備管理器列表中顯示。
如何解決這種情況呢?下面我們一起來(lái)分析一下安全管家的設(shè)備管理器補(bǔ)丁。該補(bǔ)丁是一個(gè)正常的apk,反編譯之,代碼結(jié)構(gòu)如下
?
主要類(lèi)DeviceAdminProxy代碼如下:
?//上面方法的主要內(nèi)容就是對(duì)比直接通過(guò)DevicePolicyManager獲得的已經(jīng)激活的設(shè)備管理器列表a和通過(guò)遍歷注冊(cè)了android.app.action.DEVICE_ADMIN_ENABLED?action的列表b進(jìn)行對(duì)比,如果發(fā)現(xiàn)列表a中的設(shè)備管理器沒(méi)有在列表b中出現(xiàn),就調(diào)用如下代碼彈出取消激活的activity,讓用戶手動(dòng)取消。
?代碼中有一個(gè)RootMain的類(lèi),這個(gè)類(lèi)在當(dāng)能獲得root權(quán)限的時(shí)候使用,找到利用這個(gè)漏洞的設(shè)備管理器后直接調(diào)用DevicePolicyManager的removeActiveAdmin方法取消激活,該方法需要system以上權(quán)限才能執(zhí)行。
關(guān)于android.app.action.DEVICE_ADMIN_ENABLED引起的漏洞都這里就結(jié)束了,下面說(shuō)一下在分析中遇到的另外一件有趣的事。
前面講到setting獲取管理器列表時(shí),有這么一段代碼,如下圖
?
代碼中實(shí)例DeviceAdminInfo對(duì)象,DeviceAdminInfo.java在frameworks\base\core\java\android\app\admin\DeviceAdminInfo.java
關(guān)鍵代碼:
?
之前我們?cè)趍anifest的receiver中有如下配置:
?
如果不配置meta-data,DeviceAdminInfo類(lèi)就會(huì)拋出異常,DeviceAdminSettings中獲取異常,按照上面圖中的代碼可以發(fā)現(xiàn),同樣setting的設(shè)備管理器列表也無(wú)法顯示。這樣setting雖然不顯示了,但是,如果不配置meta-data,設(shè)備管理器時(shí)沒(méi)辦法正常激活的。怎么辦呢?用正常的設(shè)備管理器程序安裝,正常激活,然后刪除該程序的meta-data配置,生成apk,以更新安裝的形式安裝到android設(shè)備上。這個(gè)時(shí)候卸載該程序會(huì)發(fā)現(xiàn),該程序已經(jīng)激活為設(shè)備管理器,但是在setting設(shè)備管理器列表中找不到。因?yàn)樵O(shè)備管理器注冊(cè)了android.app.action.DEVICE_ADMIN_ENABLED,所以使用上述的設(shè)備管理漏洞補(bǔ)丁也是找不到的。
那么如何取消激活呢?從上面對(duì)于設(shè)備管理器漏洞補(bǔ)丁apk的分析可以得出兩種取消激活的方法分析(其實(shí)是三種):
一、??DevicePolicyManager獲得的已經(jīng)激活的設(shè)備管理器列表,然后使用下面的代碼?
啟動(dòng)取消激活的activity。測(cè)試結(jié)果是行不通的,因?yàn)镈eviceAdminAdd也需要解析meta-data中的信息。具體參見(jiàn)DeviceAdminAdd.java位于packages\apps\Settings\src\com\android\settings\?DeviceAdminAdd.java。
二、??獲取到激活的設(shè)備管理器列表后直接調(diào)用DevicePolicyManager的removeActiveAdmin方法取消激活,測(cè)試結(jié)果成功,但是需要system以上的權(quán)限。DevicePolicyManager.java位于frameworks\base\core\java\android\app\admin\DevicePolicyManager.java。
問(wèn)題分析到這里的時(shí)候可能有些童鞋已經(jīng)發(fā)現(xiàn)了,使用正常的apk激活設(shè)備管理器,然后使用異常的apk避免設(shè)備管理器被取消。那如果android設(shè)備重啟了呢?重啟以后還能保持激活嗎?答案是否定的,重啟設(shè)備以后,無(wú)法保持激活。原因是什么呢?分析如下:
主要代碼frameworks\base\services\java\com\android\server\DevicePolicyManagerService.java
Android設(shè)備重啟以后,SystemServer啟動(dòng)DevicePolicyManagerService服務(wù)同時(shí)調(diào)用systemReady方法重新初始化設(shè)備管理器列表。如下:
?
loadSettingsLocked方法中調(diào)用findAdmin
?
代碼到這里就可以看到了,在獲取meta-data的時(shí)候會(huì)捕獲異常,返回空值。
?
所以第三種方法:重啟……
如有不對(duì)的地方歡迎指正。
Android?在實(shí)現(xiàn)設(shè)備管理器時(shí),需要再manifest.xml中注冊(cè)一個(gè)廣播接收者,代碼如下
??<receiver
????????????android:name=".MyDeviceAdmin"
?????????????????????android:permission="android.permission.BIND_DEVICE_ADMIN"?>?
?????????????<meta-data
????????????????android:name="android.app.device_admin"
????????????????android:resource="@xml/device_admin"?/>?
?????????????<intent-filter>
???????????????<action?android:name="android.app.action.DEVICE_ADMIN_ENABLED"?/>
????????????</intent-filter>??
????????</receiver>?
OBAD如何在setting的管理器列表隱藏呢,我們可以通過(guò)setting的源碼找到答案。相關(guān)代碼:packages\apps\Settings\src\com\android\settings\DeviceAdminSettings.java
??主要方法:
void?updateList()?{
????????mActiveAdmins.clear();
????????List<ComponentName>?cur?=?mDPM.getActiveAdmins();
????????if?(cur?!=?null)?{
????????????for?(int?i=0;?i<cur.size();?i++)?{
????????????????mActiveAdmins.add(cur.get(i));
????????????}
????????}
//獲得已經(jīng)激活設(shè)備管理器列表mActiveAdmins
????????mAvailableAdmins.clear();
//?mAvailableAdmins?setting的設(shè)備管理器列表
????????List<ResolveInfo>?avail?=?getActivity().getPackageManager().queryBroadcastReceivers(
????????????????new?Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED),
????????????????PackageManager.GET_META_DATA);
//獲取所有注冊(cè)了DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED即android.app.action.DEVICE_ADMIN_ENABLED?action的廣播接收者列表avail
????????int?count?=?avail?==?null???0?:?avail.size();
????????for?(int?i=0;?i<count;?i++)?{
????????????ResolveInfo?ri?=?avail.get(i);
????????????try?{
????????????????DeviceAdminInfo?dpi?=?new?DeviceAdminInfo(getActivity(),?ri);
???????????????
????????????????if?(dpi.isVisible()?||?mActiveAdmins.contains(dpi.getComponent()))?{
????????????????????mAvailableAdmins.add(dpi);
??????????//如果應(yīng)用注冊(cè)了包含該action的廣播接受者并且激活了設(shè)備管理器,就會(huì)在setting的設(shè)備管理器列表中顯示
????????????????}
????????????}?catch?(XmlPullParserException?e)?{
????????????????Log.w(TAG,?"Skipping?"?+?ri.activityInfo,?e);
????????????}?catch?(IOException?e)?{
????????????????Log.w(TAG,?"Skipping?"?+?ri.activityInfo,?e);
????????????}
????????}
???????????????getListView().setAdapter(new?PolicyListAdapter());
????}
但是沒(méi)有注冊(cè)android.app.action.DEVICE_ADMIN_ENABLED?action的應(yīng)用也可以激活為設(shè)備管理器。這就導(dǎo)致了激活后的設(shè)備管理器無(wú)法在setting的設(shè)備管理器列表中顯示。
如何解決這種情況呢?下面我們一起來(lái)分析一下安全管家的設(shè)備管理器補(bǔ)丁。該補(bǔ)丁是一個(gè)正常的apk,反編譯之,代碼結(jié)構(gòu)如下
?
主要類(lèi)DeviceAdminProxy代碼如下:
?//上面方法的主要內(nèi)容就是對(duì)比直接通過(guò)DevicePolicyManager獲得的已經(jīng)激活的設(shè)備管理器列表a和通過(guò)遍歷注冊(cè)了android.app.action.DEVICE_ADMIN_ENABLED?action的列表b進(jìn)行對(duì)比,如果發(fā)現(xiàn)列表a中的設(shè)備管理器沒(méi)有在列表b中出現(xiàn),就調(diào)用如下代碼彈出取消激活的activity,讓用戶手動(dòng)取消。
?代碼中有一個(gè)RootMain的類(lèi),這個(gè)類(lèi)在當(dāng)能獲得root權(quán)限的時(shí)候使用,找到利用這個(gè)漏洞的設(shè)備管理器后直接調(diào)用DevicePolicyManager的removeActiveAdmin方法取消激活,該方法需要system以上權(quán)限才能執(zhí)行。
關(guān)于android.app.action.DEVICE_ADMIN_ENABLED引起的漏洞都這里就結(jié)束了,下面說(shuō)一下在分析中遇到的另外一件有趣的事。
前面講到setting獲取管理器列表時(shí),有這么一段代碼,如下圖
?
代碼中實(shí)例DeviceAdminInfo對(duì)象,DeviceAdminInfo.java在frameworks\base\core\java\android\app\admin\DeviceAdminInfo.java
關(guān)鍵代碼:
?
之前我們?cè)趍anifest的receiver中有如下配置:
?
如果不配置meta-data,DeviceAdminInfo類(lèi)就會(huì)拋出異常,DeviceAdminSettings中獲取異常,按照上面圖中的代碼可以發(fā)現(xiàn),同樣setting的設(shè)備管理器列表也無(wú)法顯示。這樣setting雖然不顯示了,但是,如果不配置meta-data,設(shè)備管理器時(shí)沒(méi)辦法正常激活的。怎么辦呢?用正常的設(shè)備管理器程序安裝,正常激活,然后刪除該程序的meta-data配置,生成apk,以更新安裝的形式安裝到android設(shè)備上。這個(gè)時(shí)候卸載該程序會(huì)發(fā)現(xiàn),該程序已經(jīng)激活為設(shè)備管理器,但是在setting設(shè)備管理器列表中找不到。因?yàn)樵O(shè)備管理器注冊(cè)了android.app.action.DEVICE_ADMIN_ENABLED,所以使用上述的設(shè)備管理漏洞補(bǔ)丁也是找不到的。
那么如何取消激活呢?從上面對(duì)于設(shè)備管理器漏洞補(bǔ)丁apk的分析可以得出兩種取消激活的方法分析(其實(shí)是三種):
一、??DevicePolicyManager獲得的已經(jīng)激活的設(shè)備管理器列表,然后使用下面的代碼?
啟動(dòng)取消激活的activity。測(cè)試結(jié)果是行不通的,因?yàn)镈eviceAdminAdd也需要解析meta-data中的信息。具體參見(jiàn)DeviceAdminAdd.java位于packages\apps\Settings\src\com\android\settings\?DeviceAdminAdd.java。
二、??獲取到激活的設(shè)備管理器列表后直接調(diào)用DevicePolicyManager的removeActiveAdmin方法取消激活,測(cè)試結(jié)果成功,但是需要system以上的權(quán)限。DevicePolicyManager.java位于frameworks\base\core\java\android\app\admin\DevicePolicyManager.java。
問(wèn)題分析到這里的時(shí)候可能有些童鞋已經(jīng)發(fā)現(xiàn)了,使用正常的apk激活設(shè)備管理器,然后使用異常的apk避免設(shè)備管理器被取消。那如果android設(shè)備重啟了呢?重啟以后還能保持激活嗎?答案是否定的,重啟設(shè)備以后,無(wú)法保持激活。原因是什么呢?分析如下:
主要代碼frameworks\base\services\java\com\android\server\DevicePolicyManagerService.java
Android設(shè)備重啟以后,SystemServer啟動(dòng)DevicePolicyManagerService服務(wù)同時(shí)調(diào)用systemReady方法重新初始化設(shè)備管理器列表。如下:
?
loadSettingsLocked方法中調(diào)用findAdmin
?
代碼到這里就可以看到了,在獲取meta-data的時(shí)候會(huì)捕獲異常,返回空值。
?
所以第三種方法:重啟……
如有不對(duì)的地方歡迎指正。
最后附上此次使用的apk
原文地址: http://bbs.pediy.com/showthread.php?t=183692
總結(jié)
以上是生活随笔為你收集整理的关于android设备管理器的一些分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 微信系列研究之-----资源文件保护的小
- 下一篇: Omnispace 收藏夹