SSL/TLS IIIReading time: 17 mins
After the lengthy presentation of SSL, let’s go with the fun stuff, namely:
Attacks on SSL
There have been many attacks on SSL, some building on implementation errors, others on true protocol weaknesses.
One must remember that while SSL is one of the most attacked protocols (since it is very high profile: a successful application to SSL looks very nice in the abstract of a research article), SSL is also one of the most repaired protocols. It is to be considered to be robust precisely because all known ways to attack transport protocols have been tried on SSL, and SSL has been patched where appropriate.
In the early days of SSLv3, SSLv2 was still widely used, and therefore clients were commonly sending SSLv2-compatible
ClientHello messages, which merely indicated that SSLv3 was supported as well; the server would then take the hint and respond in SSLv3+ dialect (see annexe E of RFC 2246 for details). Since SSLv2 had weaknesses, it was in the best interest of the attacker to arrange for a client and server, both knowing SSLv3, to nonetheless talk with each other using SSLv2. This is called a version rollback attack. The concept formally extends to later versions as well.
Kludges have been added to detect rollback attempts. For the back-to-SSLv2 rollbacks, a client who knows SSLv3+ should employ a special padding for the RSA encryption step (SSLv2 supported only RSA-based key exchange): in PKCS#1, the data which is to be encrypted is supposed to be padded with a number of random bytes; an SSLv3-aware client is then supposed to set the last eight of these padding bytes to the fixed value 0x03. The server then checks these bytes; if the eight 0x03 are found, then a rollback is most probably attempted, and the server rejects the attempt (an SSLv2-only client has probability only 255-8 to use such padding bytes out of sheer lack of luck, so false positives occur at a negligible rate).
For rollbacks to an old version of SSL/TLS, but not older than SSLv3, another kludge was added: in the pre-master secret of 48 bytes which the client encrypts with the server’s RSA key, the first two bytes are not random, but should equal the “maximum supported protocol version” which the client wrote first in its
ClientHello message. Unfortunately, some clients got it wrong, and this kludge works only with a RSA-based key exchange, so the protection against rollback is very limited there. Fortunately, SSLv3+ has another, much more powerful protection against rollbacks, which is that the handshake messages are hashed together when the
Finished messages are built. This protects against rollbacks, unless the “old version” would be so thoroughly weak that the attacker could totally break the whole encryption before the end of the handshake itself. This has not happened yet (SSLv3 is still reasonably robust).
Weak Cipher Suites
Some of the standard cipher suites are intentionally weak in some way. There are:
- some cipher suites with no encryption at all, only integrity check, e.g.
- some cipher suites with 40-bit encryption, such as
TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5(cipher suites meant to comply with the stringent US export rules from last century – these regulations have been mostly lifted at the end of the Bill Clinton era);
- some cipher suites with 56-bit encryption, such as
TLS_RSA_WITH_DES_CBC_SHA. 56-bit DES is breakable with existing technology, but that’s still a bit hard for an amateur (even a bored student with access to a few hundred university machines), so I tend to qualify 56-bit DES as “medium strength”.
This opens the road to a variant of version rollback attacks, in which the attacker forces client and server to agree on a weak cipher suite, the idea being that the attacker modifies the list of cipher suites announced by the client. This is workable for the attacker if the selected cipher suite is so weak that he can break it in order to recompute an apparently correct
Finished message. Actually, the MAC used in SSLv3+ (even when based on MD5) is robust enough to prevent that. So no actual worry here. Also, my opinion is that any real weakness here is when a client or a server accepts to use a weak cipher suite at all.
By default, modern Web browser do not allow the use of such weak cipher suites.
Private Key Theft
If a SSL connection uses RSA key exchange, and an attacker keeps a copy of the records, and then later on (possibly months after, possibly by inspecting all backups on discarded hard disks or tapes) obtains a copy of the private key, then he can unravel the handshake and decrypt the data.
Perfect Forward Secrecy is about countering this “later on”. You get it by using the
DHE cipher suites. With a DHE cipher suite, the actual private key which could be used to unravel the handshake is the ephemeral Diffie-Hellman key, not the server’s RSA (or DSS) private key. Being ephemeral, it existed only in RAM, and was never written to the hard disk; as such, it should be much more resilient to ulterior theft.
So the lesson is: as a rule, try to use a DHE cipher suite if possible. You should still mind your backups and not let your private key leak, but, at least, the DHE suites make such leakage a bit less of an issue, especially if it happens after the end of the key lifetime (i.e. the corresponding certificate is no longer valid).
The whole certificate business is a sore spot in SSL.
Technically, SSL is quite independent from X.509. The certificate chains are exchanged as opaque blobs. At some point, the client must use the server’s public key, but the client is free to “know” that key in any way that it sees fit. In some specific scenarios where SSL can be used, the client already knows the server’s public key (hardcoded in the code) and just ignores the certificate sent by the server. Nevertheless, in the common case of HTTPS, the client does validation of the server’s certificate chain as described in X.509 (read it at the expense of your sanity; you have been warned).
This yields a number of attack vectors, for instance:
Validation entails verifying that the certificates are still valid at the current date. How does the client machine knows the current date ? By its internal clock, and possibly by talking with NTP servers (in a quite unprotected way !). The client could be off by several minutes, hours, days, even years (I have seen it), and, to some extent, a powerful attacker could force it by fiddling with NTP messages. This would allow the attacker to use obsolete certificates which have been revoked years ago. Note a fun fact: the SSL “client random” and “server random” should contain 28 random bytes and the local date and time (over 4 bytes). This inclusion of time was meant to be part of a workaround against time-based attacks. I am not aware of any implementation which really checks it.
Up to circa 2003, the implementation of certificate validation in Internet Explorer / Windows did not process the “Basic Constraints” extension properly. The net effect was that anybody with a 100$ certificate could act as a CA and issue “certificates” with arbitrarily chosen name and keys.
X.509 includes a damage containment feature called revocation: this is about publishing list of banished certificates, which look good, cryptographically speaking, but should not be trusted (e.g. their private key was stolen, or they contain an erroneous name). Revocation works only as far as the involved parties (i.e. browsers) accept to download mammoth revocation lists (which can be several megabytes long !) or to contact OCSP servers. Modern browsers now do it, but a bit reluctantly, and many will accept to connect anyway if they could not obtain revocation status information in a timely fashion (because the human user is not patient). The overall situation improves over the years, but quite slowly.
Some root CA did commit some blunders in the past (e.g. Comodo and DigiNotar). This resulted in issuance of fake certificates (the name is
www.microsoft.combut the private key is not in the hand of Microsoft at all…). These blunders were discovered, and the certificates revoked, but it still raises some uncomfortable questions (e.g. are there other CA who had such problems but did not reveal them, or, even worse, never noticed them ?).
X.509 is a very complex assembly of algorithms, technologies, specifications and committees, and it is very hard to get it right. Trying to decode X.509 certificates “by hand” in an unprotected programming language like C is an easy way to obtain buffer overflows.
Daniel Bleichenbacher found in 1998 a nice attack against RSA. When you encrypt a piece of data with RSA (as occurs for the
ClientKeyExchange message in SSL), the data which is to be encrypted must be padded in order to make a byte sequence of the same length as the RSA modulus. The padding consists mostly of random bytes, but there is a bit of structure (notably, the first two bytes after padding must be 0x00 0x02).
Upon decryption (on the server, then), the padding must be found and removed. It so happens that, at that time, when the server decrypted but obtained an invalid padding (the 0x00 0x02 bytes were not there), then it reported it with an alert message (as per the SSL specification), whereas a valid padding resulted in the server using the seemingly decrypted value and keeping on with the handshake.
This kind of things is known as a padding oracle. It allows an attacker to send an arbitrary sequence of bytes as if it was an encrypted pre-master secret, and know whether the decryption of that sequence would yield a valid padding or not. That’s a mere 1-bit information, but it is sufficient to recover the private key with a few millions of requests (with cunningly crafted “encrypted” strings).
Workaround: when the decryption results in an invalid padding, the server keeps on using a random pre-master secret. The handshake will then fails later on, with the
Finished messages. All current implementations of SSL do that.
The Padding Oracle Strikes Back
Another area where a padding oracle was found is in the records themselves. Consider CBC encryption and HMAC. The data to encrypt is first MACed, then the result is encrypted. With CBC encryption, the data to be encrypted must have a length which is a multiple of the block size (8 bytes for 3DES, 16 bytes for AES). So some padding is applied, with some structure.
At that time (the attack was found out by Vaudenay in 2002), when a SSL implementation was processing a received record, it returned distinct alert messages for these two conditions:
- Upon decryption, no valid padding structure was found.
- Upon decryption, a valid padding was found, but then the MAC was verified and it did not match.
This is a padding oracle, and that can be used to recover some encrypted data. It requires an active attacker, but it is not that hard. Vaudenay implemented it, and it was extended to the case where a modified SSL implementation returned the same alert message in both case, but was slightly slower to do it in the second case, because of the time taken to recompute the MAC (a nice demonstration of a timing attack).
Because people never learn, the Microsoft implementation of SSL used in ASP.NET was still unpatched as of 2010 (eight years later !) when Rizzo and Duong reimplemented the Vaudenay attack and built a demonstration which recovered HTTP cookies.
See this page for some pointers. One must note that if SSL had used encrypt-then-MAC, such problems would have been avoided (the faulty records would have been rejected at the MAC level, before even considering decryption).
The BEAST attack is again from Duong and Rizzo, and, again, it is a remake of an older attack (from Philip Rogaway in 2002). To get the idea, consider CBC. In this mode of operation, each block of data is first XORed with the result of the encryption of the previous block; and that’s the result of the XOR which is encrypted. This is done in order to “randomize” the blocks and to avoid the leaks which are found with ECB mode. Since the first block does not have a “previous” block, there must be an Initialization Vector, which plays the role of previous block for the first block.
It turns out that if an attacker can control part of the data which is to be encrypted, and also can predict the IV which will be used, then he can turn the encryption machine into yet another decryption oracle and use it to recover some other encrypted data (that the attacker does not choose). However, in SSLv3 and TLS 1.0, the attacker can predict the IV for a record: it is the last block of the previous record ! So the attacker must be able to send some data in the stream, in order to “push” the target data, at a point where the implementation built and sent the previous record (typically when 16 kB worth of data have been accumulated), but did not begin to build the next one.
TLS 1.1+ is protected against that, because in TLS 1.1 (and subsequent versions), a per-record random IV is used. For SSLv3 and TLS 1.0, a workaround is to send zero-length records: that is, records with a payload of length zero – but with a MAC and padding and encryption, and the MAC is computed from a secret key and over the sequence number, so this plays the role of a random number generator. Unfortunately, IE 6.0 chokes on zero-length records. Other strategies involve a 1/n-1 split (a n bytes record is sent as two records, one with a single byte of payload, the other with the remaining n-1).
Another workaround is to force the use of a non-CBC cipher suite when possible – the server selects an RC4-based cipher suite if there is one in the list of cipher suites sent by the client, even if the client would have preferred a CBC-based cipher suite. This tool can tell you if a given server apparently acts like that. (Note: BEAST is an attack on the client, but, by selecting an RC4 cipher suite, the server can protect a careless client.)
See this page for some pointers. While TLS 1.1 is from 2006, the BEAST attack may force the browser vendors to finally upgrade.
As for any Hollywood franchise, Duong and Rizzo published in 2012 the sequel of the sequel. CRIME exploits a leakage which was theorized years ago, but as vividly demonstrated as in the demonstration they recently published. CRIME exploits compression, in the same setup than the BEAST attack (attacker can send some data of its own in a SSL connection, where interesting target data such as a cookie is also sent). Roughly speaking, the attacker puts in its data a potential value for the target string, and, if it matches, compression makes the resulting records shorter. See this question for a (pre-cognitive) analysis.
CRIME is avoided by not using TLS-level compression at all, which is what browsers now do. Internet Explorer and IIS never implemented TLS-level compression in the first place (for once, sloppiness saved the day); Firefox and Chrome implemented it, and deactivated this summer (they were forewarned by Duong and Rizzo, who are quite responsible in their activity).
CRIME shows why I wrote, near the beginning of my SSL explanations:
SSL fulfills these goals to a large (but not absolute) extent.
Indeed, encryption leaks the length of the encrypted data. There is no known good solution against that. And length alone can reveal a lot of things. For instance, when observing with a network monitor a SSL connection, we can spot the “extra handshakes” within the stream (because the first byte of each record identifies the type of data in the record, and it is not encrypted); with the lengths of the records, it is pretty easy to see whether the client provided a certificate or not.
The “Poodle” attack exploits a flaw that is specific to SSL 3.0 with CBC-based cipher suites. It relies on an often overlooked feature of SSL 3.0: most padding bytes are ignored. In TLS 1.0, the padding (bytes added in a record to make the length compatible with CBC encryption, which only processes full blocks) is fully specified; all the bytes must have a specific value and the recipient checks that. In SSL 3.0, padding byte contents are ignored, which allows an attacker to perform alterations that go mostly unnoticed. The alteration impact only non-applicative data, but can be used as a decryption oracle in a way vaguely similar to BEAST.
More details can be read in this answer.
Humans never learn. There is a lot of pressure to add nifty extensions to SSL for a lot of reasons which always look good at the beginning, but can induce extra problems.
Consider, for instance, SSL FalseStart. Mainly, this is about the client sending its application data right after having sent its
Finished message (in a full handshake), without waiting for the
Finished message from the server. This reduces latency, which is good and well-intentioned. However, it changes the security situation: before having received the
Finished message from the server, the latter is only implicitly authenticated (the client has no proof yet that the intended server was really involved at all; it just knows that whatever it sends will be readable only by the intended server). This can have impacts; for instance, an attacker could emulate the server up to that point and force, e.g., the client to use a CBC-based cipher suite or TLS compression. Therefore, if a client implements FalseStart, then it decreases effectiveness of protection measures against BEAST and CRIME, as could otherwise be enforced by the server.
(Google disabled FalseStart this spring, apparently because of compatibility issues with some servers. Anyway, the “30% latency reduction” looked weird, because FalseStart would have some influence only on full handshakes, not abbreviated handshakes, so I don’t believe in these alleged benefits; not to that magnitude, at least.)