Understanding the Shellshock Bash bug

So you may have heard about the Bash bug called Shellshock and the hype that goes with it. You may even have also seen the mysterious looking command string to check if you are vulnerable to Shellshock:

env x='() { :;}; echo YOU ARE VULNERABLE’ bash -c ‘echo hello there’ 

OK, so if you are not familiar with the Unix/Linux Bash Shell, this may look daunting. In this post I aim to explain the behaviour that leads to Shellshock, how this weird statement works and how it might affect your internet of connected things.

When I started to look at the Shellshock issue, I found it hard to get my head around the problem so this post serves as a guide to how I came to understand the problem and how to check for the vulnerability.

This is a two part post, this post deals with understanding the behaviour that leads to the Shellshock vulnerability and a second post (Exploiting the Shellshock bug) provides a walk-through of exploiting this behaviour against a test web-page.

In the examples, I’m using a version of Kali Linux that has not been patched; it runs as a Virtual Machine and sits behind a router and firewall so is reasonably safe. If you are interested in experimenting as I have I would certainly suggest this is the way to go.

If you have live systems that are seemingly vulnerable to Shellshock, then it goes without saying that you should consider applying the relevant patches.

Before we get started – remember that testing for Shellshock on systems that you do not have permission to do so may mean you fall foul of local laws. If in doubt ask permission from the system administrator.

Note: that this is considered the basic or classic Shellshock test but there are a number of other patterns that can and should be used to fully test the viability of Shellshock. This becomes important if you are testing a system post-patching.

Let’s start with Bash

Bash is a command line interface that is common to many Linux and Unix Operating Systems (OS) that allow you to interact with the OS; in the Unix/Linux world, Bash is known as a Shell, in the windows world you’d know these as the Command Prompt. In Unix/Linux, Bash is probably the most common default Shell but is certainly not the only one.

So first off the Shellshock issue only affects Unix/Linux based systems that are running the Bash Shell. If you are running Windows, this vulnerability should not impact you, but Linux in particular is widely used as a web-server for web-sites and embedded into devices such as routers so you may be affected, but just don’t realise it.

If you have a Unix/Linux machine you can check what your default shell is using the following command:

echo $SHELL

If it displays /bin/bash then your default is a Bash shell.

Shellshock_01

Within the Bash shell, we can use the command bash -c <command> to start a new instance of bash, run the commands and then exit that shell instance so for example the following command would evaluate the commands between the single quotes and then execute theses in a sub-shell:

bash -c ‘echo testers rock’

Shellshock_02

While this example is not particularly impressive, this capability has its uses. One challenge is that any local functions and environment variables are not passed into the sub-shell so if we created a function as follows:

WhatAreTesters() { echo ‘they are awesome’; };

And then called this function with the command WhatAreTesters we can see that the function gets called.

Shellshock_03

Note that the commands that make up the function are enclosed within a pair of curly brackets and terminated by a semi-colon. (i.e. { <some commands> };) the reason for emphasising this will become apparent when we talk about the Shellshock bug.

However if we attempt to run this in a sub-shell using the bash -c command, we can’t as the sub-shell doesn’t know about the function we created.

Shellshock_04

One way around this is to use the export -f command to export the function and make it available to the sub-shell; this works because the export command adds the function to the list of environment variables and these are passed to the sub-shell as part of its context.

Shellshock_05

In the above sequence of commands, we have first used the grep command to display any lines in the environment variable file that contains the text WhatAreTesters. The first time we run this, there is no output since the function has not been exported to the environment variables file, after the export command, we use the grep command again and we can see that there is now a variable called WhatAreTesters and this is equal to the string () { echo ‘Testers are awesome’ }.

Now if we call the bash -c command we can observe that this environment variable has been passed to the sub-shell as part of its context.

Shellshock_06

Another option is to use the env command to create a modified environment that is made available to the sub-shell as follows:

Shellshock_07

We can also define functions in this way and pass them to the sub-shell.

Shellshock_08

If we use the grep option again (within the sub-shell) we can see that the function we created using the env command has been passed to the sub-shell as part of it’s context.

Shellshock_09

An important point to note, is that we created the function but it is not executed in the sub-shell until we explicitly call it.

On to the Shellshock bug

So all that is normal, useful and expected behaviour within the Unix/Linux world but there is a defect in Bash that, if additional commands are placed after the function definition but within the pair of single quotes, then Bash interprets these as valid commands and executes then. If you remember, when we created a function, the content of the function is not executed unless it is called explicitly.

So to see this in action, the following command sequence creates a function as before, but appends some additional commands (highlighted in yellow) and although we are not calling the function explicitly, the additional commands are executed.

Shellshock_10

The output shows the text Testers Are Cool followed by the text This is a test; if Bash has been working as expected then we should only have seen the text This is a test. In fact, if you enter the above command into your Bash shell and you see both sets of text as above, then you are vulnerable to Shellshock.

Shellshock is a vulnerability caused by the Bash shell automatically executing commands inserted after a function definition; if exploitable then it would allow Arbitrary Code Execution (ACE) you’re your machine which is considered a significant vulnerability.

As mentioned in the early part of this post, a command structure such as the following is now routinely being used to check for the existence of the Shellshock.

env x='() { :;};echo YOU ARE VULNERABLE’ bash -c ‘echo hello there’ 

This is a similar format to the examples we gave before except for the someone esoterically looking function definition { :;); – this is just a null function, the semi-colon doesn’t do anything (previously we had statements such as echo Testers Are Cool).

If you execute this in the Bash Shell and you see the text YOU ARE VULNERABLE displayed, guess what…you are vulnerable.

However, there is a difference between something being vulnerable and something being exploitable. The examples above work because someone has access to the command line shell; without this the vulnerability cannot be exploited. The challenge is that we may not be fully aware of how components we rely upon work and they may use Bash in the background and so expose the vulnerability.

In the next post, we’ll look at an example of the Shellshock bug being exploited via a web-site.