Lucene search

K
seebugRootSSV:92489
HistoryOct 25, 2016 - 12:00 a.m.

Android Rowhammer attack vulnerability (Drammer)

2016-10-2500:00:00
Root
www.seebug.org
70

EPSS

0.001

Percentile

23.7%

Project Description

Drammer is a new attack that exploits the Rowhammer hardware vulnerability on Android devices. It allows attackers to take control over your mobile device by hiding it in a malicious app that requires no permissions. Practically all devices are possibly vulnerable and must wait for a fix from Google in order to be patched. Drammer has the potential to put millions of users at risk, especially when combined with existing attack vectors like Stagefright or BAndroid.

Drammer is the first Android root exploit that relies on no software vulnerability and is an instance of the Flip Feng Shui exploitation technique. After Dedup Est Machina and Flip Feng Shui, Drammer is our group’s third in a series of Rowhammer exploitation research. Our Drammer exploit and companion Drammer test app (see below) were implemented in collaboration with the University of California, Santa Barbara.

Rowhammer

is a hardware bug that allows attackers to manipulate data in memory without accessing it. More specifically, by reading many times from a specific memory location, somewhere else in memory a bit may flip (a one becomes a zero, or a zero becomes a one). Our work is the first to show that Rowhammer is possible on mobile, ARM-based hardware.

Flip Feng Shui

or FFS is a technique that allows for reliable exploitation of a hardware vulnerability (e.g., Rowhammer) by combining it with a memory massaging primitive (to land sensitive data on a vulnerable location). Drammer is the first to show that such deterministic Rowhammer exploitation is possible without relying on fancy memory management features. Although we focus mainly on mobile devices, this makes that Drammer comes with a wider impact; allowing FFS attacks without memory deduplication, for example.

Papers

[1] V. van der Veen, Y. Fratantonio, M. Lindorfer, D. Gruss, C. Maurice, G. Vigna, H. Bos, K. Razavi, C. Giuffrida,Drammer: Deterministic Rowhammer Attacks on Mobile Platforms, in: CCS, 2016.

Drammer Test App

We developed an Android app – not yet in Google Play, but available directly – to test your device for the Rowhammer bug. The app uses a native binary for which we also released the source code. After a successful run, the app uploads anonymized output. We will use this to get a better understanding of how widespread the Rowhammer bug is. Of course, you can opt out of sharing results.

Please note the following:

  • Currently, when finished its hammering session, the app does not give you a nice popup that tells you whether you are vulnerable or not. We will try to add this as soon as possible. Meanwhile, you can easily spot induced bit flips by glancing over the output and looking for the obvious keyword FLIP.
  • Your phone might still be vulnerable, even if the app detected zero flips! There are two main reasons for this. First, our current implementation of address selection is conservative: we recently discovered that the current code is only hammeringhalf of the rows on a Nexus 5. On your device, the DRAM geometry might be different enough for our app to completely fail selecting addresses for double-sided rowhammer. Second, the app may only have tested a very small fraction of your DRAM. Ideally, a single run takes at least an hour and scans a couple hundred of MB. The current code already tries to free as much memory as possible to hammer (affected by the aggressiveness factor), but there are probably better ways of doing this.

Hammertime simulator

We developed Hammertime, an open-source Rowhammer simulator – available on github – to foster further research on the Rowhammer bug. The simulator allows researchers and practitioners to simulate hardware bit flips in software, using bit-flip patterns (or fliptables) from a large set of DRAM chips. We plan to integrate bit-flip patterns we observed with Drammer on ARM soon.

Statistics

Not every phone is susceptible for the Rowhammer bug. For our paper, we tested 27 devices and were able to flip bits on 18 of them. In the table below, you can find statistics on devices that were tested so far.

