Shellshock is a family of exploits which lets attackers execute arbitrary code through Unix Bash Shells.
A user can append commands to a function definition. And the function definition can be attached to an environment variable of the shell. Therefore, if an attacker could pass an arbitrary value to an environment variable in Bash, then any machine can be exploited.
For example, if user can set VAR to following,
VAR=() { ignored; }; /bin/id
/bin/id is executed upon the variable being imported to bash process. The execution is independent of the variable name. The execution follows the function definition, which itself could be set to any payload (within any length boundaries of the program used to initialize the variable). This allows for any arbitrary code to be executed.
Let us look at a specific exploit of this family, which allows code injection with Apache CGI Scripts. Exploit code can be found from rapid7/metasploit-framework git repository
In this particular example, the code is injected through Apache HTTP Server’s mod_cgi module, which handles execution of CGI (Common Gateway Interface) scripts, which are console-like programs executed directly on the server. CGI scripts are used to generate dynamic responses according to the HTTP requests received from clients with the URL referring to a specific script. Script is run and output is passed back as a HTTP Response. CGI scripts are capable of defining environment variables, which is where the problem lies. While the variables are limited to script environment itself, if Bash is called, they are exported to bash. This generates the perfect window for code injection.
The default HTTP header used by malicious requests to inject code is the “User-Agent” header (as defined by the default parameters in above code). A valid use case for this scenario could be outputting the headers required for a well-formed HTTP response (albeit much more secure ways to generate this response can be thought of).
Aforementioned exploit from Metasploit framework can be used to deliver multiple payloads to a target system running Apache HTTP server with cgi scripts enabled. It can be used in conjunction with a payload such as “reverse_tcp”, which will connect back to the attacker, and spawn a command shell, providing a very nice backdoor and the satisfaction of a successfully executed privilege escalation attack.
This can be attributed to multiple factors. The biggest contributor was Unix being the most common operating system used in servers worldwide in the form of various Linux flavors and MacOS. The universal use of Bash and Apache HTTP servers also did not help. But these factors are not exclusive to Shellshock.
CGI scripts being able to execute Bash if required was a big mishap. To make matters worse, Bash function definition being able to be set into any arbitrary code, which could be self-called in the trailing code, resulting in many payloads being able to be executed was another mishap. But the third and the most contributing factor for the success of this attack was the lack of input sanitization by the Bash itself.
How could this attack have been prevented or mediated?
To further cement above suggestions, check out an initial patch to the Shellshock vulnerability which implements the following.
We are never fully aware of the full functionality of an application. We only use it for what we need and then let it be. But if we are calling something else from something that is public facing, we have to sanitize the input, restrict privileges to only what needs to be done and nothing else, and keep a close eye on new vulnerabilities. To conclude while being sinfully generic, what I can say is that Input sanitization will never hurt, and that programs only need privileges to do what were meant to do, and nothing else.