Post

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

MachineNest
OSWindows
DificultyEasy
Stars4.5
Release Date15 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 img_2

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. img_3

If we scroll down in the about.html page, we will find the following: img_4 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. img_5

Well, once we have the employee names in a file, we can run the script to generate possible Active Directory usernames. img_6 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. img_7 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.

img_9

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: img_8

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: img_10

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:

img_11 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. img_12

Remote Management Users… Nice, in that case let’s get shell using evil-winrm and read the user flag. img_13


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. img_14

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.

img_15

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: img_16 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. img_17

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. img_18

This was a very easy machine, and it was enjoyable to work on, especially if you’re unfamiliar with AS-REP Roasting and DCSync.

This post is licensed under CC BY 4.0 by the author.