ShellShock vulnerability is a serious vulnerability in the widely used Bash shell.
Bash is by far the most popular shell and is the default shell
distributed with Linux and Mac OS X. In addition, it is used by many
computers and servers that are exposed to the Internet. The patch was
released on September 24th along with the announcement of the
vulnerability, but attackers on the Internet relied on the fact that
not everyone was going to promptly patch their computers and
therefore started attacking vulnerable machines on the Internet.
The ShellShock vulnerability itself was
a simple logic flaw in the Bash code rather than a memory corruption,
making it very easy for a large audience to understand and exploit.
To make matters worse, this vulnerability is “wormable” in that
it does not require user interaction, allows
untrusted/unauthenticated users to execute code on a remote machine
and its exploit can be embedded into a malicious script to automate
its proliferation around the Internet at an exponential rate. Some
currently known attack vectors include (1) CGI-based web servers, SSH
servers and DHCP clients, all of which are widely used services
around the Internet.
The Vulnerability:
The vulnerability itself was the simple
fact that Bash allowed the user to define functions and include
multiple commands inside environment variables that are passed to
Bash. This is dangerous in situations when the value of the
environment variable passed to the new Bash instance is supplied by
an unauthenticated and untrusted source.
The Fix:
The Fix for the ShellShock
vulnerability was implemented in the patch “bash43-025” released
on the GNU FTP website (2). Below is the relevant annotated code
change inside Bash 4.3, which is the newest supported version of
Bash.
//CVE-2014-6271: executed with “testbug
= () { :;}; echo VULNERABLE”
void initialize_shell_variables (env,
privmode)
char **env;
int privmode;
{
...
/*
Now, name = env variable name,
string = env variable value
char_index == strlen (name)
temp_string = "testbug () {
:;}; echo VULNERABLE"
name = "testbug"
SEVAL_FUNCDEF is OR'ed in below
indicating that this was a
function definition
SEVAL_ONECMD is OR'ed in below to
indicate that we only want
a single command
*/
if (legal_identifier (name))
parse_and_execute (temp_string,
name,
SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD);
...
}
int parse_and_execute (string,
from_file, flags)
char *string;
const char *from_file;
int flags;
{
...
while (*(bash_input.location.string))
{
...
/*
1) SEVAL_FUNCDEF was OR'ed into
line that called this function
2) command->type ==
cm_connection != cm_function_def
Therefore we execute inside the
if statement, which produces an error.
EX_BADUSAGE is eventually
returned from this function.
*/
if ((flags & SEVAL_FUNCDEF) &&
command->type != cm_function_def)
{
internal_warning ("%s:
ignoring function definition attempt", from_file);
should_jump_to_top_level = 0;
last_result =
last_command_exit_value = EX_BADUSAGE;
break;
}
...
/*
If we didn't go into the above if
statement, and we only want one
command, break out of the while
loop now...
*/
if (flags & SEVAL_ONECMD)
break;
}
...
}
The Exploit:
The exploit code (3) was also very
simple. The below Bash script code triggers the vulnerability and
prints “VULNERABLE” to the screen on vulnerable versions of Bash.
export testbug='() { :;}; echo
VULNERABLE'
bash
The first line defines a new
environment variable called testbug. This new environment variable
contains just a function definition (no actual call to the function)
followed by an additional command. The function definition is just
“() { :;};” which is an unnamed Bash function which has the
expression ':' inside of it. In Bash, when the ':' character is
evaluated as an expression, it just evaluates to true (4). The
function definition is followed by another command which in this
case, just prints “VULNERABLE” to the screen. The second line
executes a new instances of Bash which will consume this environment
variable. This explicit execution of bash is analogous to a web
server spawning a new instance of bash.
Other Events:
After the original patch was released
for the original ShellShock vulnerability, the community started to
find new variants of bugs in Bash and has since assigned multiple new
CVEs to these bugs. As of the time of this writing, the discoveries
are ongoing. Considering how long ago Bash was written, the old
coding style, and the amount of string manipulation that is happening
in C, it is very likely that new vulnerabilities (especially memory
corruptions) will continue to be found.
Workarounds:
A possible way to avoid execution of
vulnerable codepaths includes avoiding setting environment variables
to untrusted user supplied input. This advice takes into
consideration that new and currently unknown attack vectors and
variants are likely to be discovered in the upcoming days and weeks.
References