Memory corruption in Postfix SMTP server Cyrus SASL

2011-05-15 / 2011-05-16
Risk: Medium
Local: No
Remote: Yes
CWE: CWE-119


CVSS Base Score: 6.8/10
Impact Subscore: 6.4/10
Exploitability Subscore: 8.6/10
Exploit range: Remote
Attack complexity: Medium
Authentication: No required
Confidentiality impact: Partial
Integrity impact: Partial
Availability impact: Partial

[On-line version will be at http://www.postfix.org/CVE-2011-1720.html] Summary ======= The Postfix SMTP server has a memory corruption error when the Cyrus SASL library is used with authentication mechanisms other than PLAIN and LOGIN (the ANONYMOUS mechanism is unaffected but should not be enabled for different reasons). See below for instructions to determine what systems are affected. Examples of affected Cyrus SASL authentication methods are CRAM-MD5, DIGEST-MD5, EXTERNAL, GSSAPI, KERBEROS_V4, NTLM, OTP, PASSDSS-3DES-1, and SRP. The error was introduced with the Postfix SASL patch, and is present in all Postfix versions where the command "postconf mail_release_date" reports a value of 20000314 (March 14, 2000) or greater. This problem was discovered by Thomas Jarosch of Intra2net AG. The memory corruption is known to result in a program crash (SIGSEV). Remote code execution cannot be excluded. Such code would execute as the unprivileged "postfix" user. This user has no control over processes that run with non-postfix privileges including Postfix processes running as root; the impact may be reduced with configurations that enable the Postfix chroot feature or that use platform-dependent privilege-reducing features. The problem is fixed in Postfix stable releases 2.5.13, 2.6.10, 2.7.4, 2.8.3; in the Postfix 2.9 development release as of May 1, 2011; patches exist for Postfix version 1.1 and later. All this is available from Postfix mirrors at http://www.postfix.org/download.html. What systems are affected ========================= The Postfix SMTP client is not affected. Affected are Postfix SMTP server configurations that have SASL authentication turned on, and that use Cyrus SASL authentication mechanisms other than ANONYMOUS, PLAIN and LOGIN. Here, * the command "postconf smtpd_sasl_auth_enable" produces as output "smtpd_sasl_auth_enable = yes"; * and the command "postconf smtpd_sasl_type" produces as output "smtpd_sasl_type = cyrus" (or "smtpd_sasl_type: unknown parameter"); * and the Postfix SMTP server's reply to the EHLO command shows AUTH methods other than ANONYMOUS, PLAIN and LOGIN. Examples of other methods are CRAM-MD5 or DIGEST-MD5. Example for the "port 25" service: $ telnet server.example.com 25 Connected to server.example.com. Escape character is '^]'. 220 server.example.com ESMTP Postfix ehlo client.example.com 250-server.example.com 250-PIPELINING 250-SIZE 10240000 250-STARTTLS 250-AUTH DIGEST-MD5 LOGIN PLAIN CRAM-MD5 250-AUTH=DIGEST-MD5 LOGIN PLAIN CRAM-MD5 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN quit 221 2.0.0 Bye Connection closed by foreign host. Example for the "port 587" (submission) service. This service is not enabled by default. $ openssl s_client -quiet -starttls smtp -connect server.example.com:587 [TLS handshake information deleted] 250 DSN ehlo client.example.com 250-server.example.com 250-PIPELINING 250-SIZE 10240000 250-AUTH DIGEST-MD5 LOGIN PLAIN CRAM-MD5 250-AUTH=DIGEST-MD5 LOGIN PLAIN CRAM-MD5 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN quit 221 2.0.0 Bye Although it is not affected, the ANONYMOUS authentication mechanism should not be enabled as it can make an SMTP server an open relay. What systems are not affected ============================= The Postfix SMTP client is not affected. Not affected are Postfix SMTP server configurations that have SASL authentication turned off, including configurations without SASL support compiled in. Here, the command "postconf smtpd_sasl_auth_enable" produces as output "smtpd_sasl_auth_enable = no". Not affected are Postfix SMTP server configurations that use Dovecot SASL instead of Cyrus SASL. Here, the command "postconf smtpd_sasl_type" produces as output "smtpd_sasl_type = dovecot". Not affected are Postfix SMTP server configurations that enable Cyrus SASL support with only the PLAIN or LOGIN methods, or both. Here, * the command "postconf smtpd_sasl_auth_enable" produces as output "smtpd_sasl_auth_enable = yes"; * and the command "postconf smtpd_sasl_type" produces as output "smtpd_sasl_type = cyrus" (or "smtpd_sasl_type: unknown parameter"); * and the Postfix SMTP server's reply to the EHLO command shows only AUTH mechanisms of PLAIN, LOGIN, or both. Example for the "port 25" service: $ telnet server.example.com 25 Connected to server.example.com. Escape character is '^]'. 220 server.example.com ESMTP Postfix ehlo client.example.com 250-server.example.com 250-PIPELINING 250-SIZE 10240000 250-STARTTLS 250-AUTH LOGIN PLAIN 250-AUTH=LOGIN PLAIN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN quit 221 2.0.0 Bye Connection closed by foreign host. Example for the "port 587" (submission) service. This service is not enabled by default. $ openssl s_client -quiet -starttls smtp -connect server.example.com:587 [TLS handshake information deleted] 250 DSN ehlo client.example.com 250-server.example.com 250-PIPELINING 250-SIZE 10240000 250-AUTH LOGIN PLAIN 250-AUTH=LOGIN PLAIN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN quit 221 2.0.0 Bye Not affected is the ANONYMOUS authentication mechanism, but this should not be enabled as it can make an SMTP server an open relay. Workarounds =========== Disable Cyrus SASL authentication mechanisms for the Postfix SMTP server other than PLAIN and LOGIN. The mechanisms are specified in a Cyrus SASL smtpd.conf configuration file. This file may be found in /etc/postfix/sasl/, /var/lib/ sasl2/, /etc/sasl2/, /usr/lib/sasl2/ or /usr/local/lib/sasl2/. In this file, update the "mech_list:" entry and remove any methods other than PLAIN and LOGIN. For example, this configuration is not affected: mech_list: PLAIN LOGIN Execute the command "postfix reload" to make the change effective, then verify that the "port 25" and "port 587" services no longer announce other SASL mechanisms, as shown in the previous section. Technical details ================= The Postfix SMTP server creates a SASL handle for each SMTP session, when SASL authentication is enabled. The Postfix SMTP server will use this SASL handle until it closes the SMTP connection (the Postfix SMTP server may create a new server SASL handle when the client and server agree to switch from a plaintext session to a TLS-encrypted session, but this does not eliminate the memory corruption problem). According to a comment in a Cyrus SASL include source file, a server must not reuse a Cyrus SASL server handle after client authentication failure. Instead, a server must create a new Cyrus SASL server handle including mechanism list, before processing another client authentication request. The Postfix SMTP server fails to create a new Cyrus SASL server handle after authentication failure. This causes memory corruption when, for example, a client requests CRAM-MD5 authentication, fails to authenticate, and then invokes some other authentication mechanism except PLAIN (or ANONYMOUS if available). The likely outcome is that the Postfix SMTP server process crashes with a segmentation violation error (SIGSEGV, a.k.a. signal 11). In the following example, S: indicates server output and C: indicates client input. Line numbers are prepended for reference in the background discussion in the next section. 1 S: 220 server.example.com ESMTP 2 C: EHLO client.example.com 3 S: 250-server.example.com 4 S: ...other server output skipped... 5 S: 250-AUTH DIGEST-MD5 LOGIN PLAIN CRAM-MD5 6 S: 250-AUTH=DIGEST-MD5 LOGIN PLAIN CRAM-MD5 7 S: ...other server output skipped... 8 C: AUTH CRAM-MD5 9 S: 334 PDg5ODE0OTI3MS4xMDQyMTg1OUBzZXJ2ZXIuZXhhbXBsZS5jb20+Cg== 10 C: * 11 S: 501 5.7.0 Authentication aborted 12 C: AUTH DIGEST-MD5 13 Connection closed by foreign host. In the mail logfile, Postfix will log a warning similar to: postfix/master[2213]: warning: process /usr/libexec/postfix/smtpd pid 22585 killed by signal 11 Background ========== Each Cyrus SASL authentication mechanism is implemented with a) one statically-allocated shared data structure containing data and pointers to functions that implement the mechanism, and b) dynamically-allocated session context data structures with authentication state. When the Postfix SMTP server receives "AUTH CRAM-MD5" (line 8 above), the Cyrus SASL CRAM-MD5 method initializes one CRAM-MD5 session context data structure, and generates the "step 1" initial client challenge which the Postfix SMTP server sends in line 9 above. When the SMTP client sends "*" to abort the CRAM-MD5 authentication request (line 10 above), the CRAM-MD5 session context data structure remains attached to the Cyrus SASL server handle. Postfix fails to create a new Cyrus SASL server handle when the client sends the subsequent "AUTH DIGEST-MD5" request (line 12 above); the DIGEST-MD5 method will therefore use the "wrong" session context data structure (which was created after the "AUTH CRAM-MD5" request on line 8), and will skip its "step 1" challenge. Each Cyrus SASL authentication method has a different context data structure layout. Because of these differences, the bits from the CRAM-MD5 method's context data structure will not work as intended with the DIGEST-MD5 method. As shown in the stack trace below, the Postfix SMTP server process crashes in "step 2" of the DIGEST-MD5 authentication protocol. This happens while attempting to read from a pointer that contains an invalid address. In this particular example, the Postfix SMTP server crashes while running under control of the GDB debugger (see the Postfix master(5) manpage discussion of the -D option), while processing the SMTP commands shown in the example above. (gdb) where #0 0x884bbedf in clear_reauth_entry (reauth=0x206e6f69, type=SERVER, utils=0x88534400) at digestmd5.c:1579 #1 0x884be648 in digestmd5_server_mech_step2 (stext=0x88518150, sparams=0x8850c840, clientin=0x0, clientinlen=0, serverout=0xbfbfe140, serveroutlen=0xbfbfe144, oparams=0x8855e860) at digestmd5.c:2588 #2 0x884be9c5 in digestmd5_server_mech_step (conn_context=0x88518150, sparams=0x8850c840, clientin=0x0, clientinlen=0, serverout=0xbfbfe140, serveroutlen=0xbfbfe144, oparams=0x8855e860) at digestmd5.c:2689 #3 0x882a51e9 in sasl_server_step (conn=0x8855e000, clientin=0x0, clientinlen=0, serverout=0xbfbfe140, serveroutlen=0xbfbfe144) at server.c:1430 #4 0x882a5002 in sasl_server_start (conn=0x8855e000, mech=0x8854dc08 "DIGEST-MD5", clientin=0x0, clientinlen=0, serverout=0xbfbfe140, serveroutlen=0xbfbfe144) at server.c:1362 #5 0x08066bf7 in xsasl_cyrus_server_first (xp=0x8851af18, sasl_method=0x8854dc08 "DIGEST-MD5", init_response=0x0, reply=0x8851aee8) at xsasl_cyrus_server.c:529 [Remainder of stack trace omitted for brevity] This stack trace was obtained after informing the GDB debugger of SASL authentication methods that are linked in at runtime (example: "add-symbol-file /usr/local/lib/sasl2/libdigestmd5.so.2 0x884b8e50"). Without that information, GDB reports a corrupted stack, because it does not know that the program is executing legitimate code. Impact analysis =============== What context data structure bits does the DIGEST-MD5 method inherit from the aborted CRAM-MD5 authentication request? As mentioned earlier, different Cyrus SASL authentication methods have different per-session context data structures. In particular, the CRAM-MD5 method uses a small structure while DIGEST-MD5 uses a larger one. The DIGEST-MD5 method will therefore access memory outside the block that was allocated during the aborted CRAM-MD5 request. That is, it accesses random memory on the heap. The contents of that memory will depend on the malloc implementation and on the program execution history. Version 2.1.23 of the Cyrus SASL library implements 12 authentication methods. Of these, 9 methods maintain server session context data structures that contain some mix of data and data pointers. When these are read from random heap memory, or from a structure that was allocated for a different SASL mechanism, all kinds of things could happen. This is why remote code execution cannot be excluded. Why the Cyrus SASL PLAIN and LOGIN methods are not affected =========================================================== There is no memory corruption problem with the "AUTH PLAIN" method, because this does not use or create a dynamically-allocated session context data structure. In particular, sending "AUTH LOGIN" after aborting or failing an "AUTH PLAIN" request does not result in memory corruption, because the PLAIN authentication method does not allocate a session context data structure. Also, sending "AUTH PLAIN" after aborting or failing an "AUTH LOGIN" request does not result in memory corruption, because the PLAIN authentication method ignores the per-session context data structure that is created by the LOGIN authentication method. Finally, there is no memory corruption when the LOGIN authentication method inherits a session context data structure from an aborted or failed "AUTH LOGIN" request. It is for these reasons that Postfix SMTP servers with Cyrus SASL support for only PLAIN and LOGIN are not affected. Fortunately, PLAIN + LOGIN is the most commonly-used configuration, usually combined with TLS encryption to protect passwords on the wire. There will be a minor memory leak, but the Postfix SMTP server limits the number of failed requests and thereby limits the leak. There is no memory corruption problem with the "AUTH ANONYMOUS" method, because just like "AUTH PLAIN" this does not create or use a dynamically-allocated session context data structure. However, "AUTH ANONYMOUS" support should not be enabled as it can make an SMTP server an open relay. Timeline ======== * April 8, 2011: Thomas Jarosch (Intra2net AG) reported the problem. * April 18, 2011: After completing a detailed analysis of what configurations are affected, and after testing solutions for Postfix 1.1 .. 2.9, Wietse asked CERT/CC to notify vendors. Thank you, CERT/CC. * April 20, 2011: Pre-release versions available for Postfix 2.5 .. 2.8 and patches for Postfix 1.1 .. 2.9. * Most vendors honored Wietse's request to avoid non-public information in plaintext email headers or content. The exceptions were SUSE and Red Hat. Shame on you, SUSE and Red Hat. * May 9, 2011: Announcement and public release of fixes.

References:

http://www.kb.cert.org/vuls/id/727230
http://www.securityfocus.com/bid/47778
https://bugzilla.redhat.com/show_bug.cgi?id=699035
http://xforce.iss.net/xforce/xfdb/67359
http://www.ubuntu.com/usn/usn-1131-1
http://www.securityfocus.com/archive/1/archive/1/517917/100/0/threaded
http://www.postfix.org/CVE-2011-1720.html
http://www.postfix.org/announcements/postfix-2.8.3.html
http://www.osvdb.org/72259
http://www.mail-archive.com/postfix-announce@postfix.org/msg00007.html
http://secunia.com/advisories/44500


Vote for this issue:
50%
50%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2018, cxsecurity.com

 

Back to Top