We’re all used to Windows treating usernames as not being case sensitive, i.e. a username of JOE.BLOGGS is the same as joe.bloggs. However this idea falls apart when you use that username as part of the salt for AES encryption, which is case sensitive. This is exactly what happens when we perform Kerberos preauthentication using AES encryption (the default encryption level in current versions of Windows).
So why doesn’t this cause problems when we supply the username in the incorrect case?
In AD we have a user setup with a username that has uppercase letters in it, in this case “joe.BLOGGS”
Then we run a command like Net Use and specify the username in all lowercase:
Net Use \\server.kerb.local\Share /user:kerb.local\joe.bloggs
This does use Kerberos and does use the correct case username for the AES salt even though we didn’t supply it like that, but how?
The short answer:
Windows sends an authentication request without any encrypted preauth data to begin with (so the AES salt is not needed yet). The DC responds with an error saying preauth is required but it also includes the username in the exact same case it is stored as in AD. So then Windows just uses that as the salt for the encryption and tries again, which should be successful.
The long answer:
When we execute something like the Net Use command above, regardless of whether we specify the username in the correct case this is what happens:
1: Windows sends an authentication request (AS-REQ) without encrypting any preauthentication data, but telling the server that it supports AES encryption.
2: The server responds with a message that contains the error “PREAUTH_REQUIRED” but importantly it also includes the following section because the original request said it supported AES:
As you can see this tells us the exact salt to use for this user, which is the domain name in uppercase (KERB.LOCAL) followed by the username in the exact same case that was in the user’s AD account (joe.BLOGGS).
3: So now Windows can just send another AS-REQ but this time using the correct salt to encrypt the preauth data (which is a timestamp to avoid replay attacks, as I explained in this video):
4: This time the server responds with an AS-REP which contains the user’s TGT and then they can go ahead and use that to request service tickets.
If the user account has preauth disabled then none of this matters as the client doesn’t need to encrypt anything using their username as a salt. So after the first AS-REQ the server just responds with the AS-REP containing the user’s TGT (message 4 in the info above).
Also some attacker tools skip straight to the second AS-REQ that includes encrypted preauth data, so they do need the username to be in the correct case. For example if you the “brute” command in Rubeus and supply usernames and passwords but with the usernames not matching the case they are in AD, it will tell you that no valid credentials were found even though you did have a correct username and password combo. I’m hoping to work around this in my Rubeus GUI tool but I’ll make another post about that soon. EDIT: After way more work than I anticipated, I’ve now made my Rubeus GUI tool handle this correctly so usernames are no longer case sensitive 🙂
Lastly, if any of the Kerberos lingo above didn’t make much sense to you, check out my in depth explanation of Kerberos here: