ADPRIV-012: Privileged Users No Kerberos Pre-Auth
- Platform
- Active Directory
- Category
- AD Privileged Account Security
- Severity
- Critical
- Zero Trust pillar
- Identity (weight 3)
- Golden fixtures
- 3
- Branch coverage
- Observed: fixtures prove the verdicts they exercise
- Provenance
- baseline
What it checks
The check executes a single LDAP filter against the domain naming context that combines the DONT_REQ_PREAUTH bit-test with the adminCount predicate: (&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304)(adminCount=1)(!(userAccountControl:1.2.840.113556.1.4.803:=2))) The matching rule 1.2.840.113556.1.4.803 is LDAP_MATCHING_RULE_BIT_AND. 4194304 (0x400000) is UF_DONT_REQUIRE_PREAUTH. 2 (0x2) is ACCOUNTDISABLE and is excluded because a disabled account cannot be roasted. adminCount=1 is the persistent marker stamped by the Security Descriptor Propagator (SDProp) on any principal that is currently, or was previously, a member of a default protected group; it is the same indicator BloodHound, AD security assessment tooling, and adversary tooling (PowerView Get-NetUser -AdminCount) use to identify high-value targets. The query is also re-run with a second arm that expands membership of the well-known protected SIDs (S-1-5-21-<domain>-512 Domain Admins, S-1-5-21-<domain>-519 Enterprise Admins, S-1-5-21-<domain>-518 Schema Admins, S-1-5-32-544 Administrators, S-1-5-32-548 Account Operators, S-1-5-32-549 Server Operators, S-1-5-32-550 Print Operators, S-1-5-32-551 Backup Operators) recursively and intersects the result with the DONT_REQ_PREAUTH set. This catches accounts that hold live privilege but have been re-stamped by SDProp such that adminCount=0 due to recent removal, and accounts that carry adminCount=1 only as legacy residue. For each match the check captures sAMAccountName, distinguishedName, userAccountControl in full, pwdLastSet, lastLogonTimestamp, memberOf, servicePrincipalName, msDS-SupportedEncryptionTypes, and whether the account is a member of the Protected Users group (S-1-5-21-<domain>-525).
Why it matters
Pre-authentication is the only thing standing between an unauthenticated attacker and an offline crack of a privileged account password. With the flag cleared, an attacker who can reach TCP/UDP 88 on any reachable domain controller can request an AS-REP for the targeted privileged account with one network round trip. No credential is required. No log entry on the attacker side is produced. The DC emits a 4768 with Pre-Authentication Type 0, which most environments do not alert on. The encrypted blob carried in the AS-REP is then taken offline and fed to hashcat in mode 18200 (RC4-HMAC, $krb5asrep$23$...) or 19900 (AES256). RC4 cracks at hundreds of millions of guesses per second on a single modern GPU; AES at tens of millions. Any password that is not strictly random and at least 25 characters falls in hours to days against a serious cracker. When the cracked account is a Domain Admin, an Enterprise Admin, or any direct or nested member of the default protected groups, the result is full-domain compromise with no exploit and no malware footprint. The pattern is especially common in environments that inherited Unix-Kerberos interoperability requirements from the early 2000s, in environments where help-desk tooling pre-staged accounts with DONT_REQ_PREAUTH for self-service password reset flows, and in environments where a long-departed administrator set the flag on their own admin account to silence a broken legacy client and never reverted it. SpecterOps, Mandiant, and Microsoft Incident Response have all documented intrusions whose initial credential was sourced from a single AS-REP against a forgotten privileged service account.
Attack path
1. Discovery. With any authenticated foothold the attacker runs an LDAP query identical to the one Guerrilla runs: (&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304)(adminCount=1)). PowerView one-liner: Get-DomainUser -PreauthNotRequired -AdminCount. Without any foothold, the attacker can still attempt the attack against a guessed username list: impacket-GetNPUsers corp.contoso.com/ -usersfile users.txt -no-pass -format hashcat -outputfile asrep.txt. The -no-pass flag tells GetNPUsers to attempt the AS exchange unauthenticated; the KDC responds with a full AS-REP only for accounts that carry the flag. 2. Username harvest, if needed. Kerbrute (TryHackMe / ropnop) uses the KDCs differential error responses (KRB5KDC_ERR_PREAUTH_REQUIRED for valid users, KDC_ERR_C_PRINCIPAL_UNKNOWN for invalid) to enumerate valid sAMAccountNames at thousands of attempts per second against a single DC. Public sources (LinkedIn, GitHub, the GAL via OWA) yield admin candidates by name. 3. AS-REP request. The attacker sends an AS-REQ with no PA-ENC-TIMESTAMP. The KDC, observing DONT_REQ_PREAUTH on the account, returns AS-REP including the enc-part sealed with the long-term key. Rubeus.exe asreproast /user:<admin> /format:hashcat /outfile:hash.txt and impacket-GetNPUsers both serialize this into hashcat mode 18200 format. 4. Offline crack. hashcat -m 18200 hash.txt rockyou.txt -r best64.rule -O. A typical RTX 4090 cracks RC4 AS-REP at 1.4 billion candidates per second. Operators routinely report sub-hour cracks for any password under 14 characters that touches a known wordlist or pattern. 5. Authenticate as the privileged identity. The recovered plaintext (or its AES/RC4 key) is used with Rubeus asktgt /user:<admin> /password:<cracked> /domain:corp.contoso.com /ptt to acquire a TGT in the current logon session, or with runas /netonly, kinit, or any Kerberos-aware tool. The attacker is now indistinguishable on the wire from the legitimate Domain Admin. 6. Tier-0 actions. From the privileged context the operator proceeds directly to DCSync (impacket-secretsdump -just-dc corp/<admin>@dc01 or mimikatz lsadump::dcsync /user:krbtgt) to extract the krbtgt hash and forge Golden Tickets, modify the Domain Controllers OU, and persist via AdminSDHolder ACEs. The entire chain (discovery to Golden Ticket) is achievable in under one hour against a vulnerable target.
How Guerrilla assesses it
Guerrilla binds to any reachable domain controller over authenticated LDAP and issues a single combined bit-test filter against the domain naming context. The primary filter: (&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304)(adminCount=1)) This is the same query an attacker holding any low-privilege foothold runs to identify high-value AS-REP candidates. Guerrilla supplements it with a recursive expansion of the well-known protected SIDs (Domain Admins 512, Enterprise Admins 519, Schema Admins 518, Administrators 544, Account Operators 548, Server Operators 549, Print Operators 550, Backup Operators 551) so that current members whose adminCount has not yet been (re)stamped by SDProp are not missed. For every match the check enriches the record with: ACCOUNTDISABLE state, pwdLastSet age in days, lastLogonTimestamp age, full userAccountControl flag breakdown (including TRUSTED_FOR_DELEGATION and PASSWORD_NOTREQD as compounding risks), every group in memberOf including transitive membership, servicePrincipalName (so a privileged account that is also Kerberoastable is double-flagged), msDS-SupportedEncryptionTypes (RC4-only accounts are flagged Critical regardless of password age), and Protected Users membership. The native PowerShell equivalent the check emits as a remediation pivot is Get-ADUser -Filter "DoesNotRequirePreAuth -eq $true -and AdminCount -eq 1 -and Enabled -eq $true" -Properties DoesNotRequirePreAuth, AdminCount, PasswordLastSet, LastLogonDate, MemberOf, ServicePrincipalName, msDS-SupportedEncryptionTypes. The check requires only authenticated read of the domain NC; no privileged rights are needed locally.
Recommended value
No privileged accounts with 'Do not require Kerberos preauthentication' flag set
Remediation
Identify accounts using Get-ADUser -Filter {DoesNotRequirePreAuth -eq $true -and AdminCount -eq 1}. Enable Kerberos pre-authentication immediately on all privileged accounts. Rotate passwords on affected accounts as they may have already been compromised via AS-REP Roasting
Fixture-proven verdicts
Every verdict below is proven by a golden fixture in the module's gating test suite. This table derives from the last green run; it cannot be edited by hand.
| Scenario | Expected verdict |
|---|---|
| clean | PASS |
| known-bad | FAIL |
| throttled | Not Assessed |
Framework mappings
- NIST SP 800-53
- IA-5(2), AC-2
- ANSSI
- R36
- CIS AD Benchmark
- 4.3.3
- MITRE ATT&CK
- T1558.004