Linux distributions are one of the most popular and commonly used operating systems. All Linux distributions including Debian, Ubuntu, Fedora, Red Hat Enterprise Linux (RHEL), and SUSE Linux Enterprise Server (SLES) suffer from a serious authentication bypass vulnerability which can allow anyone to bypass authentication and gain complete access to the system within just 70 seconds.
This vulnerability is very reliable as it’s not affected by the change in system settings or configuration changes. Using this vulnerability attackers can gain control of the system and do anything- copy, modify, format hard disc as well as transfer data over the network.
All Linux distributions provide an additional layer of security during installation sequence where OS and its core files will be put into an encrypted volume (partition). It is called ‘Encrypt the new Ubuntu installation for security’. This option is available only while installation. If the Linux distribution is installed without using this option, then it’s not affected by this authentication bypass vulnerability while as if system partition is encrypted while installation then it is vulnerable to authentication bypass.
Below is a representative image of Ubuntu installation asking for partition encryption.
The flaw exists in the implementation of the Cryptsetup, which is used for encrypting hard drives through Linux Unified Key Setup (LUKS). All Linux distributions use LUKS as a standard implementation of disk encryption. This vulnerability allows obtaining a root initramfs shell on affected systems.
Vulnerable or Not?
As discussed only those Linux distributions which have encrypted their root partition are vulnerable. We can check the status of the system using the command “blkid“. In general,
/dev/sdbx: UUID=”xxxxxxxxxxxx” TYPE=”crypto_LUKS” #encrypted
/dev/sdbx: UUID=”xxxxxxxxxxxx” TYPE=”ext4″ #not encrypted, fs is ext4
Below figures show the result of running ‘blkid’ command on encrypted and not encrypted system.
The actual flaw is in the Cryptsetup utility, in the way it handles password failures during decryption process when a system boots up. It allows a user to enter the password multiple times and after these multiple failed password attempts, the user is dropped to a shell (Busybox in Ubuntu) that has root privileges.
Due to incorrect password checking in the /initramfs-tools/scripts/local-top/cryptroot script if the user exceeds the maximum number of password attempts, then boot sequence continues normally. The default value for the maximum number of password attempts is 3 as shown in figure designated by variable ‘crypttries’.
Once all the three password attempts are used, the control should have passed to the ‘if’ block saying a maximum number of tries are exceeded. But in practice, the control never passes to the required ‘if’ block and boot sequence continues although all the attempts are exhausted.
After 3 failed password attempts once the script “/scripts/local” fails to mount the encrypted device, it tries to recover it using the function local_device_setup(). It then tries to recover device multiple times. For a PowerPC machine, it tries 180 times and up to 30 times for others. Thus, for non-PowerPC machine each out of 3 password attempts leads to 30 more attempts totaling for 90. Initial 3 failed password attempts make a total number of attempts to 93.
What happens after 93 attempts?
If the user has used up all 93 attempts, then the user is dropped to a shell that has root privileges (as is clear from local_device_setup function from above code). The attacker can just press and keep pressing the [Enter] key at the LUKS password prompt until the count of 93 exceeds and gain access to a root initramfs (initial RAM file system) shell.
After Root Shell?
As the system partition is encrypted, it is not possible to decrypt it but other partitions which may not be encrypted will be accessible. It is also possible to delete the information on all the disks. Since the boot partition is typically not encrypted, it can be used to store an executable file which can later be used. Also if the boot is not secured, then it would be possible to replace the kernel and the initrd image.
One of the obvious solutions to this problem is to stop boot sequence once the number of password attempts has expired. This can be easily done by fixing code in ‘scripts/local-top/cryptroot’. Patch to do so is available, as shown in the figure below.
Another way to solve this vulnerability is to avoid user to get to shell once all the password attempts are exhausted. The ‘panic’ function is the one that launches the shell. We can prevent console access if the kernel is booted with the “panic” parameter. Adding the ‘panic’ parameter to the kernel entry in the grub configuration will prevent a shell. To achieve the same add the following commands to your boot configuration:
sed -i ‘s/GRUB_CMDLINE_LINUX_DEFAULT=”/GRUB_CMDLINE_LINUX_DEFAULT=”panic=5 /’ /etc/default/grub grub-install