
Shell Shock Exploitation Vectors - dfranke
https://www.dfranke.us/posts/2014-09-27-shell-shock-exploitation-vectors.html
======
patio11
On the theory that it is more likely to help HNers than the bad guys:
[http://httpd.apache.org/docs/2.2/mod/mod_ssl.html](http://httpd.apache.org/docs/2.2/mod/mod_ssl.html)
. Note in particular the part about StdEnvVars. The docs say it is off by
default, but it is actually on in a lot of common deployment scenarios, for
example if most of your apache configs were sourced from the big "apt-get
install foo bar baz" line everyone copies from a blog post to get a working
LAMP installation on an Ubuntu box.

I have not POCed this yet, but if I were trying to, I'd first try to make a
client certificate with a highly non-standard Distinguished Name. It doesn't
particularly matter if it fails validation as long as it doesn't fail in such
a way that Apache dies before passing your information deeper into the guts of
the web app.

After that point you're just looking for e.g. any page or library in the web
app you can coerce to do a system() call or similar. While I was poking around
in my own apps something like system(...) in Ruby on Ubuntu actually called
/bin/sh rather than bash, but I think that is probably not the case for every
combination of stack and distro.

~~~
patio11
Another thing that interested HNers can feel free to bird dog: PHP + Nginx is
often deployed using fastcgi. (And, in my limited experience, far, far more
likely to be deployed in greenfield development in the 2010s versus an actual
CGI script. I think probably in excess of 20% of "technically savvy young
software companies" I run this, the vast majority motivated by one
ridiculously common piece of software that I'll refrain from naming because it
suggests a trivial spray-and-pray for loop.)

fascgi_params puts a lot of attacker controlled data into "environment
variables", but depending on php.ini's variables_order setting those might not
actually go into what the rest of the word thinks is an environment variable
(and hence not get passed to subprocesses, which is the point of the
exercise). If php.ini's variables_order includes an "E", then the environment
variable QUERY_STRING (among other things) will include attacker-chosen data.
variables_order does include E by default, but does not in the php.ini which
ships with the obvious apt-get commands for e.g. Ubuntu.

~~~
xorcist
I would like to reply to this but it is very hard to understand what you are
alluding to. What is this software that one fifth of companies run and why is
technically savvy in scare quotes, along with some veiled reference to
something called spray-and-pray?

It's really impossible to understand you, but fastcgi_params does not put
attacker controlled data into environment variables (without the quotes). That
much is clear so normal usage of fastcgi is not in danger.

~~~
patio11
I will try being maximally explicit.

 _What is this software that one fifth of companies run_

A ridiculously popular application, written in PHP, which is widely useful to
software companies (among others).

 _why is technically savvy in scare quotes_

I originally wrote "startup" then thought "Actually, this is deployed by a lot
of people who aren't startups or who are only arguably startups, hmm, that is
an unproductive debate, let's just say what I mean then move on."

 _some veiled reference to something called spray-and-pray?_

Many applications have a well-known set of URLs associated with them. A spray-
and-pray exploit is one which you can just fire at a well-known URL at every
machine which responds to port 80 in IP4 space. The reason I am not
identifying the vulnerable software written in PHP is that it would allow any
script kiddie smart enough to text edit the existing exploit scripts to
exploit that software as an additional vector.

 _fastcgi_params does not put attacker controlled data into environment
variables (without the quotes)_

I'm absolutely positive that fastcgi_params does indeed clobber $_ENV with
attacker supplied data if PHP is configured as described above. I am less
strongly confident that some configurations of PHP will allow $_ENV to get to
at least some subprocesses. I am absolutely confident that some configurations
of PHP will not allow you to set $_ENV nor set environmental variables. I have
figured out ways to configure it which put the fastcgi_params in $_SERVER but
not $_ENV and, separately, in $_ENV but not in environment variables passed to
subprocesses. I'm aware of a PHP command which the documentation suggests
defaults to passing $_ENV as actual environment variables to subprocesses but
which I have not been able to verify actually works as the documentation says,
due to it being 6 AM in the morning local time and me having insufficient
motivation to continue finding more reasons to justify the conclusion that
this bug is very, very bad news and bash needs to get patched immediately
everywhere.

~~~
xorcist
> I'm absolutely positive that fastcgi_params does indeed clobber $_ENV with
> attacker supplied data if PHP is configured as described above.

This is irrelevant. There is no known hole with global variables containing
untrusted data.

> I am less strongly confident that some configurations of PHP will allow
> $_ENV to get to at least some subprocesses.

This could be relevant, if it is indeed passed in the environment.

However I can find no reference in the PHP documentation to this. That does
not count for much, admittedly, and I am not very fluent in PHP. If this is
real then it is a problem for many people so please share.

> I'm aware of a PHP command which the documentation suggests defaults to
> passing $_ENV as actual environment variables to subprocesses

Please spell it out already. I've been testing for the better part of two
hours to find what you are alluding to, but I have no idea if I'm wasting my
time or not.

------
js2
Always protect your OpenVPN instances with tls-auth, especially if your
instance accepts connections from any IP. It prevents the SSL negotiation from
even occurring if it doesn't match. It would have protected you from heart
bleed, and it protects against shell shock.

There is no downside to using it. However, keep in mind that the key file is
shared across all clients, so you probably want to change it periodically
depending upon how much you trust your clients not to become hostile. You
could run multiple server instances on different ports/IPs to subdivide your
client base, or when rolling out a new key.

~~~
Wilya
I wish the official OpenVPN howto [0] highlighted this sort of things a bit
more.

As it is, it provides a clear and easy to follow path to a minimally viable
setup, but only mentions many additional security parameters (tls-auth,
running as unpriviledged user, chroot, increasing key size) under "Hardening
OpenVPN Security", very far down the page, where people probably miss it. And
this, even though some of these elements vastly increase the security with
little to no downside.

[0] [https://openvpn.net/index.php/open-
source/documentation/howt...](https://openvpn.net/index.php/open-
source/documentation/howto.html)

------
danielweber
Maybe a small note, but the variable needs to start with the _bytes_ "() {",
not the _characters_.

For example, () {̀ also triggers the parsing code. That's a ` over the { using
Unicode.

FWIW, I haven't been able to actually exploit it this way, but referencing
that variable in the new shell generates errors, so there might be something
there:

bash: () {̀ :;}; echo vuln2: invalid variable name for name reference

------
_delirium
One thing that'd be somewhat useful, with respect to #2 ("It must invoke
bash"), is to separate it into those which specifically invoke bash, versus
those that invoke /bin/sh. If bash is not installed as /bin/sh, as is the case
on Debian and Ubuntu, do any of these (inetd, exim, etc.) still explicitly
call it? Put differently, is this mainly an issue for distributions that ship
bash as /bin/sh? Or do users of distributions like Debian also need to worry
about common system services setting bash shell variables?

Maybe I'll try to answer that by pulling a bunch of Debian source packages and
grepping for explicit calls to bash...

~~~
pja
Even if they don't explicitly invoke bash, it's possible that they call a
program which calls a program which invokes a bash script somewhere.

Debian switched /bin/sh to link to dash a while back, but some maintainers
decided to simply change the #!/bin/sh at the top of the shell scripts in
their packages to #!/bin/bash rather than remove the bashisms. dhclient is the
worst offender in the current kerfuffle, but I'm sure there are others.

~~~
tokenizerrr
They did switch /bin/sh to dash, which is why it seems to me that grepping for
"bash" would be quite effective.

------
idorosen
For Mac OS X, until Apple releases a software update, I've applied the
original CVE-2014-6271 (shellshock) patch and the CVE-2014-7169 patch.
Repository and instructions to reproduce without trusting me are located here:
[https://github.com/ido/macosx-bash-92-shellshock-
patched](https://github.com/ido/macosx-bash-92-shellshock-patched)

Binary releases are here: [https://github.com/ido/macosx-bash-92-shellshock-
patched/rel...](https://github.com/ido/macosx-bash-92-shellshock-
patched/releases) ...including a .pkg file that can be installed with a
double-click.

Instruction here: [https://github.com/ido/macosx-bash-92-shellshock-
patched/blo...](https://github.com/ido/macosx-bash-92-shellshock-
patched/blob/master/README.md)

~~~
JackC
This appears (to me) to be another good temporary fix for OS X:

[http://apple.stackexchange.com/a/146851](http://apple.stackexchange.com/a/146851)

It provides a one-step copy and paste into the terminal to download, patch and
compile bash from apple.com and gnu.org.

------
lambda
You missed one of the big ones, DHCP. dhclient calls dhclient-script with
attacker controlled environment variables, and on several Linux distros I
checked, dhclient-script explicitly uses Bash, so even Debian and Ubuntu,
which use dash as sh, are vulnerable.

~~~
dfranke
Someone else already pointed this out in my comments section. I'm working on
an update.

------
zobzu
rather than adding fixup to these (which arent all exactly directly
exploitable, and sometimes have dodgy POCs), it'd be nice if we stopped
calling the shell at all and when necessary, always wipe the env entirely and
parse the user input by allowing a specific white list.

these methods were used a decade ago and programs not doing stuff like
clearing the env were seen as poorly made programs in need of rewrite.
Unfortunately that has changed.

~~~
dkubb
Thank you for mentioning this. What I don't understand is that no one is
talking about the responsibility of the programs reading the user input. They
have a responsibility to validate anything they receive using a whitelisting
approach (i.e. denying anything that doesn't match expected patterns).

If a program simply slurps in user input without doing any basic validation
according to published RFCs then there's a bug in that program.

------
AsakiIssa
I wonder if anyone has thought of any indirect vectors? Imagine a Windows
based virus that can scan a private network and use the shellshock exploit to
infect never-before-seen unix devices with a HTTP service?

------
brador
So assuming it's an online EC2 server not-updated LAMP stack with an empty cgi
folder and a lone html page with hello world. Is that vulnerable to bash
exploitation in any way?

~~~
dfranke
Probably not, unless there's something really weird in your Apache config.

------
seanp2k2
I feel like the only reasonable thing to do now is to capture all traffic
going to a web server and analyze every field for that's that eventually
become env vars.

~~~
clarry
Or fix the shell or use another one.

------
X-Istence
This of course assumes that bash is set as the default shell for those users
all those programs run under. None of my systems have bash installed, thus
they aren't vulnerable. FreeBSD by default does not ship with bash, and unless
it is specifically installed for 3rd party software use, it is not required
for anything, and certainly won't be found as /bin/sh...

Shell shock is being blown out of proportion, people are worried local
machines they use to browse internet are going to get popped when in reality
it is only really Linux machines that have bash as the default shell that
should be worried.

~~~
nitrogen
Any program that calls a library that calls a program that executes a script
with #!/bin/bash could be vulnerable, client or server. There are many ways
data can get into an environment variable.

For example, a hypothetical encryption library might be a wrapper around
/usr/bin/gpg or /usr/bin/openssl, and to avoid having arguments show up in
_ps_ or _top_ , it might pass arguments as environment variables. Later a
secure e-mail program might use that library to validate a signature from an
e-mail, and pass signature data in an environment variable. So that's MacOSX
and Fedora owned with /bin/bash as /bin/sh. Say the encryption library used a
script written in Bash to do some other processing. That's BSD owned.

~~~
X-Istence
Except that bash is not installed by default... if bash is not installed how
does BSD suddenly become vulnerable?

~~~
nitrogen
It would have been installed as a dependency of whatever used it in some
obscure way.

~~~
nitrogen
Okay, since someone actually downvoted _both_ of my comments, I'll point out
that libgpgme is a common encryption library that calls /usr/bin/gpg.
Fortunately it uses execv(), but that leaves the environment unchanged so if
anything further down the chain uses Bash it's still vulnerable.

I'll also provide a list of files from /usr/bin that are actually implemented
using Bash (from a Linux Mint system). Anything using these with user-
controlled environment variable values is vulnerable:

    
    
        $ grep -nR '#!.*bash' * | grep :1:
        apg:1:#!/bin/bash
        aptitude-create-state-bundle:1:#!/bin/bash
        aptitude-run-state-bundle:1:#!/bin/bash
        banshee:1:#!/usr/bin/env bash
        cautious-launcher:1:#!/bin/bash
        checkinstall:1:#!/bin/bash
        cinnamon2d:1:#!/bin/bash
        dns-fix:1:#!/bin/bash
        editdiff:1:#!/bin/bash
        fakenect:1:#!/bin/bash
        fakeroot:1:#!/bin/bash
        fakeroot-sysv:1:#!/bin/bash
        fakeroot-tcp:1:#!/bin/bash
        gnome-www-browser:1:#!/bin/bash
        google-chrome:1:#!/bin/bash
        google-chrome-stable:1:#!/bin/bash
        gufw-pkexec:1:#!/bin/bash
        im-config:1:#!/bin/bash -e
        init-checkconf:1:#!/bin/bash
        installwatch:1:#!/bin/bash
        inxi:1:#!/bin/bash
        itweb-settings:1:#!/bin/bash
        javaws:1:#!/bin/bash
        lcf:1:#!/bin/bash
        ldd:1:#! /bin/bash
        libtool:1:#! /bin/bash
        lua2dox_filter:1:#!/bin/bash
        lzcmp:1:#!/bin/bash
        lzdiff:1:#!/bin/bash
        lzegrep:1:#!/bin/bash
        lzfgrep:1:#!/bin/bash
        lzgrep:1:#!/bin/bash
        lzless:1:#!/bin/bash
        lzmore:1:#!/bin/bash
        mate-help:1:#!/bin/bash
        mintBackup:1:#!/bin/bash
        mint-fortune:1:#!/bin/bash
        mintupload:1:#!/bin/bash
        mintupload-manager:1:#!/bin/bash
        muinshee:1:#!/usr/bin/env bash
        mysqld_safe:1:#!/bin/bash
        p7zip:1:#!/bin/bash
        pipelight-plugin:1:#!/usr/bin/env bash
        pnmindex:1:#!/bin/bash
        policyeditor:1:#!/bin/bash
        ppmquantall:1:#!/bin/bash
        rarian-sk-config:1:#!/bin/bash
        rarian-sk-extract:1:#!/bin/bash
        rarian-sk-rebuild:1:#!/bin/bash
        rarian-sk-update:1:#!/bin/bash
        scrollkeeper-config:1:#!/bin/bash
        scrollkeeper-extract:1:#!/bin/bash
        scrollkeeper-rebuilddb:1:#!/bin/bash
        scrollkeeper-update:1:#!/bin/bash
        sotruss:1:#! /bin/bash
        steam:1:#!/usr/bin/env bash
        su-to-root:1:#!/bin/bash
        tomboy:1:#!/usr/bin/env bash
        tzselect:1:#!/bin/bash
        ucf:1:#!/bin/bash
        ucfr:1:#! /bin/bash
        usb-devices:1:#!/bin/bash
        X11/scrollkeeper-config:1:#!/bin/bash
        X11/fakenect:1:#!/bin/bash
        X11/lzgrep:1:#!/bin/bash
        X11/cautious-launcher:1:#!/bin/bash
        X11/xzdiff:1:#!/bin/bash
        X11/aptitude-create-state-bundle:1:#!/bin/bash
        X11/mint-fortune:1:#!/bin/bash
        X11/mate-help:1:#!/bin/bash
        X11/scrollkeeper-extract:1:#!/bin/bash
        X11/fakeroot:1:#!/bin/bash
        X11/editdiff:1:#!/bin/bash
        X11/lzdiff:1:#!/bin/bash
        X11/apg:1:#!/bin/bash
        X11/mintupload-manager:1:#!/bin/bash
        X11/gnome-www-browser:1:#!/bin/bash
        X11/ucfr:1:#! /bin/bash
        X11/lzcmp:1:#!/bin/bash
        X11/libtool:1:#! /bin/bash
        X11/im-config:1:#!/bin/bash -e
        X11/xzmore:1:#!/bin/bash
        X11/mintupload:1:#!/bin/bash
        X11/xzegrep:1:#!/bin/bash
        X11/javaws:1:#!/bin/bash
        X11/xchat-systray:1:#!/bin/bash
        X11/itweb-settings:1:#!/bin/bash
        X11/dns-fix:1:#!/bin/bash
        X11/su-to-root:1:#!/bin/bash
        X11/checkinstall:1:#!/bin/bash
        X11/usb-devices:1:#!/bin/bash
        X11/rarian-sk-extract:1:#!/bin/bash
        X11/tzselect:1:#!/bin/bash
        X11/google-chrome-stable:1:#!/bin/bash
        X11/xzcmp:1:#!/bin/bash
        X11/xzgrep:1:#!/bin/bash
        X11/pipelight-plugin:1:#!/usr/bin/env bash
        X11/lcf:1:#!/bin/bash
        X11/scrollkeeper-rebuilddb:1:#!/bin/bash
        X11/banshee:1:#!/usr/bin/env bash
        X11/cinnamon2d:1:#!/bin/bash
        X11/xzfgrep:1:#!/bin/bash
        X11/muinshee:1:#!/usr/bin/env bash
        X11/lzfgrep:1:#!/bin/bash
        X11/mintBackup:1:#!/bin/bash
        X11/tomboy:1:#!/usr/bin/env bash
        X11/fakeroot-sysv:1:#!/bin/bash
        X11/aptitude-run-state-bundle:1:#!/bin/bash
        X11/gufw-pkexec:1:#!/bin/bash
        X11/init-checkconf:1:#!/bin/bash
        X11/x-www-browser:1:#!/bin/bash
        X11/lzegrep:1:#!/bin/bash
        X11/rarian-sk-update:1:#!/bin/bash
        X11/sotruss:1:#! /bin/bash
        X11/ldd:1:#! /bin/bash
        X11/ppmquantall:1:#!/bin/bash
        X11/rarian-sk-rebuild:1:#!/bin/bash
        X11/xzless:1:#!/bin/bash
        X11/rarian-sk-config:1:#!/bin/bash
        X11/p7zip:1:#!/bin/bash
        X11/google-chrome:1:#!/bin/bash
        X11/lzmore:1:#!/bin/bash
        X11/fakeroot-tcp:1:#!/bin/bash
        X11/mysqld_safe:1:#!/bin/bash
        X11/ucf:1:#!/bin/bash
        X11/policyeditor:1:#!/bin/bash
        X11/lzless:1:#!/bin/bash
        X11/lua2dox_filter:1:#!/bin/bash
        X11/installwatch:1:#!/bin/bash
        X11/inxi:1:#!/bin/bash
        X11/scrollkeeper-update:1:#!/bin/bash
        X11/steam:1:#!/usr/bin/env bash
        X11/pnmindex:1:#!/bin/bash
        xchat-systray:1:#!/bin/bash
        x-www-browser:1:#!/bin/bash
        xzcmp:1:#!/bin/bash
        xzdiff:1:#!/bin/bash
        xzegrep:1:#!/bin/bash
        xzfgrep:1:#!/bin/bash
        xzgrep:1:#!/bin/bash
        xzless:1:#!/bin/bash
        xzmore:1:#!/bin/bash

~~~
clarry
And before you believe that your Linux box is any indication of how common a
dependency bash is...

I just grepped all the Makefiles in my ports tree for 'shells/bash', and came
up with 48 matches. This includes ports that depend on bash at build time, at
test time, and at runtime. So for people who just use packages, the number of
things that are going to pull in bash (as a runtime dep) is lower than that.

We have many of the same programs you have, but they do not use bash. For
example, all your executables that start with xz or lz. I have them, most of
them anyway, but they use /bin/sh, not /bin/bash.

I use BSD on the desktop, and out of the three hundred packages I have
installed, _none_ have pulled bash in as a dep. I don't have bash, I haven't
had it for years.

~~~
X-Istence
There is a couple more ports out there that require it for run, but the
numbers are quite low considering the amount of software that is available in
the ports tree:

[http://www.freshports.org/shells/bash](http://www.freshports.org/shells/bash)

~~~
clarry
My numbers are from the OpenBSD ports tree.

------
moduloo
[https://access.redhat.com/articles/1200223](https://access.redhat.com/articles/1200223)

CUPS probably too, but no POC seen yet

------
wesley
I've got an old red hat somewhere, without yum and apt-get, what can I do to
update bash on there? (RHEL3).

~~~
nknighthb
I've posted what I did (as best as I can recall) here:
[https://gist.github.com/anonymous/56afdedbf92ea98ba237](https://gist.github.com/anonymous/56afdedbf92ea98ba237)

It's entirely possible I forgot something. I haven't built an RPM in years and
didn't do it often in the first place. I almost didn't bother now except I
can't entirely exclude the possibility that two RHEL3 servers that aren't
going anywhere might have an attack vector hidden in them somewhere.

Edit: Changed link to fixed gist.

------
moduloo
suphp __might __be exploitet, but only with stupid settings

[https://8ack.de/guides/suphp_shellshock](https://8ack.de/guides/suphp_shellshock)

------
calpaterson
Somewhat ironic for all the noise made about qmail that many configurations of
it are vulnerable. I wonder if Bernstein will be paying out that $1000 reward,
and if so, to who

See section 1.3:

[http://cr.yp.to/qmail/qmailsec-20071101.pdf](http://cr.yp.to/qmail/qmailsec-20071101.pdf)

~~~
dfranke
The qmail bounty explicitly disclaims "bugs outside of qmail", which this one
clearly is. So, no.

~~~
kag
Why it's not exploitable without the shellshock-vulnerable bash, you could
argue that qmail is not validating the input in accordance with the RFCs. In
fact, that's one of the things I said here:
[http://marc.info/?l=qmail&m=141183309314366&w=2](http://marc.info/?l=qmail&m=141183309314366&w=2)

~~~
panic
Input validation is an orthogonal issue here, since bash doesn't know anything
about RFC821/RFC2821, doesn't expect data in that format, and doesn't make any
guarantees about what it will or won't do on such data.

The only reasonable policy for a shell to follow is to be entirely input-
agnostic and never execute code based on the contents of an environment
variable (regardless of which RFCs the contents conform to).

~~~
kag
Of course bash doesn't know and shouldn't know about the SMTP RFCs. Yes, bash
shouldn't execute code in variables. I was talking about input validation in
qmail itself, not bash.

Even though bash shouldn't have executed the code, better input validation and
RFC conformance in qmail could have prevented exploitation of bash. You know,
defense-in-depth.

