Exploitation - Azure AD Connect
Overview
Azure Active Directory (AD) Connect
is a Microsoft utility used to connect on-premises Active Directory forests with Azure AD. Using Azure AD Connect
on premise users can access cloud-based services in an hybrid identity model, across (Windows Server) Active Directory and Azure AD.
During Azure AD Connect
installation, an user account is created in the on-premise Active Directory forest: the Azure Active Directory Domain Services (AD DS) Connector account
. The account is by default named MSOL_<HEX_ID>
(for example: MSOL_a8a17814304d
). Additionally, an Azure AD user is also automatically created (named Sync_<AAD_CONNECT_SERVER_HOSTNAME>_<HEX_ID>@<AZURE_TENANT>
, with a matching <HEX_ID>
).
Synchronization modes - Password Hash Sync vs Pass-through Authentication
Azure AD Connect
currently implements two synchronization modes / sign-in methods:
Password Hash Sync (PHS)
, in which on-premises Active Directory users' NTLM password hashes (NTLM hashes and Kerberos keys) are extracted and synchronized from the on-premises Active Directory forest to Azure AD.PHS
is the mode configured by default whenever using the "Express Settings" option during the Azure AD Connect installation.Pass-through Authentication (PTA)
, in which on-premises Active Directory users' passwords are not synchronized with Azure AD. The authentication requests (of non cloud-only accounts) made Azure side are instead directly sent to theAzure AD Connect
server to be validated by an on-premise Domain Controller.
In a Password Hash Sync
setup, the Azure AD DS Connector account
is granted replication privileges (Replicate Directory Changes
and Replicate Directory Changes All
) in the Active Directory forest in order to be able to extract the users' password hashes.
Active Directory Federation Services alternative
While Azure AD Connect
is sufficient for connecting an on-premise Active Directory environment with Azure AD, Active Directory Federation Services
may be used as well. ADFS
is an utility developed by Microsoft to provide single sign-on access to external resources and that implements a claims-based access-control authorization model. ADFS
establishes a trust between two federation servers: one client-side and another resources-side. On the client-side, ADFS
connects to the on-premise Active Directory Domain Services
to authenticates users using the Active Directory database and issues a token that can be transmitted to the resources-side federation server. ADFS
presents the advantage of enabling federation with various compliant federation services (such as Software as a Service (SaaS)
applications, ADFS
servers from external Active Directory forests, etc.) but is however much more difficult to deploy and administrate than Azure AD Connect
.
Azure AD Connect identification
The following PowerShell commands, that rely on cmdlets from the Microsoft Remote Server Administration Tools (RSAT)
utilities, can be used to identity the Azure AD DS Connector account
and whether the account is granted replication privileges or not.
Initial compromise of the Azure AD Connect server
The compromise of the Azure AD Connect
server is a prerequisite of the attacks introduced below. The Azure AD Connect
server may benefit from a lower security level than the Domain Controllers usually identified as critical infrastructure resources.
The initial compromise of the Azure AD Connect
server can be achieved in a number of ways (out of the scope of the present note):
Description | Related note(s) |
---|---|
Compromise of an account that can (remotely or using a local connection) execute OS commands through the |
|
Remote code execution vulnerability or compromise of a service allowing for remote code execution on an exposed service. |
|
Compromise of mutualized local Administrators accounts or domain accounts member of the local |
|
Exploitable |
|
Code execution through |
|
Prior compromise of an account trusted for Kerberos delegations on the |
|
... | ... |
Password Hash Synchronization exploit
After achieving command execution in an elevated context on the Azure AD Connect
server, the Azure AD DS Connector account
cleartext password can be retrieved in a number of ways:
by dumping and extracting the authentication secrets stored in the
LSASS
process. This technique is usually more closely defended against byEndpoint detection and response (EDR)
products than the other one presented below. Refer to the[Windows] Post exploitation - Credentials dumping
note for more information on how to dump credentials fromLSASS
as stealthy as possible.by retrieving the
Azure AD DS Connector account
encrypted password from theMSSQL
ADSync
database (encrypted_configuration
column of themms_management_agent
table) and decrypting it using functions implemented in theMicrosoft Azure AD Sync\Bin\mcrypt.dll
DLL
.On out of date
Azure AD Connect
servers installed before early 2020, the decryption key can be simply retrieved with sufficient privileges using functions from themcrypt.dll
DLL
.Since an update changing the way the decryption key is handled, it is now necessary to execute code in the context of the
NT SERVICE\ADSync
Virtual Account to access the decryption key stored as aDPAPI
key. This can be achieved in two notable ways:By injecting in a process running as the
NT SERVICE\ADSync
account and using the previous technique. This can be done using various tools such asmetasploit
'smeterpreter
or in aCobalt Strike
beacon.By executing operating system commands through the
MSSQL
service (usingxp_cmdshell
for instance), which run under the security context of theNT SERVICE\ADSync
account.
Once in possession of the Azure AD DS Connector account
password, refer to the [ActiveDirectory] ntds.dit dumping
note for a procedure and tooling to conduct passwords replication (DCSync
).
Against outdated Azure AD Connect installations
Multiple tools may be used to conduct the extraction and decryption process against outdated Azure AD Connect installations:
The AdSyncDecrypt VB.NET tool.
The
AdDecrypt.exe
binary must be executed:in a folder with the
mcrypt.dll
DLL
present.with the AD Sync binary folder as the working directory or with the folder added to the PATH environment variable.
adconnectdump, which is composed of the
ADSyncDecrypt
,ADSyncGather
, andADSyncQuery
C# utilities as well as theadconnectdump.py
Python script.ADSyncDecrypt
andADSyncGather
work similarly toAdDecrypt.exe
and require code execution on the targetedAzure AD Connect
server.ADSyncQuery
present the advantage of conducting the extraction through remoteRPC
calls. It however requires a localMSSQL
instance to be installed on the attacking computer.The azuread_decrypt_msol.ps1 PowerShell script.
Against up-to-date Azure AD Connect installations
The azuread_decrypt_msol_v2.ps1 PowerShell script implements the operating system commands execution through the MSSQL
service described above to achieve code execution under the security context of the NT SERVICE\ADSync
account.
Pass Through Authentication exploit
In Pass-through Authentication (PTA)
mode, the authentication requests are sent to the Azure AD Connect
server through a connection established by the Azure AD Connect Authentication Agent
(AzureADConnectAuthenticationAgentService.exe
). Note that cloud-only accounts will not affected by the exploit as their authentication requests are processed only Azure AD-side.
The agent rely on the LogonUserW
Win32 API function to validate the received credentials against a on-premise Active Directory Domain Controller. In order to make use of the Win32 API LogonUser
functions, the Authentication Agent must be in possession of the authentication request cleartext username and password.
The compromise of the Azure AD Connect
server, or more precisely put obtaining code execution in a security context with the SeDebugPrivilege
privilege enabled, thus allow:
for the retrieval of the authentication requests' cleartext username and password
the implementation of a backdoor, such as an hardcoded password that would validate access for any accounts (similarly to what could be achieved against on-premise Domain Controllers with the
skeleton key
attack).
The attacks against the PTA
, and the code introduced below, are based on original research done by Adam Chester and Eric Saraga.
Win32 API LogonUserW hooking
The following code should be compiled as a DLL
and injected into the AzureADConnectAuthenticationAgentService
process on the Azure AD Connect
server.
Disclaimer: the DACL
on the payload DLL
must be configured to grant Read
access to the NETWORK SERVICE
identity. If output files are being used to log the authentication requests, the DACL
on the output folder / files should also allow write access.
The payload DLL
will:
Enter the
DllMain
entry point upon loading in theAzureADConnectAuthenticationAgentService
process.Retrieve the address of the
LogonUserW
function, which is exported by theadvapi32.dll
library.Update the virtual address space protection of the
LogonUserW
function region toPAGE_EXECUTE_READWRITE
(in order to be able to modify the function code).Inject in the legitimate
LogonUserW
function a jump to the hookingLogonUserWHook
function.Restore the original virtual address space protection.
Whenever an Azure AD authentication will be processed by the AzureADConnectAuthenticationAgentService
process, the LogonUserW
function and, in turn, the LogonUserWHook
function will thus be called. In order to properly authenticate users, the LogonUserWHook
function returns the result of a call to the LogonUserExW
function (which implement the same validation but does not rely on the LogonUserW
function).
The injectAllTheThings
project can be used to inject the payload DLL
in the process using a number of techniques. One technique consist of copying the payload DLL
path into the remote process, using VirtualAllocEx
and a subsequent WriteProcessMemory
call, and then remotely starting a thread that will load the payload DLL
. A remote thread can be created using CreateRemoteThread
and instructed to execute (Kernel32
's) LoadLibraryW
.
Authentication requests interception
The following code can be inserted in the LogonUserWHook
function (<INJECTED_CODE_INTERCEPTION>
) to log the authentication requests.
Authentication Agent backdoor (Azure Skeleton Key)
The following code can be inserted in the LogonUserWHook
function (<INJECTED_CODE_BACKDOOR>
) to define a password that grant access to any accounts (backdoor known as Skeleton Key
).
References
https://blog.xpnsec.com/protecting-your-malware/ https://blog.xpnsec.com/azuread-connect-for-redteam/ https://www.synacktiv.com/publications/azure-ad-introduction-for-red-teamers.html https://github.com/fox-it/adconnectdump https://vbscrub.com/2020/01/14/azure-ad-connect-database-exploit-priv-esc/ https://www.varonis.com/blog/azure-skeleton-key/ https://docs.microsoft.com/fr-fr/azure/active-directory/manage-apps/migrate-adfs-apps-to-azure https://docs.microsoft.com/fr-fr/azure/active-directory/hybrid/how-to-connect-password-hash-synchronization https://docs.microsoft.com/fr-fr/azure/active-directory/hybrid/how-to-connect-pta
Last updated