CTF collection Vol.2 – TryHackMe Writeup

This room in TryHackMe is a collection of 20 web challenges. We have to search for those flags in the provided website using all kind of web penetration testing skills. To submit the flag we have to follow the following snippet: THM{flag}.

At the moment of finding a flag (Easter egg) we will see which one (#) it is. also, it’s not required to find them all in order.

Table of Contents

Easter 1

If we visit robots.txt we can see a collection of numbers which seems to be in hexadecimal.

Numbers in robots.txt

The easiest way to decoded it is with CyberChef. At the first attempt with “From Hex” operation we can get the first flag.

Easter 1.

Easter 2

If we go again to robots.txt, there’s a disallowed entry. The path looks very long but the “=” at the end might indicate this is a base64 encoded string.

Disallow in robots.txt.

To decode the string I used CyberChef as well, you will realize after the first decoding attempt that it was encoded multiple times. The “recipe” is the following: From Base64 > URL Decode > From Base64 > Remove whitespace > From Base64 > Remove whitespace > From Base64.

At the end we get a three words phrase joint with underscores. If we go to that URI, we can get the first flag- It should look like this: http://<ip address>/Last_found_flag/.

At a first glance, the page has no the desired content unless we try to underline the web content of see in the source code:

Easter 2.

Easter 3

For this one, we should had enumerated the website looking for any interesting page, the room itself recommends to use common.txt wordlist and it can be done with a tool like Gobuster. As an extra hint, it should be a page with a web form like this:

Web form.

As the same title says, we are not required to register. What we can do is to check in the source code:

Easter 3.

Easter 4

From the web form from the last flag, we could try to get more information with SQL injection. For that I’ll use SQLMap, that will make the process easier.

Checking the parameters and the method of the form we can create the base SQLMap command like this:

http://<ip address>/<page>/ --data "username=name&password=pass" --method POST

The first we should fetch if the database names with the --dbs parameter. We have that it’s indeed SQLi vulnerable and the databases are the following:

Databases.

The interesting one seems to be “THM_f0und_m3“, then we can dump it with the “-D THM_f0und_m3 --dump” parameters. This might take a long time, the best option is to get the table names first, their column names and finally dump only the most interesting ones.

We get two tables, at this point just one to them is interesting:

Easter 4.

Easter 5

As I mentioned before, we got 2 tables from the SQLi, the second one has some users and their passwords:

Table ‘user’.

You can crack it with the tool you want, this time you can use whichever you know. Once cracked the only option to use those credentials in the web form we use for SQLi. There we can get the following:

Easter 5.

Easter 6

We can get this flag from the headers of the http request, this can be done with curl with the -I parameter as follows:

curl -I https://<ip address>/

The response will be:

Easter 6.

Easter 7

If we check in the cookies we will see one called “Invited” set to “0”, also in the site itself, there is a section which says “Who are you? Did I invite you?”.

Did I invite you?

This seems related, so we can try to change the cookie’s value, in this case to “1”, reload the page and let’s see what happen:

Easter 7.

Easter 8

To get this one we need to use Safari 13 on a iOS device:

I’m poor.

Well… that’s not required. A user agent is a string which is sent in each http request and let the server identify the software/browser which is making the request. So we can just change the User-Agent header in the request.

There are a few options to do this: use curl and change the user-agent, use a browser extension or change the headers with a proxy (BurpSuite).

The User-Agent we need is ‘Mozilla/5.0 (iPhone; CPU iPhone OS 13_1_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.1 Mobile/15E148 Safari/604.1‘. You can find it google to easy.

I used curl as it’s fast and easier:

curl http://<ip address>/ -A 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_1_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.1 Mobile/15E148 Safari/604.1'

We just need to check for the desired string in the long html response:

Easter 8.

Easter 9

If we want to watch the world burn we just have to click a button:

Click here button.

After clicking, the site is redirected to a page after a little moment in displaying an image. We can get its content looking the source code or using curl. We can see at the original page hovering in the red button:

curl http://<ip address>/ready/

The content is the following:

Easter 9.

Easter 10

We can get a free gift, maybe a subscription voucher for TryHackMe by just clicking in a link:

Free gift.

The problem is, we need to come from tryhackme:

Only people from tryhackme.

The Referer HTTP header contains the address from which a resource was requested. So, we can use this to look like we came from tryhackme.

For this I’ll be using BurpSuite. First thing we have to do is to intercept a request to this page and we need to change the Referer value “tryhackme.com“:


Changing Referer header.

After forwarding the request from BurpSuite, we get a different content in the page:

Easter 10.

Easter 11

In the middle of the page, we can see some kind of menu in a drop-down input. You can check the message shown after selecting every option, however “salad” gives and interesting hint:

Salad option.

Seems like we have to select the “egg” option, but it’s not in the menu. There are a few different methods to achieve that.

The first one could be to change the value of any option of the select input to “egg”:

Value equals to egg.

Another one is to intercept the request with BurpSuite and change the value to the desired one as follows:

Intercepted request with BurpSuite.

It could also be done with curl or any other tool that handles http requests. After making the request we should see the next Easter egg:

Easter 11.

Easter 12

If we take a look into the source code of the page, it’s importing a jQuery library. The site doesn’t seem to have advanced functionalities, so let’s check its content:

jQuery library.

We just have a function called ahem(). Looking in the source code, it’s not called anywhere. Anyways, we can call it from the console itself:

Easter 12.

Easter 13

This is an easy one, after clicking the red button for “watching the world burn” we get it:

Easter 13.

Easter 14

In the source code there a very long comment which seems to be an image as it has an img HTML tag.

Very long comment.

This can be decoded in different ways, eve with the terminal itself. The easiest way is using an online toll like this. Just after pasting the base64 string we’ll get the decoded image:

Easter 14.

Easter 15

In the website we have a big link called “Game 1”. After clicking on it we can see a kind of game in which we have to guess a combination. We also have a hint, a series of numbers.

You can try with any word and the numbers given doesn’t seem to be their hexadecimal representation.

Testing with “qwerty” string.

To solve this one, I got the number representation of each character in the alphabet (uppercase and lowercase), then I sorted them in an understandable way and got the following:

a  b  c  d  e  f  g
89 90 91 92 93 94 95

h  i  j
41 42 43

k  l  m  n  o  p  q
75 76 77 78 79 80 81

r  s  t  u  v  w  x  y  z
10 11 12 13 14 15 16 17 18
A  B   C   D   E   F
99 100 101 102 103 104

G  H  I  J  K  L  M  N
51 52 53 54 55 56 57 58

O   P   Q   R   S   T
126 127 128 129 130 131

U   V   W   X   Y   Z
136 137 138 139 140 141

Having this, we just have to get the letters series which represent the “51 89 77 93 126 14 93 10”, given as a hint in the page, if the hash and the hint match, we’ll get the flag.

Easter 15.

Easter 16

There is a second game in the website: “Game 2”. Now we have three buttons and after click any of them we get the following message:

Testing game 2.

To get this done, we need to be able to send the values from the three buttons in a single request. This can also be done in different ways, I’ll be using curl command. The only thing we have to get from the page is the name and the value of the buttons, this is buttonN.

The command should be as follows:

curl -X POST -d 'button1=button1&button2=button2&button3=button3&submit=submit' http://<ip address>/game2/

And the output:

Easter 16.

Easter 17

If we check the source code of the site, we can see where is the Easter 17 in a comment:

Location of Easter 17.

As we can see, the code will never work due to the button is calling the nyan() function but we have just defined catz(). It should print a binary encoded string in the webpage.

Instead of trying to fix the code, we can just decode the string, I’ll be using CyberChef. After pasting the the box the code and selecting “From Binary” operator, we don’t get any readable output, but let’s see some details:

Trying to decode binary.

We can try changing the delimiter of the string or even the byte length (don’t do it), but no clear text is given. Looking in the length of the string we see 255, which is not a multiple of 8. This means the string is missing a digit, we can try adding a null value digit “0” at the beginning and see the result:

Easter 17.

Easter 18

In a second level title we have a good hint for this one:

The page will show the egg.

As the text says that the page will show the egg if we send (say) something to the page, this might mean we need to set a new HTTP header in the request, in this case “egg: Yes”. This can easily be done with curl, but BurpSuite will show a more didactic PoC.

What we have to do is to intercept a request and the just add the needed header:

Adding new HTTP header.

Once the request is forwarded the next flag will be in the page:

Easter 18.

Easter 19

Again, looking in the code, we see a very small image called “small.png“. It’s actually difficult to see in the page, it’s just a thin line which looks like the horizontal line (hr) HTML tag.

Looking at that image in full size will show the flag:

Easter 19.

Easter 20

Finally the last one and once again we have a big hint the the page, it’s almost at the end of the page:

Last hint.

This is an easy one, we have to send via POST the provided credentials. curl is an easy and fast solution:

curl -X POST -d 'username=DesKel&password=heIsDumb' http://<ip address>/

And we got it:

Easter 20.

Conclusion

In this writeup I showed how I got the flags and the tools I used, but this can be done in many different ways, in the same post I mentioned some alternatives to the solutions I gave.

The room itself help us to understand many topic related to web penetration testing. Feel free to show your solutions in the comments or suggest new tools to do it.