OpenSMTPD Vulnerability (CVE-2020-8794) Can Lead to Root Privilege Escalation and Remote Code Execution
By Alexander Elkholy (Threats Analyst)
A root privilege escalation and remote execution vulnerability (designated as CVE-2020-8794) has been discovered in the free and open-source Unix Daemon, OpenSMTPD. The flaw originates from an out-of-bounds read, which attackers can take advantage of to execute arbitrary code on vulnerable systems.
What is the vulnerability about?
Discovered by Qualys Research Labs and disclosed on February 24, 2020, the vulnerability affects all versions of OpenSMTPD prior to 6.6.4. Part of the OpenBSD project, OpenSMTPD facilitates email communications to allow the retrieval and delivery of mail, and implements the Simple Mail Transfer Protocol (SMTP) protocol.
This is the third OpenSMTPD vulnerability found in the last month, with the previous two being a remote code execution vulnerability (CVE-2020-7247) that allows attackers to execute arbitrary commands as root through a specially crafted SMTP session and a vulnerability (CVE-2020-8793) that allows local users to potentially read arbitrary system files.
This vulnerability (CVE-2020-8794) is especially notable since it affects default installations of OpenSMTPD and the most current release of OpenBSD (version 6.6 at the time of writing) ships with a vulnerable version.
CVE-2020-8794, originally introduced to OpenSMTPD in version 5.7.1 and included in OpenBSD as of December 2015, allowed attackers to run commands as any non-root user. The effect of the flaw worsened after OpenSMTPD switched to a new message grammar in May 2018, where it allowed attackers to run commands as root.
How can the vulnerability be exploited?
The location of the vulnerability is in mta_session.c, specifically, in the mta_io function that is responsible for parsing multiline replies from an SMTP server. The out-of-bounds error occurs when the last line of the reply does not follow the standard format of three-digit code/space/text (e.g., instead of “250 DATA”, we pass “250”).
When this occurs, the pointer the program uses to read the string ends up pointing to a location that is found after the ‘