Validating users with Kerberos



Introduction

Kerberos is a network authentication protocol, it is designed to provide strong authentication for client/server applications by using secret-key cryptography. Interestingly, Kerberos gets its name from Cerberus because if its three key areas: The client, the Resource Server and the Key Distribution Centre (KDC).

A Kerberos Metaphor from adsecurity:

As mentioned earlier, Kerberos has 3 components, the client, the server, and the KDC (trusted 3rd party). The process is similar to when you travel to a foreign country.

  • You visit the local passport office with a birth certificate (get the Ticket Granting Ticket ticket from the KDC)
  • You request an entrance Visa for your passport in order to enter the country (get the Ticket Granting Service ticket from the KDC – ok, so you would get the Visa from the country’s embassy, but you still need the passport and something authoritative the country’s immigration guard will accept).
  • You travel to the country with the passport and the country’s entrance Visa (present authoritative documentation to gain access to the resource server).

The article linked above discusses Kerberos in good detail, I'll reference it again here, but it will also be in the references list at the end.

Enumerating Users

To discover a valid username, a bruteforce-style attack is launched against the Kerberos service. When Kerberos receives an invalid username, the server will respond with the error code: KDC_ERR_C_PRINCIPAL_UNKNOWN. This can allow an attacker to determine the validity of a username. If a username is valid, it will illicit either the TGT (Ticket Granting Ticket) in a AS-REP response OR receive the KDC_ERR_PREAUTH_REQUIRED message from Kerberos. Either of these responses reveal that the user exists. Another useful response from Kerberos is KDC_ERR_CLIENT_REVOKED. This response means that the clients credentials have been revoke. Meaning, the account is either locked or disabled.

NOTE: Authentication Service (AS) is the first point of call that the client has with Kerberos. It is used to lookup the users password and create the TGT. The AS will also create the session key that the user will use for communcation with Kerberos.

AS-REQ: The user authenticates to the KDC by sending a message containing their identity and a timestamp encrypted with their password as proof of identity.

AS-REP: If the user can authenticate successfully, the KDC constructs a TGT that will be used by the client to request tickets for other services. Then, the TGT is a service ticket for the Ticket Granting Service (TGS) which also runs on the KDC

NOTE: The Ticket Granting Ticket (TGT) is the Kerberos ticket for the Ticket Granting Service and is encrypted with the KDC using the KDC key (the KRBTGT domain Kerberos account). This means that only the KDC can decrypt and read the ticket.

Doing the thing

There is a nmap script (nmap krb5-enum-users NSE Script) and an Metasploit script.

Ive mentioned this before, but here is how to run it:

                        
$ nmap -p88 --script=krb5-enum-users --script-args krb5-enum-users.realm='lab.local',userdb=test-users.txt 10.10.11.46

