Bypassing Authentication

‘So how would I go about actually bypassing the authentication?’, you might be asking yourself. Take the following example (which you can follow along if you copy the code earlier in this blog post):

Prerequisites

Access to a Python interpreter (I’m using 3.6)

Having Flask installed by using pip install flask (preferably in a virtual environment so it won’t make your system messy)

Before you can do anything, you’ll have to start the Flask application like so:

$ python server.py

Obtaining a session cookie

To obtain a session cookie, we’ll have to probe the server for a possible cookie. I did this by simply making a curl request to the server with the -v option to get verbose output (which prints the headers of the request), but you could also simply visit the web page and use a browser extension like EditThisCookie to get the contents of the cookie.

The server returning a session cookie

Do note that not all servers will instantly give you a session; some will only do this when trying to flash an error whereas others will only do so after logging in. You’ll have to figure this out on a case-by-case basis. For demonstration’s sake, our example server forcibly sets a session no matter what.

Creating the wordlist

While it would be possible to brute-force each possible combination of letters, numbers and characters; a better approach would be to create a wordlist with known sources where developers might have posted their secret keys.

For this, I immediately thought of the following two locations: GitHub (as seen earlier) and StackOverflow (which generously allows you to download every single comment, post and edit ever made on the platform through archive.org).

For GitHub, I simply made a throwaway script which tried going over as many commits and files with the search term secret_key as possible, and for StackOverflow I iterated over each possible piece of text and tried to match possible secret keys with the following regular expression:

Regular expression used to capture the secret keys

After a week of scraping GitHub posts on the background of my VPS, and combing through every StackOverflow post, comment and edit ever made I was left with a total of 37069 unique secret keys.

Cracking the signature

By combining a wordlist, the cookie we just obtained and parts of Flask’s session management code; we’re able to validate each secret key against the cookie to see if the signature is valid. If no error is raised, we’ll know we have a valid signature, which means we’ll have figured out the server’s secret key!

A sample session-cracking application

Crafting a session cookie

If our script was successful, we should now have found the server’s secret key! By now taking the same code, but instead of ‘load’ the session we ‘dump’ the session, we can create a cookie with any data we like.

Crafting a new session

If we were now to make a request to the same server, it should accept our crafted cookie, as it matches the expected secret key, which should trick it into believing we’re logged in.

Using our crafted cookie to bypass the server’s authentication

I would like to point out that just because you can modify a session, doesn’t mean you’ll instantly be able to bypass an authentication mechanism. Not all systems are built the same and you’ll probably have to do some research to figure what and if it is possible to use this attack to your advantage.

Flask Unsign

Due to the fact that I had to do quite some work to figure out exactly how Flask handled their sessions, I decided to put the code into an easy-to-use command line tool which lets you scan your own server’s for this issue.

To install the tool, simply head over to your terminal and install it using pip:

$ pip install flask-unsign[wordlist]

If you don’t want the fairly bulky wordlist file included and only want to use the code itself, you can simply omit the [wordlist] from the command.

$ pip install flask-unsign

If you wish to see the source code, you can find this over on my GitHub.

Usage

Flask-Unsign has three main use-cases: it lets you: Decode, Sign and Unsign (crack) a cookie, with built-in HTTP support, which prevents you from having to open up your browser.