Flask RCE Debug Mode

Slack Group

Before we get started I have started a slack group dedicated to hacking. We welcome everyone from beginner to advanced to join. I will be on everyday answer questions, doing CTFs, and talking about cool hacks. If you enjoy hacking and are looking for like minded people join below:

NEW Hacking Group Slack Channel

Introduction

Flask is a very popular Python library for creating websites and APIs. I personally use it a lot in my projects and I see it deployed in production environments as well. When software engineers are developing applications they often enable debug mode for testing purposes. If this mode is enabled on production servers it can lead to remote code execution (RCE).

Werkzeug Debug Mode

Werkzeug is a web server gateway interface (WSGI) web application library which Flask heavily relies on. A WSGI is a calling convention for web servers to forward requests to web applications or frameworks written in the Python programming language.

While developing applications it is very common for engineers to enable debugging to make their lives easier. What most people don’t know is that enabling the debugger on Werkzeug can lead to RCE. This is a known problem and the creators of this library clearly point this out on their website and in their code documentation as shown below.

Warning message to developers about using debug mode

Back in 2015 Patreon got hacked using this technique which lead to 15 gigabytes of data being stolen and published online. More information about this hack can be found below:

https://arstechnica.com/information-technology/2015/10/gigabytes-of-user-data-from-hack-of-patreon-donations-site-dumped-online/

We can easily replicate this vulnerability with the following python code:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def main():
    raise

app.run("0.0.0.0",debug=True)

Notice that debug is set to “True”. If we run the following script we should get a message warning us about enabling debug mode as shown below.

Debug mode warning message

To help prevent this vulnerability you must enter a random PIN to use the vulnerable feature. You turn the security PIN off by setting the following environment variable:

WERKZEUG_DEBUG_PIN=off

You may be thinking that no one would actually do this but just like Patreon thousands others have turned this security feature off as shown in the following github search:

Github search for debug pin off

Checking for this vulnerability is extremely easy. Go to /console and if your able to execute python commands the system is vulnerable. This will allow you to execute shell commands as shown below:

import subprocess;out = subprocess.Popen(['whoami'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT);stdout,stderr = out.communicate();print(stdout);
Debug Command Shell

As you can see above I was able to execute the “whoami” command. This could also be used to receive a shell from the victim.

If you see the following message this means the security PIN is enabled and you will need to know this in order to execute shell commands.

Security PIN enabled

If you’r looking to easily test for this vulnerability check out the following Metasploit module:

https://www.rapid7.com/db/modules/exploit/multi/http/werkzeug_debug_rce

Note this vulnerability doesn’t just impact Flask it can be found in Django as well and im sure a bunch of other web frameworks.

Conclusion

Flask is one of the most popular Python libraries for building APIs. If your not careful you could introduce a vulnerability which would allow hackers to gain RCE on your system. Debug mode is dangerous and disabling the security pin is even more dangerous.