<table>
<tbody>
<tr>
<th>Model</th>
<th>#devices</th>
<th>#vulnerable</th>
</tr>
<tr>
<td colspan=“3”><strong>ARMv7 (32-bit) devices</strong></td>
</tr>
<tr>
<td>LG Nexus 4</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>LG Nexus 5</td>
<td>15</td>
<td>12</td>
</tr>
<tr>
<td>Motorola Moto G (2013)</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>Motorola Moto G (2014)</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>OnePlus One</td>
<td>2</td>
<td>2</td>
</tr>
<tr>
<td>Samsung Galaxy S4</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>Samsung Galaxy S5</td>
<td>2</td>
<td>1</td>
</tr>
<tr>
<td colspan=“3”><strong>ARMv8 (64-bit) devices</strong></td>
</tr>
<tr>
<td>HTC Desire 510</td>
<td>1</td>
<td>0</td>
</tr>
<tr>
<td>Lenovo K3 Note</td>
<td>1</td>
<td>0</td>
</tr>
<tr>
<td>LG G4</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>LG Nexus 5X</td>
<td>1</td>
<td>0</td>
</tr>
<tr>
<td>Samsung Galaxy S6</td>
<td>1</td>
<td>0</td>
</tr>
<tr>
<td>Xiaomi Mi 4i</td>
<td>1</td>
<td>0</td>
</tr>
</tbody>
</table>

We encourage everybody to try our Drammer test app and help figuring out how widespread mobile Rowhammer is. We expect, for example, that devices equipped with LPDDR4 are less vulnerable. This is because the LPDDR4 standard includes optional hardware support for the so-called target row refresh mitigation.

Technical Walkthrough

Drammer presents two novel contributions: 1) being able to do Rowhammer on mobile devices, and 2) doing deterministic Rowhammer exploitation without relying on fancy memory management features. What follows is a technical summary of our paper, but only if you’re interested.

1. Mobile Rowhammer

Although functioning fairly well on x86, researchers have speculated that Rowhammer on ARM could be impossible. One of the main reasons being that the ARM memory controller might be too slow to induce bit flips. Not surprisingly, before Drammer, no existing work from academia or industry documents any success in reproducing the Rowhammer bug on mobile devices.

The obvious first goal of our study was to find bit flips on a mobile phone. Since Rowhammer manifests itself in DRAM, existing hammer code usually consists of a small loop that 1) reads a value from memory, and 2) flushes this value from the CPU cache. Without cache flushing, the vulnerable DRAM chip would only be accessed once during the first iteration. Every subsequent access would be served from the cache.

Working with an ARMv7-A CPU (the core of our poor LG Nexus 5 test phone), cache flush instructions are unavailable from user space (unlike Intel’s clflush instruction). We thus implemented a hammer function as Loadable Kernel Module. This allowed us to use the DCCIMVAC instruction (Data Cache Clean and Invalidate by MVA to PoC: mcr p15, 0, &lt;reg&gt;, c7, c14, 1). After some frustrating trial and error – do we not see any flips because of a bug in our code, is the controller really too slow, or is this DRAM chip simply not vulnerable? – we found a first flip. Later, once we established that the ‘row size’ of the Nexus 5 is 64 KB instead of 256 KB, this one flip became many…

1b. Direct Memory Access

Although good for feasibility analysis, flipping bits with kernel code that requires root access is not practical for writing a root exploit. Our next goal was thus to induce bit flips from user space. After establishing that existing methods for flushing or bypassing the CPU cache do not work on ARM, we tried a new approach: using direct memory access (DMA). By design, DMA memory pages have two important properties: 1) they are marked as uncached; and 2) they are physically contiguous. The former means that any read operation from DMA memory (or any write operation to it) bypasses the CPU cache and propagates to the DRAM chip directly. The latter means that pages obtained by allocations up to a certain size (4 MB on recent Linux kernels) are guaranteed to be adjacent to each other in physical memory.

DMA memory thus solves our problem of not being able to flush the CPU cache. The fact that allocated pages are physically contiguous happens to also solves another important issue. Recent kernels disabled access to /proc/self/pagemap – a special file containing the mapping of virtual to physical addresses. Without such mapping, it is hard to figure out from which ‘aggressor’ address x we should read to hammer ‘victim’ address y (x should be exactly one row above or below y to get the best chance of flipping it). If we know, however, that a chunk of memory is physically contiguous, we can compute aggressor addresses for each victim within such chunk by subtracting (or adding) the row size.

