#!/usr/bin/env python3 from burvesigner import BurveSigner from flask import Flask, make_response, render_template, request, flash from hashlib import sha256 from time import time import base64 import json import secrets import sqlite3 app = Flask(__name__) app.config["SECRET_KEY"] = secrets.token_hex() db = "database.db" signer = BurveSigner() b64p = lambda x: x + b"=" * (-len(x) % 4) b64u = lambda x: x.rstrip(b"=") b64e = lambda x: b64u(base64.urlsafe_b64encode(x)) b64d = lambda x: base64.urlsafe_b64decode(b64p(x)) def generate_token(user, role): payload = b64e(json.dumps({ "user": user, "role": role, "exp": int(time()) + 300 }).encode()) signature = signer.sign(payload) token = payload + b"." + signature return token.decode() def validate_token(token): assert token.count(".") == 1 payload, signature = token.split(".") assert signer.verify(payload.encode(), signature.encode()) payload = json.loads(b64d(payload.encode()).decode()) assert payload.get("user") and payload.get("role") and payload.get("exp") user, role, exp = payload.get("user"), payload.get("role"), payload.get("exp") assert int(time()) < exp return [user, role, exp] def create_response_data(user, role): data = f"Welcome, {user}! " if role == "admin": try: data += open("/flag.txt").read() except: data += "Flag is missing, please contact probset" else: data += "Only admin can access the flag" return data def get_role(username, password): connection = sqlite3.connect(db) cursor = connection.cursor() cursor.execute( "SELECT role FROM users WHERE username = ? AND password = ?", (username, sha256(b"gema" + password.encode() + b"steg").hexdigest()), ) role = cursor.fetchone() connection.close() assert role return role[0] @app.route("/params", methods=["GET"]) def params(): return f"
{json.dumps(signer.get_params(), indent=2)}
" @app.route("/", methods=["POST", "GET"]) def index(): if request.method == "POST": username = request.form.get("username") password = request.form.get("password") try: assert 2 <= len(username) <= 32 assert 2 <= len(password) <= 32 role = get_role(username, password) token = generate_token(username, role) validate_token(token) response = make_response(render_template( "index.html", data=create_response_data(username, role) )) response.set_cookie("token", token) return response except: flash("Invalid username and/or password") return render_template("index.html") else: token = request.cookies.get("token") if token: try: username, role, _ = validate_token(token) return render_template( "index.html", data=create_response_data(username, role) ) except: flash("Invalid token") return render_template("index.html") else: return render_template("index.html") if __name__ == "__main__": app.run(host="0.0.0.0", port=80, debug=False)