CERT/CC announces a flaw today in multiple STARTTLS implementations.
This problem was silently fixed in Postfix 2.8 and 2.9. Updates
for Postfix 2.[4-7] are made available via the usual channels.
Wietse
Plaintext injection in multiple implementations of STARTTLS
===
This is a writeup about a flaw that I found recently, and that
existed in multiple implementations of SMTP (Simple Mail Transfer
Protocol) over TLS (Transport Layer Security) including my Postfix
open source mailserver. I give an overview of the problem and its
impact, technical background, how to find out if a server is affected,
fixes, and draw lessons about where we can expect similar problems
now or in the future. A time line is at the end.
On-line information is/will be available at:
http://www.kb.cert.org/vuls/id/555316
http://www.postfix.org/CVE-2011-0411.html
Problem overview and impact
===
The TLS protocol encrypts communication and protects it against
modification by other parties. This protection exists only if a)
software is free of flaws, and b) clients verify the server's TLS
certificate, so that there can be no "man in the middle" (servers
usually don't verify client certificates).
The problem discussed in this writeup is caused by a software flaw.
The flaw allows an attacker to inject client commands into an SMTP
session during the unprotected plaintext SMTP protocol phase (more
on that below), such that the server will execute those commands
during the SMTP-over-TLS protocol phase when all communication is
supposed to be protected.
The injected commands could be used to steal the victim's email or
SASL (Simple Authentication and Security Layer) username and password.
This is not as big a problem as it may appear to be. The reason
is that many SMTP client applications don't verify server TLS
certificates. These SMTP clients are always vulnerable to command
injection and other attacks. Their TLS sessions are only encrypted
but not protected.
A similar plaintext injection flaw may exist in the way SMTP clients
handle SMTP-over-TLS server responses, but its impact is less
interesting than the server-side flaw.
SMTP is not the only protocol with a mid-session switch from plaintext
to TLS. Other examples are POP3, IMAP, NNTP and FTP. Implementations
of these protocols may be affected by the same flaw as discussed here.
Technical background: SMTP over TLS
===
For a precise description of SMTP over TLS, see RFC 3207, on-line
at http://www.ietf.org/rfc/rfc3207.txt.
SMTP over TLS uses the same TLS protocol that is also used to encrypt
traffic between web clients and web servers. But, there is a subtle
difference in the way TLS is used, and that makes this flaw possible.
SMTP sessions over TLS begin with an SMTP protocol handshake in
plaintext. Plaintext means no encryption (thus no privacy), and no
protection against modification (no integrity). The plaintext
handshake is needed because SMTP has always worked this way. Simply
skipping this plaintext phase would seriously break internet email.
During the plaintext handshake phase, the SMTP server announces
whether it is willing to use TLS. If both SMTP client and server
support TLS, the client sends a "STARTTLS" request to turn on TLS.
Once TLS is turned on, all further traffic is encrypted and protected
from modification. The client and server repeat the entire SMTP
protocol handshake, and the client starts sending mail.
Demonstration
=
The problem is easy to demonstrate with a one-line change to the
OpenSSL s_client command source code (I would prefer scripting, but
having to install Perl CPAN modules and all their dependencies is
more work than downloading a .tar.gz file from openssl.org, adding
eight characters to one line, and doing "./config; make").
(The OpenSSL s_client command can make a connection to servers that
support straight TLS, SMTP over TLS, or a handful other protocols
over TLS. The demonstration here focuses on SMTP over TLS only.)
The demonstration with SMTP over TLS involves a one-line change in
the OpenSSL s_client source code (with OpenSSL 1.0.0, at line 1129
of file apps/s_client.c).
Old:BIO_printf(sbio,"STARTTLS\r\n");
New:BIO_printf(sbio,"STARTTLS\r\nRSET\r\n");
With this change, the s_client command sends the plaintext STARTTLS
command ("let's turn on TLS") immediately followed by an RSET command
(a relatively harmless protocol "reset"). Both commands are sent
as plaintext in the same TCP/IP packet, and arrive together at the
server. The "\r\n" are the carriage-return and newline characters;
these are necessary to terminate an SMTP command.
When an SMTP server has the plaintext injection flaw, it reads the
STARTTLS command first, switches to SMTP-over-TLS mode, and only
then the server reads the RSET command. Note, the RSET command was
transmitted during the plaintext SMTP phas