SIK-2016-030
Title:
Residue Attack Extracting Masterpassword From Dashlane Password Manager
Report ID
SIK-2016-030
Summary:
- Vendor: Dashlane
- Product: Dashlane Password Manager
- Affected Version: Version Code=1378, Version Name=“4.3.3.1378-armeabi-v7a“
- Severity: high
- Short summary:
The user can store the master password for the Dashlane manager on the device. The encrypted password is stored encrypted in the Android AccountManager. An implementation flaw in the Android operating system allows to extract credentials from the AccountManager without root permission.
Details:
It is possible to steal the master password from the AccountManager
with a so called “residue attack”. Due to an implementation flaw in verifying the application id (UID) accessing the AccountManager in Android, this attack type is possible (tested up to Android 6) for the dashlane password manager.
Residue attack:
Each data stored in the AccountManager
defines a „type“, which is the string com.dashlane (in the case of the dashlane app). If another app with another UID tries to access com.dashlane
accounts by defining the same type a SecurityException
will be thrown. Android checks the UID of the requesting app and if the UID is not matching the access is rejected. Nevertheless, a dashlane attacker app can at least register the type com.dashlane
.
After uninstalling the dashlane app, Android did not remove the stored AccountManager data of dashlane, because it recognized that there is still a matching account type registered. But now it ignores the mismatching UID and allows the attacker app to read out the residue account data.
To steal the whole credentials from the app a combination of the residue attack and the attack of SIK-2016-028 is required.
The described attack scenario requires physical access to the device (evil maid attack). Parts of the attack can be automated by a malicious app, in combination with tapjacking/overlay attack a user can be fooled and allow a malicious app to steal the data. For convenience we consider and describe here only the evil maid attack.
The combination of the found vulnerabilities (WebView sandbox escape, credential residue attack) allows an attacker to steal the data base containing the encrypted data and the master password without root access.
Requirement:
The attack requires PIN code lock option of the dashlane Android app to be enabled. After that the master password is stored in encrypted manner in the Android AccountManager. The PIN is encrypted with the master password and stored in the md5($user_email).xml
shared preferences file.
Attack:
- The dashlane app is installed and the user sets a PIN code for easy access. If this is the case,
dashlane encrypts the master password with a static key and saves this in the account manager. - Read with the browser file vulnerability the encrypted databases and shared preferences of
dashlane (see section 1). - Install a dashlane attacker app (see section 1 and Appendix)
- Uninstall the dashlane app. All of the dashlane app data will be removed but, because of the attacker app and the registered account type, Android does not delete the stored credentials.
- Start the dashlane attacker app and hit read. Since the original dashlane app is gone, it is now possible to read the accounts listed under account type
com.dashlane
which reveals the account string. - Use the jni decrypt function of the dashline
libdashlane.so
library to decrypt the stolen password. This is possible because the library contains a hard coded crypto key and can be used to decrypt the stolen credentials off device. - Use the master password to the stolen database. The master password can also be used to decrypt the stolen (encrypted) PIN from the shared preferences file …
POC code for residue attack app:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button addbutton = (Button)this.findViewById(R.id.button); addbutton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Account account = new Account("contact@team-sik.org", "com.dashlane"); AccountManager acmanager = AccountManager.get(getApplicationContext()); acmanager.addAccountExplicitly(account, "SECRETPASS", null); Toast.makeText(getApplicationContext(), "Added Secret Account", Toast.LENGTH_LONG).show(); } }); Button readbutton = (Button)this.findViewById(R.id.button2); readbutton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { AccountManager acmanager = AccountManager.get(getApplicationContext()); try { Account[] accounts = acmanager.getAccountsByType("com.dashlane"); for (Account a : accounts) { Toast.makeText(MainActivity.this, a.toString(), Toast.LENGTH_SHORT).show(); String password = AccountManager.get(getApplicationContext()).getPassword(a); Toast.makeText(MainActivity.this, password, Toast.LENGTH_SHORT).show(); Log.d("DASH", "Encr password: " + password); } } catch (Exception e) { e.printStackTrace(); } } });
Workaround
The user should avoid to store the master password on the device. Setting the phone lock (PIN, pattern or password) will also help against physical attacker access (evil maid attack).
Suggested Mitigation
Using hard-code symmetric keys in application is not state-of-the-art practice implementing cryptographic functions. For persisting cryptographic keys, the keys should be stored in the Android Keystore. Additionally the application should show a warning screen if the user tries to store the credentials on a rooted device. Furthermore avoid storing sensitive data in the AccountManager.
Timeline
- 2016-09-23 Vulnerability Discovered
- 2016-09-26 Vulnerability Reported
- 2016-10-25 Vulnerability Fixed