Sunday, 21 December 2014

Remote code execution on misconfigured systems using Werkzeug

One of the most popular WSGI utility frameworks for Python is Werkzeug. It simplifies the handling of HTTP connections within your Python application but also provides a powerful debugger that permits one to execute code from within the browser.

While the provided link warns those to not enable the debugger on anything production, it is often ignored or forgotten about and ends up being enabled in the first place. It is possible to search for systems on the Internet that have the debugger enabled and execute Python code remotely.

It should be noted that this affects both the Flask and Django frameworks mainly but could be used elsewhere.

Revealing and using the debugger

Getting the debugger to reveal itself is fairly simple: cause an exception. This can be achieved by writing some faulty code or by simply making it happen yourself such as in this code example using the Flask framework:
from flask import Flask

app = Flask(__name__)

def main():
All you need to do is execute the above as a Python script and the following should be outputted:
$ python
 * Running on
 * Restarting with reloader...
Now view the page via the URL it provides and you'll have access to the debugger as follows:

And as you can see it is pretty straightforward too:
You can view the code by highlighting over the code on the right.

Python code can be executed as if you were running the interpreter locally.

Finding affected hosts

Finding hosts is trivial using a search engine such as Google or a service like Shodan.

At the time of this writing, using Google does not net any results but previously during some research on this matter it did. It appears that any services that are indexed are being taken down fairly quickly.

If you wanted to try a Google search for the future, this search may provide a result:
intitle:"Werkzeug Debugger" "You can execute arbitrary Python code in the stack frames"
However, Shodan makes it easier to find servers that specifically run Werkzeug.

Finding servers that error out is fairly simple.
Some fine-tuning is required to find hosts that can have the code executed but they are there.

It should be noted that the debugger can be activated even without executing the HTTP server internally. Documentation exists that allows one to enable the debugger via Apache if you so dare.

It goes without saying that you should not execute any code if you run across a machine that has the debug mode enabled.

Preventing your application from being vulnerable

If you're developing an application that makes use of Werkzeug, you should avoid hard-coding a debug mode into it.

My suggestion is to try something like this:
import sys
if __name__ == '__main__':
    debug = 'debug' in sys.argv
This should require you to add 'debug' to the command line arguments when running the code, allowing you to just leave it to local development.

Wednesday, 10 December 2014

The 'joke' behind the signed Sony malware

Last night, I tweeted out a series of tweets correcting the stories issued by Kaspersky and ArsTechnica regarding the origin of the signing of the malware that had infected Sony. As a result, it got picked up by a CSO Online sometime after I had gone to bed and in the morning I had a  bunch of people on Twitter asking me questions.

The origin of the story is that a researcher (who wishes to be referred to as "yosposbithc") in an IRC channel I am in had been going through the Sony data and came across some PFX files used for code signing. With luck, he had quickly determined that the password to the file was in fact the filename itself ("spe_csc").

\Cert2\USERS\AMcMillian\Sony\Projects\The Big Picture\Certificates\spe_csc.pfx

In discovering this, we were asked, "what should I sign" by him. I initially suggested just signing 'calc.exe' since that tends to be used for demonstrating any RCE vulnerabilities. However, it was then decided that using a source from Malwr that the actual attacking malware used on Sony would be used instead.

Screenshot from Kaspersky's recent article
It was uploaded to VirusTotal and then tweeted out by myself shortly after. The time between it being signed and then showing up on VirusTotal itself was something like 10 minutes. It has not been used in the wild, I doubt that the researcher executed it at all, and it in its signed form is not available for download.

Kaspersky has since updated their article with the following:

So far, we have not encountered the signed sample in the wild. We've only seen it submitted to online malware scanning services. However, the existence of this sample demonstrated that the private key was in the public domain. At that point we knew we had an extremely serious situation at hand, regardless of who was responsible for signing this malware.
Reports indicate the "researcher" reached out to the certificate authorities to get the certificate revoked after submitting the malware online. The certificate would have been revoked without the creation of new malware. There really was no need to create new malware to prove that the certificate hadn't been revoked yet.
What is said here is true. Having myself previously worked at an anti-virus vendor, I can safely say that Kaspersky more than likely got the sample from VirusTotal as that was the case for when I still worked in their industry.
The certificate was revoked on December 7

However, Kaspersky erroneously reported that the certificate had yet to be revoked at the time of their writing. This was not the case as the researcher had reached out to DigiCert shortly afterwards and it was revoked on the weekend.

There is not much more to this story other than that. I do not have a copy of the certificate myself as I have chosen to not touch the Sony data. The unsigned malware itself is available from the Malwr link I previously supplied and copies of the signed malware are floating about now.