You may have heard about the shellshock bash vulnerability that allows remote code execution by setting a specially crafted environment variable before running bash. I investigated whether it was possible to place something in front of bash to attempt to detect and protect against a potential exploit.
Overview
The shellshock bug allows code to be executed when a starting bash process encounters a specially crafted environment variable. This happens more often than you might think and has the potential to affect a large number of systems. The vulnerability has been assigned CVE id CVE-2014-6271.
For instance, web servers set certain environment variables before running CGI scripts (which can be shell scripts). These variables are set based on user supplied information.
sendmail also has the prog mailer, which will pass the contents of an email through a program. This usually uses /bin/sh as the shell, but on some Linux distributions, /bin/sh is a symbolic link to /bin/bash. I need to see what variables it sets, and to what values, to see if that could also be an attack vector.
I have developed some code to sit in front of /bin/bash and check to see if any of the environment variables match a given regular expression. If none of the variables match, then it runs the original bash command. If any of the variables match, then it logs the variable and the process id of the parent process.
This logging allows an administrator (or log file monitor) to detect a potential shellshock exploit attempt, and which process was used to attempt to exploit the bug.
Disclaimer
#include “standard_disclaimer.h”
I have tested the regular expression with various environment variables that exploited the bug and didn’t exploit the bug, and I have also tested my bashwrapper.c code, however, I can’t guarantee that it will protect against all possible exploit strings (as there may be numerous ways of encoding it, depending on how the exploit string is being delivered). It may also detect some false positives.
Obviously I haven’t been able to test it in all environments and situations, so please test it in a test/dev environment before installing it in to a production environment.
This is not a substitute for patching your systems, but it will hopefully help to mitigate the risk until you do. It will also highlight if any exploit attempts are being made against your systems (I’m also hoping to get a Suricata rule out).
Feel free to leave a (polite) comment if you can think of any improvements (to the regular expression, code, or these instructions/description).
Warning
If bash is used as a login shell, then you can potentially stop users (including root) from being able to login and/or su. Always test that you can still login from scratch, and gain root privileges, before logging out of your root shell!
Installation
My wrapper can be installed as follows. Note that your bash executable may be installed in a location other than /bin (especially on Solaris or non-Linux UNIX systems. If this is the case, then simply substitute the correct path for /bin in the instructions below):
- Download the source from http://malwaremusings.com/supporting-files/bashwrapper-c/.
- Edit the VERBOSE setting at the top of the source
- Compile it with: gcc -o bashwrapper -Wall bashwrapper.c
- Gain root privileges, either by running su, or by using sudo -i (the latter will change your current working directory)
- Copy the binary to /bin (or to wherever your bash executable is installed): cp -a bashwrapper /bin/
- Change ownership: chown root:root /bin/bashwrapper
- Give it execute permissions: chmod 755 /bin/bashwrapper
- Make it operational: cd /bin ; mv -i bash bash.real && ln -s bashwrapper bash
If bash is used as your login shell, then check that you can login on a separate terminal and gain root privileges before you drop your current root privileges and/or logout!
You may want to change the file name of the real bash process, both in the mv command above and in the bashwrapper.c source code (the constant defined in line 21). This is because it may be possible for attackers to specify the path to the bash executable. If they see this source code (which is reasonably likely), and they are in a position where they can specify the path to the bash executable, then they can simply run /bin/bash.real instead and bypass bashwrapper.
Usage
The VERBOSE constant in line 19 of the C source causes some extra logging. It will log whether it is starting the real bash. This can be used to log whether a process is running /bin/bash at all.
bashwrapper will log the following messages to syslog, using facility LOG_USER and priorities LOG_INFO and LOG_WARNING:
- detected possible shellshock exploit
- regular expression failed to compile
- starting real bash
- failed to exec() real bash
- NOT running real bash
1) is logged if any part of an environment variable matches the regular expression defined in line 20.
2) is logged if the regular expression defined in line 20 fails to compile. This is so that you don’t think that it is protecting you, when in fact it isn’t. If the regular expression fails to compile, it will run the real bash as normal. This stops a bad regular expression from stopping bash from running.
3) is logged if you have the VERBOSE constant (line 19) set to 1, and bashwrapper is going to run the real bash.
4) is logged if bashwrapper was going to run the real bash, but failed to do so.
5) is logged if you have the VERBOSE constant (line 19) set to 1, and bashwrapper is not going to run the real bash.
You may also want to use the strip command to strip symbol information from the compiled bashwrapper executable — it doesn’t matter much, but it will make the executable file smaller.
I don’t like this WordPress create page layout, as when you scroll down the page, the Publish button appears where the Preview Changes button was. The fact that it is 01:50 in the morning and I need sleep isn’t helping either.
More Information
More information on shellshock can be found at the following locations: