General··6 min read

HTB Sauna

1. Recon: a closed domain and a team page

Hosts entry first:

HTB Sauna
hosts file with sauna.htb entry

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.

HTB Sauna
full-port scan: the DC footprint

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:

HTB Sauna
null-session share enumeration 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.

HTB Sauna
no users anonymously, guest disabled

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:

HTB Sauna
null-session LDAP queries return empty

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:

HTB Sauna
curl -sI: static IIS 10.0 site

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:

HTB Sauna
nxc --asreproast returns the fsmith hash

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:

HTB Sauna
hashcat autodetects mode 18200
HTB Sauna
cracked: Thestrokes23

Credential validated over SMB:

HTB Sauna
evil-winrm session as fsmith

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.

HTB Sauna
evil-winrm session as fsmith
HTB Sauna
user flag read first

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:

HTB Sauna
six domain users

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:

HTB Sauna
shares: one writable printer decoy
HTB Sauna
SYSVOL Registry.pol: EFS blobs, nothing usable

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

HTB Sauna
whoami /priv: nothing exploitable

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:

HTB Sauna
Winlogon registry: autologon credentials in cleartext

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:

HTB Sauna
second shell, as svc_loanmgr

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:

HTB Sauna
bloodhound-python collection

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:

HTB Sauna
GetChanges edge from SVC_LOANMGR to the domain

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:

HTB Sauna
secretsdump: NTDS.dit via DCSync

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

HTB Sauna

References

Related Posts