Validating users with Kerberos
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.
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 | email@example.com |_ firstname.lastname@example.org 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
|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|
|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|
|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|