Starting Nmap 7.60 ( https://nmap.org ) at 2019-04-03 20:03 BST
Nmap scan report for 10.10.11.46
Host is up (0.00030s latency).

PORT   STATE SERVICE
88/tcp open  kerberos-sec
| krb5-enum-users: 
| Discovered Kerberos principals
|     standard.user@lab.local
|_    administrator@lab.local

Nmap done: 1 IP address (1 host up) scanned in 0.37 seconds

As for metasploit, it wasn't to happy about being ran. I set the following options:

                        
use auxiliary/gather/kerberos_enumusers
set DOMAIN swamp.onion
set RHOSTS 192.168.0.1
set USER_FILE users.txt

It gave the following output:

                        
[*] Running module against 10.10.11.46

[*] Validating options...
[*] Using domain: LAB.LOCAL...
[*] 10.10.11.46:88 - Testing User: "standard.user"...
[*] 10.10.11.46:88 - KDC_ERR_PREAUTH_REQUIRED - Additional pre-authentication required
[+] 10.10.11.46:88 - User: "standard.user" is present
[-] Auxiliary failed: NoMethodError undefined method `id' for nil:NilClass
[-] Call stack:
[-]   /opt/metasploit-framework/embedded/framework/modules/auxiliary/gather/kerberos_enumusers.rb:96:in `report_cred'
[-]   /opt/metasploit-framework/embedded/framework/modules/auxiliary/gather/kerberos_enumusers.rb:77:in `block in run'
[-]   /opt/metasploit-framework/embedded/framework/modules/auxiliary/gather/kerberos_enumusers.rb:65:in `each'
[-]   /opt/metasploit-framework/embedded/framewo   
   
   

So, thats how to validate users with Kerberos. A valid path would be to get a list of names via OSINT and confirm them with Kerberos. The nmap utility is 100% better than the MSF one in my opinion, and is the one I'll stick to.

For anyone who cares, here are all the Kerberos Error messages

Error Codes

Error Error Name Description
0x0 KDC_ERR_NONE No error
0x1 KDC_ERR_NAME_EXP Client's entry in KDC database has expired
0x2 KDC_ERR_SERVICE_EXP Server's entry in KDC database has expired
0x3 KDC_ERR_BAD_PVNO Requested Kerberos version number not supported
0x4 KDC_ERR_C_OLD_MAST_KVNO Client's key encrypted in old master key
0x5 KDC_ERR_S_OLD_MAST_KVNO Server's key encrypted in old master key
0x6 KDC_ERR_C_PRINCIPAL_UNKNOWN Client not found in Kerberos database
0x7 KDC_ERR_S_PRINCIPAL_UNKNOWN Server not found in Kerberos database
0x8 KDC_ERR_PRINCIPAL_NOT_UNIQUE Multiple principal entries in KDC database
0x9 KDC_ERR_NULL_KEY The client or server has a null key (master key)
0xA KDC_ERR_CANNOT_POSTDATE Ticket not eligible for postdating
0xB KDC_ERR_NEVER_VALID Requested start time is later than end time
0xC KDC_ERR_POLICY Requested start time is later than end time
0xD KDC_ERR_BADOPTION KDC cannot accommodate requested option
0xE KDC_ERR_ETYPE_NOTSUPP KDC has no support for encryption type
0xF KDC_ERR_SUMTYPE_NOSUPP KDC has no support for checksum type
0x10 KDC_ERR_PADATA_TYPE_NOSUPP KDC has no support for PADATA type (Pre-Authentication">Kerberos Pre-Authentication data)
0x11 KDC_ERR_TRTYPE_NO_SUPP KDC has no support for transited type
0x12 KDC_ERR_CLIENT_REVOKED Client’s credentials have been revoked
0x13 KDC_ERR_SERVICE_REVOKED Credentials for server have been revoked
0x14 KDC_ERR_TGT_REVOKED TGT has been revoked
0x15 KDC_ERR_CLIENT_NOTYET Client not yet valid—try again later
0x16 KDC_ERR_SERVICE_NOTYET Server not yet valid—try again later
0x17 KDC_ERR_KEY_EXPIRED Password has expired—change password to reset
0x18 KDC_ERR_PREAUTH_FAILED Pre-Authentication">Kerberos Pre-Authentication information was invalid
0x19 KDC_ERR_PREAUTH_REQUIRED Additional Pre-Authentication">Kerberos Pre-Authentication required
0x1A KDC_ERR_SERVER_NOMATCH does not know about the requested server
0x1B KDC_ERR_SVC_UNAVAILABLE is unavailable
0x1F KRB_AP_ERR_BAD_INTEGRITY Integrity check on decrypted field failed
0x20 KRB_AP_ERR_TKT_EXPIRED The ticket has expired
0x21 KRB_AP_ERR_TKT_NYV The ticket is not yet valid
0x22 KRB_AP_ERR_REPEAT The request is a replay
0x23 KRB_AP_ERR_NOT_US The ticket is not for us
0x24 KRB_AP_ERR_BADMATCH The ticket and authenticator do not match
0x25 KRB_AP_ERR_SKEW The clock skew is too great
0x26 KRB_AP_ERR_BADADDR Network address in network layer header doesn't match address inside ticket
0x27 KRB_AP_ERR_BADVERSION Protocol version numbers don't match (PVNO)
0x28 KRB_AP_ERR_MSG_TYPE Message type is unsupported
0x29 KRB_AP_ERR_MODIFIED Message stream modified and checksum didn't match
0x2A KRB_AP_ERR_BADORDER Message out of order (possible tampering)
0x2C KRB_AP_ERR_BADKEYVER Specified version of key is not available
0x2D KRB_AP_ERR_NOKEY Service key not available
0x2E KRB_AP_ERR_MUT_FAIL Mutual Authenticationfailed
0x2F KRB_AP_ERR_BADDIRECTION Incorrect message direction
0x30 KRB_AP_ERR_METHOD Alternative authentication method required
0x31 KRB_AP_ERR_BADSEQ Incorrect sequence number in message
0x32 KRB_AP_ERR_INAPP_CKSUM Inappropriate type of checksum in message (checksum may be unsupported)
0x33 KRB_AP_PATH_NOT_ACCEPTED Desired path is unreachable
0x34 KRB_ERR_RESPONSE_TOO_BIG Too much data
0x3C KRB_ERR_GENERIC Generic error; the description is in the e-data field
0x3D KRB_ERR_FIELD_TOOLONG Field is too long for this implementation
0x3E KDC_ERR_CLIENT_NOT_TRUSTED The client trust failed or is not implemented
0x3F KDC_ERR_KDC_NOT_TRUSTED The KDC server trust failed or could not be verified
0x40 KDC_ERR_INVALID_SIG The signature is invalid
0x41 KDC_ERR_KEY_TOO_WEAK encryption level is needed
0x42 KRB_AP_ERR_USER_TO_USER_REQUIRED User-to-user authorization is required
0x43 KRB_AP_ERR_NO_TGT No TGT was presented or available
0x44 KDC_ERR_WRONG_REALM Incorrect domain or principal

References

attackdebris: Kerberos Domain User Enumeration

nmap: krb5-enum-users

ms14_068_kerberos_checksum

Kerberos, Active Directory's Secret Decoder Ring

Kerberos: Enumerating Domain Usernames