TryHackMe CTF Collection Vol. 2

A beginner-friendly CTF walkthrough (Part 2)

Abdul Issa
InfoSec Write-ups

--

TryHackMe CTF Collection Vol. 2
TryHackMe CTF Collection Vol. 2 (Source: tryhackme.com)

This is the second instalment of the CTF collection series. The second volume focuses on web-based challenges. There are a total of 20 easter eggs a.k.a flags can be found within the box. Let see how good is your CTF skill. Now, deploy the machine and collect the eggs!4

For the challenges (without peeking at the solutions) see the link below:

🏠 TryHackMe CTF Collection Vol. 2 (Official website)

The previous volume in the series focused on general CTF skills. If you would like to revisit that, see my write-up below:

Introduction

Greetings, Cyber Mavericks!

We’re back again to hone our skills with another TryHackMe CTF room, boasting 20 puzzles or easter eggs waiting to be discovered by uncovering flags on a web-based target. With a “Medium” difficulty level, this second volume definitely ups the ante!

You can find my writeup on the first volume here:
TryHackMe CTF Collection Vol. 1”.

A notable thing about this CTF volume is the lack of challenge descriptions. The only and best way to find out which flag correlates to an Easter Egg is by using the associated hint. It’s perfectly fine to make use of the hints.

Note: All the challenge flags are formatted as THM{flag}.
I have removed the flags to avoid sploilers

Without further ado, let’s get into it and put our beginner CTF skills to the test!

Easter Egg 1

Hint: check robots

We always begin with making things easier for ourselves. Let’s add the IP address of the target to /etc/hosts and associate it with our chosen hostname “ctfvol2.thm”. We will be using this to refer to the target machine throughout this article.

echo "10.10.53.15 ctfvol2.thm" >> /etc/hosts

What we need to do next is carry out a standard web directory enumeration exercise (brute-forcing) to discover web directories of interest.

$ gobuster dir -u http://ctfvol2.thm -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt 

===============================================================
[+] Url: http://ctfvol2.thm
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2024/04/04 12:06:33 Starting gobuster
===============================================================
/index (Status: 200)
/login (Status: 301)
/button (Status: 200)
/static (Status: 200)
/cat (Status: 200)
/small (Status: 200)
/who (Status: 200)
/robots (Status: 200)
/iphone (Status: 200)
/game1 (Status: 301)
/egg (Status: 200)
/dinner (Status: 200)
/ty (Status: 200)
/ready (Status: 301)
/saw (Status: 200)
/game2 (Status: 301)
/wel (Status: 200)
/free_sub (Status: 301)
/nicole (Status: 200)
/server-status (Status: 403)
===============================================================
2024/04/04 12:07:26 Finished
===============================================================

Quite a few interesting web folders. Let’s park that for now and revisit them later. For now, let’s start with the website’s robots.txt.

curl http://ctfvol2.thm/robots.txt

We get the following encoded message:

User-agent: * (I don't think this is entirely true, DesKel just wanna to play himself)
Disallow: /VlNCcElFSWdTQ0JKSUVZZ1dTQm5JR1VnYVNCQ0lGUWdTU0JFSUVrZ1p5QldJR2tnUWlCNklFa2dSaUJuSUdjZ1RTQjVJRUlnVHlCSklFY2dkeUJuSUZjZ1V5QkJJSG9nU1NCRklHOGdaeUJpSUVNZ1FpQnJJRWtnUlNCWklHY2dUeUJUSUVJZ2NDQkpJRVlnYXlCbklGY2dReUJDSUU4Z1NTQkhJSGNnUFElM0QlM0Q=


45 61 73 74 65 72 20 31 3a 20 54 48 4d 7b 34 75 37 30 62 30 37 5f 72 30 6c 6c 5f 30 75 37 7d

You didn’t think it would be that easy to contain the flag, did you? :)

There are two encoded messages. Let’s start with the bottom message:

45 61 73 74 65 72 20 31 3a 20 54 48 4d 7b 34 75 37 30 62 30 37 5f 72 30 6c 6c 5f 30 75 37 7d

This is Hex encoding. We’ll use CyberChef’s “From Hex” recipe to decode:

