There is a chroot environment in /var/myroot, and an attacker has obtained arbitrary machine code execution in a process running as root (EUID 0) in the chroot. But the processes under control of the attacker don't have all capabilities enabled (just filesystem capabilities). The attacker wants to escape the chroot, and append a line to /etc/passwd outside the chroot. How can he do it?

The following security measures have been set up:

  • To prevent the chdir("..") chroot escape technique, the chroot environment was entered using pivot_root(2) rather than chroot(2). See in jchroot.c how it can be done.
  • When the first process in the chroot was started, it didn't have any file descriptors open pointing outside the chroot.
  • Each process in the chroot has at most CAP_CHROOT and CAP_FOWNER, CAP_FSETID, CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH, CAP_SETGID, CAP_SETUID capabilities and is not able to gain other ones. In short, the attacker is able to make arbitrary filesystem reads and writes, bypassing permission checks etc., but he is not able to send arbitrary signals to processes (CAP_KILL) or send arbitrary packets on the network (CAP_NET_RAW) or reboot the system (CAP_SYS_BOOT) or modify arbitrary bytes in memory (CAP_SYS_RAWIO) etc.
  • unshare(CLONE_NEWUSER) was not called, the UID 0 of the chroot process is the same as UID 0 outside the chroot.
  • unshare(CLONE_NEWPID) was called, so the attacker doesn't see processes running outside the chroot.
  • unshare(CLONE_NEWNS) was called when setting up the chroot, and the following filesystems are visible:
    • /var/chroot is visible as /, remounted with MS_NODEV and MS_NOSUID. (MS_NODEV is used so that the attacker can't write to /dev/sda, and MS_NOSUID is used so that the attacker can't gain new capabilities from file capabilities.)
    • A proc filesystem is visible as /proc, with the following paths removed (by putting an empty file there using a bind-mount): /proc/kcore, /proc/latency_stats, /proc/timer_list, /proc/timer_stats, /proc/sched_debug, /proc/scsi, and the following paths made read-only: /proc/asound, /proc/bus, /proc/fs, /proc/irq, /proc/sys, /proc/sysrq-trigger.
    • A sysfs filesystem is not mounted.
    • A devpts filesystem is not mounted.
    • A tmpfs filesystem is mounted as /dev without MS_NODEV, prepopulated with a few devices.
    • No other filesystems are visible from the chroot.
  • Block device nodes are not available in the chroot (and CAP_MKNOD is not available, so the attacker is not able to create them).
  • Only the following character device nodes are available: /dev/null, /dev/zero, /dev/full, /dev/random, /dev/urandom, /dev/tty, /dev/ptmx (same as /dev/pts/ptmx) and a /dev/pts/X, the terminal which was used outside the chroot.
  • If the attacker calls ioctl(..., TIOCSTI, ...) (simulate typed input) on /dev/pts/X, and exits the chroot, probably an interactive shell outside the chroot will read those simulated bytes, so simulating this can be useful: sudo sh -c 'echo pwned::0:0:pwned:/:/bin/bash >>/etc/passwd'. To prevent this from succeeding, the parent process which created the processes in the chroot will flush all terminal input before returning to the shell.

FYI My use case is the following: there is a Debian system in /var/myroot (possibly created by debootstrap), and I'd like to be able to install untrusted packages there without exposing the host system to attacks by install scripts in malicious packages. Unfortunately sudo chroot /var/myroot apt-get install MALICIOUS-PACKAGE is not secure enough, because e.g. the install script of the package can create the block device node /dev/sda1, find the /etc/passwd file there and modify it, thus potentially escaping from the chroot. I'm now exploring what other options are secure enough, and a hardened chroot as described above is one of the candidates. (In this question I'm not looking for other candidates.) In this question I'd like to understand how secure it is.

FYI There is a command-line tool chw00t to escape from chroot. About its techniques:

  • -0 does not work here because pivot_root(2) was used.
  • -1 does not work because there are no file descriptors pointing to outside the chroot available.
  • -2 may work, I need to check if it works with pivot_root(2).
  • -3 does not work because unshare(CLONE_NEWPID) was called.
  • -4 does not work because block devices are not available.
  • -5 may work, I need to check if it works with pivot_root(2).
  • -6 does not work because unshare(CLONE_NEWPID) was called.
  • -7 does not work because there are no file descriptors pointing to outside the chroot available.
  • @A.B: Thank you for the link about breaking out of a chroot! I've modified the question title, now it says hardened chroot. It's in fact a chroot, because chroot("/var/myroot") was called after unshare(CLONE_NEWNS). (Is there something more secure that should be called instead?) – pts Jan 4 at 14:41
  • To those who are voting to close this question as too broad: Could you please advise me how I can make it less broad? I was trying really hard to make it as specific as possible, and I'd be happy to extend it if needed, but I fail to see how. – pts Jan 4 at 14:48
  • 2
    Just run strace on lxc to see how it's doing: it's using clone(CLONE_NEWNS...) + mount(... MS_BIND ...) + pivot_root and never chroot . pivot_root (existing as command too) is secure. I think you'd better run a container with ready software (eg: lxc) than trying to reinvent the wheel. LXC's container running debian is usually installed by LXC using debootstrap, or with some minor tweaking can be pointed to an existing installation. – A.B Jan 5 at 13:08
  • @A.B: I agree that using a well-maintained container setup tool (such as LXC or runc) gives better security than reinventing the wheel and doing it halfway. However, in this question I'd like to better understand what the attack vectors are (some of which may be mitigated by LXC and runc, some aren't). I've just updated the question to state that's using pivot_root(2) to enter the chroot environment, and I'm looking for more attack vectors. – pts Jan 5 at 16:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.