HTB: Sauna Writeup
In this post, we're resolving Sauna Machine from HackTheBox, where we'll deal with an Active Directory environment. We will exploit AS-REP Roasting on a domain account, reading autologon credentials and doing some domain ACEs analysis using BloodHound, finally we will perfom a DCSync attack to escalate our privileges.
Machine Information
Synopsis
Sauna is an easy difficulty Windows machine that features Active Directory enumeration and exploitation. Possible usernames can be derived from employee full names listed on the website. With these usernames, an ASREPRoasting attack can be performed, which results in hash for an account that doesn’t require Kerberos pre-authentication. This hash can be subjected to an offline brute force attack, in order to recover the plaintext password for a user that is able to WinRM to the box. Running WinPEAS reveals that another system user has been configured to automatically login and it identifies their password. This second user also has Windows remote management permissions. BloodHound reveals that this user has the DS-Replication-Get-Changes-All extended right, which allows them to dump password hashes from the Domain Controller in a DCSync attack. Executing this attack returns the hash of the primary domain administrator, which can be used with Impacket’s psexec.py in order to gain a shell on the box as NT_AUTHORITY\\SYSTEM
.
General Information
Machine | Nest |
---|---|
OS | Windows |
Dificulty | Easy |
Stars | 4.5 |
Release Date | 15 Feb 2020 |
Recon
Let’s start by enumerating active services in the machine, we can use nmap in order to do this, besides of running nmap scripts, and enumerating versions.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
❯ sudo nmap -p- -sSVC --min-rate 7000 --min-parallelism 100 -oN machine_services.txt -n 10.10.10.175
Stats: 0:01:56 elapsed; 0 hosts completed (1 up), 1 undergoing Script Scan
NSE Timing: About 99.96% done; ETC: 14:27 (0:00:00 remaining)
Nmap scan report for 10.10.10.175
Host is up (0.28s latency).
Not shown: 65515 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Egotistical Bank :: Home
| http-methods:
|_ Potentially risky methods: TRACE
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2024-09-08 04:26:02Z)
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: EGOTISTICAL-BANK.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: EGOTISTICAL-BANK.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 msrpc Microsoft Windows RPC
49674/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49676/tcp open msrpc Microsoft Windows RPC
49689/tcp open msrpc Microsoft Windows RPC
49697/tcp open msrpc Microsoft Windows RPC
Service Info: Host: SAUNA; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-time:
| date: 2024-09-08T04:26:55
|_ start_date: N/A
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
|_clock-skew: 6h59m39s
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 134.97 seconds
We can see some interesting services running on the machine. Since it is running DNS, Kerberos, LDAP, etc; we can assume that we’re dealing with a domain controller. We can also see that the server is hosting a web server, so we definitely we must take a look at it.
First, let’s obtain the domain name in order to add it to our hosts file. We can use crackmapexec
for this.
1
2
❯ crackmapexec smb 10.10.10.175
SMB 10.10.10.175 445 SAUNA [*] Windows 10 / Server 2019 Build 17763 x64 (name:SAUNA) (domain:EGOTISTICAL-BANK.LOCAL) (signing:True) (SMBv1:False)
Now egotistical-bank.local
will be resolved
We can attempt to get null or anonymous sessions on SMB or LDAP, but note that this is likely to fail. So let’s take a look at the website…
Analyzing the Website
It appears to be a bank’s website, but I didn’t find anything interesting. There are some contact forms, but they don’t work, we’ll receive a Method not allowed
HTTP response. I prefer to not to put effort into trying to making them work.
If we scroll down in the about.html
page, we will find the following: We see that there are some employee names. We can use these names to create a username wordlist to try to find valid usernames in the domain. Who knows?, they might have domain accounts, let’s figure out.
To achieve this, I’ve created a basic Node.js tool that will do exactly what we need, you can download it from it’s GitHub repository: AD-Username-Generator
Generating a username wordlist
We can use curl
and grep
using LookAround expressions to easily extract the employes names the from the about webpage. Alternatively, we could simply copy the names and paste them into a file manually. I preffer to complicate things to myself.
Well, once we have the employee names in a file, we can run the script to generate possible Active Directory usernames. There is also a great tool for generating this type of wordlist. You can download it from its GitHub repository if you prefer using Python: username-list-generator
Nice, now that we’ve got a username wordlist, we can use Kerbrute
to enumerate valid users through Kerberos. Kerbrute will request a TGT for every user in the wordlist without providing a password. If the user exists, the KDC will notify us that the user does not have the DONT_REQ_PREAUTH
flag set. If the user does not exists, the KDC will return an ERR_C_PRINCIPAL_UNKNOWN
error. This way, Kerbrute
can determine wheter a user exists or not. Obviusly, if the user has the DONT_REQ_PREAUTH
flag set, Kerbrute
will mark the user as valid. Cool, we’ve enumerated one valid user, that might be enough. Let’s find out.
AS-REP Roasting
Now that we’ve found a valid user, we can use impacket-NPUsers
to check whether FSmith
requires pre-authentication or not.
Great, FSmith
does not require pre-authentication to request a TGT from the KDC. This means we can send a KRB_AS_REQ
message without providing the user password which will let us receive a KRB_AS_REP
message, which contains the TGT
, and the following items encrypted with a secret key derived from the user’s password:
- Session Key
- TGT Expiration Time
- User Nonce
So, when we attempt to take advantage of a user who has the DONT_REQ_PREAUTH
flag set, we’re going to focus on bruteforce the mentioned package, not directly the TGT as the TGT is encrypted using a secret key derived from the user krbtgt
password, which is a very large password. Although we don’t need to worry about this, as Hashcat will do all the stuff for us but is good to know this kind of things. Anyway we can refer to this process as TGT Cracking
. Here we can take a look in the KRB_AS_REP
package from Wireshark:
We can see that there are two encrypted parts (enc-part): one is in the ticket
part, which is the TGT , and the another at the same ticket level; is the data that the user can decrypt with his password.
Now if we see again the encrypted data that we obtain using impacket-NPUsers
, we’ll notice that is exactly the same value that we obtain from Wireshark in the user encrypted part (59b7fd23ed…..) but with some additional information that will help cracking tools to recognize the format ($krb5asrep$23$fsmith@EGOTISTICAL-BANK.LOCAL:
).
Foothold
Cracking the Ticket
To crack the TGT we can use several tools, I prefer to use Hashcat
, but John
is a great option too. Hashcat need us to provide a hash mode
with -m
parameter. We can find the mode for AS-REP
with the following command:
Nice, the appropiate mode is 18200
, now let’s see if we can get the password.
Used command:
1
❯ hashcat -m 18200 -a 0 ./fsmith.kirbi /usr/share/wordlists/rockyou.txt
Output:
And we’ve got the password for the
FSmith
user: Thestrokes23
Logging in as user FSmith
Now we can use PywerView
to see which domain groups FSmith
belongs to.
Remote Management Users… Nice, in that case let’s get shell using evil-winrm
and read the user flag.
Privilege Escalation
System Enumeration
Now that we’ve obtained a shell, we will proceed to enumerate the system. To do this, I’m going to use WinPeas.exe
. Let’s see what we can find.
If we search for the password
keyword, we’ll find plain text autologon credentials for the user svc_loanmanager
. I really got stuck with these credentials, because the user is actually svc_loanmgr
and not svc_loanmanager
, I guess the registry hive for autologons is outdated. Anyway, if we list user directories in C:\Users\
, we’ll find the real username.
Well, now let’s use evil-winrm
again with these new credentials and continue enumerating with this new user. Since we have a service account we should consider using Bloodhound
to easily look at that privileges do we have in the domain.
I’m gonna use SharpHound
to collect the domain data, you can download it from its GitHub repository: SharpHound.
DCSync
If we filter by Principals with DCSync rights, we’ll see the following: The user
svc_loanmgr
has DCSync
rights; kinda strange permissions for a service account meant to manage loans.
To exploit a domain using DCSync
rights, we essentially tell the Domain Controller that we are another Domain Controller and we want to synchronize the domain database. So we request the whole database which includes absolutely all the domain information, including NTLM hashes of every account in the domain. This database is named NTDS
and is present in every domain controller.
So now let’s use impacket-secretsdump
to dump the NTDS.
PtH as Administrator
Now we can use the Administrator NTLM Hash to perform a Pass-the-Hash attack. There are a lot of tools that support authentication using NTLM hashes, I’ll use evil-winrm
.
This was a very easy machine, and it was enjoyable to work on, especially if you’re unfamiliar with AS-REP Roasting and DCSync.