Using CyberChef to decode a Hex string to ASCII
Easter Egg 1: decoding from Hex to ASCII

Bingo! First blood :)

Easter Egg 2

Hint: Decode the base64 multiple times. Don’t forget there are something being encoded.

Continuing with the robots.txt file, let’s look into the first message.

VlNCcElFSWdTQ0JKSUVZZ1dTQm5JR1VnYVNCQ0lGUWdTU0JFSUVrZ1p5QldJR2tnUWlCNklFa2dSaUJuSUdjZ1RTQjVJRUlnVHlCSklFY2dkeUJuSUZjZ1V5QkJJSG9nU1NCRklHOGdaeUJpSUVNZ1FpQnJJRWtnUlNCWklHY2dUeUJUSUVJZ2NDQkpJRVlnYXlCbklGY2dReUJDSUU4Z1NTQkhJSGNnUFElM0QlM0Q=

Simply browsing to “/VlNCcElFSWdTQ0JKSUVZZ…..” will not load the hidden page. We’d have to decode it first. You may have guessed that it is a Base64 encoded text.

The first round of decoding seemed to yield another Base64. After several rounds of Base64 decoding, we finally got the decoded text.

Decoding base64 with CyberChef
Easter Egg 2: decoding base64 with CyberChef

Decode from Base64:
DesKel_*************

Now we know the name of the hidden folder, we can browse to it:

URL: http://ctfvol2.thm/DesKel_secret_base

Browsing to the hidden web directory
Easter Egg 2: browsing to the hidden web directory

Right, THM is really teasing us now. No flag is visible on the page.
Have you checked the source code though to find any more clues?

Bingo!

Hidden flag in the HTML source code
Easter Egg 2: hidden flag in the HTML source code

Are you getting the hang of it yet? Another flag!

Easter Egg 3

Hint: Directory buster with common.txt might help.

It’s a straightforward process here to run the web directory brute-forcing tool GoBuster with the suggested dictionary “common.txt”.

gobuster dir -u http://ctfvol2.thm -w /usr/share/wordlists/dirb/common.txt
GoBuster results for ctfvol2.thm
GoBuster results for ctfvol2.thm
  • /button: only a button.gif loads. Saved for later inspection
  • /cat: only a cat.gif loads. Saved for later inspection
  • /cgi-bin: error. We need to call a specific script. Let’s ignore for now
  • /iphone: contains iphone.jpeg image. Saved for later inspection
  • /login: a login form with no registration. Looks very interesting!
  • /small: small.png contains Easter Egg 19. Let’s save it for now
  • /static: only loads a static.gif image. Saved for later inspection
  • /who: contains a who.gif image. Saved for later inspection

Given that the hint suggested no steganography, I did not focus my efforts on analyzing the images I found. We have also already explored the main index page and the robots.txt file.

We can safely ignore some folders such as server-status. This leaves us with /login as an interesting outlier. So we focused on this form.

Easter Egg 3: login form found in /login
Easter Egg 3: login form found in /login

We first inspect the source code to find any clues or comments. It is a good place to start to understand the code behind the login forum.

Easter Egg 3: Found the flag hidden in the HTML source code
Easter Egg 3: Found the flag hidden in the HTML source code

Lo and behold, we found our flag hiding there in the source code.

Easy day in the office :)

Easter Egg 4

Hint: time-based sqli

This challenge requires an input field, most likely a login form, search box or something similar. Hint: look back at your GoBuster results from the previous task, Easter Egg 3! Indeed, the login form at /login is our target.

The quickest way to get this flag is by using an automated SQLi tool such as SQLmap, an open-source penetration testing tool to automate SQL injection and exploitation.

First, we need to capture a POST request to the login form, and “Copy” it to a file e.g. request.txt using your browser or a proxy tool such as Burp.

Easter Egg 4: Saving an intercepted POST request to the login form
Easter Egg 4: Saving an intercepted POST request to the login form

The following commands helped me enumerate the database:

