Wednesday, July 27, 2016

SSL/TLS for the layman (Attacks) - Part 2

As with the previous SSL post, this post is NOT a replacement for reading any of the official papers on this attack. It is just my attempt to summarize all of these attacks into a form that is easily readable and understandable by anyone. For the gory details, search for the original paper for each of these attacks and read those.I'll try and link to as many as I can find here

And before we start, its a good idea to bookmark this post and the previous one. I will try and keep both these updated as and when newer recommendations or/and attacks come out. Of course I could miss things, and am reliant on anyone who chooses to trust this post - to tell me that I missed something. Then I can read, understand and add things here. Here goes then.

Sweet32
This is an attack (very similar to BEAST) that targets a property of 3DES and probably any other cipher (I think) that uses 8 byte blocks while encrypting plain text. There's lots of pre-requisites though, for this attack to be successful. Here is a nice read, that I thought broke things up really well.

  • A victim needs to be passing something confidential and which consistently appears in every request (like a session cookie).
  • The attacker must somehow trick the victim to visit a website under the attacker's control, that will make a very large number of requests to the target site.
  • The attacker must be in a position on the network to be able to actually capture all that encrypted traffic.
  • There should eventually be a collision (Apparently this can happen in 2^32 attempts. Please read the link above for why). In other words, bits of plain-text traffic, despite the encryption algorithm doing everything right, must look the same when encrypted.
  • The bit of confidential data should always appear in the same place, when traffic is encrypted.

If all these conditions are met, an attacker could steal the confidential information (session cookie) and impersonate the victim.

The fix is to start disabling 3DES ciphers on your servers or at least ensure that it is not a preferred cipher. Use AES. AES has 16 byte blocks, which means it will take much much longer to have a collision. Limit the amount of time a connection stays open, so even if an attacker *does* steal a cookie, it is of no use.

Beast
Beast is a client-side SSL attack. A server is never affected. Here is a link to the original paper.

A victim needs to be logged in to a target site and must have been assigned something secret - say a session cookie. A user then, has to visit an attacker-controlled home page. The attacker, while sending those requests out, must be able to somehow add data to every single request, just before the cookie. If the attacker can't do this, this is not a valid attack.

This page the victim visited then (maybe via JavaScript) makes a large number of requests to the target site, into which the victim is logged in. The attacker then uses these requests and aims at decrypting the secret cookie. This is an example of a chosen plain-text attack. An attacker can send a million plain-texts, get their ciphertexts, analyze them and try and break things.

The attacks described in this paper allow an attacker to obtain the cookies even if HTTPS is in use and the secure flag is turned on. The attack is an attack, because of how CBC works by default - every single cipher suite that uses CBC internally, is affected.

RC4 was suggested as a defence as it was a good cipher (at that time) that didn't use CBC. But RC4 is bad for many other (worse) reasons - some of which are described in my previous post. So don't use RC4 and ignore anyone who tells you to.

TLS 1.1/1.2 on the other hand is better as it protects you against BEAST by default. So if you have all your clients supporting TLS 1.1/1.2 and none that depend on TLS 1.0/SSL3.0, disable RC4 and go this route instead.

Heartbleed
Heartbleed is one of the most well known recent attacks just because of how high the impact is. An attacker could, with no user intervention of any sort, connect to a server and extract secrets from the server's memory. This XKCD cartoon, I thought personally was brilliant in explaining the true impact of the issue.

These could be passwords, private keys, PII.. pretty much anything. Once that information is stolen, what can be done with the stolen information, depends on if there are other mitigations in place to protect users. For example: You could steal a root password for some server, but if you have NO way to reach that server, while it's still bad... there is a mitigating control in place.

The only fix is to apply the relevant patches for OpenSSL running on your OS. Hopefully its all seamless, and the libraries on your system will be patched during your 'automatic update' process, however that takes place.

Crime
Generally, 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. CRIME is an attack that abuses how SSL compresses these user requests.

The attacker needs to know that some part of a request is always going to be present. For example: She could predict that a request will always have one bit called Cookie: secret=. She wouldn't know what that value is, but the first part .. is always going to be there. So now, if say she can append a second Cookie: secret=, SSL compression would kick in.

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.

