This directory contains the source code for both anc
and revanc
. anc
is an implementation
of the ASLR^Cache (AnC) attack which is an EVICT+TIME
side-channel attack on the MMU. AnC
relies on the fact that page table lookups by the MMU are stored in the last level cache (LLC) in
order to speed up the next required translation. By flushing parts of the LLC and timing the page
table lookup, AnC can identify which parts of the LLC store page tables. On top of flushing the
LLC, AnC also needs to flush the TLB as well as page table caches. Since the information on the
size of the TLB and the LCC is available, the AnC attack can be used to reverse engineer the
properties of the page table caches that are of interest to attackers, like their internal
architecure and size. revanc
is an implemention that retrofits AnC to acquire this information.
With anc
, we have demonstrated that numerous x86-64, ARMv7-A and ARMv8-A microarchitectures are
affected by the AnC attack. Furthermore, with revanc
we have been able to detect the existence
of page table caches and the amount of entries that they contain on these microarchitectures. As
the code is written with portability in mind, it should be easy to add support for other
potentially affected platforms that share a similar MMU design.
We invite you to visit our project page for more information.
To build the code, simply type:
make
After the code has been built, the anc
and revanc
programs should be available in the obj
directory.
The results generated by the anc
program by plotted as MMU-grams using the Python 3 script
provided. As this script depends on numpy
and matplotlib
, these dependencies should be
installed first:
sudo apt-get install python3-numpy python3-matplotlib
Then after running the anc
program, the script can be run as follows:
scripts/plot.py
The script will then generate a file named mmugram.pdf
.
On x86-64, the cpuid
instruction is used to automatically detect the sizes of the caches and the
TLBs. As such, it is often sufficient ro anc
without any arguments:
./obj/anc
However, since the TLB sizes are also used as a guideline to evict the page table or translation
caches, it is sometimes necessary to specify the sizes of these caches. While Intel Ivy Bridge and
older microarchitectures do implement a translation cache for PDPTEs, there either is no TLB to
cache 1G huge pages, or cpuid
does not report its existence. As such we have to specify that this
cache consists of four entries manually:
./obj/anc --pl3-entries=4
Similarly, several AMD microarchitectures implement a page table cache with 24 entries:
./obj/anc --pl2-entries=24
With the revanc
program, these page table and translation caches can be reverse engineered.
However, to optimise the results it is currently advised to specify the virtual address:
./obj/revanc --target=0x222e2599000 --runs=10
For ARMv7-A and ARMv8-A, the sizes of the caches and TLBs cannot be determined automatically yet. As such, it is important to specify these manually. Further, while the ARMv7-A and ARMv8-A platforms do offer Performance Monitoring Units with a register similar to the Timestamp Counter on x86-64, this is not used as it is not accessible from user mode by default. On these platforms a thread that increments a volatile global variable simulating a cycle counter is used instead. Hence it is important to take more timing samples (e.g. 100 rather than the default of 10). For instance, for the Nvidia Tegra K1 the following can be used:
./obj/revanc --target=0x10040000 --evict-target=0x80000000 --runs=10 --cache-size=4M --pl1-entries1=544 --rounds=100
Some ARMv7-A platforms have Large Physical Address Extensions enabled. If this is the case, then
the arm-lpae
page format has to be specified as well:
./obj/revanc --target=0x10040000 --evict-target=0x80000000 --runs=10 --cache-size=4M --pl1-entries1=544 --page-format=arm-lpae --rounds=100
On ARMv8-A another target address is recommended. For instance, for the Allwinner A64, the following can be used:
./obj/revanc --target=0x116565000 --runs=10 --cache-size=2M --pl1-entries=522 --rounds=100
Q. What processor architectures are currently supported/affected?
The anc
and revanc
can currently be built for and run on the x86-64, ARMv7-A and ARMv8-A
architectures and show that these architectures are affected.
Q. What operating systems are currently supported?
The code can currently be built for Linux, BSD and Mac OS X.
Q. Does this attack work on hardened systems with ASLR enabled?
Yes, the native implementation of the attack has been reported to work on an Intel Xeon E3-1505M v5 running HardenedBSD/amd64 (thanks to Shawn Webb).
Q. Does this attack work in virtualised environments?
Yes, we have run this attack within KVM guests running Linux on an Intel Atom C2750 and an Intel
Xeon E5-2658 v2. In fact, because the hypervisor makes use of the MMU as well, the page table
and/or translation cache(c) used by the MMU may end up being (partially) evicted already, amplying
the AnC attack. However, because the MMU is used by the hypervisor as well, the revanc
program
cannot reliably determine the sizes of these caches.
For other questions, please refer to the project page first.