sqlmap -r request.txt --dbs --level 3 --risk 3
sqlmap -r request.txt --level 3 --risk 3 -D THM_f0und_m3 --tables
sqlmap -r request.txt --level 3 --risk 3 -D THM_f0und_m3 -T nothing_inside --columns
sqlmap -r request.txt --level 3 --risk 3 -D THM_f0und_m3 -T nothing_inside --dump-all
Easter Egg 4: Using SQLMap to attack the login form
Easter Egg 4: Using SQLMap to attack the login form

Snatched that flag from the database like a pro scavenging treasure from a dragon’s lair! Nice!

Easter Egg 5

Hint: Another sqli

This Easter Egg continues on from the SQLMap session we started earlier during the Easter Egg 4 attack. See the previous challenge if you have to restart the session.

Once you have recovered the flag for Easter Egg 4, you will be presented with a question of whether you would want to continue the attack by cracking hashes found in the “user” table. Respond with “Y” to that question.

Easter Egg 5: Found user hash for DesKel
Easter Egg 5: Found user hash for DesKel

Sticking with the default dictionary for SQLMap is fine and will yield a successful match for the password: “cutie”.

Easter Egg 5: Cracking the hash for user DesKel
Easter Egg 5: Cracking the hash for user DesKel

Let’s use the credentials we found in MySQL on the login page.

User: DesKel
Password: cutie

Easter Egg 5: Login as DesKel using found credentials
Easter Egg 5: Login as DesKel using found credentials

Once we have successfully logged in, we should be greeted with the flag!

Easter Egg 5: Flag is provided upon successful login as DesKel
Easter Egg 5: Flag is provided upon successful login as DesKel

Easter Egg 6

Hint: Look out for the response header.

This challenge is asking us to pay close attention to Response headers. This is a task for our trusty Burp Suite which I hope you still have fired up and monitoring traffic from the website for any interesting interactions or potential flag hints.

Let’s browse to the main page again and reload the page.

Easter Egg 6: GET Request/Response for the base URL
Easter Egg 6: GET Request/Response for the base URL
Easter Egg 6: The flag is sent with the Response Header “Busted”
Easter Egg 6: The flag is sent with the Response Header “Busted”

We got that sweet flag!

Easter Egg 7

Hint: Cookie is delicious

Task 7 hints at using cookies to uncover the 7th Easter Egg. For this exercise, we can use Inspector or Burp.

We need to obtain a cookie which contains the flag. After a quick check using Inspector, I did not have something meaningful or a cookie.

I’ve inspected the GET request sent to the server and it contained an interesting header parameter for “Cookie:”

Easter Egg 7: Not invited to get a cookie!
Easter Egg 7: Not invited to get a cookie!

Send the GET request to the Repeater tab to manipulate further and let’s change that value from “0 to “1". We like to be invited and a “1” looks good to us!

Easter Egg 7: Changed the cookie value to “1”
Easter Egg 7: Changed the cookie value to “1”

Let’s send this request. We should now receive the flag!

Easter Egg 7: The flag was sent after manipulating the Cookie value
Easter Egg 7: The flag was sent after manipulating the Cookie value

Job done!

Easter Egg 8

Hint: 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

The hint suggests we should consider using a different User-Agent when browsing the website and also provides us with a User-Agent we can try.

Using Burp, intercept a GET request to the main page (or /) and pay attention to the current User-Agent value.

Easter Egg 8: Current User-Agent value
Easter Egg 8: Current User-Agent value

Now let’s replace that with the User-Agent given to us in the hint.

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

Easter Egg 8: Using the User-Agent string from the hint gives us the flag
Easter Egg 8: Using the User-Agent string from the hint gives us the flag

Voila! The flag is in the Response from the webserver.

Easter Egg 9

Hint: Something is redirected too fast. You need to capture it.

For this task, we refer back to our web directory enumeration results from the GoBuster tool. As we browsed all of the found directories before we started the challenge (recon, recon, recon) we found one directory called "/ready”, where the page redirected after a few seconds.

Easter Egg 9: The “/ready” page redirected us to “gone.php”
Easter Egg 9: The “/ready” page redirected us to “gone.php”

It’s fast enough for us not to catch it by viewing the page’s source code. However, if monitor the traffic using the Burp proxy tool we should be able to spot the flag in the server’s response.