Now the attacker will send multiple requests via the victim's browser. Lets say this happens because a victim opens another tab, visiting the attacker's site. Also, lets 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. And this means, that the length of the request will again go down. But crucially, it'll go down by a little more than for every other character. Meaning if secret=0 or secret=1 .. length will be 25, but if secret=2 .. length will be 24. Meaning, the first byte of the cookie is 2 :). And so on.

The best explanation for this attack was here. The fix apparently is to disable compression. Most vendors have probably rolled relevant patches out as well, so just apply those.

Breach
The core principle behind Breach is very similar to that of CRIME, exploits the facts 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. Its just mentioned here because CRIME and BREACH tend to be mentioned side by side very often.

There's some pre-requisites for the attack. The server should use HTTP response compression (most do), user input (and preferably a secret which is the target) is reflected back in the HTTP response.

Similar to 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. Instead of CRIME though, where the attacker measured the length of the requests (which reduced, because of TLS compression) - the attacker measures the sizes of 'HTTP compressed responses' in this case.

And remember, the attacker's input has to get reflected back in the response, multiple times, for compression to even kick in. If it does, then he could send a large number of requests (very similar to CRIME) and observe the effects on the length of the returned (now compressed) response, thus guessing byte-by-byte.

There's no real 'one-size-fits-all fix' for BREACH. If CSRF tokens are the main target, since those are very commonly returned in responses - changing the token after every request, while invalidating the former ones.. will defend against this attack.

Do note that there are many other partial mitigations suggested as well as numerous 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 :).

Berserk
This was a Mozilla NSS library specific bug. Alice can bypass signature verification for TLS certificates issued for specific websites. So, if the signature isn't verified properly it means that Alice can construct a certificate... another certificate for say mail.google.com, that looks exactly like the original one... without having the private TLS key for mail.google.com at all.

And once she has the malicious certificate, she'll install that on a website somewhere. And the website (the most common use case anyway) will look just like mail.google.com. Phishing website. And then somehow get people to come and visit that website.

That's not as simple as it sounds, because if you tell everyone to go to mail.google.com, they'll end up going to the real site and not Alice's fake site. So Alice then has to perform other MITM attacks like ARP poisoning, DNS cache poisoning, BGP route hijacking (all I can think of now :)) and somehow tell users to go to Alice's site, when they type in mail.google.com in their browsers.

This is a more detailed read on this attack, just jump to the Berserk section below. The fix really is to just ensure you have the latest security patches in place for all the software that uses the NSS libraries.

Padding Oracle
This is one of the most famous crypto attacks on which a number of posts have been written about. This and this are the best reads about it, that I found. Details are always important in any exploit, but since its likely that you want to know more about this than other attacks, just because its so famous, do read carefully.

In a nutshell though, an attacker sends a number of encrypted texts to the server, which decrypts all of them. That's fine, 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 byte, just based on that information leak.
There's a few key principles to internalize while you're reading.

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. Assuming that it's a 16 byte block. Its 0x1 when you're trying to predict the block's last character. Its 0xF if you're trying to predict the 1st 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?'. Its 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 a number of times, till you get this step. Do NOT go on till you get this.
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.

This is far from a perfect description but its almost impossible for me to explain this any better in a smaller space than I have here. It is after all just an overview of stuff, so you can read some more. Like everything else.

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 tell the user that their padding is wrong. So there's no way for an attacker to brute-force bytes and eventually guess plaintext.

So that got fixed. However, SSL/TLS still took different amounts of time while calculating the MAC, for differing padding lengths. And some smart people somehow (:-o) managed to figure that out, and decrypt entire blobs of plaintext again. Crypto's hard, isnt it? :)

Fixes of adding random delays apparently do not solve the problem. Another fix suggested was using RC4 ciphers, but that's a bad idea too as mentioned earlier. So, the only real fix for this is to ensure that people switch to TLS 1.2 and use the AEAD ciphers instead. This apparently is harder than it looks.

Most libraries that are vulnerable to this have fixed this now though, so make sure you have applied all the necessary updates.

Poodle (SSLv3)
The attack itself, conceptually is very very similar to the padding oracle attack. The only difference really, 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 at all.

I'm not going to describe the vulnerability again, since I went through it in a fair amount of detail earlier :). But if you'd like to read the original paper - I've linked it here.

Downgrade attack (TLS_FALLBACK_SCSV)
Now, after reading that brief note about SSL 3.0, one might say that SSL 3.0 isn't a preferred protocol by default at all. Which means that most clients will communicate using TLS 1.x. Which is probably true.

