back to article Shellshock over SMTP attacks mean you can now ignore your email

Yet another round of Shellshock attacks is emerging, according to the SANS Internet Storm Center – this time, botnets are tapping hosts over SMTP. At the moment, the report is sparse, with the ISC diary post stating merely that Shellshock exploit attempts are travelling over the mail protocol because “the sources so far have …

  1. vagabondo

    Are there any mail transfer agents or clients that would try to execute, as opposed to read a mail header?

    1. Flocke Kroes Silver badge

      Mutt gets so close that I decided to check

      Mutt does almost everything by delegating the task to some other program selected in the ~/.muttrc file. For example, sending and email is controlled by a setting like this:

      set sendmail=“/usr/sbin/sendmail -oem -oi”

      man muttrc for the sendmail variable says:

      "Mutt expects that the specified program interprets additional arguments as recipient addresses."

      When you reply to an email, mutt creates a string by appending the recipient addresses to the sendmail variable, then getting the user's shell (probably bash) to interpret the result.

      I tried changing the reply address in an email to things like $(hostname)@localhost and replying. Mutt kept sanitizing the reply address so bash never saw anything dangerous.

      I had to hunt through muttrc's man page for about quarter of an hour before I found a way to get the reply address into a command line. Mutt lets you put all sorts of things into command lines, for example %h is replaced by the local hostname. The list of substitutions is different for each variable. I did not find any remotely generated strings available as substitutions in shell commands. Someone thought carefully about blocking advanced users so they cannot accidently reconfigure remote execution flaws into their mail reader.

      I was surprised to find mutt was using bash. I expected it to use the 'system' function which calls /bin/sh which (on Debian systems) is a link to dash, not bash. It probably found bash in the SHELL environment variable, which defaults to bash on most Linux distributions.

      Linux is covered in places where every detail can be reconfigured with a shell script. The mail system is often extremely flexible, with support for different delivery and transport agents, and multiple spam and virus checkers on incoming, outgoing and forwarded messages. I am not surprised that crackers are looking weaknesses here. There might even be one to exploit (on systems where a half-competent sysadmin has failed to do something clever).

      Updating to a recent bash will block this exploit search, so if you haven't already, do it now.

      1. Phil O'Sophical Silver badge

        Re: Mutt gets so close that I decided to check

        When you reply to an email, mutt creates a string by appending the recipient addresses to the sendmail variable, then getting the user's shell (probably bash) to interpret the result.

        Sounds dangerous. Sanitizing shell input is notoriously difficult and undependable. There are many tricks to sneak escape characters past filters, especially if multibyte characters are permitted, as they now are in email addresses. A value which may seem like a single multibyte character to some code could be seen as a sequence of 2 or 4 simple characters to code that only handles 8-bit. If one of those bytes happens to be significant to a shell, like a ";" or a "\" then all bets are off.

        The only safe approach is never to pass remote user input to a local shell, santiized or not.

      2. This post has been deleted by its author

      3. eulampios

        are you sure mutt needs

        >>..then getting the user's shell (probably bash) to interpret the result

        Not in my case at least. My shell, according to /etc/passwd is /bin/bash, however, mutt uses /bin/dash (or /bin/sh on my LMDE system) in the "set whatever=`blah-bla-blah`" constructs. It is only used for the set directives. Neither it uses or needs a shell to glue sendmail and addresses together, unless you specify them out of the command you launch mutt (that would be the current shell to do that job then, BTW) Moreover, Mutt might only use env, no shell at all to interpret the system environment.

        Also, I don't have set sendmail in my muttrc file, it uses /usr/sbin/sendmail from postfix.

        In the set directive /bin/sh evaluates the environment variables or can launch commands in the usual `` way, but this is exactly what it is meant to be. In no way you can set the system or user environment variables from or in mutt, BTW.

        Also, the fact that any kind pf shell is used to evaluate env variables contradicts the fact that neither mutt(-patched) nor postfix claim shells or system utilities as their dependencies. Mutt just expects that the best way to consult about the env variables on a Unix-based system is via /usr/bin/env.

        According to Michael Elkin's own manual:

        "UNIX environments can be accessed like the way it is done in shells like sh and bash: Prepend the name of the environment by a ``$''. For example,

        set record=+sent_on_$HOSTNAME"

      4. eulampios

        Re: Mutt gets so close that I decided to check

        >>I was surprised to find mutt was using bash. I expected it to use the 'system' function which calls /bin/sh which (on Debian systems) is a link to dash, not bash. It probably found bash in the SHELL environment variable, which defaults to bash on most Linux distributions.

        Again, why are you convinced it uses /bin/bash? Because, it said so when you used ${SHELL} or $SHELL in the set var="" directive? Well, that just what the env says, indeed I got the following going on my system:

        dash -c 'echo $SHELL';ksh -c 'echo $SHELL'

        /bin/bash

        /bin/bash

        So, both dash and ksh "disguise" themselves as /bin/bash.

        Anyways, as I mentioned earlier when mutt expects you to use shell it will indeed use /bin/sh, dash in case of Debian-based systems.

        Moreover, I got this

        perl -e 'system("echo \${SHELL\%\%sh}")'

        /bin/ba

        As you would expect from dash or ash, yes and the good ol' bash :)

        When I put "set alias_file=${SHELL%%sh}/.mutt/aliases1" I get the error :

        line 13: /.mutt/aliases1: No such file or directory

        So, mutt doesn't seem to use even the system() or sh to evaluate and expand the variables.

      5. eulampios

        to dissipate all speculations and hearsay on the Mutt email client

        Just to put all the wild guesswork of others at rest on how Mutt works.

        1) A Unix shell is not a requirement for Mutt to work properly.

        2) Mutt doesn't use any shell to communicate with the sendmail, its substitute or any other SMTP agent

        3) Mutt does NOT use the user's shell (from /etc/passwd ) to do anything internally, unless it is launched in a given shell, in which case, it would be used externally as with any other utility or command launched in the shell.

        4) According to the source code in the init.c file Mutt uses the standard getenv() function provided by the stdlib.h to evaluate the environment variables for the "$" or "${...} " constructs in the set directives (when supplied in the init muttrc file, -e option or the ":" command inside of mutt).

        5. The standard system() function or /bin/sh is used to interpret the back-tick shell constructs, it is NOT the user's shell. If unknown the USER, HOME and MAIL variables can be evaluated through /bin/sh as well, as follows from the init.c source file

    2. Anonymous Coward
      Anonymous Coward

      Thank god we run Exchange Edge Transport Server for our SMTP gateways...

  2. sisk

    For crying out loud people, patch your bash already. The shellshock fix was rolled into every major distro's security updates weeks ago. Why are there still vulnerable systems out there? I'm one who usually doesn't update without a good reason, but this is not your typical priviledge-escalation-if-the-attacker-is-at-the-keyboard bug that most Linux vulnerabilities are. This one is big and remotely exploitable. GO RUN YOUR UPDATES FFS!

    1. Lee D Silver badge

      I think the news is not that people who haven't updated bash are vulnerable. That much is obvious.

      The news is that there's another major sector of programs handing off to bash in order to do the simplest of things (read the mutt post above). While that appears fine, it's something that not many are aware of, and means pulling in a huge codebase into the path of your external network functions that just increases the attack vector and makes it harder to effectively audit the code.

      The problem, ironically, is systematic - not bash - in that we're relying on the shell to do far too much. The "one tool for the job" mentality of UNIX is falling apart where we've done this, and nobody noticed for quite a while. I wasn't aware that mutt or Apache were pulling in full bash shells to set environment variables, were you? It would have rung alarm bells for me if I'd known that, even on a casual, personal-use basis.

      Where else are we pulling in unnecessarily powerful tools to do simple jobs that might be better achieved somehow else? Are those places vulnerable to outside attack? Have they been audited? Are people aware of the possibility? And, most importantly, someone somewhere must have known about these things - imagine the SELinux people, for example. They are generating signatures of exactly what a program needs to operate, including if it executes other programs, and either allowing or disallowing it. But yet nobody noticed that there might be a problem existing in bash for DECADES if it's used in this way.

      I love Linux, but we seem to have strayed from the UNIX philosophies too far - we shouldn't be allowing software to pull in entire other programs to do simple tasks. Hell, why is there not just a "set" program that we can pull in when we need to set environment variables and that's ALL it can do? Why are we using full bash from our web servers which gives us the potential to embed (and successfully execute) a ping command, or any other, from a remote HTTP request?

      The bash patch is just the sticking plaster over the wound. But we've been doing dangerous things for too long, and we need to look and change. It's not just a matter of "update bash", we're finding that this affects almost every remote service we offer and is a gaping security hole - and it's time we looked into what the security distros are doing in allowing it, and what we can do to make sure that the mutt author, for example, doesn't feel the need to pull in the full bash just to set an email address into an environment variable.

      1. Rob Carriere

        I think the biggest problem is that system() is far more convenient than fork() + the exec*() family of functions.

        Water flows downhill. You can rant at people not to do the wrong things until you're blue in the face, but you will only achieve reliable results when it is easier to it right than to do it wrong. At some level, this might be considered a bug in the design of the API.

        1. Charles 9

          "Water flows downhill. You can rant at people not to do the wrong things until you're blue in the face, but you will only achieve reliable results when it is easier to it right than to do it wrong. At some level, this might be considered a bug in the design of the API."

          But the problem is that the secure way is ALWAYS a HARD way. Like locking the door. Sure, you can make a door that auto-locks, but there are side effects (locking yourself out, for starters). Turnkey security is an elusive, if not outright impossible goal. Sometimes, you just can't fix stupid. And if stupid's your superior...

          The problem becomes much harder when you ALSO have a deadline, meaning you can't just do it right but also have to do it right QUICKLY. Doing things rightfast is daunting.

          1. Rob Carriere

            Turnkey security is hard and not always possible, sure. That doesn't mean we shouldn't try to get as close as we can.

            You could think of a library that contains the fork/exec boilerplate and a globbing function. Some scripting languages in effect do this.

            Alternatively, you could make a safer version of system() that only passes environment variables you explicitly request.

            system("foo --bar *.baz", "EMACS", "TMPDIR");

            or something like that.

            1. sisk

              Attacks that fail don't make the news. The ones in this article should be failing because there shouldn't be more than a handful of machines still running an unpatched Bash out there by now. That was my point.

              Also, to answer the question posed, yes I was aware of Apache's pulling in of Bash (knowledge which, given that I'm a web developer, should surprise no one), but I was unaware that Mutt did it. I sort of doubt it's going to change though. There are just too many tasks easily done with a half dozen lines of Bash that take a thousand lines of C++. More code means more bugs. More bugs means more security holes. Plus programmers are lazy sorts when it comes to reinventing the wheel (hence the popularity of OOP and reusable libraries).

      2. Anonymous Coward
        Anonymous Coward

        "Where else are we pulling in unnecessarily powerful tools to do simple jobs that might be better achieved somehow else?"

        Because if it ain't broke, don't fix it. The problem with embedding is that it essentially means rolling your own interpretation, and that means a new potential point of failure or exploit. I think this is the essential part of the UNIX KISS Principle: don't build a second of something you already have. Sure, with things like bash there's a potential for a wide-ranging exploit, but because it's JUST in bash, it's also pretty simple to fix: patch bash and the problem goes away. It's a lot better than every program having its own interpretation of a faulty bash function which means all the copies have to be patched which means your system can be at the mercy of some third party whose updating habits have lately gotten flaky.

      3. Irony Deficient

        why is there not just a “set” program […] to set environment variables and that’s ALL it can do?

        Lee D, it’s because there’s never been a system-level function to allow setting the value of an environment variable in a caller-specified process. The setenv() function can only set an environment variable’s value in the calling process.

      4. eulampios

        what mutt doesn't do

        >>pulling in full bash shells to set environment variables

        It's evaluating, not setting the environment variables, which are local. It won't need any shell to set it's own mutt's variable, more so, it would not interpreter anything beyond /etc/profile ~/.profile or whatever is the shell profile is in use. On my Debian system it's dash, BTW.

        If you'd need to use env variables at all why reinventing the wheel... I mean the shell all the time?

      5. eulampios

        getenv() instead of shell, @Lee D

        No, Lee D, it turns out that Mutt doesn't set its variables by using the shell, unless you put your strings in the back-tick construct ``, where you specifically ask it to, that it's the system shell /bin/sh or system(), not the user's shell as was suggested above. The standard system getenv() function is used instead, just look in the init.c file of the Mutt source. There are two places to get PWD, USER and HOME dir where it could consult sh though to know the default locations of many things, like muttrc, Mail etc

        Another great point about open source that it needs very little back engineering to establish things, just look inside the code :)

  3. Adam 1
    1. Flocke Kroes Silver badge

      501 Syntactically invalid HELO argument(s)

      1. Anonymous Dutch Coward

        HELO bashthis.evilhacker.com

  4. krivine

    Windows users: don't forget Cygwin

    Linux at home. Windows at work, with little-used Cygwin. I forgot all about it, till our IT department sent round a note listing what needs patching.

  5. Anonymous Coward
    Anonymous Coward

    a perl-based botnet

    It is truly the end-times.

    1. John Brown (no body) Silver badge
  6. Anonymous Coward
    Anonymous Coward

    Had this

    Had this very attack happen yesterday on our companies hosting servers. 27 emails in quick succession dated 1st Jan 1970 from the server root with commands to fetch script from a compromised server. Absolutely crapped myself until I remembered I'd patched. Can't imagine what I'd have felt or what would have happened if I hadn't patched.

POST COMMENT House rules

Not a member of The Register? Create a new account here.

  • Enter your comment

  • Add an icon

Anonymous cowards cannot choose their icon