Easter Egg 9: The flag displayed before the redirection takes place
Easter Egg 9: The flag displayed before the redirection takes place

Nice and easy!

Easter Egg 10

Hint: Look at THM URL without https:// and use it as a referrer.

For this task, we found the related page by systematically inspecting the results from our earlier web directory enumeration using GoBuster.

The path for this challenge was found on /free_sub.

Easter Egg 10: the /free_sub page does not allow us to claim vouchers yet
Easter Egg 10: the /free_sub page does not allow us to claim vouchers yet

Let’s look at the Request header and the server’s response to it.

Easter Egg 10: Typical Request/Response
Easter Egg 10: Typical Request/Response

As the hint suggested, let’s add a new HTTP Request Header parameter called “Referer with the value of “tryhackme.com”.

Easter Egg 10: The flag was given after spoofing our Referer URL
Easter Egg 10: The flag was given after spoofing our Referer URL

Bingo! We have been awarded the flag for successfully tampering with our “Referer” header parameter.

Easter Egg 11

Hint: Temper the html

This one was tricky to find where on this super busy and noisy page I could find attack vectors for “tempering the HTML”. Let’s define that term first.

Tempering HTML means modifying or altering HTML code. This can involve various actions such as inserting, deleting, or modifying HTML elements, attributes, or content within a web page.

Now we know what it means, where can we find some possible targets that are candidates for tempering attempts?

In a CTF scenario, we usually look for hidden elements, comments, or metadata within the HTML source code that could provide clues for potential areas to tamper with. Since we do not have any clues provided, the next best thing to do is to focus on areas where user input or dynamic content is displayed or processed. This could include forms, input fields, JavaScript functions, AJAX requests, or any other interactive elements where HTML is generated or manipulated based on user actions or input.

One element that fits that description is the Dinner Menu drop-down.

Easter Egg 11: The dinner menu provides a ‘tamperable’ drop-down menu
Easter Egg 11: The dinner menu provides a ‘tamperable’ drop-down menu

Let’s head to our trust Burp and send a valid choice, such as “salad” or “chicken sandwich”, then click on “Take it!” and observe the request/response for that.

Easter Egg 11: Observing the behaviour of the drop-down menu
Easter Egg 11: Observing the behaviour of the drop-down menu

I have attempted to change the “dinner=” value to a few food-related items. Although I got lucky with my third choice, I want to demonstrate how you would attack this if you were unable to guess the correct “food” item.

head to a website where you can create a custom “wordlist” or dictionary of food-related items, preferably typical breakfast or lunch items.

I have used the following website. Note that you’d have to do some formatting of the text so you can have all items neatly into a text file, one item per line. Food Vocabulary Word List.

To launch a brute-force attack using Burp, we will send one request to Intruder’s Sniper Attack. make sure you select the dinner value and “Add”.

Easter Egg 11: Intruder Sniper Attack
Easter Egg 11: Intruder Sniper Attack

Load your wordlist by either copying & pasting or loading from a file.

Easter Egg 11: Loading payloads from a food wordlist
Easter Egg 11: Loading payloads from a food wordlist

Now run the attack and analyze the difference in responses. Notice the “Length” value is different for the payload “egg” compared to the rest.

Easter Egg 11: Intruder Sniper Attack Results
Easter Egg 11: Intruder Sniper Attack Results

Inspect the response associated with that request and boom, we got our flag!

Easter Egg 11: Intruder response for “egg” yields the flag
Easter Egg 11: Intruder response for “egg” yields the flag

We got the flag in the response from the server as seen above.

Easter Egg 12

Hint: Fake js file

For this task, we need to ensure we have enabled the “Script” option in both the “Target > Sitemap” and the “Proxy > HTTP History” tabs. See below.

Easter Egg 12: Enable “Script” MIME type in Target’s Sitemap
Easter Egg 12: Enable “Script” MIME type in Target’s Sitemap tab
Easter Egg 12: Enable “Script” MIME type in Proxy’s HTTP History tab
Easter Egg 12: Enable “Script” MIME type in Proxy’s HTTP History tab

In the HTTP response of the JavaScript “jquery-9.1.2.js”, you will notice a function called ahem() which contains a Hex string that must be converted into ASCII code.

