Thursday, September 25, 2014

Shellshock! A forgotten feature becomes a major security hole

My prior post, was that my next series would be about HTML5 frameworks for mobile. But I've been busy on other projects, and mobile stuff hasn't been on the high-pri list. Speaking of today's high-pri list, how about that Shellshock bash bug?

I'm gonna jump on the bandwagon a bit here,  and admit that this bug should scare the heck out of you. If you run anything that hands out shells to the unknown Internet, then anybody smart enough to make a fake User Agent can run arbitrary shell commands on your server. I tried it and verified it: it took me 30 minutes to write a working exploit, starting from when I first typed "bash bug" into Google.

In a Nutshell


What is the "bash" Unix shell? Briefly, this means "the thing that's used to type commands after you connect via SSH" but for web folks working in PHP this also means "the thing used to execute command-line scripts such as passthru() and the `` operator" If you use shell_exec() et cetera then you're using a shell, and it's probably bash.

Bash has a feature going back some 25 years, that it can auto-execute code when you start a new shell. This code will conveniently set "environment variables" which facilitate other work. The problem with this very-obscure feature, was only discovered last week: Web programs such as CGI and PHP also set environment variables, some of them read directly from the browser without any sanitization or checking. So any browser on the Internet, may be able to:
  • Send an environment variable that will be passed as-is to your shell. The most common such variable would be your User Agent (your browser's name), which is loaded as-is into an environment variable called HTTP_USER_AGENT
  • Which your shell would then interpret as a command to be executed before it executes your shell command.
But that means technical skill to set your browser's User Agent, right? Wrong. Browser add-ons already exist to set your User Agent string to some common values (Firefox can pretend it's GoogleBot) and it's also trivially simple to set it in your browser's config. (Firefox is described below) Again, I hadn't heard about this bug before today and it took me about 30 minutes to craft an exploit against one of our servers which was vulnerable.

The Limits


The exploit allows command execution, only if the following conditions are met:
  • A remotely-executable program exists which does not require trust and authentication, e.g. a PHP script or a CGI script which executes under bash. Services which do not execute shells, or which execute them only for trusted individuals, are of significantly less concern, e.g. FTP and MySQL servers don't run subshells and don't read user-supplied data for environment variables anyway, and SSH only gives you a shell after you have logged in.
  • That program executes a subshell. In PHP this is the `` or shell_exec() functions. Any program which does not use those functions is fine... until you need to use those functions.
  • The system's default shell /bin/sh is in fact Bash and not an alternative such as ksh or dash. On Ubuntu 12.04 /bin/sh is in fact Dash and is not affected by this bug unless you have a CGI script which specifically uses Bash.

A Quick Test

Login to your server, and run this from your shell:
env x='() { :;}; echo vulnerable' /bin/sh -c "echo this is a test"
Hopefully you'll see an error about a function definition:
    ./bash: warning: x: ignoring function definition attempt

If you see "vulnerable" in the output, then your system shell is Bash and is a version which is potentially affected by this issue. And remember, it's not Bash here at the command-line that should worry you, but any web program which launches shells.

If you don't see vulnerable, you may not be entirely safe. Try again, this time replacing /bin/sh with /bin/bash Even if Bash isn't your system default shell, any CGI programs or launched shells whicyh specifically use Bash may still be affected.

A Quick Exploit (A)

Like I said, it's not rocket science, just setting your User Agent.

Load up Firefox.

Go into about:config Create a new value (or edit if it already exists) called
general.useragent.override
and set it to this odd-looking string:
() { :; }; touch /tmp/shellshock
Congratulations, your browser will now supply an auto-executing function in the environment... if you hit up something that spawns a subshell.

On your webserver, try creating this very small PHP program. Or, try simply hitting any program of your own which uses shell_exec() or similar functions.
<?php
# anything that uses any shell function, will trigger the bad HTTP_USER_AGENT variable
print "Tmp Folder:\n";
passthru('/bin/ls /tmp');

Now visit that PHP program in your browser, and then have your sysadmin check out the new /tmp/shellshock file. And imagine for a moment what happens if someone were to do this repeatedly, and knew their way around a shell.

P.S.: Don't forget to "reset" that User Agent override when you're done.


Another Quick Exploit (B)

For command-line wonks, here's an even simpler version of the exploit using cURL from the command line:
curl 'http://www.example.org/whatever.php' -H 'User-Agent: () { :; }; touch /tmp/shellshock'
Point it at any web service which uses a subshell (e.g. a PHP using shell_exec() ) and they'll be surprised to find a new file on their server.

Okay, I'm Scared... Now What?

The most expedient fix, is to upgrade bash. There is already a patch (4.3-25) available.

This page gives practically copy-and-paste instructions:
    https://news.ycombinator.com/item?id=8364385

Now give everything a test again, and breathe a sigh of relief!

Update: Looks like the 25 patch to Bash fixes only one of two so-far-determined methods of attack. A second version has been named CVE-2014-7169 and is not fixed by 4.3-25  The "A Quick Test" for this second vulnerability is:
env X='() { (a)=>\' sh -c "echo date"; cat echo
If the output has the date in it, then the date command was executed and you're still vulnerable.



No comments:

Post a Comment

Note: Only a member of this blog may post a comment.