Shellshock was a security threat that was identified
by Stéphane Chazelas on 12 September 2014 and was disclosed and announced to
the public on 24th September 2014 with the fix ready for
distribution. It was assigned the identifier as CVE-2014-6271.
By the way, this is another security bug with cool
logo after Heartbleed.
1. What is Shellshock?
Shellshock is a name given to a vulnerability in Bash
which allows an attacker to execute remote commands on vulnerable system. Bash
is a command-line interpreter available on most of the operating systems like
Apple’s OSx, windows and present on many versions of Linux. Bash also acts as a
parser for the functions given to it.
2. Why is it harmful?
Shellshock is significantly harmful for the servers
connected to internet. Since, it lets attacker to escalate their privileges and
potentially they can gain access to root. This gives access to the attacker as
if they are the actual user and they can perform any operation that the owner
can do. Also the attacker can inject code without any authentication.
The shellshock is an example of arbitrary code
execution (ACE) vulnerability. Usually they require high understanding of
system's working, sophisticated understanding of internals of code execution,
memory layout etc. In other words, ACE requires an expert to make it happen. But
in case of shellshock vulnerability it doesn't require any sophisticated
knowledge of the environment and its working. There are demonstrations present
on internet on how to exploit it and how it can be used, which makes it more
harmful.[10]
There are other shells present in the market but since
bash shell is the default one for Linux and Mac OS X, this makes it even more
harmful. Also, this bug existed for last 25 years this means that there may be
people who already knew about this bug and chose not to disclose about it and
due to this many servers might have already compromised.
3. Where is it in the source code?
So, which part of the source code made it possible for
an attacker to execute this code?
There were few more similar bugs found after it was
disclosed publically but let’s focus on the first bug identified as CVE-2014-6271.
Download the source code for any older version of bash
and open variable.c file. At line number 315 we have this method called initialize_shell_variables(env, privmode).
/* Initialize the shell variables from the current environment.
If PRIVMODE is nonzero, don't import functions from ENV or
parse $SHELLOPTS. */
void
initialize_shell_variables (env, privmode)
char **env;
int privmode;
{
char *name, *string, *temp_string;
int c, char_index, string_index, string_length, ro;
SHELL_VAR *temp_var;
create_variable_tables ();
for (string_index = 0; string = env[string_index++]; )
{
char_index = 0;
name = string;
while ((c = *string++) && c != '=')
;
if (string[-1] == '=')
char_index = string - name - 1;
/* If there are weird things in the environment, like `=xxx' or a
string without an `=', just skip them. */
if (char_index == 0)
continue;
/* ASSERT(name[char_index] == '=') */
name[char_index] = '\0';
/* Now, name = env variable name, string = env variable value, and
char_index == strlen (name) */
temp_var = (SHELL_VAR *)NULL;
/* If exported function, define it now. Don't import functions from
the environment in privileged mode. */
if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4))
{
[…]
if (posixly_correct == 0 || legal_identifier (name))
parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST);
[…]
}
The code accepts the env argument which is a two dimensional char array and then a loop
is iterated over this. An ‘if’
condition checks for privileged mode i.e. privmode, this is disabled most of
the time. Once the string reads as “() {”
as first four character of the env variable it will start parsing and executing
the commands, this is done by parse_and_execute
method. This is the point where the bug lies, the code should not execute any
extra command once the function mentioned in the env is completed.
The flag passed to this method are SEVAL_NONINT and
SEVAL_NOHIST. SEVAL_NONINT which means that the command is not interactive
(Interactive commands wait for user input) and another flag is SEVAL_NOHIST
which means that it will not add definition to bash history. These two flags
don’t provide prevention of sending other things than function definition.
4. What was the fix?
The patch given for this bug, introduced two more
flags as below:
SEVAL_FUNDEF: this is used to allow only function definition
SEVAL_ONECMD: this is used to allow a single command
These flags were sent to parse_and_execute
method. Below code snippet shows the fix
in variable.c file:
/* Don’t import function names
that are invalid identifiers from the environment */
if(legal_identifier (name))
parse_and_execute(temp_string,
name, SEVAL_NONINT | SEVAL_NOHIST | SEVAL_FUNDEF | SEVAL_ONECMD)
The above changes in the code will stop the execution
of the extra commands sent with the instructions.
5. How it works?
Web
servers receives request from client in form of request. These request have
three parts which are susceptible to the shellshock attack. They are: request
URL, header, and arguments that are sent with the header. [10]
This
header contains information about the browser like what is the language, the
site the user is accessing and which browser the user is using. The webserver
translate them into variables to get these details as:
HTTP_ACCEPT_ENCODING=gzip,
deflate
HTTP_ACCEPT_LANGUAGE=en-US,
en;q=0.5
HTTP_CACHE_CONTROL=no-cache
HTTP_PRAGMA=no-cache
HTTP_USER_AGENT=
|
Mozilla/5.0
(Windows NT 6.3; WOW64; rv:33.0) Gecko/2010010 Firefox/33.0
|
HTTP_HOST=192.168.137.224
The
shellshock bug won’t create a problem if they remain till webserver, the
problem arises when these variables are sent to shell. These variables like
User-Agent can be changes by the user. Imagine the attacker changing this value
of :
Mozilla/5.0 (Windows NT 6.3; WOW64; rv:33.0) Gecko/2010010 Firefox/33.0
To
() { :;} /bin/eject
As
we saw in the source code that “() { :;}” string is given a special treatment
and process in a special manner, the above value sent as USER_AGENT will get
executed. This example won’t do much harm rather than ejecting the CD/DVD drive
(This was one of the attacks that attackers tried according to CloudFlare) but
imagine the attacker trying to get the password file from this computer, that
will be a serious problem.
6. Which versions of bash are affected?
Surprisingly this bug was in Bash from its first
version released in 1989 and resided there for 25 years. After disclosing it to
public on 24th September 2014 lot of servers were compromised
because the patch provided as a fix didn’t covered all the scenarios and was a
partial fix for the problem. After that few more versions of this vulnerability
were identified and given the CVE identifier as CVE-2014-6277, CVE-2014-6278, CVE-2014-7169,
CVE-2014-7186 and CVE-2014-7187. We can’t be sure if this issue is completely
fixed yet. Best way of prevention for now is to keep the bash up to date.
7. How to check if the systems is vulnerable to this bug?
Copy the below command and execute it in your bash
shell and check if you are still vulnerable to it.
env x=’() { :;}; echo
vulnerable system’ bash –c “echo sample message”
If you see the output as:
vulnerable system
sample message
This means that your system is not secure and you are
vulnerable. On the contrary if you have already taken latest updates then you
might only see:
sample message
8. How to exploit it?
Now we know that the system is vulnerable let’s try
few commands to see how the attacker can retrieve data from your computer.
To exploit this vulnerability first you need a
webserver where CGI (Common Gateway Interface) is enabled. For demo purpose I
have created such a server locally on one of my VM which is running Ubuntu
14.04 with downgraded bash to version 3.2. Let’s try to access this server from
my other VM which is running fedora 12.
Apache2 running on
Ubuntu 14.04
Now we can check the webserver accessibility from
fedora browser by entering the URL, in our case it is
Accessing the vulnerable
server from browser in Fedora
The content shown in the browser is the content of the
test1.cgi file.
Now switch to /tmp directory and execute below
command.
wget -U "() { test;};echo
\"Content-type: text/plain\"; echo; echo; /bin/cat /etc/passwd"
http://192.168.137.224/cgi-bin/test1.cgi
Output after
executing the command
This command will copy the content of /etc/passwd file
to your current directory i.e. /tmp/test1.cgi. Basically the attacker can save
these files at his end. Now if we check the content of this file:
This is just an example of how a vulnerable system can
be exploited. It depends on the attacker how he can use the data extracted from
these servers and then sky is the limit.
9. How to protect your systems from shellshock?
Security teams can take preventive measures to protect
their systems from shellshock by
1.
Reducing exposure
of their systems.
2.
Taking latest
updates for bash as well as network and security products present on the system.
3.
Switching to other
version of shell if the team is not able to find proper patches or updates for
their system.
10. Who all are affected due to this bug?
Shellshock
affected many operating systems and big companies like Cisco and Oracle. Oracle
found out that dozens of their products were affected due to this. Cisco
identified 71 products that are exposed to this vulnerability. These companies
are releasing patches for fixing these issues.
Other
than big companies the individual users can be at risk. Currently there are no
confirmed reports on exploitation of individual users. Now a days the increase
of handheld devices and wearable are increasing which have UNIX like systems on
them which again comes with default bash shell. These IoT devices are at risk
too due to bugs like shellshock.
Consumers who are aware of these issues knows that in
order to prevent these problems they can upgrade/patch their software but if we
think about a regular consumer who is just using a router at his home is not
aware of such vulnerabilities, he is unaware of such security issues. They
don’t know that the devices like router uses shell for its operation and they
are vulnerable. This remains a problem for all such users.
Conclusion
In
this paper we gathered information about Shellshock and various critical
problems created by it. We also successfully reproduced the issue by creating a
vulnerable webserver locally and have some insights on how this can be prevented.
The fact about this bug that it was present in the application for last two
decades also proves that making a perfect application is very difficult and
challenging task. Even if the issue seems solved for now, we can’t be 100% sure
if this is fixed completely. But, we can try to make good software by careful
design and analysis, rigorous testing of modules and like this we can reduce
the number of vulnerability in our products.
Very helpful article. Thanks a lot!
ReplyDeleteThis comment has been removed by the author.
ReplyDelete