autoupdate
[postfix-master.git] / postfix-master / CVE-2011-0411.html
blob38d7e5821ad1ce33716e1ac21e347e57f30639b0
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
2 "http://www.w3.org/TR/html4/strict.dtd">
4 <html>
6 <head>
8 <title> Plaintext command injection in multiple implementations of
9 STARTTLS (CVE-2011-0411) </title>
11 <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
12 <link rel='stylesheet' type='text/css' href='postfix.css'>
14 </head>
16 <div id='left'>
18 <p> <img src="mysza.gif" width="130" height="91" alt="[LOGO]"> </p>
20 <p class='nav'><a href="#summary">Summary</a> </p>
22 <p class='nav'> <a href="#overview"> Overview and impact </a> </p>
24 <p class='nav'> <a href="#background"> Technical background </a>
25 </p>
27 <p class='nav'> <a href="#demonstration"> Demonstration </a> </p>
29 <p class='nav'> <a href="#anatomy"> Anatomy of the flaw </a> </p>
31 <p class='nav'> <a href="#plumbing"> It's the plumbing </a> </p>
33 <p class='nav'> <a href="#worldview"> Switching world views </a>
34 </p>
36 <p class='nav'> <a href="fix"> Fixing the problem </a> </p>
38 <p class='nav'> <a href="#conclusion"> Conclusion </a> </p>
40 <p class='nav'> <a href="timeline"> Time line </a> </p>
42 </div>
44 <div id='main'>
46 <h1> Plaintext command injection in multiple implementations of
47 STARTTLS (CVE-2011-0411) </h1>
49 <p> Author: Wietse Venema </p>
51 <p> Last update: March 7, 2011 </p>
53 <h2> <a name="summary"> Summary </a> </h2>
55 <p> This is a writeup about a flaw that I found recently, and that
56 existed in multiple implementations of SMTP (Simple Mail Transfer
57 Protocol) over TLS (Transport Layer Security) including my Postfix
58 open source mailserver. I give an overview of the problem and its
59 impact, technical background, how to find out if a server is affected,
60 fixes, and draw lessons about where we can expect similar problems
61 now or in the future. A time line is at the end. </p>
63 <h2> <a name="overview"> Problem overview and impact </a> </h2>
65 <p> The TLS protocol encrypts communication and protects it against
66 modification by other parties. This protection exists only if a)
67 software is free of flaws, and b) clients verify the server's TLS
68 certificate, so that there can be no "man in the middle" (servers
69 usually don't verify client certificates). </p>
71 <p> The problem discussed in this writeup is caused by a software
72 flaw. The flaw allows an attacker to inject client commands into
73 an SMTP session during the unprotected plaintext SMTP protocol phase
74 (more on that below), such that the server will execute those
75 commands during the SMTP-over-TLS protocol phase when all communication
76 is supposed to be protected. </p>
78 <p> The injected commands could be used to steal the victim's email
79 or SASL (Simple Authentication and Security Layer) username and
80 password. </p>
82 <p> This is not as big a problem as it may appear to be. The reason
83 is that many SMTP client applications don't verify server TLS
84 certificates. These SMTP clients are always vulnerable to command
85 injection and other attacks. Their TLS sessions are only encrypted
86 but not protected. </p>
88 <p> A similar plaintext injection flaw may exist in the way SMTP
89 clients handle SMTP-over-TLS server responses, but its impact is
90 less interesting than the server-side flaw. </p>
92 <p> SMTP is not the only protocol with a mid-session switch from
93 plaintext to TLS. Other examples are POP3, IMAP, NNTP and FTP.
94 Implementations of these protocols may be affected by the same flaw
95 as discussed here. </p>
97 <h2> <a name="background"> Technical background: SMTP over TLS </a> </h2>
99 <p> For a precise description of SMTP over TLS, see RFC 3207, on-line
100 at <a href="http://www.ietf.org/rfc/rfc3207.txt">
101 http://www.ietf.org/rfc/rfc3207.txt</a>. </p>
103 <p> SMTP over TLS uses the same TLS protocol that is also used to
104 encrypt traffic between web clients and web servers. But, there
105 is a subtle difference in the way TLS is used, and that makes this
106 flaw possible. </p>
108 <p> SMTP sessions over TLS begin with an SMTP protocol handshake
109 in plaintext. Plaintext means no encryption (thus no privacy), and
110 no protection against modification (no integrity). The plaintext
111 handshake is needed because SMTP has always worked this way. Simply
112 skipping this plaintext phase would seriously break internet email.
113 </p>
115 <p> During the plaintext handshake phase, the SMTP server announces
116 whether it is willing to use TLS. If both SMTP client and server
117 support TLS, the client sends a "STARTTLS" request to turn on TLS.
118 Once TLS is turned on, all further traffic is encrypted and protected
119 from modification. The client and server repeat the entire SMTP
120 protocol handshake, and the client starts sending mail. </p>
122 <h2> <a name="demonstration"> Demonstration </a> </h2>
124 <p> The problem is easy to demonstrate with a one-line change to
125 the OpenSSL s_client command source code (I would prefer scripting,
126 but having to install Perl CPAN modules and all their dependencies
127 is more work than downloading a .tar.gz file from openssl.org,
128 adding eight characters to one line, and doing "./config; make").
129 </p>
131 <p> (The OpenSSL s_client command can make a connection to servers
132 that support straight TLS, SMTP over TLS, or a handful other protocols
133 over TLS. The demonstration here focuses on SMTP over TLS only.)
134 </p>
136 <p> The demonstration with SMTP over TLS involves a one-line change
137 in the OpenSSL s_client source code (with OpenSSL 1.0.0, at line
138 1129 of file apps/s_client.c). </p>
140 <blockquote>
142 <table border="0">
144 <tr> <td> Old </td> <td> &nbsp </td> <td> <tt>
145 BIO_printf(sbio,"STARTTLS\r\n");</tt> </td> </tr>
147 <tr> <td> New </td> <td> &nbsp </td> <td> <tt>
148 BIO_printf(sbio,"STARTTLS\r\nRSET\r\n");</tt>
149 </td> </tr>
151 </table>
153 </blockquote>
155 <p> With this change, the s_client command sends the plaintext
156 STARTTLS command ("let's turn on TLS") immediately followed by an
157 RSET command (a relatively harmless protocol "reset"). Both commands
158 are sent as plaintext in the same TCP/IP packet, and arrive together
159 at the server. The "\r\n" are the carriage-return and newline
160 characters; these are necessary to terminate an SMTP command. </p>
162 <p> When an SMTP server has the plaintext injection flaw, it reads
163 the STARTTLS command first, switches to SMTP-over-TLS mode, and
164 only then the server reads the RSET command. Note, the RSET command
165 was transmitted during the plaintext SMTP phase when there is no
166 protection, but the server reads the command as if it was received
167 over the TLS-protected channel. </p>
169 <p> Thus, when the SMTP server has the flaw, the s_client command
170 output will show two "250" SMTP server responses instead of one.
171 The first "250" response is normal, and is present even when the
172 server is not flawed. The second "250" response is for the RSET
173 command, and indicates that the SMTP server has the plaintext
174 injection flaw. </p>
176 <blockquote>
177 <pre>
178 $ apps/openssl s_client -quiet -starttls smtp -connect server:port
179 [some server TLS certificate details omitted]
180 250 some text here <=== Normal response, also with "good" server.
181 250 more text here <=== RSET response, only with flawed server.
182 </pre>
183 </blockquote>
185 <p> How would an attacker exploit this? It would play man-in-the-middle
186 on the connection between SMTP client and server, perhaps using ARP
187 spoofing at a public WIFI access point. Instead of adding a harmless
188 RSET command, it could steal email or authentication credentials.
189 </p>
191 <h2> <a name="anatomy"> Anatomy of the flaw </a> </h2>
193 <p> The flaw is made possible by two ingredients: I already discussed
194 the switch mid-session from plaintext SMTP to SMTP over TLS. This
195 allows an attacker to piggy-back commands onto the SMTP client's
196 plaintext STARTTLS ("let's turn on TLS") request, such that the
197 server may read those commands after the switch to TLS is completed,
198 as if the commands arrived through the TLS-encrypted session. </p>
200 <p> The second ingredient is a layered software architecture through
201 which those piggy-backed commands bubble up from the network to the
202 application. In the case of SMTP, we have the following major
203 layers before and after the switch to TLS: </p>
205 <blockquote>
207 <table border="0">
209 <tr> <th align="center"> Before switch to TLS </th> <th> &nbsp;
210 </th> <th align="center"> After switch to TLS </th> </tr>
212 <tr> <td colspan="3"> &nbsp; </td> </tr>
214 <tr> <td align="center"> SMTP protocol engine </td> <td> </td> <td
215 align="center"> SMTP protocol engine </td> </tr>
217 <tr> <td align="center"> || </td> <td> </td> <td align="center">
218 || </td> </tr>
220 <tr> <td align="center"> TCP/IP protocol engine </td> <td> </td>
221 <td align="center"> TLS protocol engine </td> </tr>
223 <tr> <td align="center"> || </td> <td> </td> <td align="center">
224 || </td> </tr>
226 <tr> <td align="center"> Internet </td> <td> </td> <td align="center">
227 TCP/IP protocol engine </td> </tr>
229 <tr> <td align="center"> </td> <td> </td> <td align="center">
230 || </td> </tr>
232 <tr> <td align="center"> </td> <td> </td> <td align="center">
233 Internet </td> </tr>
235 </table>
237 </blockquote>
239 <p> Each layer hides details of what is happening inside. Layering
240 makes it easy to switch from plaintext to TLS, with minimal changes
241 to existing code. </p>
243 <p> To insert the TLS layer between the SMTP engine and the O/S
244 TCP/IP engine, simply adjust the plumbing between the layers, and
245 make all information flow through the TLS layer. </p>
247 <h2> <a name="plumbing"> It's all about the plumbing </a> </h2>
249 <p> Whether a program may have the plaintext injection flaw depends
250 on how it adjusts the plumbing, as it inserts the TLS protocol layer
251 in-between the SMTP protocol layer and the O/S TCP/IP protocol
252 layer. I illustrate this with examples from three open source MTAs:
253 Postfix, Sendmail and Exim. </p>
255 <p> The diagram below zooms in on the plumbing between the SMTP and
256 TLS layers, and shows how different MTAs handle the switch from
257 plaintext to TLS (the non-HTML version of this text is best viewed
258 with a fixed-width font, for example from the Courier family). </p>
260 <blockquote>
262 <table border="0">
264 <tr>
266 <th colspan="2" align="center"> Postfix MTA <br> before/after <br>
267 switch to TLS </th>
269 <th> &nbsp; &nbsp; &nbsp; </th>
271 <th colspan="2" align="center"> Sendmail MTA <br> before/after <br>
272 switch to TLS </th>
274 <th> &nbsp; &nbsp; &nbsp; </th>
276 <th colspan="2" align="center"> Exim MTA <br> before/after <br>
277 switch to TLS </th> </tr>
279 <tr> <td colspan="8"> &nbsp; </td> </tr>
281 <td align="center"> SMTP </td> <td align="center"> SMTP </td>
283 <td> &nbsp; </td>
285 <td align="center"> SMTP </td> <td align="center"> SMTP </td>
287 <td> &nbsp; </td>
289 <td align="center"> SMTP </td> <td align="center"> SMTP </td>
291 <td> &nbsp; </td>
293 <td align="left"> SMTP layer </td>
295 </tr>
297 <tr>
299 <td align="center"> || </td> <td align="center"> || </td>
301 <td> &nbsp; </td>
303 <td align="center"> || </td> <td align="center"> || </td>
305 <td> &nbsp; </td>
307 <td align="center"> || </td> <td align="center"> || </td>
309 </tr>
311 <tr>
313 <td align="center"> <b> stream </b> </td> <td align="center">
314 <b> stream </b> </td>
316 <td> &nbsp; </td>
318 <td align="center"> <b> stream </b> </td> <td align="center">
319 <b> stream' </b> </td>
321 <td> &nbsp; </td>
323 <td align="center"> || </td> <td align="center"> || </td>
325 </tr>
327 <tr>
329 <td align="center"> buffers </td> <td align="center"> buffers
330 </td>
332 <td> &nbsp; </td>
334 <td align="center"> buffers </td> <td align="center"> buffers'
335 </td>
337 <td> &nbsp; </td>
339 <td align="center"> rw </td> <td align="center"> r'w' </td>
341 <td> &nbsp; </td>
343 <td align="left"> stream layer </td>
345 </tr>
347 <tr>
349 <td align="center"> rw </td> <td align="center"> r'w' </td>
351 <td> &nbsp; </td>
353 <td align="center"> rw </td> <td align="center"> r'w' </td>
355 <td> &nbsp; </td>
357 <td align="center"> || </td> <td align="center"> || </td>
359 </tr>
361 <tr>
363 <td align="center"> || </td> <td align="center"> || </td>
365 <td> &nbsp; </td>
367 <td align="center"> || </td> <td align="center"> || </td>
369 <td> &nbsp; </td>
371 <td align="center"> || </td> <td align="center"> || </td>
373 </tr>
375 <tr>
377 <td align="center"> || </td> <td align="center"> TLS </td>
379 <td> &nbsp; </td>
381 <td align="center"> || </td> <td align="center"> TLS </td>
383 <td> &nbsp; </td>
385 <td align="center"> || </td> <td align="center"> TLS </td>
387 <td> &nbsp; </td>
389 <td align="left"> TLS layer </td>
391 </tr>
393 <tr>
395 <td align="center"> || </td> <td align="center"> || </td>
397 <td> &nbsp; </td>
399 <td align="center"> || </td> <td align="center"> || </td>
401 <td> &nbsp; </td>
403 <td align="center"> || </td> <td align="center"> || </td>
405 </tr>
407 <tr>
409 <td align="center"> O/S </td> <td align="center"> O/S </td>
411 <td> &nbsp; </td>
413 <td align="center"> O/S </td> <td align="center"> O/S </td>
415 <td> &nbsp; </td>
417 <td align="center"> O/S </td> <td align="center"> O/S </td>
419 <td> &nbsp; </td>
421 <td align="left"> TCP/IP layer </td>
423 </tr>
425 </table>
427 </blockquote>
429 <p> As shown in the diagram, both Postfix and Sendmail use an
430 application- level stream abstraction, where each stream has
431 properties such as read/write buffers, read/write functions (indicated
432 with rw), and other properties that are omitted for brevity. </p>
434 <p> When Postfix switches to SMTP over TLS, it replaces the plaintext
435 read/write functions (rw) with the TLS read/write functions (r'w').
436 Postfix does not modify any of the other stream properties including
437 the read/write buffers. A patch for qmail that introduces TLS
438 support uses the same approach. This approach of replacing only
439 the stream read/write functions, but not the buffers or other stream
440 properties, can introduce the plaintext injection flaw. </p>
442 <p> When Sendmail switches to SMTP over TLS, it replaces the entire
443 stream, along with its read/write buffers and read/write functions.
444 Exim. on the other hand, does not seem to have a stream abstraction
445 like Postfix, Sendmail or qmail. Instead of replacing streams or
446 stream properties, Exim replaces plaintext read/write functions
447 with TLS read/write functions. Because of their program structure,
448 Sendmail and Exim didn't suffer from the plaintext injection flaw.
449 </p>
451 <h2> <a name="worldview"> Switching world views </a> </h2>
453 <p> When the switch from plaintext to TLS mode is made, all layers
454 above the TLS layer need to purge all information that they have
455 received through the plaintext session. This "world view switch"
456 needs to be implemented consistently. Otherwise, information that
457 was sent as unprotected plaintext may slip through the cracks. </p>
459 <p> In the case of Postfix and other affected MTAs, this "world
460 view switch" was incomplete. Postfix it did not account for
461 information that lingered in stream buffers at the boundary between
462 two layers. This allowed an attacker to piggy-back commands onto
463 the plaintext "let's turn on TLS" request, such that the commands
464 could be read after the switch to TLS was completed, as if they had
465 arrived through the TLS-encrypted session. </p>
467 <h2> <a name="fix"> Fixing the problem </a> </h2>
469 <p> There are two solutions to address the flaw, and both solutions
470 can be used together. </p>
472 <ul>
474 <li> <p> Report an error when unexpected plaintext is received after
475 the STARTTLS command. As documented in RFC 3207, STARTTLS must
476 be the last command in a pipelined group. If plaintext commands
477 are received after STARTTLS, then that is a protocol violation.
478 </p>
480 <p> This measure can also be implemented outside the MTA, for
481 example in a protocol-aware firewall. </p>
483 <li> <p> If a program uses the same input buffer before and after
484 the switch to TLS, it should discard the contents of the input
485 buffer, just like it discards SMTP protocol information that it
486 received during the plaintext protocol phase. </p>
488 </ul>
490 <h2> <a name="conclusion"> Conclusion </a> </h2>
492 <p> This plaintext injection problem is likely to recur when some
493 development moves the plaintext-to-ciphertext switch outside the
494 application: for example, into the kernel, into the local hardware,
495 into a proxy, or into other infrastructure. This encourages
496 applications to use the same application-level streams and buffers
497 and read/write functions before and after the switch to ciphertext.
498 When this migration happens, plaintext injection becomes once more
499 a possibility. </p>
501 <p> Postfix did not reject plaintext commands that were piggy-backed
502 onto the plaintext "let's turn on TLS" request. This reflects what
503 once was the primary mission of Postfix: to deliver mail, not to
504 force other systems to implement all the Internet RFCs correctly.
505 Nowadays, strict protocol compliance is becoming a requirement for
506 senders to get their email delivered. As this episode shows, stricter
507 protocol enforcement by receivers can bring security benefits,
508 besides blocking spambots. </p>
510 <h2> <a name="timeline"> Time line </a> </h2>
512 <ul>
514 <li> <p> Jan 5 2011 While finishing Postfix for its
515 annual release, I found this flaw in the server and client
516 implementations of SMTP over TLS. It had been sitting there for
517 six years ever since TLS support was adopted into Postfix. Not
518 wanting to delay the release schedule, I silently fixed the problem
519 and sent an email to co-developer Victor Duchovni. </p>
521 <li> <p> Jan 6-10 2011 As we investigated the scope of
522 the problem, Victor discovered quickly that many other SMTP over
523 TLS implementations were also affected. Among those affected were
524 email service providers, email anti-spam/virus service providers,
525 anti-spam/virus appliances, as well as other mail server implementations.
526 It was clear that this problem's resolution was going to involve
527 many organizations. </p>
529 <li> <p> Jan 11 2011 Contact CERT/CC to help coordinate
530 with the problem's resolution. </p>
532 <li> <p> Mar 7 2011 Public announcement, and Postfix legacy release
533 updates. </p>
535 </ul>
537 </div>
539 </body>
541 </html>