Side Channel Attacks on iPhones with the iTimed Toolkit
checkm8 has led to huge amounts of novel Apple-related research being generated by all types of security researchers. This public exploit created a shortcut that people who are not familiar with the ins and outs of iOS reverse engineering and exploitation can use to bootstrap other cool research, or just to learn about the platform in a general sense. checkm8 was released just about when I started my MSc program, and I happened to be taking a class in hardware security at the time. The two ideas seemed to generally go well together, and two years later we open-sourced the iTimed toolkit as a direct result of this idea.
In the same way that checkm8 lowered the barrier of entry for iOS research, the iTimed toolkit aims to specifically lower the barrier of entry for hardware security research on Apple’s devices. A lot of really cool work has been released as a result of checkm8 (checkra1n and Project Sandcastle being my two favorites, and two of the major components of the iTimed toolkit), but putting these pieces together is often nontrivial. This is especially true for academic hardware security researchers who often tend to be experts in electronics, fabrication, and statistics rather than software exploitation. There’s academic value in creating an easy-to-use toolkit which allows researchers to quickly bootstrap a familiar research environment, including all standard libraries, compilers, and utilities, as well as offering a high degree of hardware control (which is often necessary for hardware security experiments). None of these are really offered by Apple’s iOS -- but they are by Linux.
The purpose of this article is to run through the series of steps needed to get the iTimed toolkit working, and to demonstrate a simple side channel attack while considering some optimizations. To that extent, you’ll need an iPhone 7 since this is currently the only device model supported by our toolkit. You’ll also need a computer running Linux, optionally with a powerful processor if you’re planning to develop custom changes to the toolkit.
The main part of the iTimed toolkit is a Dockerfile which automatically downloads, configures, and compiles a large array of related tools. First of these is checkra1n, the well known jailbreaking tool. In addition to providing an awesome userland jailbreak, checkra1n also includes an intermediate bootloader/patcher/full-fledged operating system named pongoOS. While checkra1n itself has not yet been open-sourced, pongoOS has -- this makes it very desirable for the iTimed toolkit. We use checkra1n to boot to pongoOS, and then use pongoOS to boot to a fully functional Linux kernel, courtesy of Corellium.
Project Sandcastle includes a Linux kernel with a custom driver patchset as well as a Buildroot project which automatically combines the kernel and all necessary userspace utilities. Within the iTimed Dockerfile, we manually clone and build all of these components (which can take quite a while -- bring a few hours of free time). A build can be started simply by cloning the core_image repository and typing docker build . . Of course, through GitHub Actions, we can simply build these images within the cloud. For the purposes of this article, simply log into ghcr.io and run:
docker pull ghcr.io/iTimed-toolkit/core_image:default
While several flavors of this image are available, today we’ll be mainly working with the default one. This image strikes a good balance between functionality and size -- other images, such as the devel one, are often larger than 10GB.
Next, we need to start the Docker image in such a way that it can access USB-connected devices. This will allow us to run checkm8 on the target device, and proceed up the boot chain all the way to Project Sandcastle. Note that this is currently only supported on Linux hosts. To start the container, simply do:
docker run --privileged -v /dev/bus/usb/:/dev/bus/usb/ -it core_image
You'll be dropped into a shell within the container -- running ls, you'll see a few directories containing the toolkit's source code, Makefiles, and other useful scripts. You'll first want to run source env.sh in order to set up the correct environment variables. We can then navigate to platforms/linux, which is the root directory for the toolkit's Linux environment. This directory also contains the source code for the iTimed attack program, located under platforms/linux/programs/iTimed. We'll be running this program later.
For now, though, first put the phone into DFU mode. For iPhone 7s, this can be accomplished by holding the power and volume-down buttons for 10 seconds. Then, let go of the power button but continue to hold the volume-down button for 10 more seconds.
Then, within the Docker image, cd platforms/linux and type make boot. The Makefile in this directory would typically also take care of building all dependencies (including kernels, libraries, userspace, etc) but since we downloaded the default image, this is already taken care of. Scanning the attached USB devices which we passed through to the Docker image, the toolkit will then attempt to exploit the attached iPhone using checkm8 and boot into Project Sandcastle Linux. If everything goes well, you should see the familiar checkra1n boot sequence, and soon after that you should see the Linux kernel boot log scrolling on by.
The next step is setting up a connection to the Linux-iPhone, so that we can remotely log in and run our experiments. By far the easiest way to do this is through the USB gadget interface. If your computer has support for it (most do), a network interface should have been created as soon as the iPhone has finished booting Linux. On my system, the interface enp0s20f0u1u1 seems to be used. Then, you can simply add the correct ip address to this interface:
sudo ip addr add 172.16.1.2/24 dev enp0s20f0u1u1
and then log into the iPhone using ssh email@example.com using the default password alpine.
Running a simple SCA on an iPhone
Now that we have a full Linux system running on the iPhone, we can basically do whatever we want with the device’s hardware! For a simple proof of concept, we’ll be running the iTimed PRIME+PROBE cache attack. PRIME+PROBE attacks work by maliciously using a CPU’s cache as a communication channel between otherwise isolated programs. In the iTimed attack, we use PRIME+PROBE to steal secret cryptographic keys from OpenSSL’s AES implementation using the shared L1 cache as a timing channel. The full source code for the iTimed attack is available under platforms/linux/programs/iTimed -- simply navigate to this directory within the docker image and type make to build the program which is, by default, named aes_prime_probe. Then, copy the program to the iPhone:
scp aes_prime_probe firstname.lastname@example.org:~
and run it:
ssh email@example.com cpupower frequency-set -g userspace && cpupower frequency-set -f 275mhz ./aes_prime_probe
The cpupower line is to keep the iPhone from overheating. Running this program will throw the CPU into the fastest operating state, since Linux has no concept of the iPhone’s power/temperature management -- it’ll simply see “high CPU load”. Then, since there are no temperature drivers, this power state will be maintained even if the iPhone begins to overheat. This could be dangerous, since the battery will heat up drastically as well. It’s always a good idea to manually specify the desired CPU frequency when running an experiment with the iTimed toolkit.
You should be seeing many side-channel measurements of the shared cache flow by. Although our analysis code for this information sadly isn’t publicly available, it should be straightforward to implement based on the information in our paper. Alternatively, it is available by request.
It's useful to give some examples of how this research toolkit has helped us run advanced side channel attacks on a really opaque, locked down platform. Running the attack described above will lead to key breaks -- eventually. As described above, the attack actually suffers from a fair degree of noise. At any point the experiment program could be interrupted by another program, destroying the delicate state of the cache and leading to an invalid side channel measurement. We can make some improvements to make the attack work better, for which we’ll need the devel image (rather than default):
docker pull ghcr.io/iTimed-toolkit/core_image:devel
Luckily, the Linux kernel includes functionality which will help us explicitly separate out processes and control the scheduler to a tighter degree. We need to enable this option on the kernel command line. Within the devel image, navigate to sources/sandcastle/linux-sandcastle/arch/arm64/boot/dts/hx/ which is the directory containing device-tree files for the Project Sandcastle kernels. Open the device tree corresponding to your iPhone 7 model, and edit the line:
- bootargs = "earlycon=hx_uart,0x20a0c0000 console=tty0 console=ttyHX0 selinux=1 enforcing=0 androidboot.selinux=permissive printk.devkmsg=on androidboot.hardware=ranchu"; + bootargs = "earlycon=hx_uart,0x20a0c0000 console=tty0 console=ttyHX0 isolcpus=1 nohz_full=1";
These kernel command-line parameters (isolcpus, nohz_full) will fully remove the second CPU from the scheduler and make sure that programs on CPU cores will never be interrupted (if only one is scheduled to that core), respectively. Then, reset the iPhone by entering DFU mode, type make boot (which should re-compile some of the sources), and wait until the Linux environment boots up again. Then, re-running the experimental program on the second CPU core:
taskset 0x2 ./aes_prime_probe
will lead to much higher-quality side channel traces since we have now removed the main source of noise for the experiment. This type of control would not have been possible on an iPhone 7 running iOS instead -- no such scheduling controls are available on this platform.
The iTimed toolkit is a combination of a whole lot of other cool tools, with the express goal of making hardware security research on Apple devices easier. To that extent, the toolkit includes a full Linux kernel which anyone familiar with kernel programming can use to create powerful, customized research environments. In this article, we simply showed a straightforward cache attack which targets a software-based cryptography implementation. However, much more than this is possible -- drivers can be written for Apple’s hardware crypto, for example, which can then be investigated with an incredibly high level of hardware control. Our hope for the iTimed toolkit is that other researchers will find it useful, and to generally increase the amount of insight we can have into locked-down computing systems which we nevertheless use every day.
This article was contributed by Gregor Haas (twitter: @grg_haas), one of the authors of the iTimed paper referenced in this article.