Understanding Spectre and memory addressing

645 Views Asked by At

First a disclaimer: I don't intent to hack anyone, I'd just like to see the exploit in action on my own machine.

I've compiled the Spectre example in VS2017 on x64 Windows 10.

The example works when reading from its own process memory, but if I try to read from my test app, I only get at string of zeros or other similar characters.

test app:

#include "stdafx.h"
#include <string>
#include <iostream>

const char *gotroot = "The Magic Words are Squeamish Ossifrage.";

using namespace std;
int main()
{
    printf("%p",gotroot);

    string endd;
    cin >> endd;

    printf("%s", gotroot);
    return 0;
}

I start the app and copypaste the address to the Spectre commandline, but I don't get the string.

I couldn't figure out if Windows 10 has already been patched?

But I've also tried in Ubuntu 17.04 that hasn't be updated in a while, with the same result.

Is there something wrong with my approach?

1

There are 1 best solutions below

5
On

Spectre is a vulnerability. I assume this "spectre command line" you mention is some specific implementation / testing tool? What target branch does it exploit? Presumably an indirect branch in the kernel, otherwise you could only give it addresses in the virtual address space of whatever target program it was attacking.

So you'll need the kernel address of the physical memory your target process is using, in the part of kernel virtual address space that maps all physical memory. (Or whatever Windows does, I forget. But it's apparently different from Linux's simple map-all-the-memory with 1G hugepages design). But both use the upper half of virtual address space for kernel addresses. The Meltdown paper explains how / why kernels map all the memory (and would leave it mapped globally, protected by the user/supervisor bit in the page tables if they didn't need to work around Meltdown on Intel CPUs. Meltdown defeats that permission bit.) But the kernel will have it mapped any time it's executing its own code, and thus Spectre can take advantage of that mapping. The Meltdown workaround is to unmap kernel pages when running user-space code. Spectre tricks the CPU into speculatively executing some kernel instructions in kernel mode.

Anyway, this is different from the char* value that your process uses in its own virtual address space. The same page of physical memory is mapped globally to a high address, as part of the kernel's map-everything region, and (when your process is executing) also to a low address for use by user-space code. It's this latter address that you see with %p.