Subtitles section Play video Print subtitles So imagine if JavaScript could just read anything on your computer. If some tab on your browser just had access to reading all your passwords or knowing what your other programs are doing. That would be pretty bad, wouldn't it? By a computer I of course mean any kind of computing device, like your smartphone. What would be particularly worrying is if this were to happen without exploiting any software vulnerabilities or without fooling you to do so. That's actually the state of affairs right now. We are currently seeing a series of attacks called Spectre and Meltdown, in what I'm going to call here the "Spectre Meltdown". I'm want to explain the core of these vulnerabilities to a wider audience. I'm going to skim a lot of the technical details. So we're not going to go into some of the necessary technical details that make exploitation possible. But I just wanted to give you the idea of what these vulnerabilities are doing. My name is Ymir Vigfusson and I'm Assistant Professor of Computer Science at Emory University. Before we get started, I just wanted to give credit where credit is due. These vulnerabilities were found by actually concurrently separate teams, who have done fine work on writing up the details, and I encourage you to look at it. So let me introduce the three ingredients that are we are going to need to understand the attacks. The first one is to understand how memory works. At a high level. The second one is to understand "speculative execution" in your CPU. And the third one is something called "side-channel attacks". Naturally, Spectre and Meltdown are at the convergence of these new kinds of attacks that are becoming particularly worrying as, well as hardware errors that are also worrying. So it's in the intersection of something that we need to be looking out for in the coming future. Let's get to it. How does your computer work? Well... Let's take it at a really high level, simplified view of your computer. A computer is really a bunch of different components that are strung together. These components include things for input/output, like your monitor, and your keyboard, your mouse. And then there is a CPU in the middle that does all the processing. And finally, there is memory, and I'm counting hard disks or SSDs as being part of your memory. Really what happens when you are doing something on your computer is that you're going to load a program from a disk, and it's going to be executed by the CPU. Your CPU is going to do a bunch of computations, and those computations involve memory, so it's going to go back and forth a bit. And finally it may produce some output and that output may end up on your monitor, on through the network. That's basically what execution on a modern computer looks like. So let's zoom in on the CPU and memory. Inside your memory you actually have contents of all the different kinds of programs that you're currently running. This could be programs you're running; it could be data pertaining to the operating system that you're running, like Linux, Windows or MacOS, and so forth. And it's your user data. Memory is an amalgam of all these different types of things that could be used, as well as storing intermediate computations for the CPU. Let's look at memory a little bit more in detail. There is a lot to a memory hierarchy inside a computer. If we think about memory, it's actually very helpful to just visualize it as a long sequence of boxes that you can open. Each box contains one bit, or one byte of information in our case. There are actually several layers of memory. What I've drawn here is something called DRAM, which is actually very big but veeery sloooow for the CPU to retrieve. If the CPU wants wants to retrieve some data from it, it has to wait for a while. So what we have are actually several other layers called cache memory. So let me draw cache memory here in front. Suppose I wanted to open one of these boxes. My request -- it's fast memory over here -- that this particular orange box over here be opened. Well... it's going to taaake a whiiile. Whereas if I try to open up a different box, if I open up this one, I can actually first ask the really fast cache memory. And that has an exact copy of what I need. Now, the way cache memory is maintained is that when you retrieve something, you often take a copy and put it into the cache memory so that the next time you might need it, you have it laying around really quickly. But cache memory is small, and tends to be pretty expensive. So you have to kick something else out. This is actually the subject of much of my research. So! This is how caches work. Let's move on to the next ingredient. What are side-channel attacks? Now.. let me illustrate it with an example. Suppose that you are asking a computer to authenticate, and there is a particular password that the computer knows is there. This has actually happened on several routers. This is something known as a "timing attack". This is a kind of a side-channel attack, but I think it illustrates the point. Suppose the password is, randomly, "hunter2". Now, what you might do is to start guessing. You say, like, "Well, is the password 'a' ?" And the computer has to run around and check if it matches. It looks at the first character 'a'. Looks at the first character of the password, and sees that it's 'h'. It doesn't match and so it returns. Now you might guess: "b?" You do the same thing. Of course, there are exponentially many possibilities here, and you'd be out of luck. That's why passwords are often good. But in this particular case, as you keep guessing. You guess 'g?', same thing happens. If you guess 'h?' now, what you'll notice is that it takes a little bit longer for the computer to respond to you. And if that happens, that's because the computer had to look at the letter 'h', saw that it matched, and then had to look at the subsequent letter to see if there was a match there. There was no match, because you guessed a one letter password, and the password is actually longer. So now you might actually be pretty confident, just by looking at the timing information, that the first character is 'h". So you move on to 'ha?' and you see it takes just a long as what you guessed initially. And then you would try 'hb?' and so on and so forth. This actually makes password guessing linear in the length of the password, rather than exponential, which is terrible. The side-channel here is the timing information. It's something about the physical implementation of this algorithms, this password-checking algorithm, that you are exploiting. In this case, the timing difference. So, let's keep that also as an ingredient. The third thing I wanted to tell you about is called "speculative execution". This might be -- might look something like this from Rick and Morty. When your CPU is trying to execute a bunch of instructions what it will run into is the fact that memory is slooow, like we talked about. So, you have your really fast CPU, it has a lot of gigahertz. It's running around, it's executing stuff. And what it runs into is that, ultimately, your program is going to need some data from memory. So it talks to memory, and then you're just waiting for the response. And the response takes a whiiile. So you're spending a lot of your time just waaaiting for meeemory. That's an absurd way of having a CPU go about its business. So, 20 years ago, what people came up was: "well, what if we just make our CPUs do speculative execution?" What I mean by that is that, suppose your program looks something like this. There is a branch -- there is an IF sentence that depends on memory in some way. There's really only two options. Either, what you're going to get from memory is going to be 0 in this case, or it is not. So what if you just guess? You think that maybe the most likely thing to happen in this case is that you're going to get a zero from memory. Now, you are waiting here for memory and you decide to just sprint ahead. You come here, and you just execute the instructions that are coming, even before you get your response from memory. Huh... interesting. So if memory is 0, you're actually ahead of curve: you know what's going to happen. You can resume from instructionD onwards. It's very convenient. Now, if that didn't happen -- if it so happens that the response from memory wasn't zero, then you actually have to roll back all the changes that you made. So have to be very cognizant of not changing the state of the program, registers externally, so that you can actually go back to the other branch of that IF sentence. This is very interesting. Now, the flaw that Spectre and Meltdown are exploiting is the fact that actually when you're doing speculative execution, the state of the CPU actually looks a little bit different because of cache when it has to abort a branch. Now we actually have all the ingredient needed to explain Spectre and Meltdown at a very high level. Suppose we have our memory here. This is our slow memory. And, as we talked about before, what your operating system kernel is doing is that it allocated this memory to different applications, or possibly different virtual machines if you're living in the cloud. That means that there could be adjacent parts of memory allocated to different victims. I'm pretty much describe Spectre right now, but the same concepts apply to Meltdown. So there is part of memory here, what we call victim memory, that we want to enumerate. We want to know what it says. It could contain a password that we're after. Normally, what an operating system tries to do is to make sure that your program, including your JavaScript in your browser, cannot access somebody else's memory. There is isolation between processes. It would be an illegal operation to try to read from the red memory -- the memory on the right. What we're going to do instead is to exploit the fact that there's also the fast cache. Suppose we want to read this blue dot over here. There is fast cache here in front that has copies of some things in memory. What we're going to do is the following trick. We're going to set up an array here -- let's call it A. It's a part of memory that we control. It's samll. What we're going to do is that we're going to say like: "Well, I don't want to read the two elements that are array A. I'm going to over-extend. I'm going to go out-of-bounds. I'm going to read what's at A and element number x, where x is way too big." Normally, when you would be doing this on your CPU, your CPU or your operating system would actually trigger a fault. They would say like "Hey! This is not allowed! I'm going to kill this program." It's going to perform an illegal operation, if you like. But we're going to do it speculatively... So let's look at how that plays out. We're going to set up something called the "instrument". It's another part of memory that we're keeping out of the cache. We specifically tell the CPU not to cache any of it -- it's all in slow memory. It's consecutive parts of memory. I'll explain what this does in just a little bit. When I say Instrument, you can imagine it being an actual instrument -- something like a keyboard. That's how I think about it. It's different notes. Suppose the code that you're executing is as follows. It's a branch -- it's an IF sentence that just asks for something absurd. "IF the world is flat", we're going to do the following instruction. Now, normally what your CPU would be doing is to completely ignore what's going on after this branch because it's waiting for computations from memory accesses to figure out if the world is flat. And then it just dumps things out. But because of speculative execution, there is a chance that what's inside this branch is going to executed. So it actually looks at it speculatively -- it's going to perform speculative execution of the subsequent instruction. In our case, we're going to run the following instruction. We are going to try to access the part of memory that lies instrument of A of x. Whoa. That's a mouthful. Let's have a look at what that means. Suppose that what we're after is the part part of victim memory, the blue dot here, and it contains the letter 4, or the number 4. We don't know this, but we want to find this out -- that's what the attacks are about. So what we're going to do is to look at how speculative execution deals with the following. The fact that it says 4, the fact that the CPU is now executing this instruction (without actually executing it) means that it's going to say: "Oh, okay, I'm supposed to look at A[x]. Okay, I don't know that it's out-of-bounds, yet, because that's the role of kernel. I will find this out later if this was actually what's going to get triggered, the kernel will kill the program because it's reaching memory it shouldn't. But as a speculative execution engine, I'm just going to look ahead in memory and see what's there. And I see that it's actually the letter 4, or the number 4, or G as a note if you like my musical analogy. I'm going to take that, and I'm going to look it up in the instrument array at location 4 (or note G) -- I'm going to play it." What that does -- and this is the crucial part of this attack -- is that it brings that part of the instrument array into cache. That's where your timing attack comes into play. So, now, the final part of this attack is that you're going to go through and retrieve every note in your instrument. You could play the zeroth note, and it's slow. First one, and it's slow. But once you reach the fourth note, it's really fast. It's coming from fast memory! Why? Because when the speculative execution happened for the code, it rolled back all of the registers, but it did NOT roll back the cache accesses. There is leakage of information from the fact that there is speculation happening. And that speculation happened across administrative boundaries. Consequently, you're now in a situation where you can actually find out that your victim memory contained the letter or number "4". And, of course, we can now extend this yellow range and make it really big, maybe 256 bytes. Or even bigger, because caches are actually a little trickier, you need bigger blocks. That's technical details. This is the crux of the Spectre Meltdown attack. So if you look at the actual code that's provided by the authors, you'll see something very similar to what I explained for Spectre, and a something a little bit different but still the same core idea for Meltdown. As a promise to you, I asked "What if JavaScript could read something from arbitrary memory?" Well, as it turns out, you can simulate the exact same set of instructions in JavaScript, which means that you now have a website you get onto, and it could try to read parts of kernel memory.This is because it's private information, including your passwords. So as the authors of these attacks actually demonstrated that you could read, for instance, stored passwords. It's pretty bad. But I'll leave it to other people to explain the consequences of this attack, and how we're going to react to it. I just want to leave you with a set of URLs where you can learn about this very interesting sets of attacks and the authors who found them. Thank you very much.
B1 US memory cpu cache spectre meltdown speculative Spectre and Meltdown attacks explained understandably 18 0 bruce19950331 posted on 2018/01/07 More Share Save Report Video vocabulary