HackBlue

Tools · Active Directory defense · 13 / 23

Audit risky Active Directory account flags: password not required, never expires, reversible encryption

Find accounts with PASSWD_NOTREQD, DONT_EXPIRE_PASSWORD, reversible encryption, DES-only, and SID history, and understand why each matters.

9 min read · practice only with authorization

Flags worth checking

userAccountControl holds many bits. PASSWD_NOTREQD lets an account have an empty password regardless of policy. DONT_EXPIRE_PASSWORD exempts an account from password age policy, common for service accounts. ENCRYPTED_TEXT_PWD_ALLOWED stores the password with reversible encryption, which is close to plaintext. USE_DES_KEY_ONLY forces obsolete Kerberos encryption.

sIDHistory is not a flag but belongs here: it lets an account carry SIDs from another domain, used during migrations and abusable if it contains privileged SIDs.

Queries for each

PowerShell exposes most flags as properties. sIDHistory needs an LDAP filter for presence. Run these monthly and keep the results so you can see when a new account appears.

A domain-wide fine-grained password policy or reversible encryption setting in the Default Domain Policy affects every account, so check the policies too with Get-ADDefaultDomainPasswordPolicy and Get-ADFineGrainedPasswordPolicy.

Snippet
Get-ADUser -Filter 'PasswordNotRequired -eq $true -and Enabled -eq $true' | Select Name
Get-ADUser -Filter 'PasswordNeverExpires -eq $true -and Enabled -eq $true' -Properties PasswordLastSet | Select Name, PasswordLastSet
Get-ADUser -Filter 'AllowReversiblePasswordEncryption -eq $true' | Select Name
Get-ADUser -Filter 'UseDESKeyOnly -eq $true' | Select Name
Get-ADObject -LDAPFilter '(sIDHistory=*)' -Properties sIDHistory | Select Name, sIDHistory
Get-ADDefaultDomainPasswordPolicy

Lab: set, find, clear

Set PasswordNotRequired and reversible encryption on two lab users, run the queries, and confirm both appear. Clear them with Set-ADUser and Set-ADAccountControl. For reversible encryption, the stored reversible password remains until the next password change, so force a reset.

For PasswordNeverExpires on service accounts, the long-term fix is a gMSA rather than clearing the flag and breaking the service.

Snippet
Set-ADUser user3 -PasswordNotRequired $true
Set-ADUser user4 -AllowReversiblePasswordEncryption $true
# fix
Set-ADUser user3 -PasswordNotRequired $false
Set-ADUser user4 -AllowReversiblePasswordEncryption $false
Set-ADUser user4 -ChangePasswordAtLogon $true

Prioritize by privilege

A flag on a privileged account is far more urgent than on a standard user. Cross-reference results with the privileged group membership list from the previous tutorial.

Clean up sIDHistory after migrations finish. SID filtering on trusts blocks foreign SIDs across trusts, but within a domain, a privileged SID in sIDHistory grants those rights.

Diagram

Risky flags and their effect

Each one weakens a different control.

  • Password not required

    Account may have an empty password.

  • Password never expires

    Old passwords live forever; common on service accounts.

  • Reversible encryption

    Password stored in a recoverable form.

  • DES only

    Obsolete, weak Kerberos encryption.

  • sIDHistory

    Extra SIDs, potentially privileged.

Check yourself

1. Why is PASSWD_NOTREQD dangerous?

2. After clearing reversible encryption, what else is needed?

3. Why review sIDHistory after a migration?