Active Directory Password Policy

Password Policy

Diese Seite ist auch auf Deutsch verfĂĽgbar.


Unfortunately, setting a good password policy for Active Directory is difficult. This is also because there are several best practices that sometimes contradict each other. In this post, I will try to address the various best practices and give my own recommendation.

Table of Contents

Existing Good Practices

NIST Password Guidelines

This guideline is nowadays the quasi-standard and can be found here: https://pages.nist.gov/800-63-3/sp800-63b.html

NIST recommends settings for different types of passwords. Normal users in Active Directory usually have a “Memorized Secret”, which they must enter manually at each login. For this type of password, NIST summarizes the following policy (important: SHALL is a bit confusing, but it’s simply a synonym for MUST):

  • Password length at least 8 characters. However, this can be set higher depending on the context.
    • Verifiers SHALL require subscriber-chosen memorized secrets to be at least 8 characters in length.

    • The minimum password length that should be required depends to a large extent on the threat model being addressed.

  • Complexity requirement is not recommended.
    • Verifiers SHOULD NOT impose other composition rules (e.g., requiring mixtures of different character types or prohibiting consecutively repeated characters) for memorized secrets.

  • Regular password change is not recommended.
    • Verifiers SHOULD NOT require memorized secrets to be changed arbitrarily (e.g., periodically). However, verifiers SHALL force a change if there is evidence of compromise of the authenticator.

It actually sounds quite simple. However, there are a few additional requirements:

  • The password must be stored as a salted hash that is resistant to offline attacks.
    • Verifiers SHALL store memorized secrets in a form that is resistant to offline attacks.

  • There must be a blacklist of weak passwords (e.g., “Summer2024”, “aaaaaaaa”).
    • […] verifiers SHALL compare the prospective secrets against a list that contains values known to be commonly-used, expected, or compromised.

  • There must be brute-force protection.
    • Verifiers SHALL implement a rate-limiting mechanism that effectively limits the number of failed authentication attempts that can be made on the subscriber’s account […]

Important point: This is a password policy, not a recommendation for secure passwords. Everyone should be free to choose a 50-character long password and change it every 90 days. The idea behind the guideline is that overly strict password policies do not contribute to security but just annoy users and ultimately lead to users becoming creative to circumvent the policy (e.g., appending an exclamation mark to meet the complexity).

Length and complexity requirements beyond those recommended here significantly increase the difficulty of memorized secrets and increase user frustration. As a result, users often work around these restrictions in a way that is counterproductive. Furthermore, other mitigations such as blacklists, secure hashed storage, and rate limiting are more effective at preventing modern brute-force attacks. Therefore, no additional complexity requirements are imposed.

It would be too simple if we could implement this policy 1:1 in Active Directory. The problems are as follows:

  • Active Directory does not offer secure password hash. The best password hash offered is the NT-Hash. NT-Hashes have no salt and are not resistant to offline attacks. An 8 character alphanumeric password can be cracked in minutes.
  • Active Directory does not offer an out-of-the-box solution for a blacklist of insecure passwords.

Microsoft Recommendations for Password Policies

Unfortunately, Microsoft’s recommendation is a bit confusing and seems contradictory at first glance. The first article you find on this topic is this one: https://learn.microsoft.com/en-us/microsoft-365/admin/misc/password-policy-recommendations?view=o365-worldwide

The recommendations in this article are very similar to those in the NIST password policy. The problem: the article refers to M365, not to on-premise Active Directory. Therefore, these recommendations are not really applicable in our case.

The recommended password policy for Active Directory can be found here: https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/security-policy-settings/password-policy. Or in the articles linked below.

The Good Practice summarized looks as follows:

  • Passwords must be changed every 30-90 days (Maximum Password Age).
  • The last 24 passwords are stored (Password History) to prevent the reuse of previous passwords.
  • The password may only be changed once a day (Minimum Password Age) to prevent circumvention of the password policy through repeated changes.
  • Minimum password length of 8 characters (Minimum Password Length).
  • Passwords must be complex, meeting at least 3 out of the 4 complexity classes (Must Meet Complexity Requirements).
  • Passwords must not be stored using reversible encryption. This is a legacy setting that should never be activated. If it is active, passwords are essentially stored in plaintext.

This policy contradicts NIST in almost every aspect and is very annoying for users. Applied, it looks like this:

C:\Users\alice>net accounts
Force user logoff how long after time expires?:       Never
Minimum password age (days):                          1
Maximum password age (days):                          90
Minimum password length:                              8
Length of password history maintained:                24
Lockout threshold:                                    Never
Lockout duration (minutes):                           10
Lockout observation window (minutes):                 10
Computer role:                                        WORKSTATION
The command completed successfully.

