chroot-jail ?? whats this
cedric at itactics.itactics.com
Thu Mar 2 17:56:35 UTC 2000
On 29 Feb 2000, Doug Siebert wrote:
> >Consider that you have built the "chroot" env
> >to isolate this app/daemon from the "real" system. If by some means
> >root is acquired in the "chroot" env, then it may be possible to alter the
> >files shared between the "chroot" env and the real env in such a way as
> >to allow a root access in the real env. I would strive to make the
> >2 environments as independent as possible.
> If root is acquired in the chroot filesystem, all is lost unless it is
> mounted read only and no directories exist within the chroot hierarchy.
> (Plus the more obvious ones about not having any devices, etc.)
> chdir("../../../../../.."); /* as many as needed to get to real / */
> 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.
My read is that for root to escape the prison, the system
must have one of the following:
a) an incompetantly written chroot()
b) a skilled person gaining root in a prision with
old file handles that relate to the real "/"
or someother subdirectory. (no to mention access to
proper binaries, etc, to take advantage of
c) a person gains root in a properly designed prison.
that person then needs enough skill and
intimate system knowloedge to:
1) transfer into the prision via
their exploit sufficent utilities
for the following (ie: precompiled
binaries for the system in question)
2) create their own /dev/kmem type dev file
3) pick through the live kernal and fix
by hand the filesystem root pointer
for the process that they are
inheriting their handles from.
-- or --
somehow hack the kernel's chroot function
in the live kernel.
I'd say that chroot jails would definately be a problem for
the script kiddies to manuveour around, and for that matter,
most everyone else who should try to circumvent them.
For the benefit of the list, I will enclose a copy of the
best explaination I have RE: the theory and actual operation
of a POSIX compliant chroot. I know it's long already, but
it does have some bearing on people who might be trying to
make up their mind regarding the merits of running bind
=+=+= Begin enclosure:
chroot("pathname") does not make "pathname" the current directory. If the
caller (who usually must have special priviledges) is not *in* "pathname"
or some descendant thereof, then after the chroot() call the caller is
still not imprisoned. Therafter *relative* pathnames will be calculated
outside the chroot prison until such time as the relative path, in it's
interpretation, enters the prison (see examples below). Absolute
pathnames, will, of course, immediately after the chroot() call, be
interpreted relative to the new root. Another important item to keep in
mind is that all previously open file descriptors remain open and valid.
So, if a caller opens the directory "/etc", then calls
chroot("/daemon/root"), then calls chdir("/") he will be in the physical
directory "/daemon/root", which will appear to him to be "/". at that
point he has no access, via pathnames, to anything outside of the chroot
prison. *However*, he may still call fchdir() with the open file
descriptor on "/etc", and his physical and apparent directory will
thereafter be "/etc".
The *only* way to temporarily change the current root and then change it
back is to keep an open file descriptor on "/", (marked close on exec!)
chroot() to a prison, fork a child that you *know* will exec, and then the
parent can call fchroot() with the "/" file descriptor and regain it's
access to the entire filesystem while the child is left in it's prison.
I do *not* believe that even root, once in a chroot prison, can
chdir("../../../") out of it! *I* certainly didn't implement [**hidden**]'s
chroot() that way! I also firmly believe that if the caller of chroot()
is situated within the hierarchy rooted by the argument thereto when
making that call, the caller is imprisoned upon the return thereof.
Example of relative pathname resolution from outside to within a chroot
getcwd() returns: "/usr/daemon/bin"
getcwd() still returns: "/usr/daemon/bin"
getcwd() returns: "/usr/spool/mqueue" and means the real "/usr/spool/mqueue"
getcwd() returns: "/bin" and means the imprisoned "/usr/daemon/root/bin"
I.e., passing into /usr/daemon/root even while interpreting a single
relative pathname rooted *outside* the prison results in imprisonment (of
that pathname: it could have just been a file open, not a chdir()).
This all works because current working directories and current roots are
stored as special file descriptors in the kernel. I can explain if
Also, in case I wasn't clear above, the pathname argument to chroot() is
interpreted in the context of the current root. Gaining root access
within a prison does *not* mean that you can simply chroot() out of the
prison. If there are extrapenitential open directory file descriptors
inherited from before the original chroot() occurred, becoming root would
allow one to call fchroot() thereupon and change the prison in which one
=+=+= end enclosure.
| CCj/ClearLine - Unix/NT Administration and TCP/IP Network Services
| 118 Louisa Street, Kitchener, Ontario, N2H 5M3, 519-741-2157
Cedric Puddy, IS Director cedric at thinkers.org
PGP Key Available at: http://www.thinkers.org/cedric
More information about the bind-users