ShellShock: 'bash' vulnerability

A vulnerability in 'bash', popularly called 'ShellShock' has been all over the news this week. I've spent a lot of time talking to clients about it over the last couple of days, and checking up on systems, so I thought I'd write some of those conclusions down.

In case you've been hiding under a rock this week, or are reading this far into the future, here's some articles:

What is this vulnerability, really?

Under certain circumstances, the 'bash' shell can execute commands passed to it in an environment variable, even if it isn't asked to. This is surprising behaviour indeed, although it is arguable that it isn't a critical failure in bash but rather a misuse of bash in situations where another shell would have been more appropriate.

But basically, bash scripts run in a situation where environment variables may be set by untrustworthy people may be suspect.

1. DHCP Clients

One potential target identified in the Redhat article above is the DHCP client. The DHCP client, generally /sbin/dhclient, communicates with a DHCP server to obtain some system parameters and then passes those parameters to a script to set up the system. On linux systems, that script is generally a bash script called /sbin/dhclient-script, and it is run as root.

The problem here is that the parameters come from the DHCP server, and are passed to the script as environment variables. If the DHCP server passes parameters with the special ShellShock format, this would cause the DHCP client script to execute those commands as root, a very serious security problem indeed.

The good news is that I had a look at ISC DHClient, as used in Ubuntu, and both an old version (Ubuntu 10.10, ISC DHClient 3.2.3) and a recent version (Ubuntu 14.04, ISC DHClient 4.1.4) included code which explicitly filters parameters received from the DHCP server before passing the the dhclient script.Unless I've missed something there, all parameters are filtered, and any parameters which don't look right are flagged with a cheery:

dhclient: suspect value in server_name option - discarded

This may not be true for all DHCP daemons however, so this is still a potential attack vector worth considering. The client script could be run under a less vulnerable shell, though, or could be replaced with a more modern scripting language altogether.

2. SSH with restricted commands

The idea here is that you're allowing a remote user restricted access to run a particular command on a system, and only that command. This is generally done using the ForceCommand directive in the sshd config.

The problem is, ssh copies across the TERM environment variable, and may also set the SSH_ORIGINAL_COMMAND environment variable. If the user's shell is bash, or they can somehow else run a bash script, this will expose this vulnerability. This lets a user bypass the restrictions on the command to be run.

As with the above, a more security-concious shell should be used in these circumstances.

3. CGI and Bash

The rather ancient CGI protocol transfers HTTP headers to scripts using environment variables. If those scripts are written in bash, or call bash scripts without cleaning the environment, they're going to allow a remote user to run arbitrary commands as the webserver user. This is not good.

However, using CGI is a bit anachronistic these days: if I recall correctly we were all jumping ship for mod_perl back in 2000 or so, and since then WSGI and very many others have pretty much taken over, and moved away from setting environment variables.

Plus, to activate ShellShock, you need to actually call a bash script. Please don't tell me that anyone sane writes CGI scripts in bash. (Embedded devices sometimes have their web interfaces depend a lot on Busybox, but that uses Ash not bash, and ash is not believed to be vulnerable at this point.)

And while it is not at all unknown for Perl scripts to call out to external commands using system, or backticks ` ` , these functions either call the external command directly without invoking a shell, or invoke the plain-old-bourne-shell /bin/sh instead of the far more complicated bash. Python's os.system, likewise.

If your distribution symlinks /bin/bash to /bin/sh, that's just silly. Bash is unnecessarily complicated for this job.

EDIT1: It's been brought to my attention that having ``/bin/sh`` as a symlink to ``/bin/bash`` is actually rather common across Redhat, Debian and many others. I stand by my opinion that this is silly.

EDIT2: apache2 mod_perl2 also sets the CGI variables if you have the "`+SetupEnv <>`_" flag set.


So, is ShellShock the end of the world or not?

I'd argue it is nowhere near the disaster that the media have made it out to be. Most servers won't actually expose the vulnerability.

EDIT3: The situation is a little worse than I at first thought ...

However, the systems most likely to suffer from it are precisely those systems which are rarely updated or maintained: elderly utility interfaces, embedded systems, set top boxes, that kind of thing. Tracking down and fixing these systems will be tricky.