The Spectre attack – how does it work?
... and will it kill me?
January 5, 2018
TLDR: How should you deal with Spectre and Meltdown? NCSC has guidance here.
The birth of Spectre
On January 2nd 2018, researchers from Google’s Project Zero and the modern-day genius Paul Kocher, made public their discovery that millions of chips in use in todays laptops, servers, smartphones and other devices were vulnerable to a new kind of attack, which could allow attackers to discern private information about a device, and potentially bypass all security measures. They named this class of attack “Spectre”.
When a vulnerability is discovered, software companies are usually informed first; the idea is to keep the inner workings of the hack secret, until patches can be produced. This stops any malicious third parties from exploiting the vulnerability (or that’s the idea). Unfortunately for us, Spectre attacks aren’t possible because of badly written software, but possible because of nuances in hardware. The problem itself lies in how the physical chip works. This obviously can’t be fixed by downloading a patch (except microcode updates), so chip designers are having to revise their designs, and software companies are producing workarounds (which can slow machines down by up to 30%).
Should you be worried? Some say yes. Some say no. Let’s explore the Spectre attack vector and make a decision ourselves. So, how does it work?
Memory and caching – the quest for performance
Let’s start with memory, or your RAM, specifically. RAM holds information about currently running apps; the contents of your browser window, the data in your spreadsheet or the audio data for the track you’re currently listening to. The thing is, each app you run shouldn’t be able to read the memory of other apps. This makes complete sense – imagine the invasion of privacy if visiting Facebook revealed your personal finances, or doing a quick search on Google sent your family photos off to an “internet gangster”. Separating memory between applications (or processes, as we will now call them) is the responsibility of the processor. If a process tries to read a memory address that is outside of it’s allocated memory space, it will throw an error, keeping our data safe.
Now, RAM can be slow compared to other types of memory, so processors have a tiny amount of internal memory called a cache (actually many different caches). Different types of processors have different levels of caching, but they all operate in a similar way. If data held in RAM is frequently used, it is copied to the processor cache. This allows the process accessing the memory to read from the cache itself, not the RAM, which means reading the data is over 100 times quicker than reading directly from RAM. Quite a speed increase! To sum up: frequently used data is quick to read, infrequently used data is a lot (100x) slower to read.
Caching alone isn’t enough though. We’re always on the lookout for performance gains, and chip manufacturers introduced another speed enhancing feature called “Speculative Execution” in the late 90’s, which is commonplace today. Speculative Execution is essentially performing some calculation in advance, if the processor thinks it might be needed. If the calculation isn’t needed, the results are discarded, and the processor state is rolled back to the point before the calculation. What this means is that we can make great performance gains by using excess processing power to calculate answers to questions that may be asked in the future. When code is speculatively executed, but discarded, we call this a mis-speculation. It happens all the time. There is a period of time between the execution of the code, and the realisation that the code has been mis-speculated that we call the mis-speculation window. It’s inside this short time window that we can perform our attack, allowing us to reveal memory belonging to another process.
By attempting to read from memory that we know isn’t cached (by manipulating the cache), and encouraging the processor to speculatively execute the code that read the memory, we can temporarily bypass the security measures that disallow reading from other processes’ memory, but only for a few nanoseconds. Once the processor realises we’re trying to read memory that’s not owned by our process, it discards the result and rolls back to the state prior to the read operation. The thing is, because RAM is so slow and cache is so fast, we’ve actually got quite a bit of time to perform some other operations before the mis-speculation window is up and the roll-back occurs, providing the data we’re spying on wasn’t initially in the cache…
If we’re clever (programmers – the code is here), we can try to read a memory address that we have access to inside the mis-speculation window, and we can choose that address based on the value of the data that we’re spying on. For example, if the spied value is “1”, we read address 300, and if it’s “0”, we read address 200. When the mis-speculation window is up, and our cheeky peek into un-owned memory is rolled back and discarded, we can simply check to see which address we accessed in our own memory space by timing the time taken to read it (if we accessed it inside the speculative execution, it will be cached, and quick to read), and therefore determine if the data that we’re spying on is either a “1” or a “0”. So if we access address 300 and it’s quicker to read than address 200, we know the spied value is a “1”.
Repeat the process over and over, and you could read out the entire memory of the machine, with no security measures, including things like private keys, passwords and personal information. The thing is, this attack is performed a bit at at time, and that’s slow. We have to perform this process 8 times in order to retrieve a small numeric value. To read one single international character, we would need to run this 32 times. Bear in mind we also need to manipulate the processor cache and speculative execution state in between each of these attempts, which slows the process down even more. Researchers at Google have only managed to read 1500 bytes a second on a high performance server CPU, which means that in order to read out the entire contents of a typical Google Chrome browser session, it would take just over 97 hours! Calculation below:
Typical Chrome Memory Usage: 500MB 500MB = 524288000 Bytes 524288000 Bytes / 1500 Bytes per second = 349525 Seconds = 97 Hours
So, the speed of the attack might be an obstacle for potential attackers, but if they knew with absolute certainty the address of a specific piece of data they wanted access to (a password, for example), the attack would be viable. Luckily it’s difficult to determine the memory address of specific variables, but it’s far from impossible.
To sum up…
So, now you know the rough outline of the Spectre attack, you can start to decide for yourself how this may affect you. If you’re a home user, surfing the web and Skyping the family, my advice would be to wait for software patches to be released, then update your operating system but continue using your device in the meantime and don’t worry. If, however, you’re holding the keys to a chunky Bitcoin wallet, I’d pull the plug on the machine, and buy a new patched processor once they’re out on the market. For more information for home users, check out the NCSC’s advice here.
As for businesses operating servers or cloud services – deal with this NOW! Guidelines are here.
- There are actually 3 variants of this attack; Meltdown and two others. See the Project Zero blog post for more.
- Apple patched their iOS and Mac devices back in December 2017 for Meltdown.
- KAISER and KPTI are patches for Meltdown on the Linux kernel.
- Lots more info at https://spectreattack.com/