The ahem() function simply takes a hexadecimal string as input, decodes it into ASCII characters, and returns the resulting string. It’s likely used to reveal a hidden flag encoded in hexadecimal format.

Hex string: 4561737465722031322069732054484d7b68316464336e5f6c337d

You can convert this string either by using RapidTables.com (see below):

Easter Egg 17: Converting the Hex string to ASCII using RapidTables.com
Easter Egg 17: Converting the Hex string to ASCII using RapidTables.com

Or you can do it beautifully on the command line using thexxd tool.

echo "4561737465722031322069732054484d7b68316464336e5f6c337d" | xxd -r -p

Easter 12 is THM{***********}

Easter Egg 13

Hint: None!

No hints were provided for this task as it was one of the easiest flags we could get. By scrolling down until you encounter a giant, crimson button, practically begging for a tap, you will be tempted into “pushing the red button”, George Bush style, and watching the world burn or at least set the digital world ablaze!

After all, who wouldn’t be tempted to orchestrate a digital do-over? Just kidding — let’s keep the peace, shall we?

Easter Egg 13: Giant Red Button that begs to be pushed!
Easter Egg 13: Giant Red Button that begs to be pushed!

Push the button, trust me it is safe to do so on this occasion :)

Easter Egg 13: Redirection to a “Ready” page
Easter Egg 13: Redirection to a “Ready” page

You will be redirected to an interim page called “ready” before you land on the final target page where the world burns.

Easter 13: The mushroom cloud containing our flag
Easter 13: The mushroom cloud containing our flag

Are you still here? That means the world didn’t all burn and you deserved your post-apocalypse flag!

Easter Egg 14

Hint: Embed image code

Browse to the base URL or the IP of the target machine, in my case, I have created an /etc/hosts entry to map the IP of the box to ctfvol2.thm.

In Burp, observe the Response body to our GET request to the base URL http://ctfvol2.thm. We notice a PNG image encoded in Base64.

Easter Egg 14: HTTP Response included an encoded PNG image
Easter Egg 14: HTTP Response included an encoded PNG image

Copy the entire value (it’s quite long!) excluding the double quotes "".

It should start with “iVBORw" and end with "AAAAASUVORK5CYII=". Use the “From Base64CyberChef Recipe.

Easter Egg 14: Using CyberChef to decode the image
Easter Egg 14: Using CyberChef to decode the image

CyberChef should be able to detect it as a PNG image. In the Output box, click on the “Save output to file” and choose a name for your PNG image.

Easter Egg 14: CyberChef detected a binary file as a PNG image
Easter Egg 14: CyberChef detected a binary file as a PNG image

Open the newly saved PNG image as it contains the flag.

Easter Egg 14: The flag file
Easter Egg 14: The flag file

Easter Egg 15

Hint: Try guest the alphabet and the hash code

Again, while inspecting all web folders we found in our previous web directory enumeration efforts, we found this game in “/game1".

We are presented with a challenge where we need to guess what alphabet letter is represented by a numeric hash value. We were given the following numbers that we must convert to letters: “51 89 77 93 126 14 93 10

Easter Egg 15: Guess the letters represented by the numeric hash values
Easter Egg 15: Guess the letters represented by the numeric hash values

I performed the usual checks first, such as the ASCII table conversion and tried to convert the numbers to letters. That didn’t work as the numbers did not seem to match.

So we have to figure this out using the game itself. By inputting a letter, you will be provided with its matching hash value. Let’s try a few values such as “A”, “B”, “a” and “Z”.

Easter Egg 15: The hash of the letter A is 99
Easter Egg 15: The hash of the letter A is 99
Easter Egg 15: The hash of the letter B is 100
Easter Egg 15: The hash of the letter B is 100
Easter Egg 15: The hash of the letter a is 89
Easter Egg 15: The hash of the letter a is 89
Easter Egg 15: The hash of the letter Z is 141
Easter Egg 15: The hash of the letter Z is 141

It seems like the numbers are sequential. However, the numbers “don’t add up”, pun intended!