Therefore, I suggest that we develop our own Good Practice! Of course, there is an XKCD for that (https://xkcd.com/927/):

The VidraSec Recommendation

I’m going out on a limb here and offering a specific recommendation. I welcome any feedback and am happy to adapt the recommendation.

There are fundamentally two issues that prevent the implementation of the NIST recommendation:

  • Storage of passwords with weak hashing (NT Hash).
  • Use of the password or hash in authentication protocols (NTLM) that are weaker than modern hash functions (argon2, bcrypt).
  • No out-of-the-box solution for blacklists of weak passwords.
  • Multi-factor authentication would be desirable.

Let’s consider these points one by one.

Problems

Offline Storage with Weak Hash (NT Hash)

Unfortunately, there is no better hash algorithm available in Windows Active Directory; nothing can be done about this. However, the question is: Can I circumvent the problem by setting a different password policy? NIST clearly states that neither frequent password changes nor complexity requirements lead to better passwords (e.g., “Summer2024!”):

Research has shown, however, that users respond in very predictable ways to the requirements imposed by composition rules.

For this reason, I would accept this risk. It will unfortunately still take some time before we get a better hash algorithm. A password policy cannot help us here either.

Use of Weak Protocols

This is a similar issue to the above: a password policy does not help here.

I don’t want to go into too much detail, but the following points should definitely be considered:

  • Use Kerberos instead of NTLM where possible.
  • Service accounts and other highly privileged accounts (e.g., Domain Admins) should have their own password policy. Their passwords should be randomly generated and long, and stored in a password manager.

Blacklists for Weak Passwords

While this is not an out-of-the-box feature, Microsoft now has a solution: https://learn.microsoft.com/en-us/entra/identity/authentication/concept-password-ban-bad-on-premises

There are also open-source solutions and third-party solutions. One of these solutions should be implemented to meet NIST’s recommendation.

Multi-factor Authentication (MFA)

While MFA is not a requirement, it significantly improves security. Therefore, MFA should be implemented on as many internal and external interfaces as possible.

In the Active Directory or client environment, Windows Hello for Business can be used. The beauty of Windows Hello is that login on a Windows client, for example, works with a PIN and not with the password set in Active Directory. The advantage is that users theoretically do not need to know their actual password. The password is still used by Windows Hello in the background, but this is transparent to the user. If an attacker somehow obtains the PIN, there is little they can do with it unless they also possess the notebook.

Implementation

To implement the proposed changes, one typically needs to adjust the Default Domain Policy group policy. The settings can be found under Computer Configuration\Windows Settings\Security Settings\Account Policies\Password Policy\. Here, we set the following values:

Setting New Value Reasoning
Maximum password age 0 Passwords do not need to be changed regularly.
Minimum password length 10 Depending on the level of protection, this can be set higher or lower. I recommend at least 10, better 12.
Password must meet complexity requirements Disabled We do not want to enforce complex passwords.
Store passwords using reversible encryption Disabled It is the default setting and prevents passwords from being stored in plaintext.

These settings align with the NIST recommendation, with a higher minimum password length due to the weak hash type.

The following settings are a bit more controversial and are unfortunately not addressed in the NIST guidelines:

Setting New Value Reasoning
Minimum password age 0 Allows users to change their password at any time.
Enforce password history 0 Completely disables the password history.

⚠️ These two settings actually contradict common good practices [1], [2]. However, I have not seen a similar recommendation outside of the Active Directory environment, so I dare to contradict this recommendation. But please think it through yourself! I justify my decision in the following paragraphs.

If I want to prevent a user from intentionally setting a weak password, it is better to add the password to my blacklist. The solution with a long password history is not ideal.

Password history, however, has an even bigger problem: It stores a huge list of former passwords of users. Even if the old password is no longer active in my system, it could still be used to compromise another account of the user. For an attacker, this information is valuable; for me, it may only provide a slight security gain. Therefore, I believe that password history should be disabled.

$ python3 ./secretsdump.py -just-dc-user test -history -k -no-pass vidrasec.lab/bobadmin@dc.vidrasec.lab
Impacket v0.12.0.dev1+20240418.131633.ea96b63a - Copyright 2023 Fortra
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
vidrasec.lab\test:1111:aad3b435b51404eeaad3b435b51404ee:3e24dcead23468ce597d6883c576f657:::
vidrasec.lab\test_history0:1111:aad3b435b51404eeaad3b435b51404ee:9e59e0541eb4c6ab1ac978eb512c2a3a:::
vidrasec.lab\test_history1:1111:aad3b435b51404eeaad3b435b51404ee:b32272b8729f92d524d3c90f2217c88f:::
[...]

For an attacker, these are great information; for us, however, they only represent a marginal security gain. Therefore, I believe that password history should be disabled.

Our new password policy therefore looks like this:

C:\Users\alice>net accounts
Force user logoff how long after time expires?:       Never
Minimum password age (days):                          0
Maximum password age (days):                          Unlimited
Minimum password length:                              10
Length of password history maintained:                None
Lockout threshold:                                    Never
Lockout duration (minutes):                           10
Lockout observation window (minutes):                 10
Computer role:                                        PRIMARY
The command completed successfully.

Summary

Some important points to conclude:

  • Specific policies for different user types: The proposed password policy is intended for normal users. For highly privileged accounts and service accounts, a stricter policy should be applied, where regular password changes make sense.
  • Policy activation: A new password policy comes into effect with the next password change. I often see that accounts use old passwords that do not meet current guidelines.
  • Regular reviews necessary: The passwords in Active Directory should be regularly reviewed. Are there accounts using the same hash? Are there highly privileged accounts with very old passwords? What percentage of password hashes can be cracked within a certain period?

🦦 For further questions or interest in an Active Directory audit or penetration test, as always, just contact me! Contact me here

Posts in this series

Related Services