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:
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:
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
:
Checking the password policy showed that there was no lockout threshold:
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
:
Next, I listed SMB shares:
SABatchJobs
had read access on azure_uploads
and users$
, so I used crackmapexec
to spider the shares:
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:
azure.xml
contained a password:
Using the credentials, evil-winrm
was able to make a connection as mhope
:
mhope
was a member of Azure Admins
:
Viewing the directories in C:\Program Files
showed that MSSQL and Azure AD Connect were on the system:
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:
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
):
Then, I used iex
to execute it on the target machine which revealed the password for the administrator
:
I ran psexec.py
with the admin credentials to obtain a 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:
I cloned this PoC and ran cve-2020-1472-exploit.py
which changed the password for the DC machine account to an empty string:
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:
I used psexec.py
with the administrator
user's hash to get a system shell:
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
:
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:
After changing the password back to original, trying to authenticate as MONTEVERDE$
with an empty password no longer worked:
Using secretsdump.py
as the administrator
user to dump NTLM hashes confirmed that the password for MONTEVERDE$
was restored to the original value: