
kerbrute enumerates AD usernames without alerts
kerbrute userenum -d corp.local --dc 10.0.0.10 users.txtkerberos was built in the 90s to make authentication faster and more secure than plaintext passwords flying across the wire. nobody designed it to also become a stealthy username enumeration machine, but here we are. if you run active directory, you need to understand exactly why this works, because "just watch for failed logins" will not save you here.
why this flies under the radar
when a client wants a kerberos ticket, it sends an AS-REQ to the domain controller. if the username doesn't exist, the KDC replies with KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN. if the username does exist, it replies with KRB5KDC_ERR_PREAUTH_REQUIRED, because it wants the client to prove it knows the password before handing out a ticket. that's it. that one-word difference in the error response is enough to confirm a real account exists, and none of this touches the normal "failed logon" pipeline because no actual logon attempt happened yet. it's pre-authentication, not authentication.
breaking down the command
kerbrute userenum -d corp.local --dc 10.0.0.10 users.txt
-d corp.local tells kerbrute which domain to build usernames against. --dc 10.0.0.10 points it straight at a domain controller instead of relying on dns to find one. users.txt is just a wordlist, one candidate username per line, usually built from linkedin scraping, breach dumps, or predictable naming conventions like first.last. kerbrute fires an AS-REQ for every name and sorts the replies into "exists" and "doesn't exist" buckets, fast, and with zero event 4625s generated in the process.
the password spray follow-up
kerbrute passwordspray -d corp.local valid.txt 'Autumn2026!'
once someone has a list of confirmed real accounts, they don't guess ten passwords against one user, they try one password against a thousand users. account lockout policies are usually built around "5 bad attempts on one account," so spraying one guess per account per lockout window slides right under that threshold. seasonal passwords work because humans are predictable and IT departments love telling people to "change your password to include the season and year."
what your logs actually show
this is the part most defenders miss. because the enumeration step never completes a full logon, you won't see it in the events people usually watch. what you should be watching instead is event id 4768 (kerberos TGT requested) and event id 4771 (kerberos pre-auth failed). a normal environment has a steady, boring baseline of these. a burst of 4768/4771 events from one source ip hitting hundreds of distinct usernames in a short window is not normal, that's enumeration, full stop. if your SIEM isn't correlating source ip against unique username count over a rolling time window, you're blind to this entire attack class.
shutting the door on enumeration and spraying
you can't fully stop kerberos from answering AS-REQs differently, that's a protocol design choice, not a bug you patch. but you can take away the payoff:
turn on smart lockout or a risk-based auth solution so lockouts trigger on aggregate suspicious activity, not just per-account thresholds a spray is designed to dodge. ban seasonal and pattern-based passwords at the policy level, tools like a custom banned password list (or azure ad password protection) will reject "Autumn2026!" before it ever gets set. require mfa everywhere it can be enforced, especially for anything internet-facing like vpn or o365, because a correct password from a spray is useless without the second factor. build a detection rule for the 4768/4771 burst pattern described above and alert on it, this is genuinely one of the higher signal, lower noise rules you can write. seed a few honeypot accounts with names that look real but never authenticate, any activity against them is a hard signal something's scanning your directory.
the takeaway
the scary part of kerbrute isn't the tool, it's the assumption that "no failed logins" means "no attack happening." defense here isn't about blocking a command, it's about watching the right events, killing predictable passwords before they're set, and making mfa non-negotiable so a valid username plus a guessed password isn't game over. patch your monitoring gap before someone else finds it for you.