What's also true though, is that its possible for a malicious attacker to perform a downgrade attack against a specific client, and force them to use SSL 3.0, and then use the techniques mentioned in Poodle (or any other vulnerability really) and own them.

To mitigate this to a certain extent, there is something called TLS_FALLBACK_SCSV that will detect if an active MITM attacker is forcing users to use insecure protocols to communicate with servers. In short, the client sends an extra option TLS_FALLBACK_SCSV with its list of preferred ciphers to use. The server also needs to support this option.

Lets now assume that an attacker downgraded the connection to use a weaker cipher. The downgrade will work. The server will however (eventually) notice that the client set the fallback option, and abort the connection if a weaker cipher was used. This is one of the best reads I found.

Note though that this is just a patch. If the server supports SSL 3.0 and for some reason a client uses it to communicate with the server, without an attacker messing with the connection in between... TLS_FALLBACK_SCSV will NOT protect you. So disable SSL 3.0 on every single box you own. Go now :)

Poodle (TLS)
And guess what? The TLS Poodle is very similar to the padding oracle attack again, technically. In the previous attack, I mentioned that getting rid of SSLv3 would defend against Poodle. That turns out to be incorrect as you can see :)

The problem in this case, is that there are certain servers that for some reason use the vulnerable SSLv3 code. Meaning, I could use TLS 1.2 or whatever, but if that piece of code is borrowed from an old, vulnerable version of SSL, its still going to break.

And there are further variations of this attack as well here. And scarily apparently it's not very well known and hence all vendors might not even have patched this issue.

Anyway, as with everything else there's nothing you can do but patch your code if your vendor has released a patch.

Drown

This one is seriously creepy. Here you could think you are safe because you don't support a protocol at all - but guess what - you are still vulnerable. Its crazy and I never heard of anything like this.

Drown targets SSLv2. Here's Ivan Ristic talking about it as well, its a nice overview. A lot of servers don't support SSLv2. Browsers don't talk over SSLv2 by default. So the logical conclusion is that you're safe.

But let's say you've (for some weird weird reason) reused the private key to sign another certificate - on another server - and that server supports SSLv2 as well as export-grade ciphers (really old 40 and 56 bit key ciphers). Both servers can be owned by targeting SSLv2 on the 'bad' server. Let it sink in - currently the server supports *only* TLSv1.2, it's all useless if you have some box somewhere that has a certificate that was signed using a shared private key.

As in, you can attack an SSLv2 connection between a client and the 'bad' server. This attack gives you the session key used to encrypt that particular session. Using the session key, you can recover the master key. And once you have the master key you can generate session keys and decrypt *any* sessions - even the one between the client and the good server. Read this OpenSSL advisory for a brief explanation (search for 2016-0703 on the page).

And of course here's a link (its long but its by Thomas Pornin whose answers are unbelievably good most times) on how SSL works and how to decrypt captured, encrypted traffic using the master key in Wireshark.

And yes had you configured your server to only accept cipher-suites which support Perfect Forward Secrecy, that traffic would still be safe from attacks such as Drown.

Freak
This targets the fact that clients and servers for some reason still support export-grade cryptography. Which just means encrypting your communication with ciphers that are not very strong and can hence be decrypted. By default browsers don't use these ciphers at all, but remember - the negotiation is in plain text - an attacker can see what ciphers are being chosen.

