jeromie @
garrison .
com writes:
> As far as being able to remove system calls from accessibility, I would
>like to hear about if any firewalls have done this. Removing the system calls
>from accessibility would limit potential vulerabilities.
It's not hard to do; you simply comment them out of the kernel
or appropriately modify the kernel. I staunchly refuse to accept that
these things are rocket science, or even very difficult; the kernel
is just a program and if you are smart enough to use a system you can
get source for then it's easy to fix.
Let's examine one possiblity. Suppose I am using chroot() to
protect my firewall. And the argument I want to make is that I want
to be sure, for sure, that nobody can tweak a buffer overrun and
call a socket from inside the chrooted area.
[This is all from BSDI/NetBSD.]
uipc_syscalls.c, at around line 79, has the source code
for the socket() system call. vfs_syscalls.c, at around line 613
has the source code for the chroot() system call.
You'll notice, in chroot() that the proc struct (the process
table slot) for each process has the vnode of the process' root
file system in it. That's hung off the p->p_fd, which is the
process' file descriptor table - which in turn stores the
root vnode as p->p_fd->fd_rdir. With me so far? :)
Now, there's a vnode that's stashed away (see vfs_lookup
and the system init code in init_main.c) and it's called "rootvnode."
Given it's name, you won't be shocked to discover that it's the
root filesystem's "top" vnode.
So - we can assume that if a process' root vnode is not
the same as the system's root vnode, then it's been chrooted. TA-DA!
It actually may be simpler than that, since line 127 of vfs_lookup.c
implies that processes which have NOT been chrooted have a root
vnode of NULL:
if ((ndp->ni_rootdir = fdp->fd_rdir) == NULL)
ndp->ni_rootdir = rootvnode;
Let's assume that's correct. Now we "harden" our kernel
by altering the socket() system call thusly:
uipc_syscalls.c line 78:
if(p->fdp->fr_rdir != NULL)
return(EPERM);
WHOAH! It took me 24 lines to explain it, and 2 to code it!
What this means is that a chrooted process that does a socket() will
get a permission denied. Maybe that's a bit too brute force. We
might want to put the code into connect() instead and only let the
process connect to localhost - or whatever. You get the idea. This
is trivial code that takes minutes to implement.
The *TRICK* is implementing the RIGHT code in the RIGHT
place. For this example, if I put it in socket() - what about other
forms of IPC? See - I'd need to be darn careful to cover all the
angles. That's nothing to do with the formal properties of my
protection model; that's a simple matter of Getting The Code Right
and Damn The Formal Handwaving.
>In summary, the strongest feature touted by sctc is that chroot() is vulerable
>to buffer overflows. In my eyes, this means that if a proxy were to get
>subverted, it would not take much to subvert the chroot() setuid() calls and
>gain full access over the firewall. I would like to hear if anyone has
>comments on this issue..??
Chroot() is not "vulnerable to buffer overflows" -- processes
that have chrooted are potentially vulnerable to buffer overflows.
Subverting a chroot() that has been correctly combined with
a setuid() is *HARD* - if the chroot() area is set up correctly and
the kernel is implemented correctly, and your system doesn't
automatically trust connections from itself, then you are not going
to be able to do a lot of damage. But, as I've shown above, there
are lots of ways to address that kind of thing. You can make it
impossible to break out of a chroot simply by setuid()ing to a non
root user - then you are no longer permitted to chroot again. If
there's no way in the chroot area to get privs, then there's no
way out other than via a socket - and you can nail that dead with
2 lines of code.
The easiest way, however, is to be REAL careful about not
having buffer overruns in your code. :)
This whole game is about being REAL careful about your code.
Whether it's code in the kernel or code in user space, it's just
code. Because someone's waved the orange-book over the hacks they
made to the kernel doesn't make them any fancier than the kind of
hackery I described above (but for sure they're better documented!)
mjr.
References:
|
|