Shellshock: Bashing Bash for Fun and Profit

The latest fundamental computer security vulnerability, termed Shellshock, was discovered by a vulnerability researcher Stephane Chazelas (a linux shell expert living in the UK) which allows for arbitrary code execution on linux or mac computers through creating a custom environment variable. If you haven’t already, you need to patch your system(s) and you might be hearing a lot more about this in the near future.

Since it is common for a lot of programs to run Bash shell in the background, a number of devices (the “internet of things”) may be vulnerable. I’m used to really complicated exploits, but this is really a one-liner:
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
Because of this simplicity there is massive speculation of an imminent arrival of a worm that can traverse multiple vulnerable systems.

Why does this matter?

Bash is everywhere — particularly in things that don’t look like computers (like pacemakers or cars). It is a UNIX like shell, which is on nearly every Linux system. From its creation in 1980, bash has evolved from a simple terminal based command interpreter to many other fancy uses, particularly as linux became present in our phones, cars and refrigerators.

An exploit that operates at this level will be lurking around in all various and sundry sorts of software, both local and remote. Embedded devices often have web-enabled front-ends to shuttle user input back and forth via bash shells, for example — routers, SCADA/ICS devices, medical equipment, and all sorts of web-connected gadgets are likely to be exposed. Additionally linux distributions and Mac OS are both vulnerable–even though the major attack vectors that have been identified up to this point are HTTP requests and CGI scripts.

This all happens because bash keeps executing after processing function definitions; it continues to parse and execute shell commands following a function definition. Especially problematic is the ability for environment variables with arbitrary names to be used as a carrier for a malicious function definitions which containing trailing commands. In particular, this enables network-based exploitation and therefore propagation on a large scale. To get some feel for how easy this can propagate see the example below where a simple wget (just a request for a web page) executes this in one line:

wget -U "() { test;};/usr/bin/touch /tmp/VULNERABLE" myserver/cgi-bin/test

How does it work?

The NIST vulnerability database gives the flaw 10 out of 10 in terms of severity and provides the short, but dense, description:

GNU Bash through 4.3 processes trailing strings after function definitions in the values of environment variables, which allows remote attackers to execute arbitrary code via a crafted environment, as demonstrated by vectors involving the ForceCommand feature in OpenSSH sshd, the mod_cgi and mod_cgid modules in the Apache HTTP Server, scripts executed by unspecified DHCP clients, and other situations in which setting the environment occurs across a privilege boundary from Bash execution.
Authentication: Not required to exploit
Impact Type: Allows unauthorized disclosure of information; Allows unauthorized modification; Allows disruption of service

Let’s unpack this, because it didn’t make sense to me on a first read.

The key insight is that Bash supports exporting not just shell variables, but also shell functions to other bash instances. Bash uses an environment variable named by the function name, and a function definition starting with “() {” in the variable value to propagate function definitions. What should happen here is that bash should stop after processing the function definition, however, it continues to parse and execute shell commands after the function definition. To make this concrete, assume that you set an environment variable:

VAR=() { ignored; }; /bin/exploit_now

This will execute /bin/exploit_now when the environment is imported into the bash process. The fact that an environment variable with an arbitrary name can be used as a carrier for a malicious function definition containing trailing commands makes this vulnerability particularly severe; it enables network-based exploitation.

But, how could I be vulnerable?

On first blush, why should you care? Your are not giving shell access to strangers. To characterize the initial vulnerability space, let’s look at web applications. Web applications connect most all the networks in existence and form a large part of our digital economy, but the big problem is that web applications aren’t limited to web-browsers. Your router at home has a web-server as do other embedded devices (such as my thermostat).

When one requests a web page via the HTTP protocol, a typical request looks like this:

GET /path?query-param-name=query-param-value HTTP/1.1
Host: www.mysite.com
Custom: some header value

The CGI specification maps all parts to environment variables. With Apache httpd, the magic string “() {” can appear in the values above. An environmental variable with an arbitrary name can carry a nefarious function which can enable network exploitation.

A (little) bit deeper

To understand a little more of what happens, consider the following:

$ env x='() { :;}; echo pwned' bash -c "echo this is a test"

The result above is because the parsing of function definitions from strings (which in this case are environment variables) can have wider effects than intended. Vulnerable systems interpret arbitrary commands that occur after the termination of the function definition. This is due to insufficient (or non-existent) constraints in the determination of acceptable function-like strings in the environment.

If the function defined in x does some sneaky underhanded work, there is no way that bash can check if the return value if function x is real. Notice the function is empty above. An unchecked return value can lead to script injection. Script injection leads to privilege escalation and privilege escalation leads to root access. To fix this, most patches will disable the creation of x as a function.

Good luck, and I hope this doesn’t overly burden the well-meaning folks out there who just want computers to work securely so we can do our jobs. Right now the race is on. Vulnerability was found yesterday, exploits showed up this morning. Metasploit already has a plugin. I hope your patch gets there before the exploits do. In any case, the smart money is on the arrival of a full blown worm in the next several days. Get ready.

Some deeper (better) reading:

  • https://securityblog.redhat.com/2014/09/24/bash-specially-crafted-environment-variables-code-injection-attack/
  • http://www.theregister.co.uk/2014/09/24/bash_shell_vuln/

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.