Hack The Box - Monteverde

December 20, 2023

Monteverde

Monteverde is a Windows machine with an Active Directory environment featuring Azure AD. After enumerating domain users, it can be discovered that a service account has the username set as the password. This grants access to an SMB share that contains credentials for another user, allowing for a shell over WinRM. Once on the system, enumeration can reveal that Azure AD Connect is on the box, this can be leveraged to extract an encrypted password of the replication account which in this instance is the administrator user, these credentials can then be used to obtain a system shell.

nmap scan:

nmap scan

Notable open ports:

  • 53 (DNS)
  • 88 (Kerberos)
  • 135, 593 (MSRPC)
  • 139, 445 (SMB)
  • 464 (kpasswd)
  • 389, 3268 (LDAP)
  • 636, 3269 (LDAPS)
  • 5985 (WinRM)

Active Directory:

  • domain: MEGABANK.LOCAL
  • hostname: MONTEVERDE

I wasn't able to access any shares from a null session, but I was able to list domain users:

domain users

I saved the output into a file called crackmapexec-users and used awk to extract just the usernames and wrote it into a file called users:

users list

Checking the password policy showed that there was no lockout threshold:

password policy

With the same users list for both usernames and passwords, I ran a password spray to see if any accounts had the username set as the password. crackmapexec will try every username in the list with every password which isn't necessary in this case since only one password needs to be attempted with the corresponding username, but since there wasn't a lockout threshold it didn't cause any issues.

A valid password was found for SABatchJobs:

password spray

SABatchJobs logon success

Alternatively, the following ldapsearch query will find only the usernames of accounts that have a lastLogon value greater than 1. This will narrow down the usernames to the accounts that have been active at some point. Then, the password can be tried individually for each one:

ldapsearch -H ldap://megabank.local -D '' -w '' -b 'dc=megabank,dc=local' "(&(objectClass=user)(!(objectClass=computer))(lastLogon>=1))" sAMAccountName | grep -oP 'sAMAccountName:\s*\K.*'

ldapsearch filter user accounts

Both methods above result in the credentials for SABatchJobs. Next, I listed SMB shares:

list shares

SABatchJobs had read access on azure_uploads and users$, so I used crackmapexec to spider the shares:

spider_plus

The users$ share contained an interesting file, mhope/azure.xml:

"users$": {
    "mhope/azure.xml": {
        "atime_epoch": "2020-01-03 08:41:18",
        "ctime_epoch": "2020-01-03 08:39:53",
        "mtime_epoch": "2020-01-03 09:59:24",
        "size": "1.18 KB"
    }
}

I connected to the share with smbclient and downloaded it:

get-azure-xml

azure.xml contained a password:

mhope password

Using the credentials, evil-winrm was able to make a connection as mhope:

evil-winrm shell as mhope

mhope was a member of Azure Admins

net user mhope

Viewing the directories in C:\Program Files showed that MSSQL and Azure AD Connect were on the system:

azure directories

Azure AD Connect is a tool that provides users with a common hybrid identity for on-premise (Windows Server Active Directory) and cloud (Azure, Office365) infrastructure. One of the features provided is Password Hash Synchronization (PHS) which syncs password hashes between on-premise AD and Azure AD.

One of the toolkits that could be used to exploit Azure AD Connect is adconnectdump which is able to extract and decrypt credentials stored in the ADSync database. Similar to ADSyncDecrypt within adconnectdump, there's another tool written in PowerShell featured on this blog post that can also be used to reveal credentials.

In order for the PowerShell script to establish a successful connection to the MSSQL server, I needed to modify the connection string since the target machine was running a dedicated MSSQL instance.

The syntax for a trusted connection SQL can be found here:

sql connection string

In this case, the server was MONTEVERDE and the database was ADSync, so I changed the connection string to be the following:

$client = new-object System.Data.SqlClient.SqlConnection -ArgumentList "Server=MONTEVERDE;Database=ADSync;Trusted_Connection=true"

Next, I started a python HTTP server containing the PowerShell script (azure-ad-decrypt.ps1):

http server

Then, I used iex to execute it on the target machine which revealed the password for the administrator:

administrator password

I ran psexec.py with the admin credentials to obtain a system shell:

system shell

Since this box was released in January of 2020, it was before the initial Microsoft patch for Zerologon (CVE-2020-1472) which was in August of 2020, thus, there's another method to obtain administrative privileges on the machine within a few steps.

crackmapexec has a module that can check if a target is vulnerable to Zerologon:

crackmapexec zerologon

I cloned this PoC and ran cve-2020-1472-exploit.py which changed the password for the DC machine account to an empty string:

cve-2020-1472-exploit

Now that MONTEVERDE$ had a blank password, I could authenticate as the DC machine account to reveal domain NTLM hashes with secretsdump.py. Notice that MONTEVERDE$ had an NT hash value of 31d6cfe0d16ae931b73c59d7e0c089c0 which is the MD5 hash of a blank password within the context of NTLM:

secretsdump no password

I used psexec.py with the administrator user's hash to get a system shell:

system shell with administrator hash

The PoC also provides a way to restore the password to its original value. When the DC machine account hash is changed to an empty string, the NT hash becomes 31d6cfe0d16ae931b73c59d7e0c089c0, allowing for authentication without a password. But, the original value is still stored within LSA secrets as a hex value which can be seen with secretsdump.py:

secretsdump plain password hex

Therefore, the password can be restored to the original value using restorepassword.py within the PoC directory and specifying the netbios name, IP, and hex of the password:

secretsdump plain password hex

After changing the password back to original, trying to authenticate as MONTEVERDE$ with an empty password no longer worked:

no password logon failure

Using secretsdump.py as the administrator user to dump NTLM hashes confirmed that the password for MONTEVERDE$ was restored to the original value:

secretsdump restored hash


CTF Writeups | InfoSec Topics

Written by Mike Garrity

Email RSS