At least two additional security vendors, including IBM and Palo Alto Networks, have been added to the list of vendors vulnerable to a variation on the Bleichenbacher attack called the ROBOT attack.
The attack was published by a trio of researchers, Hanno Böck, Juraj Somorovsky, and Craig Young. They dusted off the old Bleichenbacher attack against RSA key exchanges and ran it against a set of modern TLS stacks, finding that some were vulnerable. They contacted each of the vulnerable websites they found, and worked with the underlying TLS stack vendors, following the proper disclosure process.
They’ve published their research in a paper titled “Return Of Bleichenbacher’s Oracle Threat Or how we signed a Message with Facebook’s Private Key.“ In the tradition of named TLS protocol vulnerabilities that started with Heartbleed, the ROBOT attack has its own website and logo.
Disclaimer: the company I work for, F5 Networks, is vulnerable to this class of attacks. I’m put in the somewhat precarious position of judging this vulnerability and trying to stay neutral. If anything, I think my scoring system below betrays the significance of this vulnerability; but by how much is an open question.
Everything old is new again.
The Bleichenbacher “million message attack” (PDF) isn’t actually new: primers on SSL/TLS mentioned it as early as 1998. The original padding oracle attack for TLS, Bleichenbacher sends thousands of variations of ciphertext at a TLS server. The TLS server attempts to decrypt each one, and sends back one of two error codes—either the decrypt failed, or the padding was messed up. By trying many variations of a message containing a third-party’s TLS session, and differentiating between the two error codes, the attacker could eventually reconstruct the session, one bit at time. Within that TLS session the attacker might find user credentials, and then the breach is on. Bleichenbacher has since been refined (PDF) to the point where this version requires only tens of thousands of attempts.
The Bleichenbacher attack raises its head every now and then. Filippo Valsorda found one in the python-rsa library in 2016. A German team found one in XML encryption in 2012. Another German team wrote about optimizations for Bleichenbacher in this 2014 paper (PDF).
What’s the impact?
Bleichenbacher is a neat little theoretical protocol attack. However, to my knowledge, no real Bleichenbacher attack has ever been seen in the field.
Forward secret ciphers (ECDHE and DHE) aren’t vulnerable to RSA Bleichenbacher’s and 90% of today’s popular TLS stacks prefer forward secrecy, which is also supported by all major browsers. So the scope of the vulnerability is limited to two classes of users. Those that are using RSA because for legacy reasons (think Windows XP users in the third world) or organizations that specifically disallow forward secrecy because of passive monitoring requirements. Many financial organizations fall into this category, and their end-users are the ones most at risk.
86% of internet hosts prefer forward secrecy; all modern browsers do, too
The researchers claim that their proof-of-concept code can get the server to sign an arbitrary message. The obvious thing to do would be to get the oracle to sign an active TLS handshake, allowing for a real TLS man-in-the-middle attack a la LOGJAM. But an attacker could (probably) not do an MitM in real time. Even the optimized Bleichenbacher attack requires tens of thousands and that’s its biggest limitation. Running the researchers’ POC code took 12 hours on my virtual test harness. Fast server hardware gets it down to six hours, but after LOGJAM, administrators figured they should bound the SSL handshake by 6 seconds or less to avoid this kind of problem.
The other obvious target would be to get the Bleichenbacher padding oracle to decrypt someone else’s pre-master-secret, and use that to crack a recorded TLS session. That’s a real possibility with this optimized attack, and one that should be mitigated ASAP.
How does this Bleichenbacher score?
I try to provide a relative ranking of SSL/TLS vulnerabilities, independent of the CVSS scoring. My ranking is for enterprise architects with a specific focus on TLS. The numbers generated aren’t necessarily the important part; it’s the relative ranking to other vulnerabilities. So far, Heartbleed remains the worst of all time, with nothing even in the same class.
If this Bleichenbacher is used to crack a session, then its impact score is:
ROBOT stack rank score = 15
– Impact = session key derivation = 3
– Exploitability = requires MiTM and thousands of messages = 5
There are at least three mitigations for this edition of the Bleichenbacher attack.
First, if your TLS server manufacturer has issued patches, go get them and patch your appliances or software.
The second option is to require only forward-secret (non RSA) key exchange ciphers. Bleichenbacher only works against RSA handshakes, so elliptic curve and Diffie-Hellman handshakes are safe. Most of the Internet already supports (and prefers) forward secrecy, so some sites may opt for this solution. Whether you decide to is up to you—I would measure the percentage of your browsers still connecting with RSA before you make that call. RSA certificates used with forward secret ciphers are still okay.
The third option is to rate-limit SSL handshakes from individual IP addresses. If your TLS solution has a programmable data plane, a simple rule that tracks outstanding TLS requests per flow is sufficient. As a result of the LOGJAM attack from 2015, you should already be limiting TLS connection handshakes to 10 seconds or less.
Why does this keep happening?
If we all knew about Bleichenbacher as early as SSLv3, why do implementations keep falling prey to it? One reason is that TLS implementers are just nice. They write code that tries to tell you why the server rejected your message. Maybe that information would be useful to the implementer of the client side. Have you ever tried to debug a problem where the other side wouldn’t give you any useful information other than “bad input”?
In order to foil padding oracle attacks (and their uglier cousins, timing oracle attacks), implementers need to return a single error code (just pick one) and take the same amount of time to validate the input, no matter what kind of malicious input was given.
There is a proper way to do that. Instead of parsing the incoming message, the implementer of the server needs to construct a copy of what it expects to find, and then compare the incoming message to the copy. If they match, great. If not, then it should return a single error code. This fixes padding oracles and timing oracles too. But that’s next-level thinking that only fairly sophisticated infosec types have experience with. A basic, or even intermediate, programmer isn’t going to be thinking that far ahead when building a crypto library or server.
The researchers note that there do not appear to be any easy-to-run Bleichenbacher unit tests available in today’s crypto testing frameworks and conclude that few people test for them. There is no easy, free X509 parser for Python2, for example, which many testing frameworks use.
Will this be the last Bleichenbacher?
The forthcoming TLS 1.3 protocol requires forward-secret ciphers, so it will be safe from RSA Bleichenbacher attacks. But I expect adoption of TLS 1.3 to be somewhat slow, because forward secrecy isn’t free and introduces major visibility problems for enterprises with significant SSL inspection investments.
I expect TLS 1.2 and its support of RSA handshakes to be around for several more years. And at the current rate of a Bleichenbacher every couple of years, I guess we have a few more to see.