Small earthquake, not many dead (yet)

The European Court of Justice decision in the Google case will have implications way beyond search engines. Regular readers of this blog will recall stories of banks hounding innocent people for money following payment disputes, and a favourite trick is to blacklist people with credit reference agencies, even while disputes are still in progress (or even after the bank has actually lost a court case). In the past, the Information Commissioner refused to do anything about this abuse, claiming that it’s the bank which is the data controller, not the credit agency. The court now confirms that this view was quite wrong. I have therefore written to the Information Commissioner inviting him to acknowledge this and to withdraw the guidance issued to the credit reference agencies by his predecessor.

I wonder what other information intermediaries will now have to revise their business models?

Heartbleed and RSA private keys

UPDATE:

Matthew Arcus pointed out that a freed buffer will always have the first 16 bytes (x86_64) corrupted by two free list pointers, according to glibc’s malloc implementation. This means the leak mechanism I described below will only explain the partial leak I exploited, but not complete prime number leaks others have seen. In fact, the uncorrupted numbers come from the long-lived copy of p and q in the Montgomery context.

——–

By now everyone knows about the OpenSSL Heartbleed vulnerability: a missing bounds check in one of the most popular TLS implementations has made millions of web servers (and others) leak all sorts of sensitive information from memory. This could leak login credentials, authentication cookies and web traffic to attackers. But could it be used to recover the site’s TLS private key? This would enable complete decryption of previously-recorded traffic if perfect forward secrecy was not negotiated at the time and otherwise Man-in-The-Middle attacks to all future TLS sessions.

Since this would be a much more serious consequence of Heartbleed, I decided to investigate. The results were positive: I was able to extract private keys from a test Nginx server after a few day’s work. Later I applied my techniques to solve the CloudFlare Challenge. Along with a few other security researchers, we independently demonstrated that RSA private keys are indeed at risk. In this blog post, I’ll provide some detail on how to extract the private key and why the attack is possible.

How to extract the private key

Readers not familiar with RSA can read about it here. To simplify things a bit, a large (2048 bits) number N is constructed by multiplying together two large randomly generated prime numbers p and q. N is made public while p and q are kept secret. Finding p or q allows recovery of the private key. A generic attack is just factorising N, but this is believed to be difficult. However, with a vulnerability like Heartbleed, the attack is much simpler: because the web server needs the private key in memory to sign the TLS handshake, p and q must live in memory and we can try to obtain them with Heartbleed packets. Then the problem simply becomes how to identify them in the returned data. This is easy, as we know p and q are 1024 bits (128 bytes) long, and OpenSSL represents big numbers little-endian in memory, so a brute-force approach of treating every 128 consecutive bytes in the heartbleed packets as little-endian numbers and testing if it divides N is sufficient to spot potential leaks. This is how most people solved the CloudFlare challenge.

Coppersmith improvement

But wait, isn’t our scenario just like a cold boot attack? And there has been a lot of research on recovering RSA private keys with partial information. One of the most famous papers from Coppersmith presents message recovery attacks on related messages or insufficient padding, as well as factorisation with partial knowledge with the help of lattice basis reduction. With the Coppersmith attack, N can be efficiently factorised if either the top or bottom half bits of p is known. Put it in context, we only need the top/bottom 64 bytes of p in order to compute the private keys, compared to the naive brute-force which requires all 128 bytes. In practice, reaching Coppersmith’s limit is computational expensive (although still much better than factorisation), but assuming 77 bytes (60%) known we can comb the heartbleed packets for potential private key segments very quickly.

In retrospect, there were 242 instances of private key remnants suitable for the Coppersmith attack, out of 10,000 packets (64 KB each) that I had collected. Implementation of the Coppersmith attack was made easy thanks to the comprehensive computer algebra building blocks from Sage (although I later found out that Sage already has Coppersmith implemented).

Can we do even better? If you have ever viewed a RSA private key using openssl rsa -text -in server.key, you will notice that there are quite a few numbers other than the two prime factors p and q. In fact, they are precomputed values for RSA’s Chinese Remainder Theorem optimisation. If some of them are leaked they can also be used to deduce p. And what about the Montgomery representations of p and q that OpenSSL use for fast multiplication? They also admit a variant of Coppersmith so partial bits are useful as well. With this in mind I set out to search for them in the collected packets from my test server where these values are all known. But not even single one of them appears partially (> 16 bytes) in the dataset. How is this possible?

Note: all my experiments and the CloudFlare challenge are targeting Nginx which is single-threaded. It is possible that for a multi-threaded web server, more leakage can be observed.

Why p and only p leaks

When heartbleed first came out, people argued that RSA private keys should not be leaked because they are loaded when the web server starts so they occupy a lower memory address, and because the heap grows upwards, a later-allocated buffer leaked by Heartbleed shouldn’t reach them. This argument is consistent with my inability to find any CRT precomputed values, but with one exception: p is definitely leaked somehow. If we assume this argument is correct, the question becomes: why is p leaked?

To add more to the mystery, OpenSSL apparently scrubs all temporary BigNums it used! To reduce the overhead of dynamically allocating temporary values OpenSSL provides a BN_CTX which is a pool of BigNums operating in stack (LIFO) fashion. Upon finishing the context is destroyed and all allocated buffers are scrubbed. This would mean that when the heartbleed packet is constructed there shouldn’t be any temporary values left in memory (again assuming single thread) because the BN_CTX has long been released.

