Shellshock is a vulnerability associated with CVE-2014-6271 that was released on September 24, 2014, and affects the Linux shell “Bash” up to version 4.3. This vulnerability allows arbitrary command execution.
Table of Contents:
Origin of Shellshock
The vulnerability originated because previously, when assigning an environment variable, bash gave you the ability to assign a function. What happened when you assigned a function to the value of an environment variable is that bash didn’t stop at the function definition itself, but instead continued and executed the commands that were placed after the function definition.
Literally you after reading this paragraph:

Now everything will be clearer. What used to happen is that you could declare a function in an environment variable. And a bug occurred that would execute the command placed afterwards. For example, you defined the following function in the variable:
variable='() { function content;}; '
And instead of simply being defined, the bug that bash had caused the command that was after the function definition to be executed. At a conceptual level, this is everything. To better understand this vulnerability, let’s see how the env command works.
This command prints the current environment variables. But it can also be used to execute a command in an environment with a specified variable. The process it performs is as follows:
envstarts a new process- It modifies the environment of this new process
- It executes the command we specified in the created environment
For example, if we pass the env command as an argument to be executed in the environment that the first env creates, we can see the environment variables of the context that the first env creates:

Let’s say what’s happening is:
“Hey, create a completely clean environment of environment variables for me. In this environment, the only environment variable that will exist will be the one I pass as an argument. And inside this environment, execute the command I specify, in this case, env, to be able to see the environment variables of the environment I just created with the first env, which being a clean environment, will only have the environment variable I passed as an argument.”
I added the
--ignore-environmentparameter to simply explain the concept of the environment thatenvcreates. If we didn’t use it, simply in the new environment all existing environment variables in our current environment would be inherited.
Okay, now you’re like this:

It’s normal, just reread the paragraph above slowly and carefully.
Now, knowing this, this is where the bug we talked about at the beginning comes into play, Shellshock. If we define the following function in a variable:
my_function='() { :;}; echo "IT IS VULNERABLE" '

bash -c ''is the same as placingbash -c :In both cases we’re telling it that in the new instance/subprocess, to simply do nothing. I mention this because the colon appears in the characteristic Shellshock payload and it’s just for that, it sets a command that simply does nothing.
It executes, even though we’re only defining an environment variable. This happens because the new shell (the new process) sees an environment variable that starts with () and obtains the variable name to execute it and define the function in the environment. However, as already mentioned, the bug caused whatever was placed after the function to be executed.
On a non-vulnerable system, executing the command from the image above, nothing will simply happen:

And all this I’ve explained is the bug and the famous vulnerability. You might think, hey, it’s not that big of a deal, because in the end, it’s just a simple OS command injection on Linux.
Remote Shellshock
The scary thing about this vulnerability is that it can be exploited remotely, for example, on a web server, causing Remote Command Execution (RCE). Files susceptible to a Shellshock attack are those that commonly belong to any of the following extensions:
.cgi.sh
Some web servers, such as Apache, support what is called Common Gateway Interface (CGI). This feature allows external programs to make use of data coming from the web server. This functionality is related to the famous cgi-bin folder that we can often find. cgi-bin is a folder created automatically to place scripts that we want to interact with the web server.
So remote exploitation is not limited to .cgi files. It’s limited to files that interact with bash using environment variables, data from the web server. Which is what CGI allows.
So, the idea of remote exploitation is that any information received in a request from the client, such as the User-Agent, Referer, or other parameters, are stored in the form of environment variables so they can be used by external programs or scripts, which is why files located in the cgi-bin folder are susceptible to Shellshock.
Out of curiosity, the environment variables will have names like:
HTTP_<header>. For example,HTTP_USER_AGENTwould be the environment variable that would store the value of theUser-Agent.
These environment variables, since they’re ultimately headers whose value we can edit, we have everything. On one hand, we have environment variables whose content we can control, and on the other hand, we have the execution in bash of scripts that use the environment variables that we control.
If we altered the value of the User-Agent and replaced it with a payload like the one we’ve seen previously, everything we explained would be happening. A function defined in an environment variable, when passed to the context of a new environment of a bash process, will execute any command placed after the function declaration.
Remote Exploitation Example
Let’s see what the exploitation would look like using the “Shocker” machine from HackTheBox.
The first thing is to identify the file that may be vulnerable, in this case, it’s user.sh:

Once identified, it’s as simple as sending the characteristic Shellshock payload through some header, for example, the User-Agent:
curl -H 'User-Agent: () { :;}; echo; echo Is it vulnerable?' 'http://10.10.10.56/cgi-bin/user.sh'

We can also check with another header, for example, the Referer:

We can observe that in both cases the string from the second echo has been executed. This way, we just verified that it’s vulnerable. So we practically already have RCE, if we want to confirm it even more, we can try to send ourselves ICMP packets:

There are several details to comment on here. The first is that we place an
echoafter the function declaration so that the second command can display its output in the HTTP response. Even so, if we didn’t place it, even though we don’t see the command output in the response, we would be executing it.The second thing is that, if we notice, we are calling bash in an absolute way. And this is because the
$PATHvariable is empty in the environment where Shellshock executes the command.
We could also send ourselves a reverse shell:

The exploitation of this vulnerability is really as simple as this, place the classic payload and boom, RCE.