Mitigating the shellshock vulnerability (CVE-2014-6271 and CVE-2014-7169)

Updated -

Warning

These mitigations involve making changes that could lead to unintended consequences if they are not performed correctly. It is recommended that only experienced system administrators who fully understand the implications of these changes apply the mitigations documented in this article. These mitigations have only been subjected to limited testing by Red Hat.

Important: Given that package updates are available to correct the flaws these mitigations were provided for, these mitigations should only be used in exceptional circumstances and not as a replacement for installing the updated packages. Red Hat recommends all users of Bash to upgrade to the updated packages as swiftly as possible.

Network-based mitigations

Network mitigation 1: mod_security rules

The following mod_security rules can be used to reject HTTP requests containing data that may be interpreted by Bash as a function definition if set in its environment. They can be used to block attacks against web services, such as attacks against CGI applications.
Request Header values:

SecRule REQUEST_HEADERS "^\(\s*\)\s+{" "phase:1,deny,id:1000000,t:urlDecode,status:400,log,msg:'CVE-2014-6271 - Bash Attack'"

SERVER_PROTOCOL values:

SecRule REQUEST_LINE "^\(\s*\)\s+{" "phase:1,deny,id:1000001,status:400,log,msg:'CVE-2014-6271 - Bash Attack'"

GET/POST names:

SecRule ARGS_NAMES "^\(\s*\)\s+{" "phase:2,deny,id:1000002,t:urlDecode,t:urlDecodeUni,status:400,log,msg:'CVE-2014-6271 - Bash Attack'"

GET/POST values:

SecRule ARGS "^\(\s*\)\s+{" "phase:2,deny,id:1000003,t:urlDecode,t:urlDecodeUni,status:400,log,msg:'CVE-2014-6271 - Bash Attack'"

File names for uploads:

SecRule FILES_NAMES "^\(\s*\)\s+{"  "phase:2,deny,id:1000004,t:urlDecode,t:urlDecodeUni,status:400,log,msg:'CVE-2014-6271  - Bash Attack'"

It is possible, however unlikely, that these rules may result in false positives. These false positives, along with actual attempts, could result in log files of significant size.

Network mitigation 2: IPTables rules

It is possible to use IPTables string matching to attempt to drop packets that could be part of an attack, using:

# iptables -A INPUT -m string --algo bm --hex-string '|28 29 20 7B|' -j DROP
# ip6tables -A INPUT -m string --algo bm --hex-string '|28 29 20 7B|' -j DROP

Note that this is a weak workaround, as an attacker could easily send one or two characters per packet, which would avoid matching this signature check. It may, in conjunction with logging, provide an overview of automated attempts at exploiting this vulnerability.

System-based mitigations

The shellshock vulnerability arises from the fact that you can create environment variables with specially-crafted values before calling the Bash shell. These variables can contain code, which gets executed as soon as the shell is invoked. The initial patch for CVE-2014-6271 was found to be incomplete. The patch for CVE-2014-7169 addresses this, but it does not entirely remove the vulnerable functionality. If you entirely remove the vulnerable functionality from Bash, all possible attack variants will be mitigated.

System-based mitigation 1: LD_PRELOAD

LD_PRELOAD is an environment variable used by the runtime linking process by searching for shared libraries at alternate locations and by forcibly loading and linking libraries that would be used. This forces some symbols/functions to be loaded and prioritized over built in functions a program. This code creates a new function "strip_env" with the gcc "constructor" attribute set. Functions with this attribute set will execute before entering main(). See https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html for more details.

$ sha256sum bash_ld_preload.c
28cb0ab767a95dc2f50a515106f6a9be0f4167f9e5dbc47db9b7788798eef153 
bash_ld_preload.c
  • Compile it:
$ gcc bash_ld_preload.c -fPIC -shared -Wl,-soname,bash_ld_preload.so.1 \
-o bash_ld_preload.so
  • Copy bash_ld_preload.so to /lib:
# cp bash_ld_preload.so /lib/

If you wish to apply this workaround across the entire system:

  • Add the following to /etc/ld.so.preload on a line by itself:
/lib/bash_ld_preload.so
  • Restart all relevant services or reboot the system.

Note that this is potentially very dangerous. It is recommend that you just apply this workaround to specific services that may be exploitable on your system. This can be achieved by adding bash_ld_preload.so to the LD_PRELOAD environment variable in the script that will initialize the service. However, this will not work for services that use SUID binaries in some capacity (e.g. httpd with SUEXEC), as SUID binaries will not honour the LD_PRELOAD command.

  • Add the following two lines at the top of /etc/init.d/httpd, after the shebang line:
LD_PRELOAD=/lib/bash_ld_preload.so
export LD_PRELOAD
  • Edit httpd.conf and add the following directive and save the configuration file:
PassEnv LD_PRELOAD
  • Then restart httpd:
# service httpd restart

System-based mitigation 2: systemtap

It may be possible to mitigate by enforcing bash to use privileged mode.

install the bash debuginfo

$ sudo debuginfo-install bash

install systemtap

$ sudo yum install systemtap

Run this command:

$ nohup sudo stap -g -e '  probe process("/bin/bash").function("initialize_shell_variables") { $privmode=1 }  '

This ensures that the bash privileged mode (the equivalent of bash -p) is always enabled. To verify, test for the original vulnerability (CVE-2014-6271):

$ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
this is a test

The above is an example when it is NOT affected. Finally, test for the new vulnerability (CVE-2014-7169):

$  env X='() { (a)=>\' sh -c "echo date"; cat echo
date
cat: echo: No such file or directory

The above is an example when it is NOT affected.

Force-enabling privileged mode has side effects that some system administrators may need to be aware of. Listed below is a relevant extract from the bash man page.

  -p  Turn on privileged mode.  In this mode, the $ENV and $BASH_ENV files
      are not processed, shell functions are not inherited from the
      environment, and the SHELLOPTS, BASHOPTS, CDPATH, and GLOBIGNORE
      variables, if they appear in the environment, are ignored.  If the
      shell is started with the effective user (group) id not equal to the
      real user (group) id, and the -p option is not supplied, these
      actions are taken and the effective user id is set to the real user
      id.  If the -p option is supplied at startup, the effective user id
      is not reset.  Turning this option off causes the effective user and
      group ids to be set to the real user and group ids.

This script above is a temporary mitigation and will not persist between reboots.

Comments