Topics covered
Introduction What is Shellshock? When can it be exploited? How to check if you are vulnerable Checking your bash version Running the fancy one-liner on your terminal Technical insights of Shellshock The basics of bash shell variables Introducing bash environment variables Exporting bash functions to environment variables Parsing function definitions from strings The actual vulnerability Possible exploits
Introduction
Shellshock is now one of the buzzwords in the security community. After “Heartbleed”, it is the most widely spread word in the recent past. This article first gives you the internal details of the vulnerability. Then it walks readers through the step-by-step procedure of how to set up their own lab to demonstrate a Shellshock vulnerability along with the exploitation part.
What is Shellshock?
Shellshock is a vulnerability in GNU Bourne Again Shell (BASH), which allows an attacker to run arbitrary commands using specially crafted environment variables.
When can it be exploited?
This is the most important piece of this article. Before understanding how to exploit this Shellshock vulnerability, we need to understand the potential targets that are vulnerable to Shellshock. This will also help us in building a lab to demonstrate how to exploit this vulnerability. If you have read some news about Shellshock on the Internet, you might have heard about vulnerable targets as follows: Apache mod-cgi, SSH, DHCP, etc. I will make things clear using SSH as an example. Your SSH doesn’t really need to be exploited if you are using OpenSSH as an SSH Server as well as bash as your default shell. There are a few limitations in order to exploit this, as explained below. You may be vulnerable if you have implemented “authorization_keys” for your clients with some specific requirements like “force command” execution before the user executes the commands. Well, you don’t need to worry about this right now, as we will discuss it in detail in a moment. As of now, please keep in mind that “our services become vulnerable if we are using any program that uses a vulnerable version of bash as an interpreter and if the attacker is able to control the value of an environment variable that is being passed to bash”. Why? Because this is not a vulnerability in SSH; rather it is the vulnerability in “bash”.
How to check if your bash is vulnerable
Checking for bash version: Bash versions through 4.3 are known to be vulnerable. So, one way of checking is to check your bash version using the following command. [bash] $bash –version [/bash]
Cool! This is vulnerable. Running the fancy one-liner in your terminal: There is a one-liner which became very popular after the disclosure of this Shellshock vulnerability. [bash] $env x= ‘() { :;}; echo shellshocked’ bash –c “echo test” [/bash] Running the above line in your terminal shows if you are vulnerable to Shellshock. If “shellshocked” gets printed in the output, you are vulnerable and it’s time to update.
Technical insights of the Shellshock vulnerability Now, the following should be your questions: What does the above line do? What’s happening in the background? Why am I vulnerable if “shellshocked” gets printed? To make things clear, let’s first go through the basics. The basics of bash shell variables Generally, we can print something using the echo command as shown below. [bash] $ echo “shellshock” [/bash] Now, if you want to store the above value in a variable that’s pretty similar to any other scripting language, I am going to put it in a variable called “myvar”. [bash] $ myvar=”shellshock” $ echo $myvar shellshock [/bash] This is shown below.
Now, let us open up a child process and see if we can get the value of the variable.
As we can see in the above figure, we couldn’t read the value set by the parent process into the child process. Introducing bash environment variables This is where we can comfortably talk about environment variables. When you start your new shell session, some variables are already ready for your use. These can be called environment variables. When we want to access the above-mentioned “myvar” variable in a child process environment, we need to make it an environment variable in order to make it available for the new process. We can do it using “export”. This is shown below.
Looking at the above figure, we can clearly see that the sub process is able to access the value of “myvar”. Now, just to confirm that this is added to your environment variables, run the following command. [bash] $ env | grep ‘myvar’ [/bash]
In the above command, we are printing out all the environment variables and filtering out our target variable. Exporting bash functions to environment variables Similarly, functions can be exported to child process environments as shown below.
In the above figure, we first defined a function as shown below. [bash] x() { somecode;} [/bash] Then called this function x. In order to be able access it from the sub process, I have exported it using ‘–f’ flag as shown below. [bash] export –f x [/bash] As expected, I am able to print the text inside the subshell.
Parsing function definitions from strings
So far, we have seen how bash variables and functions work, as well as how we can export them to be able to access them in a sub process. Now, we are closer to Shellshock. J The above mentioned function definition can also be kept as a string. To show this, I am taking a new variable called “newfunction”. You will come to know why I am naming a variable as function in a moment. [bash] $ newfunction=’() { echo ‘shellshockdemo’;}’ [/bash] As we did earlier, we are just defining a variable. Now, we can access it as a regular variable as shown below. [bash] $ echo $newfunction [/bash] The above two steps are shown in the following figure.
Everything is as expected so far. Now, let us export it to environment variables and access it from the sub shell as shown below. [bash] $ bash bash-3.2$ newfunction [/bash]
Fantastic, though we are able to access it as a variable in the parent shell, it is getting interpreted as a function inside the subshell and executing the body of the function. Let’s also look at the environment variables to check for our function.
How is it possible?
When a new shell is launched as a child process, it takes the value of the string and interprets it as a function since it is starting with (). The actual vulnerability Finally, we are there! This time, I am going to terminate the function definition and pass some arbitrary commands after terminating the function as shown below. [bash] $export newfunction=’() { echo ‘shellshockdemo’;}; echo damn! I am vulnerable’ [/bash] In the above piece of code, I have added, “echo damn! I am vulnerable” after terminating the function. Now, spawn a new bash shell by typing “bash” and observe what happens. These two steps are shown below.
Bingo! The code added outside the function definition has been executed during the bash startup. If we execute the function now, it goes as expected. This is shown below.
Now, if you go back to one of our previous sections “When can it be exploited?” here is the answer: Condition 1 – Your bash version should be vulnerable (through 4.3). Condition 2 – An attacker should be able to control the environment variables being passed. Condition 3 – A new bash shell should be spawned (sub process). To automate the whole process, we are using “env” as shown below. [bash] $env x= ‘() { :;}; echo shellshocked’ bash –c “echo test” [/bash] Generally, env can be used to print all the environment variables as we have seen earlier. But if you look at the man page of env, it can also be used to run commands.
Alternatively, we can use “–help” as shown below.
First let’s look at a simple example as shown below. [bash] $env newvar=demo bash –c ‘echo $newvar’ [/bash] In the command shown above, newvar is an exported variable which is being accessed by a new subprocess and printing the value of it.
Now, if we look at our fancy command, [bash] $ env x=’() { echo accessme;} echo vulnerable’ bash –c ‘x’ [/bash] We should see the following output:
Again, the same concept. X is a variable being exported. Since its value is beginning with (), it will be treated as a function by the subshell and the definition will be executed. But before that, our “vulnerable” will be printed upon spawning a shell. This whole process is represented in the following figure.
By this time, you should understand why this simple on-line command is so dangerous.
Possible exploits
Below are the few critical instances where a Shellshock vulnerability may be exposed:
Apache HTTP Server using mod_cgi or mod_cgid scripts either written in bash, or spawn subshells. Override or Bypass ForceCommand feature in OpenSSH sshd Allow arbitrary commands to run on a DHCP client machine.
In the next article, we will see how to set up our own lab and demonstrate how to exploit vulnerable OpenSSH and Apache servers.