Auditing Active Directory Password Quality

August 7, 2016 | Michael Grafnetter | 26 Comments on Auditing Active Directory Password Quality


The latest version of the DSInternals PowerShell Module contains a new cmdlet called Test-PasswordQuality, which is a powerful yet easy to use tool for Active Directory password auditing. It can detect weak, duplicate, default, non-expiring or empty passwords and find accounts that are violating security best practices. All domain administrators can now audit Active Directory passwords on a regular basis, without any special knowledge.


The Test-PasswordQuality cmdlet accepts output of the Get-ADDBAccount and Get-ADReplAccount cmdlets, so both offline (ntds.dit) and online (DCSync) analysis can be done:

Although the cmdlet output is formatted in a human readable fashion, it is still an object, whose properties can be accessed separately (e.g. $result.WeakPassword) to produce a desired output.


I would like to thank Jakob Heidelberg for his idea to use the DSInternals module for password auditing. A big thank you also goes to Ondrej Sevecek for sharing his comprehensive auditing tool called SAPHA, from which I borrowed ideas for a few tests.

Tags: , ,

Dumping and Modifying Active Directory Database Using a Bootable Flash Drive

July 19, 2016 | Michael Grafnetter | No Comments on Dumping and Modifying Active Directory Database Using a Bootable Flash Drive

Since version 2.15, the DSInternals PowerShell Module fully supports Windows PE, the free minimalistic edition of Windows. This means that all the nasty Active Directory database stuff can now be performed from a bootable flash drive or an ISO image, including:

Windows PE DSInternals

Required access

These actions would of course require an attacker to have one of the following:

  • Physical access to a domain controller (DC).
  • Knowledge of DC’s baseboard management controller (BMC) credentials.
  • Administrative access to a virtualized DC.

In an ideal world, only Domain Admins should have such non-trivial access to the core AD infrastructure, but the everyday reality is far from perfect.

Creating the media

To create a bootable Windows PE media loaded with the DSInternals module, follow these steps:

  1. Install the Windows Assessment and Deployment Kit (ADK), including the Windows PE feature.
  2. Click Start, and type deployment. Right-click Deployment and Imaging Tools Environment and then select Run as administrator.
  3. Create a working copy of the Windows PE files. Specify either x86 or amd64:
  4. Mount the Windows PE image:
  5. Add PowerShell support to Windows PE by adding a few optional components, together with their associated language packs:
  6. Add the DSInternals PowerShell module to the Windows PE image by copying it into the C:\WinPE_amd64\mount\Windows\system32\ WindowsPowerShell\v1.0\Modules folder.
  7. Add device drivers to the Windows PE image:
  8. Configure PowerShell to start automatically after boot by creating a file called winpeshl.ini in the C:\WinPE_amd64\mount\Windows\system32 folder, containing this text:
  9. Create an ISO file containing the Windows PE files:

    The same command can be used to create a bootable flash drive or VHD.

Final thoughts

As you have seen, it is pretty straightforward to create a bootable flash drive that can be used to conquer an Active Directory domain through a physically accessible DC. One of the precautions a domain administrator can take is to encrypt all DCs using BitLocker or other tool that does full volume encryption. Deploying RODCs at smaller branch offices is also a good idea. The new features in Windows Server 2016, Virtual TPMs and Shielded VMs, also seem very promising in regards to DC security.

Tags: , , ,

How the Active Directory Expiring Links Feature Really Works

April 3, 2016 | Michael Grafnetter | 5 Comments on How the Active Directory Expiring Links Feature Really Works

One of the new features in Windows Server 2016 will be the Active Directory Expiring Links feature, which enables time-bound group membership, expressed by a time-to-live (TTL) value. Here is how it works:

Enabling the Expiring Links Feature

The Expiring Links feature had been a standalone feature in early Windows Server 2016 builds, but as of TP4, it is a part of the broader Privileged Access Management (PAM) feature. It is disabled by default, because it requires Windows Server 2016 forest functional level. One of the ways to enable the PAM feature is running this PowerShell cmdlet:

