Last month, Microsoft has introduced a new feature of Azure AD Connect called Single Sign On. It allows companies to configure SSO between AD and AAD without the need to deploy ADFS, which makes it an ideal solution for SMEs. Here is a high-level diagram of this functionality:
As we can see from the diagram above, Azure AD exposes a publicly available endpoint that accepts Kerberos tickets and translates them into SAML and JWT tokens, which are understood and trusted by other cloud services like Office 365, Azure or Salesforce. And wherever you have Kerberos-based authentication, it can be attacked using Silver Tickets.
In usual circumstances this attack can only be performed from the intranet. But what really caught my attention is the fact that with this new SSO feature, Silver Tickets could be used from the entire internet. Let’s give it a try then!
The Nasty Stuff
To test this technique, we need to retrieve some information from Active Directory first:
- NTLM password hash of the AZUREADSSOACC account, e.g. f9969e088b2c13d93833d0ce436c76dd. This value can be retrieved from AD using mimikatz:
1mimikatz.exe "lsadump::dcsync /user:AZUREADSSOACC$" exit
My own DSInternals PowerShell Module could do the same job:
12Get-ADReplAccount -SamAccountName 'AZUREADSSOACC$' -Domain contoso `-Server lon-dc1.contoso.local
Both of these commands need Domain Admins permissions.
- Name of the AD domain, e.g. contoso.local.
- AAD logon name of the user we want to impersonate, e.g. email@example.com. This is typically either his userPrincipalName or mail attribute from the on-prem AD.
- SID of the user we want to impersonate, e.g. S-1-5-21-2121516926-2695913149-3163778339-1234.
Having this information we can now create and use the Silver Ticket on any Windows computer connected to the internet. It does not even matter whether it is joined to a domain or a workgroup:
- Create the Silver Ticket and inject it into Kerberos cache:
1234mimikatz.exe "kerberos::golden /user:elrond/sid:S-1-5-21-2121516926-2695913149-3163778339 /id:1234/domain:contoso.local /rc4:f9969e088b2c13d93833d0ce436c76dd/target:aadg.windows.net.nsatc.net /service:HTTP /ptt" exit
- Launch Mozilla Firefox.
- Go to about:config and set the network.negotiate-auth.trusted-uris preference to value “https://aadg.windows.net.nsatc.net,https://autologon.microsoftazuread-sso.com”.
- Navigate to any web application that is integrated with our AAD domain. We will use Office 365, which is the most commonly used one.
- Once at the logon screen, fill in the user name, while leaving the password field empty. Then press TAB or ENTER.
- That’s it, we’re in!
- To log in as another user, run the command below and repeat steps 1-6.
It is also worth noting that the password of the AZUREADSSOACC account never changes, so the stolen hash/key will work forever. It could therefore be misused by highly privileged employees to retain access to the IT environment after leaving the company. Dealing with such situations is a much broader problem, which is aptly depicted by the following old Narnian saying:
First of all, I have to point out that this technique would not be very practical in real-world situations due to these reasons:
- The SSO feature is in Preview and has to be explicitly enabled by an AD admin. Just a handful of companies probably use it at the time of writing this article and enterprises will quite surely stick to their proven ADFS deployments even after this feature reaches GA.
- The hash/key of the AZUREADSSOACC account can only be retrieved by Domain Admins from DCs by default. But if an attacker had such highly privileged access to an Active Directory domain, he/she would be able to do some way nastier stuff than just replicating a single hash.
- The password of the AZUREADSSOACC account is randomly generated during the deployment of Azure AD Connect. It would therefore be impossible to guess this password.
As you can see, there is simply no need to panic. But just to be safe, I would recommend these generic security measures:
- Only delegate administrative access to trusted individuals and keep the number of members of the Domain Admins group (and other privileged groups) as low as possible.
- Protect backups of Domain Controllers, so no-one could extract sensitive information from them.
- Enable and enforce Azure MFA for users authenticating from external IP addresses. It is very straightforward and effective against many kinds of attacks.
- Consider implementing Azure AD conditional access.
- Deploy Microsoft Advanced Threat Analytics to detect malicious replication and other threats to your AD infrastructure.
- Force a password change on the AZUREADSSOACC account by re-deploying Azure AD Connect SSO after a highly privileged employee leaves the company. This should be done together with resetting the password of krbtgt and other sensitive accounts.
I am also quite sure that the Azure AD team at Microsoft is fully aware of this potential threat and there is chance that they could implement some kind of heuristics to detect forged Kerberos tickets in the future. It would also be nice if they implemented automatic password changes for AZUREADSSOACC (or it is already there and I just missed it). Again, we are talking about a feature that has not even reached the GA stage yet.
Although the Silver Ticket attack has been here for some years, it is now probably the first time it can be used over the internet against a cloud service, which theoretically makes it even more potent. On the other hand, it would be quite hard to perform this technique in a real-world environment due to impracticalities discussed in the previous section, so there is no need to worry. The new SSO feature of Azure AD Connect can therefore be considered safe and I would recommend using it.