For example, consider the letters “N” and “O”, where “N” corresponds to 58 and “O“ corresponds to 126. This implies that a sequential count starting from 99 may not be valid.

We have two options to discover the mappings.

Option 1: Manual Enumeration

This approach requires us to manually enter all 26 letters of the alphabet into the text box and correlate them with the respective values we receive in return. Not too painful and certainly doable.

Once we have built a table with the mappings, we can decode the numbers we were given earlier by the task (hints: 51 89 77 93 126 14 93 10).

Option 2: Automate with Linux-fu

While this method may initially seem slower than manual input, requiring time to craft an HTTP POST request and develop a bash script for automation, it offers scalability and reusability for future CTF challenges with minimal adjustments. It’s the Maverick way!

We first need to capture a request using Burp, then save it and convert it to a curl command. The next step is to cycle through the letters (A-Z) using a for loop and passing them to “answer=”.

Of course, you need to edit the hostname/URL of the target server. You’ll remember I have mapped the IP address to “ctfvol2.thm”.

#!/bin/bash

for letter in {A..Z} {a..z}; do

response=$(curl -X POST -H "Host: ctfvol2.thm" -H "User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/109.0" -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8" -H "Accept-Language: en-US,en;q=0.5" -H "Accept-Encoding: gzip, deflate" -H "Content-Type: application/x-www-form-urlencoded" -H "Origin: http://ctfvol2.thm" -H "Referer: http://ctfvol2.thm/game1/" -H "Cookie: Invited=0" -H "Upgrade-Insecure-Requests: 1" --data "answer=$letter" --compressed --silent http://ctfvol2.thm/game1/)

hash=$(echo "$response" | grep -oP '<p>Your hash:\s+\K\d+')

echo "$letter : $hash"

done

Save the bash script as answer.sh and make the file executable:

# chmod +x answer.sh

Run the script and sit back:

# ./answer.sh 
A : 99
B : 100
C : 101
D : 102
E : 103
F : 104
G : 51
H : 52
I : 53
J : 54
K : 55
L : 56
M : 57
N : 58
O : 126
P : 127
Q : 128
R : 129
S : 130
T : 131
U : 136
V : 137
W : 138
X : 139
Y : 140
Z : 141
a : 89
b : 90
c : 91
d : 92
e : 93
f : 94
g : 95
h : 41
i : 42
j : 43
k : 75
l : 76
m : 77
n : 78
o : 79
p : 80
q : 81
r : 10
s : 11
t : 12
u : 13
v : 14
w : 15
x : 16
y : 17
z : 18

We now have the correct mappings and we finally can start decoding the numbers provided to us by the task.

51 : G
89 : a
77 : m
93 : e
126 : O
14 : v
93 : e
10 : r

Let’s try this string as an answer to the challenge: GameOver

Easter Egg 15: Game Over! We got the flag
Easter Egg 15: Game Over! We got the flag

Game Over indeed! We got the flag :)

Easter Egg 16

Hint: Make all inputs into one form.

Remember the /game2 sub-directory we enumerated earlier?

This task presents us with three buttons we must simultaneously press to retrieve the flag. That is a task that can only be accomplished by using Burp proxy tool and manipulating the request since we only have one mouse!

Easter Egg 16: Press the 3 buttons simultanously
Easter Egg 16: Press the 3 buttons simultaneously

Let’s examine a typical request by pressing one of the buttons and intercepting the request using Burp.

Easter Egg 16: Submitting one button click
Easter Egg 16: Submitting one button click

One type of attack we can attempt here is tempering the HTML by submitting all three buttons in the following manner:

Easter Egg 16: Tampering with the HTML to force simultaneous button clicks
Easter Egg 16: Tampering with the HTML to force simultaneous button clicks

We magically have 3 fingers pressing on all the buttons at once. Luckily, this worked and rewarded us with the flag!

Easter Egg 16: the flag after successful tampering with the HTML
Easter Egg 16: the flag after successful tampering with the HTML

We have the flag in the response to our 3 buttons magic.

Easter Egg 17

Hint: bin -> dec -> hex -> ascii

On the main website, either in Burp or your browser’s “Inspector”, review the source code of the webpage. You’ll find a binary-encoded message embedded in the function catz().

