SSL & TLS Attacks for the Layman: Oracles

Posted by Arvind Doraiswamy on December 15, 2016 at 2:03 PM

In this five part blog series, I've been focusing on covering some of the attacks that have exploited various features in the SSL/TLS mechanism. We've covered general bad practices and bad implementation. Today we'll be discussing Oracles.


CRIME is an attack that abuses how SSL compresses user requests. Generally speaking, the way compression works is that it finds repetitive patterns in data and replaces those with a much smaller index. Then when uncompressing, it does things the other way-- looks up the index, gets the original value and constructs the overall response. The attacker needs to know that some part of a request is always going to be present. For example, they could predict that a request will always have one string called Cookie: secret=. They wouldn't know what that value is, but the first part is always going to be there. Then, in the event they can append a second Cookie: secret=, SSL compression would materialize. SSL would notice that Cookie: secret= repeated itself twice and replace itself with a super-small token; say 0. The overall length of the request will hence go down to say 25 characters. Now the attacker will send multiple requests via the victim's browser. Let’s say this happens because a victim opens another tab, visiting the attacker site. Also, let’s assume an attacker can see the victim's traffic (well, encrypted blobs anyway):

Cookie: secret=0
Cookie: secret=1
Cookie: secret=2

... and so on. The moment the first character after the '=' matches, SSL compression will, instead of finding a match for Cookie: secret= ... , find a match for Cookie: secret=2. This means that the length of the request will again go down. More specifically and crucially, it will go down by a little more for every other character. Meaning if secret=0 or secret=1, length will be 25, but i secret=2, length will be 24. Meaning, the first byte of the cookie is 2. And so on. The best explanation for this attack can be found here. The fix is to disable compression; however, most vendors have probably rolled out relevant patches so just apply those.


The core principle behind BREACH is similar to that of CRIME, exploiting the fact that content is compressed. Only it targets compression done by HTTP by default, not SSL/TLS as in CRIME. In other words, it isn't an attack targeted at SSL at all. I’ve included it because CRIME and BREACH often tend to be mentioned side by side.

There are some pre-requisites for the attack. The server should use HTTP response compression and user input (and preferably a secret which is the target) is reflected back in the HTTP response. Like CRIME, an attacker is in the middle and can read encrypted blobs of user traffic and can also get the user to visit a site under their control. With CRIME, the attacker measures the length of the requests, which is reduced because of TLS compression; with Breach, the attacker measures the size of HTTP compressed responses.

Note: the attacker's input has to be reflected back in the response multiple times for compression to kick in. When it does, then the attacker can send a large number of requests and observe the effects on the length of the returned (and now compressed) responses. This allows the attacker to determine the secret byte by byte.

There's no real one-size- fits-all fix for BREACH. If CSRF tokens are the main target, since those are commonly returned in responses, changing the token after every request while invalidating the former ones will defend against this attack. There are many other partial mitigations as well as complexities in the attack itself. The official site for the attack that was linked above is IMO the best resource for understanding this. I'd recommend reading their paper, instead of the presentation.

Padding Oracle

This is one of the most famous crypto attacks on which a number of posts have beenwritten. Here is a detailed article, but in a nutshell, an attacker sends a number of encrypted texts to the server, which decrypts all of them. This part is not of concern, but the server also tells the attacker when the padding of the message is wrong. Meaning, the attacker can brute-force the entire message byte-by- bytebased solely on that information leak. There are a few key principles to internalize:

  1. We are NOT at any point trying to predict the actual correct pad. We're using the property that it leaks if the pad is right or not, to calculate the actual plain text, little by little.
  2. You assume that the pad is 0x1 to 0xF per block and that it's a 16-byte block. It’s 0x1 when you're trying to predict the block's last character. Its 0xF if you're trying to predict the first character. Note again, you never ever actually know what the pad was.
  3. Once you find out the correct character (say X) in the previous block that does NOT give you a padding error, for say, the last byte of the last block, ask the question: "What's the valid pad here?" It’s 0x1. Now go and look at the CBC bit of the Wiki article. Stare hard at the diagram and repeat this step in your head several times, until you get this step.
  4. What you get as a result of Step 3 is NOT plain-text. Its close, but it is NOT plain-text. You have to xor X with the result of Step 3 to get the actual plain-text. The fix is to ensure that you do not tell the user if the pad is incorrect at any point in time.

Lucky 13

This is an attack that's very similar to the padding oracle I described above. The way the padding oracle is fixed is by not giving feedback to the user, by calculating a MAC and telling the user that their padding is wrong. So there's no way for an attacker to brute-force bytes and eventually guess plaintext. However, SSL/TLS still took different amounts of time while calculating the MAC for differing padding lengths. Several intelligent people managed to figure that out and decrypt entire blobs of plaintext again. Crypto is hard, isn’t it? Fixes of adding random delays apparently do not solve the problem. Another suggested fix is to use RC4 ciphers, but that's a bad idea as I mentioned earlier. The only real fix for this is to ensure that people switch to TLS 1.2 and use the AEAD ciphers instead. Most libraries that are vulnerable to this have fixed this now, so make sure you have applied all the necessary updates.


The attack itself conceptually is very similar to the padding oracle attack. The only difference is that if clients and servers choose SSL 3.0 as their encryption protocol of choice, they are vulnerable to this attack. In other words, not a single cipher suite of SSL 3.0 protects against this attack and no one should hence be using SSL 3.0.

Lucky Negative 20

This one is another padding oracle problem where the server responds with verbose error messages on decrypting carefully chosen (by the attacker) cipher text and finding something wrong in it. Based on that, the attacker decrypts bytes block-by- block. This is a problem when AES in CBC mode is used. The fix is to use AES-GCM with TLS 1.2.

Topics: developer guidance, crypto

Arvind Doraiswamy

Written by Arvind Doraiswamy

Arvind is a Senior Security Engineer who focuses on conducting security assessments for clients, contributing articles to our secure coding knowledgebase, and writing tools to improve our company's security testing efficiency for clients.