HTB Sauna
1. Recon: a closed domain and a team page
Hosts entry first:

The full TCP scan reads like a domain controller checklist: DNS on 53, IIS on 80, Kerberos on 88, RPC on 135, LDAP on 389 and 3268, SMB on 445, WinRM on 5985. The LDAP banners name the domain: EGOTISTICAL-BANK.LOCAL, host SAUNA, Server 2019.

Then the walls go up. Everything an anonymous session is supposed to be able to touch, this box refuses. Anonymous auth is accepted on SMB, which sounds promising, but the first real request answers STATUS_ACCESS_DENIED:

User listing through the same accepted session: authenticated banner, zero users. A junk login just gets STATUS_LOGON_FAILURE, and guest is disabled outright.

LDAP gets the same treatment. The account filter that finds AS-REP-roastable accounts by userAccountControl flag, the exact query this box exists to teach, returns nothing over a null session:

So SMB and LDAP enumeration are both closed, and the one unexplored surface is IIS. A header check pins it as a static site: single 32 KB HTML file, Last-Modified January 2020, no framework, no app layer to attack. The content is the payload, not the server:

The homepage is a banking template called Repay, and it has a "Meet The Team" section with six employees: Fergus Smith, Hugo Bear, Steven Kerb, Shaun Coins, Bowie Taylor, Sophie Driver. The site even narrates its own hint: "So many bank account managers but only one security manager. Sounds about right!"
From six full names to a candidate userlist, assuming the convention is first initial plus surname: fsmith, hbear, skerb, scoins, btaylor, sdriver, plus the common variants. That list is a Kerberos attack surface, and Kerberos happily tells you which usernames exist even when SMB and LDAP refuse to.
2. AS-REP roasting fsmith
AS-REP roasting in one paragraph: normally Kerberos demands pre-authentication, a timestamp encrypted with your password key, before it will issue a TGT, so the hash never leaves the client. An account with Do not require Kerberos preauthentication set gets a service response encrypted with the account's password key handed to anyone who asks. That ciphertext is an offline-cracking target, and it is obtainable with nothing but a username.
Impacket's GetNPUsers walks the userlist and asks for each name. Everything answers KDC_ERR_C_PRINCIPAL_UNKNOWN except one:
GetNPUsers.py EGOTISTICAL-BANK.LOCAL/ -usersfile user -no-pass -dc-ip 10.129.95.180$krb5asrep$23$fsmith@EGOTISTICAL-BANK.LOCAL:ba90b957fa4820206008e2a8126e95ca$53acdeca...The guess was right on both levels: Fergus Smith maps to fsmith, and his is the account running without pre-authentication. NetExec does the same loop in one line through LDAP and drops the hash straight to a file:

The ciphertext differs between requests because the AS-REP is encrypted fresh each time, but both hashes decrypt to the same password.
Cracking starts with a mistake worth logging: hashcat without -m runs autodetect, which is how the mode got confirmed before it got used, 18200, Kerberos 5 etype 23, AS-REP. Then the real run against rockyou:


Credential validated over SMB:

3. Foothold: WinRM and the user flag
Port 5985 is open, fsmith is a regular user, and WinRM lets members of Remote Management Users log in. First thing after the banner, whoami to confirm, then straight to the flag. The rule I work by: user shell lands, user flag gets read before any escalation work.


4. Post-auth enumeration, and a service account that keeps catching the eye
With credentials instead of a null session, the earlier walls disappear. The user list the anonymous session refused now comes back in one call, six accounts:

One of them is a service account with no description: svc_loanmgr. The share list has one writable entry that is pure decoy, a printer share named "RICOH Aficio SP 8300DN PCL 6" with the remark "We cant print money". Spidering everything with -M spider_plus turns up seven files, none of them interesting, and the one SYSVOL policy file with any content in it decodes to EFS certificate blobs for Administrator. No credentials:


Then the privilege check on the fsmith shell, and it comes back empty. No SeImpersonate, no SeBackup, nothing token-shaped:

I went looking for an escalation vector and found none: no token tricks, nothing to dump, no obvious path out of this shell. The one thing that kept catching the eye, a second time now, was svc_loanmgr. If the box hides a credential anywhere, a service account is where it would be. Service accounts are the ones configured to survive reboots without a human, and on Windows the blunt instrument for that is autologon.
Windows autologon writes its credentials to the registry in reversible form, readable by any authenticated user. MITRE tracks exactly this as T1552.002, Credentials in Registry. One query:

The whole service account, password in cleartext. First login attempt fails, because svc_loanmanager is the display name the registry stores and the real SAM account from the SMB list is svc_loanmgr. Second attempt, in:

5. BloodHound: the DCSync edge
Rather than guess at what a service account can do, map the domain. bloodhound-python collects remotely, no binary upload, one detail cost a retry: the DNS domain is egotistical-bank.local with a hyphen, while the NetBIOS name EGOTISTICALBANK has none, and using the wrong form in -dc makes every resolution fail. Also learned the hard way that an unquoted ! at the end of a password eats itself in bash and zsh:

That 1 computers line settles a question enumeration had left open: SAUNA is the only DC in the domain, verified rather than assumed.
Upload the zip to BloodHound CE, run pathfinding from SVC_LOANMGR to ADMINISTRATOR, and the graph answers with one edge straight to the domain node:

DCSync singals can be seen through GetChanges
6. Root: DCSync and pass-the-hash
secretsdump with the service account. The old backup method over SMB gets denied, and that line is expected noise. The DRSUAPI method, DCSync powered by the GetChanges right BloodHound just showed, returns the entire NTDS.dit:

Administrator's NT hash goes straight into evil-winrm. No password, no cracking, the hash authenticates on its own:

References
- Nmap
- NetExec
- WolfSec: Fingerprint First, recon-to-exploit framework (source of the
curl -sIfingerprint step) - Impacket (GetNPUsers, secretsdump)
- David: Attacking Active Directory, AS-REP Roasting (source of the hashcat
-m 18200step) - Hashcat
- NetExec: spidering-shares module
- evil-winrm-py: usage docs
- MITRE ATT&CK T1552.002: Unsecured Credentials, Credentials in Registry
- Microsoft Sysinternals: Autologon
- HackTricks: Windows Local Privilege Escalation
- WADComs: BloodHound.py Remote Ingestion
- The Hacker Recipes: DCSync (GetChanges + GetChangesAll requirement)
- Hackviser: evil-winrm tool reference (
-Hpass-the-hash syntax)


