Subject: Re: [TLS] [oss-security] CVE-2009-3555 for TLS renegotiation MITM attacks

From: Eygene Ryabinkin <[email-masked]>
Date: Sat, 7 Nov 2009 02:05:31 +0300

Sorry for jumping in, but I had missed the topic in the other lists,
so I am trying to ask here.  Also CC'ing [email-masked] -- sorry for
such cross-posting.

Thu, Nov 05, 2009 at 03:24:30PM +0000, Mark J Cox wrote:
> Marsh Ray of PhoneFactor has discovered a flaw in the TLS/SSL protocol
> related to the handling of the session renegotiations.  In certain
> circumstances this flaw could be used in MITM attacks, allowing an
> attacker to inject attacker-chosen plain text prefix into a secure
> session of the victim.

Had anyone considered the scenario when the server requires client
certificate from the beginning, but MITM possesses some other
credentials that will be good for authentication (but can be of no use
for authorization)?  In this case MITM can use this certificate to start
the splitting request, then initiate renegotiation and proxy client's
request through the established channel.  I see that Apache asks for the
certificate for the second renegotiation, as well as the OpenSSL's
s_server.  Here is the trace for s_server:
-----
$ openssl s_client -msg -key userkey.pem -cert usercert.pem -host somehost -port 8443 | grep -E '^(<<<|>>>)'
Enter pass phrase for userkey.pem:
>>> SSL 2.0 [length 0086], CLIENT-HELLO
<<< TLS 1.0 Handshake [length 004a], ServerHello
<<< TLS 1.0 Handshake [length 0b01], Certificate
depth=1 /C=RU/O=some/CN=CA
verify error:num=19:self signed certificate in certificate chain
verify return:0
<<< TLS 1.0 Handshake [length 010d], ServerKeyExchange
<<< TLS 1.0 Handshake [length 0055], CertificateRequest
<<< TLS 1.0 Handshake [length 0004], ServerHelloDone
>>> TLS 1.0 Handshake [length 056a], Certificate
>>> TLS 1.0 Handshake [length 0046], ClientKeyExchange
>>> TLS 1.0 Handshake [length 0086], CertificateVerify
>>> TLS 1.0 ChangeCipherSpec [length 0001]
>>> TLS 1.0 Handshake [length 0010], Finished
<<< TLS 1.0 ChangeCipherSpec [length 0001]
<<< TLS 1.0 Handshake [length 0010], Finished
R
RENEGOTIATING
>>> TLS 1.0 Handshake [length 0063], ClientHello
<<< TLS 1.0 Handshake [length 0030], ServerHello
<<< TLS 1.0 Handshake [length 0b01], Certificate
depth=1 /C=RU/O=some/CN=CA
verify error:num=19:self signed certificate in certificate chain
verify return:0
<<< TLS 1.0 Handshake [length 010d], ServerKeyExchange
<<< TLS 1.0 Handshake [length 0055], CertificateRequest
<<< TLS 1.0 Handshake [length 0004], ServerHelloDone
>>> TLS 1.0 Handshake [length 056a], Certificate
>>> TLS 1.0 Handshake [length 0046], ClientKeyExchange
>>> TLS 1.0 Handshake [length 0086], CertificateVerify
>>> TLS 1.0 ChangeCipherSpec [length 0001]
>>> TLS 1.0 Handshake [length 0010], Finished
<<< TLS 1.0 Handshake [length 060a]???
<<< TLS 1.0 ChangeCipherSpec [length 0001]
<<< TLS 1.0 Handshake [length 0010], Finished
-----
If the second certificate is used for the authorization and it is
allowed to have distinct certificates during the first and second
negotiations, then this could be the other way to trigger this attack
against the servers that are requiring certificates from the beginning.

Any thoughts?
-- 
Eygene

---

From: Marsh Ray <[email-masked]>
Date: Sat, 07 Nov 2009 10:24:18 -0600

Eygene Ryabinkin wrote:
> request through the established channel.

Yes. I regret that we didn't get a chance to update the paper before
making it generally available, so it is a bit understated:

"Other techniques allow the attacker to forward or re-purpose client
certificate authentication credentials."

> against the servers that are requiring certificates from the beginning.

It's even worse than that. In practice, clients will sign with their
client cert without user intervention.

"For one thing, browsers' behavior of allowing automatic certificate
sending is suspect and should be reconsidered. Secondly, browsers suffer
from a fundamental inability to authenticate the specific transaction
the server is about to execute, ostensibly on behalf of the client. That
underlying problem should be addressed, and will likely involve either a
protocol change or changes in the way existing protocols are implemented.

"Finally, it may make sense to require clients to authenticate servers
using the supplied certificate before handing client certificates back
to the server. This will effectively prevent the chosen-server attack
scenarios described above. This may also represent a breaking protocol
change, however, and is being investigated.

Even worse (and this is shown in some of the packet captures), web
servers will execute MITM's request as soon as they get the Finished
message from legit client, but the browser doesn't put up the scary page
until he gets the Finished from the server (which could simply be
silently dropped by the MITM).

So if a client has useful client cert (or smart card) credentials, MITM
can redirect a request to a server of his choosing that will accept
them, use them to authenticate his arbitrary transaction, and the
browser may never even show the scary cert error page.

- Marsh

---

From: Peter Gutmann <[email-masked]>
Date: Sun, 08 Nov 2009 21:42:38 +1300

Marsh Ray <[email-masked]> writes:

>For one thing, browsers' behavior of allowing automatic certificate sending
>is suspect and should be reconsidered.

It's not actually safe to reconsider this because many servers (including some
at very large sites) always request client auth, often without the site admins
being aware of this or knowing how to disable it.  I became aware of this when
I changed my code to add a roadblock until the user explicitly responded to a
client cert request, leading to many complaints about sites that formerly
"worked" and now didn't (I've found all sorts of other broken behaviour around
client-auth, for example servers that send a list of 150-odd CAs, every one
they know of, as an indication of who they'll accept certs from, and other
strangeness).  Disabling the automatic sending of client certs would therefore
obviously break, to the client, a number of (what I consider) broken servers.
What my code currently does is:

  if( cert request received )
      if( client cert present )
          send cert;
      else
          send no-cert alert;

This isn't totally safe though because there's no "tell user to make their
cert available" option if they haven't pre-emptively done so, it "works"
mostly because the extreme rarity of client cert use and stereotyped behaviour
of existing clients hides all the glitches in implementations.

Peter.

---

From: ArkanoiD <[email-masked]>
Date: Mon, 9 Nov 2009 00:54:43 +0300

BTW renegotiation handshake looks quite similar to initial handshake from
the client point of view; is there a way to detect the attack on client side
and drop the connection?

---

From: Marsh Ray <[email-masked]>
Date: Sun, 08 Nov 2009 16:32:05 -0600

ArkanoiD wrote:
> the client point of view;

Yeah, currently it looks identical.

> is there a way to detect the attack on client side
> and drop the connection?

With draft-rescorla-tls-renegotiate, the new header comes back to the
client on Server Hello, and this notifies the client that the server
believes it's a re-negotation. Even better, it ties it strongly to the
previous session, so legit renegotiations are protected, too.

- Marsh