OpenSMTPD Remote Code Execution Vulnerability (CVE-2020-7247)
Date Added to KEV Catalog: March 25, 2022
CISA Due Date for Remediation: April 15, 2022
Table of Contents
CVE-2020-7247 is a remote code execution vulnerability in OpenSMTPD. OpenSMTPD is a free smtp protocol (mail server protocol) that runs on Unix and Unix-based systems, including: Linux, FreeBSD, OpenBSD, NetBSD, DragonFlyBSD, and OSX.
NIST’s NVD CVE catalog describes CVE-2020-7247:
smtp_mailaddr in smtp_session.c in OpenSMTPD 6.6, as used in OpenBSD 6.6 and other products, allows remote attackers to execute arbitrary commands as root via a crafted SMTP session, as demonstrated by shell metacharacters in a MAIL FROM field. This affects the “uncommented” default configuration. The issue exists because of an incorrect return value upon failure of input validation.
The vulnerability is due to the smtp_mailaddr function. AQualys security advisory released the details of this vulnerability in more detail.
Mail sender email addresses are defined in the MAIL FROM field. Mail receiving email addresses are defined in the RCPT TO field. These email addresses need to be verified to prevent bad characters from being used. smtp_mailaddr() checks sender and receiver mail addresses by validating the characters used in email addresses. Email addresses can be defined in two parts: the local name before the @ symbol and domain name after the @ symbol (firstname.lastname@example.org).
The smtp_mailaddr() checks both the local and domain parts for separate sets of characters that are allowed to be used. These restrictions prevent bad characters from being used that would allow attackers to run malicious commands. CVE-2020-7247 is a vulnerability with the smtp_mailaddr() because there is a flaw when the local part becomes invalid due to bad characters. If the local part (before the @ symbol) is invalid and the domain part is empty, the email domain is automatically added and bad characters are allowed to be used. The local part becomes invalid when an attacker uses restricted characters.
The report provides these examples:
MAIL FROM:<;sleep 66;>
MAIL FROM:<;for i in 0 1 2 3 4 5 6 7 8 9 a b c d;do read r;done;sh;exit 0;>
The local part above becomes invalid with the characters < and ; and no domain name is defined. This allows for commands to be run after the restricted characters.
A common public python exploit provides a third example:
The above exploit uses makes the local name invalid with < ; and does not define a domain. It includes a CMD variable which is defined by the attacker as shown in the Exploitation section.
Systems Affected and Detection
This vulnerability affects versions the “uncommented” default version of OpenSMTPD 6.6. OpenSMTPD runs on Linux, FreeBSD, OpenBSD, NetBSD, DragonFlyBSD, and OSX.
Netcat banner grabbing and nmap can be used to show see if a smtp server is OpenSMTPD.
A common nmap script checking default SMTP port 25 looks like:
nmap -sS -sV -p 25 –script=banner <IP>
Tenable Nessus’s vulnerability scanner also checks for CVE-2020-7247.
This vulnerability can be tested with vulhub, which uses docker-compose. Exploit-DB also provides a vulnerable application to test exploits. CVE-2020-7247 can be exploited manually (explained above), with a verified Exploit-DB python exploit and a Metasploit module.
Exploit-DB Python Exploit
The vulhub environment runs OpenSMTPD on port 8825:
Netcat can also be used to get SMTP banner and connect to the service:
nc <IP> <SMTP port>
Without a specific OpenSMTPD version it can be difficult to determine if the smtp service is vulnerable. Exploit-DB shows two verified non-Metasploit exploits for OpenSMTPD. One exploit is written in Python and includes a vulnerable application and the other is written in Perl.
The python exploit, OpenSMTPD 6.6.1 – Remote Code Execution or 47984.py, lists CVE-2020-7247 and is ED-B verified:
The python exploit allows for RCE by using the characters < and ; to create an invalid MAIL FROM email address (and undefined), which allows for commands to be executed (CMD) as root.
The Vulhub environment also includes this same exploit as “poc.py”:
python3 poc.py <target ip> <target port> <command>
The example command creates a file name “x” in the /tmp directory:
Metasploit module: /unix/smtp/opensmtpd_mail_from_rce
This Metasploit module requires defining RHOSTS, RPORT, RCPT_TO, LHOST, LPORT values. By default, the RCPT_TO, valid mail recipient, is set to root.
The default payload is a cmd/unix/reverse_netcat shell. Running execute or run should return a reverse netcat shell.
Updating to the newest supported version of OpenSMTPD prevents this vulnerability. At the time of writing the most current version is 6.8.0p2.
OpenSMTPD has a portable version via GitHub and can be updated via command line.