Because of the bug, an MITM attacker can basically hijack the negotiation process - and tell a client (if vulnerable) to use export grade RSA (512 bit key which isn't strong despite it looking that way) to encrypt all traffic, until the symmetric key is decided. Remember, SSL uses public key (asymmetric) crypto to start off, decides a secret and then uses this secret to encrypt further traffic (symmetric).

Now since the public key stuff is all using export-grade RSA, an attacker can apparently 'break this' (factorization problem - not brute force) and retrieve the decryption key being used. Here's a brief overview article and a really nice article with a bit more detail on the same.

Once this key is retrieved, the attacker can decrypt traffic that passes on the symmetric key and decrypt everything for that session between the client and the server.

Now doing the 'breaking' (which really is solving RSA for manageable numbers) is not fast. So if you really had to do it per-SSL-session, it would still be a bug but less practical. But as per the wonderful Matthew Green, servers reuse a single export-grade RSA key when they start up - until they are shut down. So if an attacker manages to get one decryption key, they can get potentially capture traffic and decrypt it successfully for a number of sessions.

The fix really is to make sure that no one ever uses export grade ciphers again to do anything. This one sort of reminds me of how the NSA want to build back-doors in the IPhone today for 'good' purposes. Very eerie similarities if you ask me.

LogJam
This is very similar to FREAK described above. It targets the exact same fact that export-grade DH ciphers are supported by clients and servers. Only it attacks Diffie-Hellman (DHE) - another public key encryption algorithm - instead of RSA. The Eff also has a good read.

DH is safe because it is hard to solve the discrete logarithmic problem and get back the initial numbers (exponents) chosen at the start. If those numbers can be predicted/obtained somehow - DH is breakable. But the point is, its very very hard (impossible as of now?) to do so.

The researchers who found LogJam though, did something cool. To understand, lets take an analogy. Think of a 25 character password. If you wanted to crack it using brute force it would be pretty hard and need lots of power and time. But if you built (offline) something called a rainbow table (which by the way is also very time consuming) which had every_single_possible_password for any 25 character long password - things change. The next time you get a 25 char password all you have to do, is look that table up.

Now back to Diffie Hellman, they basically precomputed the discrete logarithm (a hard problem) for 512 bit prime-numbers. Meaning, the next time they saw DH being used, with 512 bit primes, they'd know what exponents were being used, and hence find out the actual symmetric key being used inside. And as it turns out, a lot of servers use the exact same prime number. So if you solve it once, you've basically potentially all connections to those servers.

And the second fact, servers still support export grade DH ciphers. This fact and the rainbow_table_wizardry is what LogJam is about. An MITM attacker will downgrade a connection, force the connection to use 512 bit DH, and then use the rainbow table to find the secrets out.

The mitigation is to think of all the possible services on your servers that use Diffie Hellman. Once identified, ensure they are all configured correctly - namely disable export grade DH cipher suites, and ensure that 2048 bit primes are used to compute the shared secret. On the client side, stay updated - use newer browsers and hope that browsers reject connections that use 'export-grade DH'.


Lucky Negative 20
And here's the newest one as far as I know (please tell me if I am wrong) This one is another padding Oracle problem, where the server responds with verbose error messages on decrypting carefully chosen (by 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 apparently is to (guess what) use AES-GCM with TLS 1.2.

----

By now, so much of crypto seemingly depends on AES-GCM, that I'm scared a new vulnerability will be discovered tomorrow in it, which will break the Internet again. And then what. Its pretty depressing if you ask me, that we've become so dependent on encryption as a solution to all problems.

And cryptography is hard, really hard - and very easy to get wrong even for people a million times smarter than me. And hence, I'm fairly nervous. And feel that its just a matter of time before I update this post again.

SSL/TLS for the layman (Configuration) - Part 1

There is nothing new in this post. I just got fed up of tracking all the SSL/TLS bugs that seem to come out every month, nowadays. I don't even remember which bug does what, how hard the exploit is and what needs to be done to fix it. And everytime I have to Google. Every. Single. Time. And I'm sick of it.

So, this page. Anything that is a problem with TLS configuration, that I'd report when I do a penetration test for a client, I'll try and briefly touch upon. If there's something new that comes up, I'll update this page. In a 2nd post I cover attacks. When an SSL/TLS attack comes around, I'm just going to update that page.

And no, I'm not claiming this is some pioneering, wonderful, one-stop page. It is just so I can go to a single place and remind myself on what some SSL/TLS misconfiguration is.

Weak SSL/TLS ciphers (Strength less than 128 bit)
The way SSL/TLS works is that the client and server negotiate what key size to use to bi-directionally encrypt communication. If both the client and the server have their first choice as a 40 bit key, it means that until negotiation happens again, they're going to encrypt traffic using a shared 40 bit key.

If someone gets hold of an encrypted traffic dump of this communication, they could go through all 2^40 keys, each time decrypting the traffic. When it makes sense, they'd stop and that's the key... for THAT session. Not for every session between that client and server.

That is still bad, and no one should even support ciphers that use anything less than a 128 bit key, which today is considered safe. Although this Wiki snippet says that this could be bad too, under certain conditions. For now though, its fine. Start thinking though, of supporting ciphers that are at least 256 bits long.

RC4
The only reason this is mentioned here, separately was because it was a very popular choice and the preferred cipher for all client-server communication for a long time. If I remember right, even Google had that as their preferred cipher for a long time. I'm "guessing" because it was a really fast symmetric key cipher.

Since then though lots has changed and numerous vulnerabilities have been discovered in RC4. So in short, if this is still a preferred cipher, its wrong. Please disable it on every host+service that supports SSL.

Also, thankfully browser vendors are also moving away from it, so that's good.

Really Really old protocols (SSLv1, SSLv2)
I don't think I've seen anyone use either of these protocols for a while now, even on test servers, but you never know. So yeah, just just disable support for both these. Its ridiculous to have support for either of these.

SSLv1 was apparently never public, which explains why I always saw only SSLv2 enabled even on badly broken servers :)

