0

I need to write a simple program that demonstrates a race condition. I picked the Meltdown vulnerability. I want to clarify something. I'm following this explanation https://resources.infosecinstitute.com/topic/race-conditions-exploitation-case-study/

The result of this attack is that the value of PRIVILEGED_VALUE will be revealed with high probability. This is because the Meltdown race condition means that — in parallel with the permissions check — this value will be extracted and used in the calculation BASE+PRIVILEGED_VALUE, and the resulting memory location will be accessed and the data that it is contained is moved to the cache.

This means that, when the attacker attempts to access the range of potential memory addresses, one should be accessed much more quickly than the others. This is because the address BASE+PRIVILEGED_VALUE has been recently accessed and cached, while the others (hopefully) have not been. This makes it possible for the attacker to derive the value of PRIVILEGED_VALUE by identifying the cached memory address and subtracting off the value of BASE.

I don't understand one thing. How can the attacker exploit the fact that he knows the value of the memory location of the privileged data he wants, if he doesn't have enough privileges to see it? What if this data is encrypted?

One more question: how does the computer "know" what is in the cache? Does it keep a variable saying "this cached value corresponds to this query" or something like that? I need to know this for the program I am writing.

1 Answers1

2

To perform the Meltdown attack, a program asks for the contents of a memory location it's not allowed to read, uses the value stored at that location to compute a memory location that it is allowed to read, and asks for the contents of that second location. Eventually the CPU catches up, generates an access fault, and prevents the program from continuing to run, but in the meantime, the results of the second memory access has been stored in the CPU cache.

The program knows what's in the cache because accessing main memory is slow. If a value isn't in the cache, it might take several hundred CPU cycles to retrieve it from main memory, while retrieving it from the level 1 cache might only take two or three CPU cycles.

For example, an attack program trying to read the administrator program from the operating system's memory might work like this:

  1. Attack program allocates a 256-byte chunk of memory.
  2. Attack program launches a short-lived reader program and gives it access to that 256-byte chunk.
  3. Reader program wipes the CPU cache.
  4. Reader program does something to trigger speculative execution.
  5. Reader program asks to read the first byte of the password.
  6. Reader program uses the value of that byte to decide which byte of the attack program's memory chunk to read from (for example, by adding the value of the byte to the address of the memory chunk).
  7. The contents of that byte of memory are put into the CPU cache.
  8. The CPU catches up to what the reader program has been speculatively doing, realizes that it's reading protected memory, generates an access fault, and terminates it, wiping out all visible changes it made starting with the read of protected memory. But it doesn't undo putting the byte into the CPU cache, since that isn't supposed to be a visible change.
  9. Attack program reads its 256-byte chunk of memory one byte at a time and measures how long each byte takes to read.
  10. If one of the bytes is faster to read than the others, that one corresponds to the value of the byte of protected memory.

If, for example, the 72nd byte of the shared memory chunk is faster to read than the others, then the first byte of the password must have ASCII value 72 and be an "H". The attack program can then repeat the process to figure out what the other bytes of the password are.

(Actual details of the attack will vary, to deal with things like memory alignment and cache line size, or to improve performance.)

Mark
  • 34,390
  • 9
  • 85
  • 134
  • I have some questions. "Reader program asks to read a byte of protected memory." this is possible because of the race condition, correct? The attacker would have to run this query several times then? How does he know when he was successful? "Reader program uses the value of that byte to decide which byte of the attack program's memory chunk to read from." I don't understand this part. How? Why? "If one of the bytes is faster to read than the others, that one corresponds to the value of the byte of protected memory." so what? He still can't access it. I don't see the point. – Segmentation fault Sep 15 '21 at 11:18
  • 1
    The key to Meltdown (and Spectre, and most other recent CPU attacks) is [speculative execution](https://en.wikipedia.org/wiki/Speculative_execution): while one part of the CPU is dealing with a program doing something that will take significant time, another part is making a best guess as to what the program will do next. I've updated the answer to cover your other questions. – Mark Sep 15 '21 at 20:07
  • "If, for example, the 72nd byte of the shared memory chunk is faster to read than the others, then the first byte of the password must have ASCII value 72 and be an "H"." why would the 72nd byte have the ASCII value 72 and not any other ASCII value? – Segmentation fault Sep 18 '21 at 23:54
  • Because that's how ASCII is defined: the number 72 represents the capital letter "H". – Mark Sep 19 '21 at 00:48
  • I know, but why would it be the 72nd byte of the protected data? – Segmentation fault Sep 19 '21 at 11:40
  • 1
    Because the reader program is adding the value of the first byte of the password to the address of the start of shared memory to figure out which byte of shared memory it wants to read. – Mark Sep 19 '21 at 18:09