New DPAPI Decryption Tool Fixed
The Microsoft Data Protection Application Programming Interface, or DPAPI for short, is a Windows API tool for developers to enable them to store sensitive data in a way that it is encrypted but still decryptable.It has been around since Windows 2000 which makes it more or less ancient in computer terms.However it has since been tweaked to such an extent that it is no longer recognizable, things like RSA, AES256, SHA512 and even PBKDF2 have been added or increased in rounds.
New DPAPI decryption tool
Inside the Registry file %windir%\System32\config\SYSTEM lays a system unique DPAPI key, it is encrypted with the Syskey which is to be extracted from the %windir%\System32\config\SECURITY file. Multiple tools exist to extract these on- or offline (e.g. lsadump.py from CredDump 7).
However: for this research I adjusted and/or recreated all of the scripts from both DPAPICK as DPAPILAB and made them work on Windows and Linux, in Python3 and without the need of M2Crypto (now pycryptodome).All next code examples are from this new and improved framework called DPAPILAB-NG, created especially for offline decryption of Windows secrets.
I am trying to understand how someone can decrypt the Client Secret. Based on research I've done a malicious actor will need to get the password for the service account and then use a 3rd party tool (such as DataProtectionDecryptor by NirSoft) to decrypt the Client Secret.
I created a BrowserLoginData Object to be able to store the resultant decrypted credentials. The tool instanciates a new BrowserLoginData object for each decrypted set of logins and append them to a list for output to the console or a file.
Once the data is an ASN1 object as Sequences, the values required for decryption can be extracted, and the result can be checked against a hard-coded value of password-check\x02\x02 to ensure the correct password/values were used. The MasterPassword is an empty string if no password was provided as a command line argument.
The decryption key (and initialisation vector/nonce) is then created by joining two HMAC-SHA1 values which are calculated using the previously created values. The key is taken from the first 24 bytes and the IV from the last 8 bytes.
Another simple and useful attack technique for retrieving credentials from LSASS is dumping LSASS memory completely. An attacker can take the LSASS process dump and extract the credentials offline using tools like Mimikatz.
Cortex XDR detects the usage of these tools for dumping LSASS memory based on the static indicators discussed above, such as the command line arguments. It also detects them using behavioral detections based on the methods we will describe next.
An attacker can create a custom LSASS dumping tool using the documented API functionMiniDumpWriteDump. This function gets a handle to a process (LSASS in our case), reads its memory using ReadProcessMemory, which calls the undocumented API function NtReadVirtualMemory, in order to read the process memory and copy its content.
DATA Protection API (DPAPI) is used widely by Windows itself and by different Windows applications. It enables symmetric encryption and decryption of any kind of data using the functions CryptProtectData and CryptUnprotectData, respectively. Only a user with the same credentials as the user who called the CryptProtectData for encrypting the data is able to decrypt it using UCryptUnprotectData.
When encrypting a value, the software generates some random bytes to use as initialization vector (IV) , and stores the IV in the first block of encrypted bytes. Furthermore, when a value is encrypted, the software will encrypt the value itself, combined with the hash of the value. I assume this is done to verify the decryption routine was successful and the data is not corrupted.
Because, by default, the software will only rely on the random bytes as base key, which are included in the credential file, we can generate the correct AES key to decrypt the encrypted contents in the file. I implemented a Python utility to decrypt CyberArk Credential files and it can be downloaded here. The additional verification attributes the software can use to include in the base key can be provided as command line arguments to the decryption tool. Most of these can be either guessed, or easily discovered, as an attacker will most likely already have a foothold in the network, so a hostname or IP address is easily uncovered. In some cases the software even stores these verification attributes in the file as it asks to include the restrictions in the credential file when creating one using the CreateCredFile.exe utility.
We reported this issue at CyberArk and they released a new version mitigating the decryption of the credential file by changing the crypto implementation and making the DPAPI option the default. We did not have access to the new version to verify these changes.
And here is where you see I might have buried the lede. Chromium stores lots of things in SQLite databases and it "secures" it in the same way it does passwords. Those malware authors that Trend Net identified left a lot on the table. "Credit cards" just jumps right out at me. We get the card number, name, and expiration. Everything but the security code on the back. Also think about the "cookies". Sure you can have 2-factor-authentication so just having your user name and password isn't enough for me to log in. But now I have the session key found in the cookies and can just pretend to be you using it with a tool like BurpSuite.
One last thing: I was surprised when I ran this tool on my local computer. I had switched to Brave a long time ago and it's been more than a year since I stopped letting the browser keep any passwords. The tool relentlessly searches for Chromium installs and it found my old Google Chrome install. That sample output above in Figure 2 is from that abandoned install. Make sure once you've secured your browser, head into Explorer and delete those older browser installs.
The mstsc.exe process is created when a user opens the remote desktop connection application in order to connect to other systems via the RDP protocol. API hooking could be used to intercept the credentials provided by the user and use them for lateral movement. Rio Sherri has developed a proof of concept tool called RdpThief which attempts to hook the functions used by mstsc process (CredIsMarshaledCredentialW & CryptProtectMemory) in order to retrieve the credentials and write them into a file on the disk. Details of the tool can be found in an article in the MDSec website.
The tool has been rewritten in C# by Josh Magri. However comparing to RdpThief, SharpRDPThief uses an IPC server in order to receive the credentials from the mstsc.exe process. In the event that the mstsc.exe is terminated the server will continue to run and when the process is initiated again will attempt to perform the hooking. This removes the limitation that RdpThief had that the process should already exist.
The Data Protection API (DPAPI) plays a key role in Windows security: This API is meant to be the standard way on Windows OS to store encrypted data on the disk. DPAPI is used by many popular applications including Internet Explorer, Google Talk, Google Chrome, Skype, MSN (6.5-7) to encrypt their passwords. It is also used by Windows itself to store sensitive information such as EFS certificates and Wifi (WEP and WPA) keys. DPAPI uses very opaque structures to store these encrypted data on disk and the available documentation is very sparse. Therefore prior to our work it was impossible to extract and analyze these secrets offline for forensic purposes. This is a particular huge issue for files encrypted using EFS because unless the EFS certificate protected by DPAPI is recovered these files can't be decrypted and analyzed. To address these issues, we did reverse the DPAPI and in this presentation will provide a complete walkthrough DPAPI and its structures. Afterward armed with this knowledge, anyone interested in windows forensic will be able to deal with data stored with DPAPI. We will cover the change made by Microsoft from Windows XP up to Windows Seven. Finally we will demonstrate and release DPAPick (www.dpapick.com) which we believe, is the first tool that allows to decrypt offline data encrypted with DPAPI.
This research conducted me to develop a tool capable of retrieving it, in plaintext! This could be useful when compromising AD workstations that use this kind of authentication in a Wireless Access Point.
This tool works on any version of Windows, starting from Windows XP and up to Windows 10. Both 32-bit and 64-bit systems are supported. You can use this tool to decrypt DPAPI-encrypted data in 2 different modes:
The main window displays the result of the DPAPI decryption. In the upper pane table, a new line is added for every DPAPI data block. When selecting an item in the upper pane, the lower pane displays the decrypted data in hex-dump format.
Choose the protected configuration provider. Under most circumstances DPAPI will suffice, although the RSA protected configuration is the logical choice in web farms where multiple servers are employed. The .NET Framework includes a protected configuration feature that you can use to encrypt sensitive configuration file data by using a command line tool. The following two protected configuration providers are provided although you can also implement custom providers.
We know that it will be trivial to recover the credentials (email address and password) but we actually still do not know where this credentials are stored at rest. Looking at the caller of the encryption/decryption routines the credentials are saved in a file along with other auto-connects settings. I do not like guessing and I resolved to use a more methodological approach relying on ProcMon.
It is interesting to note that, even if the client was heavily obfuscated, it would have just been possible to find the 'user.config' file and identify that 'System.Security.Cryptographic.ProtectedData' methods was used from the base64 prefix "AQAAANCM...", which is the universal 'prepended string' of DPAPI encrypted blob (due to the dpapi blob headers starting with a 'costant value').