SSLv2 had numerous vulnerabilities which have their own RFC, which is a fairly strong reason to completely avoid it. Jump straight to Section 2 of the RFC to see some of the vulnerabilities. These affect Confidentiality, Integrity and Availability for any client-server traffic. That's bad.. please never use it.

MD5/SHA1 signed things
A signature for any digital content (like certificates) means that you trust the person who signed the content. So no 2 messages should ever have the same signature. Because, if they did - it'd mean that the person reading the message wouldn't know which message is the real one. Since both appear to be signed by the same person. And could be valid...

Meaning any hash function, where it is possible (practically speaking) to find 2 messages that have the same hash at the end ((hash-collisions) should be avoided. And there's a known attack against MD5 that does exactly this. And its possible to do this with SHA1 as well.

Migrate to SHA256 or SHA512 for all your signing needs at the earliest.

Insecure Renegotiation
Renegotiation in an SSL/TLS context effectively says, 'Can we please decide again...what protocols and ciphers we're going to use to communicate?'. If a client can do this and the server supports it, it means a man-in-the-middle can inject traffic (details here or originally here) and force a client to renegotiate.

Then by getting the timing right, they could somehow piggyback on a client's request, use the client's credentials and do things that the client can do.. without the client's knowledge. Can't ever see a thing but can still do it. Sort of like CSRF inside an SSL/TLS connection.

There's also another exploit discovered that lets attackers DOS the server. There's also a tool by THC to do so. It's a bug, sure but doesn't fix the overall DOS problem as such. It defends against 1 technique. That's it. There's even arguments that this is by design.

The fix is to not let the client renegotiate at all. If a client does try, the server should just reject it. The process is different for different servers.

Lack of OCSP stapling
Clients need a way to decide whether a certificate is valid or not. If it isn't, the client shouldn't let a user visit a site. So, initially there were revocation-lists (CRLs). But those were updated only once every X days, so there was always a chance of a user being owned, in-between. Hence OCSP where the user verifies if the certificate is valid, before connecting to it.

The problem with this though is that the destination server, specially if its very busy could get overwhelmed if clients keep hitting it to check certificate validity all the time. And it consumes client resources as well.

Hence OCSP stapling. A server will do the querying-for-cert-validity and return the stapled response, when the client queries it. So no runtime queries from the client directly to the guys who signed the certificate. There isn't a security issue here, unless you think of a DOS against the guys who signed the cert.

If you can though, specially if you have a low capacity internal CA server, its good to enable OCSP stapling.

Lack of HSTS
HSTS if configured right on the server, tells the browser to always send traffic over a HTTPS connection. Its relevant only if the server supports both HTTP (for some legacy reason) as well as HTTPS. So, if its done right and I type http://site the browser will look at the HSTS header and force the traffic over HTTPS. Which is great.


Note though, that the absolute first request before the HSTS response reaches the browser is still over HTTP, and hence open to an attacker man-in-the-middling the connection and owning a user.

And that's not good either, which is why you should try and notify browser vendors in advance that you plan to implement HSTS. Or at least as soon as you implement it, to reduce the exposure to this attack.


If you only support HTTPS and port 80 isn't even open on your web-server, you can still configure HSTS, but it doesn't improve your security in any way.

No Forward Secrecy cipher support
Lets say an encrypted traffic dump is captured. Now that communication was encrypted using a specific session key, generated using the server's private key...that's how SSL works.

So if the server's private key somehow got stolen, the attacker could use it to decrypt all the traffic she captured earlier.

Lets now say that a client-server communication is encrypted using a cipher that support forward secrecy. Even if the private key is stolen, the attacker can't use it to decrypt any of the encrypted traffic she had.

So ideally, ensure you support some strong ciphers that support forward secrecy and make one of them your preferred cipher of communication.