Note that once this feature is enabled in a forest, it can never be disabled again.

Creating Expiring Links using PowerShell

Unfortunately, this feature is not exposed in any GUI (yet), so you cannot create expiring links, nor can you tell the difference between a regular link and an expiring one. We will therefore use PowerShell to do the job:

As we can see, the TTL value in the output is in seconds (2h = 7200s). As soon as the TTL expires, the DCs will automatically remove user PatColeman from the Domain Admins group and his current Kerberos tickets will also expire.

Creating Expiring Links using LDAP

PowerShell is great, but what if we needed to stick with pure LDAP? Well, if you want to add a user into a group for a limited amount of time, you do it exactly as you are used to, but you have to specify his distinguished name (DN) in the new TTL-DN form: <TTL=TimeToLive,DN>. In our sample case, it would look like this:


To view the group membership with TTLs, the corresponding LDAP search operation has to contain the LDAP_SERVER_LINK_TTL extended control (OID = 1.2.840.113556.1.4.2309). Here is a screenshot from the ldp.exe tool with this control enabled:

Link TTL

Implementation Details (Very Advanced Stuff)

I was also quite interested in how this feature is implemented in the ntds.dit file. I have found out that as soon as you enable the PAM feature, the DCs automatically extend their database schemas in the following way:

  1. The expiration_time_col column is added to the link_table table. It contains timestamps (in the UTC FILETIME / 107 format), after which the links get deactivated. This is yet another reason for the time to be in sync between DCs.
  2. The link_expiration_time_index index is added to the link_table table. It is created over these columns: expiration_time_col, link_DNT, backlink_DNT. Thanks to this index, DCs can find expired links very quickly.

Tags: , , ,

Retrieving Cleartext GMSA Passwords from Active Directory

December 28, 2015 | Michael Grafnetter | 8 Comments on Retrieving Cleartext GMSA Passwords from Active Directory

Have you ever wondered how the automatically generated passwords of Group Managed Service Accounts (GMSA) look like? Well, you can fetch them from Active Directory in the same way as Windows Servers do and see yourself. Here is how:

Creating a GMSA

To start experimenting, we need to have a GMSA first, so we create one:

We can check the result in the Active Directory Users and Computers console:

Group Managed Service AccountUnfortunately, the built-in GUI will not help us much when working with GMSAs. Although there is a nice 3rd party tool, we will stick to PowerShell.

Setting the Managed Password ACL

Now we need to provide a list of principals that are allowed to retrieve the plaintext password from DCs through LDAP. Normally, we would grant this privilege to one or more servers (members of the same cluster/web farm). But we will grant the privilege to ourselves instead:

Of course, you should not use the built-in Administrator account in a production environment.

Retrieving the Managed Password

Now comes the fun part:

Note that until now, we have only used regular, built-in cmdlets from the ActiveDirectory module, courtesy of Microsoft.

Decoding the Managed Password

Let’s have a look at the msDS-ManagedPassword attribute, that has been returned by the command above. It is a constructed attribute, which means that its value is calculated by DC from the KDS root key and the msDS-ManagedPasswordId attribute every time someone asks for it. Although documented, the cryptographic algorithm used is quite complicated. Furthermore, the value of the msDS-ManagedPasswordId gets re-generated every (msDS-ManagedPasswordInterval)-days (30 by default).

We see that the msDS-ManagedPassword attribute of our GMSA contains a sequence of bytes. It is a binary representation of the MSDS-MANAGEDPASSWORD_BLOB data structure, which contains some metadata in addition to the actual password. As there had been no publicly available tool to decode this structure, I have created one myself:

TADA!!! The CurrentPassword property contains the actual cleartext password of the GMSA in question. Why does it look like gibberish? Because it is just 256 bytes of pseudorandom data, interpreted as 128 UTF-16 characters. Good luck writing that on your keyboard. But if we calculate its NT hash, it will match the hash stored in AD.