1c. Android ION

Android provides DMA Buffer Management APIs through its main memory manager called ION. This allows userland apps to access uncached, physically contiguous memory and comes with all the benefits:

  • We do not have to rely on cache flush instructions. Moreover, since we bypass the cache completely, we break any defense that relies on monitoring cache misses (e.g., ANVIL).
  • We do not have to rely on access to /proc/self/pagemap or transparent huge pages (which may not be enabled by default).
  • We do not have to rely on fancy memory management features like memory deduplication or MMU paravirtualzation for the memory massaging phase of FFS (discussed next).

Although ION is specific to Android, we think that it is also possible to construct similar attacks on Linux/x86-64. We dedicate a section about this in our paper.

2. Deterministic Exploitation

Armed with uncached, physically contiguous memory, our third goal is to perform memory massaging in such a way that a single bit flip allows us to gain root privileges. Similar to Mark Seaborn’s attack, we use page tables as sensitive data. By flipping a bit in a Page Table Entry (PTE), we can make that entry point to a page table. This means that the associated virtual address of that PTE is now mapped to a page table which we can use to overwrite its contents. Next, we can map any physical memory address into the virtual address range defined by the page table, including kernel memory. We can use this to search for our process’ credentials structure – the data structure that the kernel uses to keep track of a process’ uid, gid, etcetera. Finally, once found, we can modify our process’ struct cred to get root privileges.

A subtle difference between the exploit from Project Zero and Drammer is determinism. Mark Seaborn sprays physical memory with pages tables and reasons that when a PTE’s physical page number changes [due to a bit flip] there’s a high probability that it will point to a page table for our process. Drammer, however, removes this non-determinism by massaging physical memory in such a way that when we flip a bit in a PTE, we make it point to its own page table. We do this by using the bit flip as addition or subtraction primitive.

2b. Flipping Bits in Page Table Entries

As an example, consider a PTE that points to a page at physical address 0x1982f000. Ignoring the lowest 12 properties bits of a 32-bit PTE, this gives the bit pattern 00011001100000101111 (0x1982f000 bit shifted 12 places to the right). If a we manage to flip the lowest 1, then the new PTE becomes 00011001100000101110. This makes the PTE point to physical address 0x1982e000, showing that a 1-to-0 flip at this offset subtracts the PTE by one page. If we flip the second 1, we would end up with PTE 00011001100000101101. This corresponds to physical address 0x1982d000; exactly two pages away from the original. Flipping the third bit moves the PTE 4 pages to the left, the 4th bit allows us to move 8 pages, etcetera.

With these primitives in hand, we ought to align physical memory in such a way that the physical address of an mmapped data page is exactly n<sup>2</sup> pages ‘away’ from its page tabl. Here n is the offset of the vulnerable bit in the PTE. Continuing previous example, if n is 5 for a 1-to-0 flip, our data page should store 16 pages before the page table. And we found a way of doing exactly this

2c. Abusing the Buddy Allocator

By releasing a large contiguous memory chunk and quickly re-allocating smaller ones, we can satisfy above requirements and make Drammer deterministic. The basic steps of our attack involve:

  1. Search physical memory for potentially exploitable flips (dubbed templating). After this step, we have exhausted all large contiguous chunks (of size 4 MB), but also all medium-sized chunks – say of size 64 KB. This means that there is no physically contiguous memory left that spans 64 KB or more.
  2. Release a large chunk that has an exploitable flip, but do hold the other chunks.
  3. Allocate (i.e., exhaust) all medium-sized chunks again. Since, in step 1, we exhausted all of these already, we know that the buddy allocator will split the large, vulnerable chunk that we released in step 2 and give us exactly 64 chunks of size 64 KB (64 * 64 KB = 4 MB), including a chunk with the exploitable bit. We can now release all chunks that are larger than 64 KB so that we won’t go out-of-memory in the next step.
  4. Release the vulnerable medium-sized chunk and force the OS to allocate a page table at the location of vulnerable page (the page with the exploitable bit).
  5. Map (with mmap) the appropriate other medium-sized chunk to create a page table entry that points to a page that is exactly n<sup>2</sup> pages away from the page table.

