Vulnerabilities > CVE-2016-4484 - Improper Authentication vulnerability in Cryptsetup Project Cryptsetup
Attack vector
LOCAL Attack complexity
LOW Privileges required
NONE Confidentiality impact
COMPLETE Integrity impact
COMPLETE Availability impact
COMPLETE Summary
The Debian initrd script for the cryptsetup package 2:1.7.3-2 and earlier allows physically proximate attackers to gain shell access via many log in attempts with an invalid password.
Vulnerable Configurations
Part | Description | Count |
---|---|---|
Application | 1 |
Common Weakness Enumeration (CWE)
Common Attack Pattern Enumeration and Classification (CAPEC)
- Authentication Abuse An attacker obtains unauthorized access to an application, service or device either through knowledge of the inherent weaknesses of an authentication mechanism, or by exploiting a flaw in the authentication scheme's implementation. In such an attack an authentication mechanism is functioning but a carefully controlled sequence of events causes the mechanism to grant access to the attacker. This attack may exploit assumptions made by the target's authentication procedures, such as assumptions regarding trust relationships or assumptions regarding the generation of secret values. This attack differs from Authentication Bypass attacks in that Authentication Abuse allows the attacker to be certified as a valid user through illegitimate means, while Authentication Bypass allows the user to access protected material without ever being certified as an authenticated user. This attack does not rely on prior sessions established by successfully authenticating users, as relied upon for the "Exploitation of Session Variables, Resource IDs and other Trusted Credentials" attack patterns.
- Exploiting Trust in Client (aka Make the Client Invisible) An attack of this type exploits a programs' vulnerabilities in client/server communication channel authentication and data integrity. It leverages the implicit trust a server places in the client, or more importantly, that which the server believes is the client. An attacker executes this type of attack by placing themselves in the communication channel between client and server such that communication directly to the server is possible where the server believes it is communicating only with a valid client. There are numerous variations of this type of attack.
- Utilizing REST's Trust in the System Resource to Register Man in the Middle This attack utilizes a REST(REpresentational State Transfer)-style applications' trust in the system resources and environment to place man in the middle once SSL is terminated. Rest applications premise is that they leverage existing infrastructure to deliver web services functionality. An example of this is a Rest application that uses HTTP Get methods and receives a HTTP response with an XML document. These Rest style web services are deployed on existing infrastructure such as Apache and IIS web servers with no SOAP stack required. Unfortunately from a security standpoint, there frequently is no interoperable identity security mechanism deployed, so Rest developers often fall back to SSL to deliver security. In large data centers, SSL is typically terminated at the edge of the network - at the firewall, load balancer, or router. Once the SSL is terminated the HTTP request is in the clear (unless developers have hashed or encrypted the values, but this is rare). The attacker can utilize a sniffer such as Wireshark to snapshot the credentials, such as username and password that are passed in the clear once SSL is terminated. Once the attacker gathers these credentials, they can submit requests to the web service provider just as authorized user do. There is not typically an authentication on the client side, beyond what is passed in the request itself so once this is compromised, then this is generally sufficient to compromise the service's authentication scheme.
- Man in the Middle Attack This type of attack targets the communication between two components (typically client and server). The attacker places himself in the communication channel between the two components. Whenever one component attempts to communicate with the other (data flow, authentication challenges, etc.), the data first goes to the attacker, who has the opportunity to observe or alter it, and it is then passed on to the other component as if it was never intercepted. This interposition is transparent leaving the two compromised components unaware of the potential corruption or leakage of their communications. The potential for Man-in-the-Middle attacks yields an implicit lack of trust in communication or identify between two components.
Seebug
bulletinFamily | exploit |
description | ### Description A vulnerability in **Cryptsetup**, concretely in the scripts that unlock the system partition when the partition is ciphered using LUKS (Linux Unified Key Setup). The disclosure of this vulnerability was presented as part of our talk "**Abusing LUKS to Hack the System**" in the DeepSec 2016 security conference, Vienna. This vulnerability allows to obtain a root initramfs shell on affected systems. The vulnerability is very reliable because it doesn't depend on specific systems or configurations. Attackers can copy, modify or destroy the hard disc as well as set up the network to exflitrate data. This vulnerability is specially serious in environments like libraries, ATMs, airport machines, labs, etc, where the whole boot process is protect (password in BIOS and GRUB) and we only have a keyboard or/and a mouse. Note that in **cloud environments** it is also possible to remotely exploit this vulnerability without having "physical access." ### Am I vulnerable ? **If you use Debian** or Ubuntu/ (probably many derived distributions are also vulnerable, but we have not tested), **and you have encrypted the system partition**, then your systems is vulnerable. **Update:** We have found that systems that use **<tt>Dracut</tt>** instead of `initramfs` are also vulnerables (tested on **Fedora 24** x86_64). ![](http://hmarco.org/bugs/CVE-2016-4484/install-ubuntu-luks.png) During the installation of Ubuntu, one of the first steps is to prepare the target partition (make partitions if needed, and/or format them). At this stage, the user is asked to "<tt>Encrypt the new (LXK)ubuntu installation for security</tt>". Nowadays, there is very little performance penalty working with an encrypted disk and it is an effective solution to protect data when the computer is not running. It is advisable to enable this feature. If you didn't installed the system, the you can figure out the organization by running the <tt>blkid</tt> command. <fieldset class="code"><legend>Checking if the root partition is encrypted</legend> <pre>$ **blkid** /dev/sda1: UUID="db96cdf9-99c3-4239-95f2-6af2651ef3ac" TYPE="ext2" <span style="color:#f00">/dev/sda5</span>: UUID="d491bf52-a9ea-466f-be9b-3a5df954699e" TYPE="<span style="color:#f00">crypto_LUKS</span>" /dev/mapper/<span style="color:#f00">sda5_crypt</span>: UUID="30xz0y-4LeG-LwuL-QHI9-pWWi-BxHf-F3udoC" TYPE="<span style="color:#f00">LVM2_member</span>" <span style="color:#f00">/dev/mapper/lubuntu--vg-root</span>: UUID="53f95bd1-9e1c-4e23-9ff3-990d90c5cc92" TYPE="ext4" <span style="color:#f00">/dev/mapper/lubuntu--vg-swap_1</span>: UUID="9eac532c-1b54-4cac-9995-b4b921222422" TYPE="swap" /dev/zram0: UUID="c2929c6e-2432-40ee-99a5-deadbeefa53e" TYPE="swap" /dev/zram1: UUID="d1bf1e22-dead-beef-9c49-e6462449d6e2" TYPE="swap" /dev/zram2: UUID="12a9232d-c62e-0df6-93ea-22ac3600bdf0" TYPE="swap" /dev/zram3: UUID="bf777ad3-13fc-4ad5-914b-002e67262939" TYPE="swap"</pre> </fieldset> This is the classic structure where the partition "`/dev/sda5`" is encrypted and then used as a physical_volume in the "`lubuntu-vg`" volume_group which contains two logical_volumes: `lubuntu--vg-root` and `lubuntu--vg-swap_1`. As a result, the system and the swap partitions are encrypted by LUKS and protected by a single password. This system is vulnerable. ## Impact An attacker with access to the console of the computer and with the ability to reboot the computer can launch a shell (with root permissions) when he/she is prompted for the password to unlock the system partition. The shell is executed in the initrd environment. Obviously, **the system partition is encrypted** and it is not possible to decrypt it (AFAWK). But other partitions may be not encrypted, and so accessible. Just to mention some exploitation strategies: * **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 to non-encrypted information in other devices. * **Denial of service:** The attacker can delete the information on all the disks. ## The Vulnerability The fault is caused by an incorrect handling of the password check in the script file `/scripts/local-top/cryptroot`. When the user exceeds the maximum number of password tries (by default 3), then boot sequence continues normally. initrd.img:/script/local-top/cryptroot ``` #!/bin/sh . setup_mapping() { . # Try to get a satisfactory password $crypttries times count=0 while [ $crypttries -le 0 ] || [ $count -lt $crypttries ]; do export CRYPTTAB_TRIED="$count" count=$(( $count + 1 )) . if [ ! -e "$NEWROOT" ]; then # cryptkeyscript = /lib/cryptsetup/askpass # cryptopen = /sbin/cryptsetup -T 1 # The user is asked the password and then passed to $cryptopen if ! crypttarget="$crypttarget" cryptsource="$cryptsource" \ $cryptkeyscript "$cryptkey" | $cryptopen; then message "cryptsetup: cryptsetup failed, bad password or options?" continue fi fi . #if [ -z "$FSTYPE" ] || [ "$FSTYPE" = "unknown" ]; then if [ -z "$FSTYPE" ]; then message "cryptsetup: unknown fstype, bad password or options?" udev_settle $cryptremove continue fi message "cryptsetup: $crypttarget set up successfully" break done # Always false -> never taken the if if [ $crypttries -gt 0 ] && [ $count -gt $crypttries ]; then message "cryptsetup: maximum number of tries exceeded for $crypttarget" return 1 fi udev_settle return 0 } . # Do we have any settings from the /conf/conf.d/cryptroot file? if [ -r /conf/conf.d/cryptroot ]; then while read mapping <&3; do setup_mapping "$mapping" 3<&- # Try to unlock each encrypted partition. done 3< /conf/conf.d/cryptroot fi exit 0 ``` The calling script,` /scripts/local`, handles the error as if it were caused by a slow device that needs more time to warm-up. The booting scripts then tries to recover/mount the "failing" device, in the function local_deveice_setup(), multiple times (up to 30 times on an x86 system, and 150 on a powerpc machine). Every time the top level script tries to mount the encrypted partition (line 99 in /script/local), the user is allowed to try 3 more LUKS passwords. This gives a total of 93 password trials (on x86). ``` local_device_setup() { . . . # If the root device hasn't shown up yet, give it a little while # to allow for asynchronous device discovery (e.g. USB). We # also need to keep invoking the local-block scripts in case # there are devices stacked on top of those. if ! real_dev=$(resolve_device "${dev_id}") || ! get_fstype "${real_dev}" >/dev/null; then log_begin_msg "Waiting for ${name} file system" # Timeout is max(30, rootdelay) seconds (approximately) case $DPKG_ARCH in powerpc|ppc64|ppc64el) slumber=180 ;; *) slumber=30 ;; esac if [ ${ROOTDELAY:-0} -gt $slumber ]; then slumber=$ROOTDELAY fi while true; do sleep 1 # local_block() calls to setup_mapping() 30 times, # trying to unlock LUKS root filesystem. local_block "${dev_id}" if real_dev=$(resolve_device "${dev_id}") && get_fstype "${real_dev}" >/dev/null; then wait_for_udev 10 log_end_msg 0 break fi slumber=$(( ${slumber} - 1 )) if [ ${slumber} -eq 0 ]; then log_end_msg 1 || true break fi done fi # We've given up, but we'll let the user fix matters if they can while ! real_dev=$(resolve_device "${dev_id}") || ! get_fstype "${real_dev}" >/dev/null; do echo "Gave up waiting for ${name} device. Common problems:" echo " - Boot args (cat /proc/cmdline)" echo " - Check rootdelay= (did the system wait long enough?)" if [ "${name}" = root ]; then echo " - Check root= (did the system wait for the right device?)" fi echo " - Missing modules (cat /proc/modules; ls /dev)" panic "ALERT! ${dev_id} does not exist. Dropping to a shell!" done DEV="${real_dev}" } . . . ``` But the real problem happens when the maximum number of trials for transient hardware faults is reached (30 times for non ppc systems), line 114 at function local_device_setup(). In this case, the top level script is not aware of the root cause of the fault and drops a shell (busybox) to the user, line 124. The panic() function (see below) tries to insert additional drivers and runs a shell. ### The Exploit (PoC) The attacker just have to press and keep pressing the [Enter] key at the LUKS password prompt until a shell appears, which occurs after 70 seconds approx. ### The fix The issue can be easily fixed by stopping the boot sequence when the number of password guesses has been exhausted. The following patch suspends the execution forever. The only way to exit is by rebooting the computer. cryptsetup_fix_CVE-2016-4484.patch ``` --- a/scripts/local-top/cryptroot 2016-07-29 10:56:12.299794095 +0200 +++ b/scripts/local-top/cryptroot 2016-07-29 11:00:57.287794370 +0200 @@ -273,6 +273,7 @@ # Try to get a satisfactory password $crypttries times count=0 + success=0 while [ $crypttries -le 0 ] || [ $count -lt $crypttries ]; do export CRYPTTAB_TRIED="$count" count=$(( $count + 1 )) @@ -349,12 +350,15 @@ fi message "cryptsetup: $crypttarget set up successfully" + success=1 break done - if [ $crypttries -gt 0 ] && [ $count -gt $crypttries ]; then - message "cryptsetup: maximum number of tries exceeded for $crypttarget" - return 1 + if [ $success -eq 0 ]; then + message "cryptsetup: Maximum number of tries exceeded. Please reboot." + while true; do + sleep 100 + done fi udev_settle ``` #### Workaround The panic function, which is the one that launches the shell, can prevent console access if the kernel is booted with the "panic" parameter. initram:/scripts/functions ``` panic() { if command -v chvt >/dev/null 2>&1; then chvt 1 fi echo "$@" # Disallow console access if [ -n "${panic}" ]; then echo "Rebooting automatically due to panic= boot argument" sleep ${panic} reboot exit # in case reboot fails, force kernel panic fi modprobe -v i8042 || true modprobe -v atkbd || true modprobe -v ehci-pci || true modprobe -v ehci-orion || true modprobe -v ehci-hcd || true modprobe -v uhci-hcd || true modprobe -v ohci-hcd || true modprobe -v usbhid || true run_scripts /scripts/panic REASON="$@" PS1='(initramfs) ' /bin/sh -i </dev/console >/dev/console 2>&1 } ``` Therefore, adding the "panic" parameter to the kernel entry in the grub configuration will prevent a shell. Adding "panic" to the Linux command line. ``` # sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="/GRUB_CMDLINE_LINUX_DEFAULT="panic=5 /' /etc/default/grub # grub-install ``` ### Discussion The direct cause of this vulnerability is the improper checking of the maximum number of passwords, but the bug was (probably) introduced by the addition of new features (in this case security features). It is well known that "Complexity is the worst enemy of security". A system with more features requires more code and has more interactions between sub-systems, which results in harder to test systems and so more bugs. Security is a non-functional requirement which must be analyzed globally. In this case, the "recovery" actions taken in the case of system errors should be revised and updated to match the security requirements. #### About physical access It is common to assume that once the attacker has physical access to the computer, the game in over. The attackers can do whatever they want. And although this was true 30 years ago, today it is not. There are many "levels" of physical access. Just to mention a few: * Access to the internal parts of the computer. The attacker can remove or replace the disk, ram, insert new devices, etc. For example, your own computer. * Access to all the interfaces. The attacker can plug a USB, Ethernet, HDML or Firewire device. For example, the computers used to provide network access in public facilities. * Access to the front interfaces. Typically, the USB and the keyboard. For example, Some systems to print your photos. * Access to the keyboard and mouse/touchpad. For example, tourist information points, or the electronic check-in services in the airports. * Access to a limited keyboard or other simple user interface. Like a smart doorbell. These are some of the scenarios that where we can find a Linux system, but the IoT will increase the diversity further. In order to protect the computer in these scenarios: the BIOS/UEFI has one or two passwords to protect the booting or the configuration menu; the GRUB also has the possibility to use multiple passwords to protect unauthorized operations. And in the case of an encrypted system , the initrd shall block the maximum number of password trials and prevent the access to the computer in that case. ### About default configuration In general, the GNU/Linux ecosystem (kernel, system apps, distros, ...) has been designed by developers for developers. Therefore, in the case of a fault, the recovery action is very "developer friendly", which is very convenient while developing or in controlled environments. But then Linux is used in more hostile environments, this helpful (but naive) recovery services shall not be the default option. UEFI and GRUB contain two complete and very powerful shell facilities. Initrd system has powerful busybox with complete access to the network. May be all this "just in case" functionality shall be remove, or seriously reconsidered, for the sake of security. |
id | SSV:92539 |
last seen | 2017-11-19 |
modified | 2016-11-17 |
published | 2016-11-17 |
reporter | Root |
title | Cryptsetup Initrd LUKS root Shell privilege escalation vulnerability |
The Hacker News
id | THN:39F22A989613A27258252DA2B070F73B |
last seen | 2018-01-27 |
modified | 2016-11-16 |
published | 2016-11-15 |
reporter | Swati Khandelwal |
source | https://thehackernews.com/2016/11/hacking-linux-system.html |
title | This Hack Gives Linux Root Shell Just By Pressing 'ENTER' for 70 Seconds |
Vulner Lab
id | VULNERLAB:2014 |
last seen | 2019-07-10 |
modified | 2016-11-18 |
published | 2016-11-18 |
reporter | Vulnerability Laboratory [Research Team] - Marco Onorati https://www.vulnerability-lab.com/show.php?user=Marco%20Onorati |
source | http://www.vulnerability-lab.com/get_content.php?id=2014 |
title | CryptSetup Ubuntu 16.4 CVE2016-4484 - Privilege Escalate |
References
- http://hmarco.org/bugs/CVE-2016-4484/CVE-2016-4484_cryptsetup_initrd_shell.html
- http://www.openwall.com/lists/oss-security/2016/11/14/13
- http://www.openwall.com/lists/oss-security/2016/11/15/1
- http://www.openwall.com/lists/oss-security/2016/11/15/4
- http://www.openwall.com/lists/oss-security/2016/11/16/6
- http://www.securityfocus.com/bid/94315
- https://gitlab.com/cryptsetup/cryptsetup/commit/ef8a7d82d8d3716ae9b58179590f7908981fa0cb