Search code examples
csecuritysegmentation-faultkernelspectre

Are other parts of physical memory accessed during a segfault?


As part of a learning project, I've worked a bit on Spectre and Meltdown PoCs to get myself more confortable with the concept. I have managed to recover previously accessed data using the clock timers, but now I'm wondering how do they actually read physical memory from that point.

Which leads to my question : in a lot of Spectre v1\v2 examples, you can read this piece of toy-code example:

if (x<y) {
  z = array[x];
}

with x supposedly being equal to : attacked_adress - adress_of_array, which will effectively lead to z getting the value at attacked_adress.

In the example it's quite easy to understand, but in reality how do they even know what attacked_adress looks like ? Is it a virtual address with an offset, or a physical address, and how do they manage to find where is the "important memory" located in the first place ?


Solution

  • In the example it's quite easy to understand, but in reality how do they even know what attacked_adress looks like ?

    You are right, Spectre and Meltdown are just possibilities, not a ready-to-use attacks. If you know an address to attack from other sources, Spectre and Meltdown are the way to get the data even using a browser.

    Is it a virtual address with an offset, or a physical address, and how do they manage to find where is the "important memory" located in the first place ?

    Sure, it is a virtual address, since it is all happening in user space program. But prior to the recent kernel patches, we had a full kernel space mapped into each user space process. That was made to speedup system calls, i.e. do just a privilege context switch and not a process context switch for each syscall.

    So, due to that design and Meltdown, it is possible to read kernel space from unprivileged user space application (for example, browser) on unpatched kernels.

    In general, the easiest attack scenario is to target machines with old kernels, which does not use address randomization, i.e. kernel symbols are at the same place on any machine running the specific kernel version. Basically, we run specific kernel on a test machine, write down the "important memory addresses" and then just run the attack on a victims machine using those addresses.

    Have a look at my Specter-Based Meltdown PoC (i.e. 2-in-1): https://github.com/berestovskyy/spectre-meltdown

    It is much simpler and easier to understand than the original code from the Specre paper. And it has just 99 lines in C (including comments).

    It uses the described above technique, i.e. for Linux 3.13 it simply tries to read the predefined address 0xffffffff81800040 which is linux_proc_banner symbol located in kernel space. It runs without any privileges on different machines with kernel 3.13 and successfully reads kernel space on each machine.

    It is harmless, but just a tiny working PoC.