Next is hammer time! We hammer the row that holds the PTE to induce the bit flip that makes it point to its own page. We suddenly get write access to a page table and scan kernel memory by writing new PTEs. Once we find our credentials data structure, we overwrite it with zeros and get root access.

2d. Phys Feng Shui

The figure below illustrates the memory massaging phase of Drammer. For more details, it’s best to have a look at the paper.

drammer-ffs

Responsible Disclosure

We contacted the Android Security Team on July 25. In conjunction with Google, we did not publicly disclose any details about Drammer prior to the CCS conference in Vienna. Google informed their partners about this issue on October 3, 2016 and provides a patch for it in their November Android Security Bulletin.

Ultimately, CVE-2016-6728 was assigned to this issue. Our bug report and Proof-of-Concept received a reward from the Android Security Reward Program. The vulnerability was marked as Critical by Google.

Note that, although Google’s patch round from November complicates our attack, it does not eradicate it. We hope to see a more sophisticated fix soon.

Due to the nature of our attack – exploiting a hardware vulnerability – implementing such comprehensive patch is not easy. It is because of this that Google first decided to disable the ION kmalloc heap. This makes it impossible for user space applications to request guaranteed contiguous physical memory through ION. However, an attacker can still exhaust the regular system heap. He can then rely on the predictable behavior of the buddy allocator to get contiguous pages anyway. In addition, the system heap allocator allocates memory from a different pool (highmem), normally separated from that used to allocate page tables and other kernel data structures (lowmem). However, an attacker can allocate many ION chunks to deplete the highmem pool and force the buddy allocator to serve new requests from lowmem. We hope that Google soon applies more fundamental changes to the Android Linux Kernel that allows for ION memory accounting. This way, Android could limit ION allocations on a per-uid base, thwarting Drammer much more. In addition, /proc filesystem entries such as /proc/pagetypeinfo that leak the state of the buddy allocator (e.g., highmem chunks available, chunks of a given size available, etc.) should be made accessible only by root.

Reception

  • Drammer was covered by both WIRED and Ars Technica.
  • Dutch news site nu.nl also wrote an article about Drammer.

Reference


                                                PoC代码请参考:    https://github.com/vusec/drammer

# Native installation
To build the native binary, you need an Android NDK toolchain. I used
android-ndk-r11c:
```
wget https://dl.google.com/android/repository/android-ndk-r11c-linux-x86_64.zip
unzip android-ndk-r11c-linux-x86_64.zip
cd android-ndk-r11c
./build/tools/make-standalone-toolschain.sh --ndk-dir=`pwd` --arch=arm --platform=android-24 --install-dir=./sysroot-arm/ --verbose
```
You should then update the `STANDALONE_TOOLCHAIN` variable and be able to compile the binary:
```
cd native
sed -i 's#^\(STANDALONE_TOOLCHAIN=\s*\).*$#\1/path/to/android-ndk-r11c/sysroot-arm/bin#' Makefile
make
```
This gives you a stripped ARMv7 binary that you can run on both ARMv7 (32-bit)
and ARMv8 (64-bit) devices. The Makefile provides an install feature that uses
the Android Debug Bridge (adb) to push the binary to your device's
/data/local/tmp/ directory. You can install adb by doing a `sudo apt-get install
android-tools-adb` (on Ubuntu) or by installing the Android SDK via
[android.com](https://developer.android.com/studio/index.html#downloads). Then
do a:
```
make install
make test
```
to install and start the Rowhammer test binary. Once installed, you may also
invoke it from the shell directly:
```
adb shell
cd /data/local/tmp
./rh-test
```