We have seen that retrieving the value of GMSA passwords is quite easy. But don’t be afraid, there is no security hole in Active Directory. The cleartext password is always passed through an encrypted channel, it is automatically changed on a regular basis and even members of the Domain  Admins group are not allowed to retrieve it by default. So do not hesitate and start using the (Group) Managed Service Accounts. They are much safer than using regular accounts for running services.

If you want to play more with this stuff, just grab the DSInternals module. And for developers, the C# code I use to decode the structure can be found on GitHub.

Tags: , , ,

Source Code Released

December 27, 2015 | Michael Grafnetter | No Comments on Source Code Released

Good news: I have open-sourced the DSInternals PowerShell Module. Its source codes can now be found at GitHub and Visual Studio 2013 is needed to build it.

Just note that it is still work in progress. It lacks documentation and needs some heavy code refactoring. Any help is welcome.

Retrieving DPAPI Backup Keys from Active Directory

October 26, 2015 | Michael Grafnetter | 3 Comments on Retrieving DPAPI Backup Keys from Active Directory


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:

Mimikatz DPAPI Backup Keys

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:

Backup Key Storage

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:

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:


I am already starting to repeat myself:

  • Restrict access to domain controller backups.
  • Be cautious when delegating the “Replicating Directory Changes All” right.


Tags: , , ,

Dumping the contents of ntds.dit files using PowerShell

October 20, 2015 | Michael Grafnetter | 73 Comments on Dumping the contents of ntds.dit files using PowerShell

Although there exist several tools for dumping password hashes from the Active Directory database files, including the open-source NTDSXtract from Csaba Bárta whose great research started it all, they have these limitations:

  • They do not support the built-in indices, so searching for a single object is slow when dealing with large databases.
  • Most of the tools are either Linux-only or running them on Windows is not simple enough.
  • Almost none of these tools can modify the database. And if they do, they do not support transaction logs and are quite cumbersome.

Therefore, I have decided to create my own set of PowerShell cmdlets that wouldn’t have these shortcomings. In the process, I have unintentionally created my own framework that is built on top of Microsoft’s ManagedEsent library and hides the complexity of the underlying database. I am planning to release it at GitHub later this year.

One of the cmdlets I have created is Get-ADDBAccount, which can be used to extract password hashes, Kerberos keys and even reversibly encrypted passwords from ntds.dit files. Here is an example of its usage:

The output is identical to what the Get-ADReplAccount cmdlet would return:

I have also created several Views that generate output for the most popular password crackers, including Hashcat, John the Ripper and Ophcrack:

But with the Golden Ticket or Pass-the-Hash functionality of mimikatz, an attacker could seize control of the entire Active Directory forest even without cracking those password hashes.

As a countermeasure, it is crucial for companies to secure physical access to domain controllers, their backups and their VHD/VHDX/VMDK images in case of virtualized DCs. Turning on BitLocker is not a bad idea either. I really look forward to the new security features planned for Windows Server 2016, including Shielded VMs and Virtual TPMs.

Tags: , ,

How Azure Active Directory Connect Syncs Passwords

October 18, 2015 | Michael Grafnetter | 11 Comments on How Azure Active Directory Connect Syncs Passwords

Many people have asked me about the security implications of synchronizing passwords from Active Directory to Azure Active Directory using the Azure AD Connect tool. Although there is an article on Technet that claims that the passwords are synced in a very secure hashed form that cannot be misused for authentication against the on-premise Active Directory, it lacks any detail about the exact information being sent to Microsoft’s servers.

post at the Active Directory Team Blog hints that the Password Sync agent retrieves pre-existing password hashes from AD and secures them by re-hashing them using SHA256 hash per RFC 2898 (aka PBKDF2) before uploading them to the cloud. This sheds some light on the functionality, but some important implementation details are still missing, including the number of SHA256 iterations, salt length and the type of hash that is extracted from AD. Some research on this topic has been done by Alan Byrne, but it is inconclusive. Therefore, I have decided to do my own research and to share my results.


Tags: , , , ,