Easter 17: Binary encoded message buried in a script
Easter 17: Binary encoded message buried in a script

Let’s copy the Binary text (below).

100010101100001011100110111010001100101011100100010000000110001001101110011101000100000010101000100100001001101011110110110101000110101010111110110101000110101010111110110101100110011011100000101111101100100001100110110001100110000011001000011001101111101

The hint suggests we need to perform the following operations to decode it: Binary → Decimal → Hex → ASCII code

We have several options

  • dCode.fr Cipher Indentifier does it in one fell swoop:
dCode.fr decoding the binary to ASCII
dCode.fr decoding the binary to ASCII
  • Rapid Tables Online Converters: Convert the Binary to Decimal and Hex first:
Easter Egg 17: RapidTables Bin to Dec and Hex
Easter Egg 17: RapidTables Bin to Dec and Hex (source: rapidtables.com)

Then convert the Hex to ASCII

Easter Egg 17: RapidTables Hex to ASCII (source: rapidtables.com)
Easter Egg 17: RapidTables Hex to ASCII (source: rapidtables.com)
  • Python conversion:

Start an interactive python3 shell using python3or ipython3, then type the following in (copy/paste also works).

# Define the binary string
b = '100010101100001011100110111010001100101011100100010000000110001001101110011101000100000010101000100100001001101011110110110101000110101010111110110101000110101010111110110101100110011011100000101111101100100001100110110001100110000011001000011001101111101'

# Convert binary to decimal
d = int(b, 2)
print(d) # Print the decimal representation

# Convert decimal to hexadecimal
h = hex(d)[2:]
print(h) # Print the hexadecimal representation

# Convert hexadecimal to ASCII
ascii_text = bytes.fromhex(h).decode('ASCII')

# Print the ASCII representation
print(ascii_text)
Easter Egg 17: Interactive Python conversion
Easter Egg 17: Interactive Python conversion

This will do the conversion from Binary to Decimal, Decimal to Hex, Hex to ASCII. The result is the hidden Easter Egg 17 flag.

Easter Egg 18

Hint: Request header. Format is egg:Yes

This task seems to be straightforward. We need to send an additional parameter called “Egg” with the value “Yes” in the request header and hopefully, we will be rewarded with a flag.

To begin, fire up Burp Suite and head over to the Proxy tab. Ensure that Intercept is toggled on so that you can catch and modify the requests. Now, fire up your browser and navigate to the base URL: http://ctfvol2.thm.

Once the request pops up in Burp’s Intercept tab, you have a couple of options. You can either tweak the headers right there in the Intercept tab or, for a bit more flexibility, shoot the request over to Repeater.

Personally, I recommend using Repeater. It allows for more experimentation, which is handy if our first attempt doesn’t quite hit the mark.

So, send the request to Repeater, and from there, start tinkering with the headers and any other parts of the request that need adjusting. Once everything looks good to go, hit that “Go” button and watch as your modified request makes its way to the server.

Easter Egg 18: Sending an Egg header parameter with the value of Yes
Easter Egg 18: Sending an Egg header parameter with the value of Yes

This seems to have worked and we now have the flag in the response!

Easter Egg 18: The flag is sent back with the server’s response
Easter Egg 18: The flag is sent back with the server’s response

Easter Egg 19

Hint: A thick dark line

The hint on this one did not make a lot of sense at first until I found the said “thick dark line” under the text “DID YOU KNOW: All swans in England belong to the queen.”

Easter Egg 19: Using Inspector to manipulate the image size
Easter Egg 19: Using Inspector to manipulate the image size

Inspecting the page in the browser shows that there is a PNG image which has been set with a height of 2 pixels, resulting in a thin, barely visible line. Since the width is set to 2000 pixels, the image will be stretched horizontally, making it appear as a long, thin line across the width of 2000 pixels.

<img height="2" width="2000" src="small.png"/>

Changing the value from “2” to “200” should make this look slightly bigger and more visible.

Easter Egg 19: The image containing the flag was made visible
Easter Egg 19: The image containing the flag was made visible

By increasing the size of the image, the hidden content within the image became visible, thus revealing the flag we were after.

