Monteverde is a Medium Windows box created by egre55. It was released on January 11th, 2020 and retired on June 13th, 2020. The users rated the difficulty 4.8/10 and gave an appreciation score of 4.3/5.
TL;DR
We can anonymously bind to an Active Directory to retrieve the list of users and service accounts. The service account SABatchJobs
password is the same as the username. With this account, we access a share that contains mhope
password in clear-text. We log in through WinRM and retrieve the user flag. As mhope
is part of the Azure Admins
groups and that Azure AD Connect is installed and configured, we can use a known set of Powershell commands to extract its configuration from the MS SQL database and decrypt the password of the service account, which is…the domain admin. We can then use psexec
to get a SYSTEM
shell and the root flag.
Reconnaissance & Enumeration
Open Ports
An NMAP scan shows the following (partial) output:
$ sudo nmap -sS -sV -p- 10.10.10.172
PORT | STATE | SERVICE | VERSION |
---|---|---|---|
53/tcp | open | domain? | |
88/tcp | open | kerberos-sec | Microsoft Windows Kerberos (server time: 2020-02-02 07:47:32Z) |
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 | |
3268/tcp | open | ldap | Microsoft Windows Active Directory LDAP (Domain: MEGABANK.LOCAL0., Site: Default-First-Site-Name) |
3269/tcp | open | tcpwrapped | |
5985/tcp | open | http | Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |
9389/tcp | open | mc-nmf | .NET Message Framing |
We discover:
- the usual ports opened in a Windows Domain Controller and __ the domain is
MEGABANK.LOCAL
, - the WinRM management service over HTTP on port 5985.
LDAP
Anonymous binding is enabled and we can browse the Active Directory with tools like Jxplorer by configuring it as follows:
We get the following information:
- the Domain Controler
monteverde.megabank.local
is a Windows Server 2019 Standard, - the user accounts:
username | memberOf |
---|---|
dgalanos | Trading |
mhope | Azure Admins, Remote Management Users |
smorgan | Operations |
roleary | HelpDesk |
- the service accounts:
username | memberOf |
---|---|
SABatchJobs | none |
svc-ata | none |
svc-bexec | none |
svc-netapp | none |
- there is an additional user
AAD_987d7f2f57d2
that is member ofAzure Admins
. Sounds like an account used for Azure AD. Its description is:
SMB
SMB requires authentication and we do not have any credentials at the moment.
Gaining Access
With what we discovered so far, let’s store the list of user accounts in a file users.txt
and check if a user has a weak password by using a small wordlist:
Nothing shows up. The next thing we can try is AS-REP Roasting. This attack is explained in detail in this blog post. To make it short, if a user is configured to not require Kerberos pre-authentication, anyone can send a request (AS_REQ) to the KDC and receive a response (AS_REP). The response contains an encrypted chunk of data related to that user that can be cracked offline to retrieve the user password. This can be automatized with tools like Impacket GetNPUsers.py
:
Same result. Trying with a medium password list is still unsuccessful. Then we tried with blank passwords and the username as password and found the following default credentials: SABatchJobs:SABatchJobs
. With that, we can list the available shares:
The azure_uploads
share is empty but the users$
one contains some user folders. However, only one folder is not empty:
– dgalanos
– mhope
– azure.xml
– roleary
– smorgan
The azure.xml
file looks like a configuration file to create a password-based Azure Service Principal and contains a plain-text password:
It happens to be mhope
password who is member of the Remote Management Users
. We can, therefore, log in through WinRM with evil-winrm
and get the user flag:
Local Reconnaissance & Enumeration
We find a .Azure
folder in the user home folder that contains cached Azure tokens inTokenCache.dat
:
They are not valid anymore but we can retrieve some information from its content. Were they still valid, we could have possibly replayed them to connect to the Azure tenant. The cache contains 2 pairs of token to access Microsoft Graph API https://graph.windows.net
and to access the Azure Resource Manager provider https://management.core.windows.net
. The token pair consists of an Access Token and an ID token in the JWT format. This is the result of an OpenID Connect authentication:
From this we get as well the user ID john@67632354763outlook.onmicrosoft.com
and the tenant ID: 372efea9-7bc4-4b76-8839-984b45edfb98
. We do not need to dig further into this for the moment.
If we have a look at the installed applications we see some applications related to Azure AD like Azure AD Connect, Azure AD Sync and MS SQL Server used by Azure AD Connect to store metadata and configuration data for the Azure AD Sync service. Azure AD Connect is used to synchronize on-premise AD objects with Azure AD in a hybrid cloud model.
Privilege Escalation
If we search for known attacks on Azure AD Connect, we come across this article that explains how to retrieve the configuration of Azure AD Sync and how to decrypt the password of the service account used to perform such synchs. In the article, the configuration is stored in an MS SQL Express LocalDB database_._ As explained, the configuration is in clear-text, except for the user password that is stored in an encrypted field. Fortunately mhope
is member of the Azure Admins
group. Let’s use the given commands:
- Connect to the database:
There is no MS SQL Express LocalDB instance on the box. The configuration is stored in a standard MS SQL instance. We need therefore to change the connection string as follows:
- Retrieve the necessary keying material stored in the database to decrypt the password:
- Retrieve the clear-text and the encrypted configuration:
We can print the configuration at this point:
We can see that the domain administrator account is used for the synch and that its password is encrypted.
- Decrypt the user password and print data:
The output of this is:
Username: administrator
Password: d0m@in4dminyeah!
We can now get a SYSTEM
shell with psexec
:
Conclusion
The first part, until the user shell, was quite easy. I really enjoyed the second part that was completely new to me. There should definitely be more boxes related to Azure, AWS and GCP!
As usual, here are some takeaways:
- disable Active Directory anonymous binding,
- change default passwords, don’t re-use then and enforce a strong password policy,
- update Azure AD Connect as soon as patches are available and use a dedicated service account with the least privileges possible.
Resources
[1] Jxplorer
http://jxplorer.org/
[2] AS-REP Roasting
https://www.harmj0y.net/blog/activedirectory/roasting-as-reps/
[3] Create an Azure Service Principal
https://docs.microsoft.com/bs-cyrl-ba/powershell/azure/create-azure-service-principal-azureps?view=azps-4.2.0&viewFallbackFrom=azps-2.5.0
[4] Microsoft Graph
https://docs.microsoft.com/en-us/graph/overview
[5] Azure Resource Manager
https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/overview
[6] OpenID Connect
https://openid.net/connect/
[7] Azure AD Connect
https://docs.microsoft.com/en-us/azure/active-directory/hybrid/whatis-azure-ad-connect
[8] Azure AD Connect for Red Teamers
https://blog.xpnsec.com/azuread-connect-for-redteam/