Just under three months ago, we wrote about a coding project called LibreSSL.
In case you missed the excitement, Heartbleed was an OpenSSL buffer overflow bug that allowed one end of a TLS connection (client or server, it didn’t matter) to trick the other end into barfing up 64KB chunks of its own private memory space.
Of course, the memory space of programs like web servers, even randomly sampled in comparatively small grabs, can contain extremely interesting, not to mention confidential, data.
As you probably know, so-called RAM scraping malware snoops on memory, albeit more systematically, to steal things like credit card numbers, which are usually encrypted on disk, but unencrypted in memory.
As US retailer Target found out at the end of 2013, malware that snooped on memory in Target’s tills managed to steal about 40,000,000 credit cards in just a few weeks.
Heartbleed didn’t provide anywhere near the precision of RAM scraping malware, but you didn’t need to infect the other end with malware first.
You could mount an attack from almost anywhere on the internet, and keep prodding the server at the other end over and over again, thouands or even millions of times, in the hope of stealing confidential data from other users’ connections.
Such as passwords, Canadian Social Insurance Numbers, and perhaps even the private keys of the server itself.
Heartbleed relied on buggy code that copied data from an input buffer without checking its size, so you could send the server 12 bytes, say, but ask it to send you back 65535, consisting of your 12 bytes and whatever happened to follow your input buffer in RAM.
How did the bug escape notice?
Disturbingly, the bug had been in the OpenSSL code for two years, which raises the question, “Even if humans missed it in static analysis, how come run-time verification tools and buffer overflow checkers never triggered in all that time?”
One reason, as OpenBSD explained back in May 2014, was that OpenSSL’s memory handling is written so as to make the product’s behaviour opaque to external bug checkers.
As Bob Beck of OpenBSD quipped, OpenSSL’s memory management acts as a sort of “exploit mitigation countermeasure.”
By asking the operating system to give it a big chunk of memory up front, and then “sub-letting” that memory itself inside the code, OpenSSL aims to boost efficiency slightly, but at considerable cost to safety.
So even if you run it on an operating system like OpenBSD, configured for strict checks on memory usage, you’ll see what looks like clean behaviour along the lines of “give me a giant buffer at the start” followed by “here it is returned in good order at the end.”
Even under a bug-finding tool like Valgrind, which deliberately reduces efficiency in return for scrupulously auditing every chunk of memory allocated, bugs and anomalies are covered up.
In a way, OpenSSL’s memory management is a bit like getting a monthly bank statement that lists only your closing balance.
If individual transactions are suppressed, you can’t tell what the bank has actually been doing with your money, even though you might have the right amount left over.
Have your creditors really been paid, or have your outgoings been remitted somewhere else? Have large and unexplained deposits suspiciously come and gone without you being aware?
Smaller is better
So, amongst other improvements, the LibreSSL coders have been increasing the quality of the OpenSSL code by decreasing its size.
They’ve thrown out the extra layer of memory management so that bugs are much more likely to show up sooner.
They’re re-organised the code into a consistent style so that it’s easier to read and review.
They’ve banished large quantities of complex and error-prone code hacks that were there only so that OpenSSL could still work (if anyone ever bothered to test it) on platforms including DOS and 16-bit Windows.
Despite that, they have produced, or have tried very hard to produce, a product that is a drop-in replacement for OpenSSL that operates in a compatible way (minus some of the bugs and much of the opacity, of course).
And they’ve just released their first version that isn’t for OpenBSD only.
The hope is that others will take it, try it, and report back what they find,now that a lot of the impenetrability of OpenSSL has been cut away.
It’s supposed to compile on “any reasonably modern version of Linux, Solaris, or OS X with a sane compiler and C library.”
It worked for me on OS X.
Let me qualify that: it built cleanly with the Clang compiler and passed its own self-tests, which is hardly “working,” but it’s a good start for a Saturday evening!
If you’re a coder interested in security, why not try it yourself?