Easter Egg 20

Hint: You need to POST the data instead of GET. Burp suite or curl might help.

For the last Easter Egg, we remember having seen a hint in the source code of the main page while working on other tasks. Search for “easter 20”.

Easter Egg 20: More hints embedded in the main page source code
Easter Egg 20: More hints embedded in the main page source code

Simply adding the data “username=DesKel&password=heIsDumb” to the Burp Request body and changing the method from GET to POST would not work.

We are missing a key piece; the addition of the Content-Type: application/x-www-form-urlencoded header parameter is essential because it informs the server about the format of the data being sent in the HTTP request body. In this case, the data is in the format of URL-encoded form data.

When you send data in a POST request, the server needs to know how to interpret that data. The Content-Type header specifies the media type of the request body, allowing the server to parse it correctly.

This is what our Burp Request looks like now:

Easter Egg 20: POST request with the credentials
Easter Egg 20: POST request with the credentials

We should hopefully get the flag in the Response.

Easter Egg 20: Burp Response contains the flag
Easter Egg 20: Burp Response contains the flag

Let’s try and do it the Maverick way and have fun with this last task.

Send a GET request to filter for the task’s hint:

$ curl -s http://ctfvol2.thm | grep "easter 20"

<h3> Hey! I got the easter 20 for you. I leave the credential for you to POST (username:DesKel, password:heIsDumb). Please, I beg you. Don't let him know.</h3>

We now send the POST request using cURL:

$ curl -s -d "username=DesKel&password=heIsDumb" -X POST http://ctfvol2.thm | grep -i "easter 20"
<h3> Hey! I got the easter 20 for you. I leave the credential for you to POST (username:DesKel, password:heIsDumb). Please, I beg you. Don't let him know.</h3>
Okay, you pass, Easter 20: THM{*****************} <br><br><br>

Let’s break the command down:

  • -s: Silent. Suppresses the progress meter and other unnecessary info.
  • -d “<data>”: Specifies the data to be sent with the request. In this case, it’s a form-urlencoded string containing two key-value pairs: “username=DesKel&password=heIsDumb”.
  • -X POST: Specifies the HTTP request method to be used.

Note: By default, curl sets the Content-Type header to application/x-www-form-urlencoded when you use the -doption to send data with a POST request. However, in some cases, the server may require the Content-Type header explicitly to be set, especially if it expects a specific format for the request body.

Conclusion

As we wrap up TryHackmes’s beginner CTF adventures with this second volume in the series, it’s worth noting their value as excellent introductions for beginner CTF players. Vol 2, especially, focused on entry-level web challenges, offering a good learning experience.

If you have’nt checked out the first volume which focuses on general CTF skills, see my write-up “TryHackMe CTF Collection Vol. 1”.

Let’s take a moment to reflect on the strategies that made tackling the challenges more effective and fun. The key lesson learned? Stay flexible in your approach. Rather than rigidly following tasks sequentially, being adaptable can lead to unexpected flag discoveries.

At the start of any web-based CTF challenge, kicking off a web directory enumeration (brute-forcing) can help you stay organized and identify potential leads to pursue further.

⚠️ Just remember to play by the rules and not overload the server. Some real-world CTFs strictly prohibit the use of scanners on their live challenge servers. They usually provide a Docker container for you to blast locally to your heart’s contents.

For web challenges, always keep Burp Suite on standby. You never know what useful clues you might uncover while peeking at the traffic.

When it comes to solving puzzles, simplicity wins the day. It’s easy to get caught up in overthinking things, but more often than not, the solution is right in front of us.

Don’t be shy about leaning on those hints. In the world of CTFs, every breadcrumb counts.

So, as we bid adieu to CTF Collection Vol 2, let’s carry these lessons forward. Stay flexible, keep it simple, and never underestimate the power of a good clue. With these lessons and some practice, we’ll be ready to tackle our next CTF challenge.

What’s next?

Thank you for your support and for visiting my blog.

Please follow me for more future content around CTFs, Ethical Hacking, Certifications, and much more. I would appreciate any comments, feedback, or queries you may have.

Happy Hacking!

CyberSecMaverick

--

--