I won’t bother you with all the pain I went through to identify the cause, so here is the spoiler: when a BigNum is being extended to a bigger buffer size, its original buffer is not zeroised before being freed. The chain of the control flow path that leads to the leak of p is even more subtle. During intial TLS handshake the server key exchange is signed with the private key. The CRT signing performs a modulo p operation, which caused p<<BN_BITS2 to be stored in a temporary variable allocated from the BN_CTX pool. Later in the CRT fault-injection check, that temporary variable is reused (remember BN_CTX operates like a stack) as val[0]. An interesting fact is that a reallocated temporary variable only gets its lowest nibble zeroised, and in the case of p<<BN_BITS2 nothing is destroyed. val[0] immediately receives a Montgomery-reduced value, but since the original buffer is unable to accommodate the new value, it gets extended and p gets released to free heap space, waiting to be grabbed. And because this happens every time a TLS handshake occurs, it can be spilled everywhere.

Since it is difficult to find which BigNums may be extended and leaked statically, I instrumented OpenSSL and experimented a bit. It turned out that a shifted version of the Montgomery representation of p will also be freed at the leaky point, but that only happened at the first RSA exponentiation when the Montgomery context is initialised, so it will live in a low memory address and I was unable to locate it in any collected packets.

The OpenSSL team has been notified about the above leak. Although to be fair this is not exactly a security bug by itself as OpenSSL is never explicitly designed to prevent sensitive data leakage to heap.

I’d like to thank Joseph Bonneau for the useful comments and proof reading.

Latest health privacy scandal

Today I gave a talk at the Open Data Institute on a catastrophic failure of anonymity in medical research. Here’s the audio and video, and here are the slides.

Three weeks ago we made a formal complaint to the ICO about the Department of Health supplying a large amount of data to PA Consulting, who uploaded it to the Google cloud in defiance of NHS regulations on sending data abroad. This follows several other scandals over NHS chiefs claiming that hospital episode statistics data are anonymous and selling it to third parties, when it is nothing of the kind.

Yesterday the Department of Health disclosed its Register of Approved Data Releases which shows that many organisations in both the public and private sectors have been supplied with HES data over the past year. It’s amazing how many of them are marked “non sensitive”: even number 408, where Imperial College got data with the with HESID (which includes postcode or NHS number), date of birth, home address, and GP practice. How officials can maintain that such data does not identify individuals is beyond me.

Current state of anonymous email usability

As part of another project, I needed to demonstrate how the various user-interface options for sending anonymous email through Mixmaster appeared to the email sender. This is very difficult to explain in words, so I recorded some screencasts. The tools I used were the Mixmaster command line tool, the Mutt email client with Mixmaster plugin, QuickSilver Lite, and finally a web-based interface.

The project is now over, but in case these screencasts are of wider interest, I’ve put them on YouTube.

Overall, the usability of Mixmaster is not great. All of the secure options are difficult to configure and use (QuickSilver Lite is probably the best), emails take a long time to be sent, recipients of anonymous email can’t send replies, and there is a high chance that the email will be dropped en-route.

Continue reading Current state of anonymous email usability

Health privacy: complaint to ICO

Three NGOs have lodged a formal complaint to the Information Commissioner about the fact that PA Consulting uploaded over a decade of UK hospital records to a US-based cloud service. This appears to have involved serious breaches of the UK Data Protection Act 1998 and of multiple NHS regulations about the security of personal health information. This already caused a row in Parliament and the Deparatment of Health seems to be trying to wriggle off the hook by pretending that the data were pseudonymised. Other EU countries have banned such uploads. Regular LBT readers will know that the Department of Health has got itself in a complete mess over medical record privacy.

Ghosts of Banking Past

Bank names are so tricksy — they all have similar words in them… and so it’s common to see phishing feeds with slightly the wrong brand identified as being impersonated.

However, this story is about how something the way around has happened, in that AnonGhost, a hacker group, believe that they’ve defaced “Yorkshire Bank, one of the largest United Kingdom bank” and there’s some boasting about this to be found at http://www.p0ison.com/ybs-bank-got-hacked-by-team-anonghost/.

However, it rather looks to me as if they’ve hacked an imitation bank instead! A rather less glorious exploit from the point of view of potential admirers.
Continue reading Ghosts of Banking Past

Financial cryptography 2014

I will be trying to liveblog Financial Cryptography 2014. I just gave a keynote talk entitled “EMV – Why Payment Systems Fail” summarising our last decade’s research on what goes wrong with Chip and PIN. There will be a paper on this out in a few months; meanwhile here’s the slides and here’s our page of papers on bank security.

The sessions of refereed papers will be blogged in comments to this post.

Health privacy: not fixed yet

I have written a letter to Stephen Dorrell, the chair of the Health Committee, to point out how officials appear to have misled his committee when they gave evidence there on Tuesday.

It is very welcome that the Health Secretary, Jeremy Hunt, announced he will change the law to ban the sale of our medical records collected via HES and care.data. He acted after it became clear that although officials told the Health Committee that our records collected via care.data could not legally be sold, records collected via a different system (HES) already had been. But that is not all.

Officials also said our records would not be sold abroad, and that only coded data would be extracted rather than free text entered by GPs during consultations. Yet our records were offered for sale in the USA; the Department signed a memorandum of understanding with the USA on data sharing; and CPRD (a system operated by MHRA, the regulator) has been supplying free text for mining.

I also sent Mr Dorrell a previously unpublished briefing I wrote for the European Commission last year on the potential harm that can follow if patients lose confidence in confidentiality. Evidence from the USA and elsewhere suggests strongly that tens of thousands of people would seek treatment late, or not at all.