Page 1 of 1

Securing tmp impossible, security hazzard?

Posted: Mon Feb 14, 2005 8:35 pm
by Shelluser
Hi there,

In the last stage of securing the Unreal installation I noticed something weird.. Its my habbit to make sure that the irc useraccount has only write access to partitions which were mounted 'noexec' in order to make sure that if a service gets compromised the amount of damage can be minimized (think about local root exploits and such).

To my surprise Unreal refused to start up after I replaced the tmp directory with a symlink. When trying to start Unreal it gave me this error:

* Loading IRCd configuration ..
* unrealircd.conf:7: loadmodule modules/commands.so: failed to load: tmp/AEDDC39
8.commands.so: failed to map segment from shared object: Operation not permitted
[error] IRCd configuration failed to load

At first I thought to be dealing with a problem in handleing symlinks (the file was created) but it soon turned out that Unreal is trying to execute code from the tmp directory. As soon as the tmp symlink points to a directory on a 'noexec' partition Unreal refuses to start. I find this quite extraordinair since it can pose a serious security threat if you need to allow it to write data which it needs to be able to execute as well.

My obvious question is simple: is there any way to avoid this kind of behaviour ?

Posted: Mon Feb 14, 2005 9:23 pm
by Syzop
Well @ whether it "executes"... yes and no... It does not start a program in tmp/, but it loads libraries from tmp/, so in that sense.. it reads from there and (indirectly) it executes code from them (sooner or later).

The tmp/ thing is needed in order to make modules able to reload from disk without forcing a server restart, so it's really something nice and not something we want to get rid of (nor do I see a good point in making it possible to disable).

Have a look at Bug #2300 to see a possible secure solution to this problem :)

[I'll probably not respond again in this thread]

Posted: Wed Feb 16, 2005 2:56 pm
by Shelluser
Syzop wrote:Well @ whether it "executes"... yes and no... It does not start a program in tmp/, but it loads libraries from tmp/, so in that sense.. it reads from there and (indirectly) it executes code from them (sooner or later).
Understandable. Well, the system detects it as executing and as such blocks it on partitions where this is impossible.
The tmp/ thing is needed in order to make modules able to reload from disk without forcing a server restart, so it's really something nice and not something we want to get rid of (nor do I see a good point in making it possible to disable).
Well, although it maybe nice where it comes to using modules (IMO there's no denying that) it is a major security risk on any *nix platform. A lot of those platforms have so called local root exploits, especially when you're looking at Linux. This basicly means that the moment someone gains access to your system and is capable of executing code he/she can compromise the box without any problem.

In order to thwart this you can mount partitions 'noexec', thus making it impossible to execute code from there. Which in its turn makes it a whole lot safer to allow certain (untrusted or public) processes to store their data there.

In short: In the current situation a machine can and will be compromised ('rooted') the moment someone has the option to execude code through Unreal.
Have a look at Bug #2300 to see a possible secure solution to this problem :)
Thanks for the link. Unfortunatly hardlinking won't be the solution to the problem since most (if not all) *nix environments won't allow it. And on the ones which do you'll risk some major filesystem corruption since you're basicly using an hack.

The best workable way I see here so far (which might be an future idea for Unreal, I don't know) is to chroot the whole process while making absolutely sure that the root privileges are dropped. Either prior to starting Unreal (which means that using the default 'chroot' command to start Unreal is a no no) or by setting the executable 'suid' while making sure its owned by the irc user. The latter option is disputable, but is very likely to work and provide some extra security.

The reason I think chroot is a very liable option here is because of the way Unreal is setup. Its already aimed at putting everything in a single directory, that will work to your advantage here. And since it doesn't need a lot of libraries, setting this up is rather easy. I'll write up my findings somewhere next week, perhaps someone else can benefit from them.

And when all else fails you can always put the entire IRC process (ircd, services, the works) in an UML, but thats a bit beyond the scope of this forum :wink:

Posted: Wed Feb 16, 2005 4:59 pm
by Syzop
(<- security expert here)
In order to thwart this you can mount partitions 'noexec', thus making it impossible to execute code from there. Which in its turn makes it a whole lot safer to allow certain (untrusted or public) processes to store their data there.
(still talking about a non-chrooted environment here)
Safer? Yes.
MUCH safer / Impossible? No. That's really just an illusion, while noexec is good security practice (like, to start with, it will often break automated rooters), you should really not expect too much of it.. There are tons of local programs that can be abused, "security holes" that are otherwise "unimportant" (non-suid binary apps). It's a bit like the ""restricted shell"" type of thingy :P.
Unfortunatly hardlinking won't be the solution to the problem since most (if not all) *nix environments won't allow it. And on the ones which do you'll risk some major filesystem corruption since you're basicly using an hack.
Huh? What a nonsense... hardlinking is a normal thing in *NIX, as long as it's on the same filesystem, which is normally the case for our purposes. It works fine on Linux/FreeBSD, and there's nothing wrong with it (we are not talking about hardlinking of directories or anything). It's fast too, and saves space, excelent for our purposes. (of course if hardlinking fails for any reason we fallback to copying).
The best workable way I see here so far (which might be an future idea for Unreal, I don't know) is to chroot the whole process while making absolutely sure that the root privileges are dropped. Either prior to starting Unreal (which means that using the default 'chroot' command to start Unreal is a no no)
Chrooting can be nice indeed. Unreal has been supporting it for years, with some improvements 6-12 months ago to make it work even nicer (like auto-generating dev/ entries on startup). So I doubt you have much to write on that -- it's changing 3 vars in include/config.h (CHROOTDIR, IRC_UID, IRC_GID) :P. Anyway, I personally run Unreal chrooted and it works great :).

That said, even if you have process fully chrooted, prevent any files from being created, then it is still possible to execute a program what your want[1] such as a nice DDoS client or ... knows what, sometimes even getting root access[2] and breaking out the chroot is possible.

Althought that again can be minimized by things like RSBAC/RBAC/systrace/etc (=sweet :p).

[1] That current exploits just do a simple execve() of /bin/bash, or often a little bit more advanced with connect-back or listen code, doesn't mean you can't do MUCH more.. like loading a whole new app in the application you just exploited. You got the whole process under your control, so you can execute ""any instructions you want"". There are 2 kits out there that do this for you, one is from metasploit.com, checkout http://metasploit.com/images/vnc.jpg, it's sweet ;). [yes that screenshot is windows but it's also possible in *NIX ;p]
[2] kernel exploits! Not exactly uncommon these days unfortunately :P.

Posted: Thu Feb 17, 2005 2:09 am
by Shelluser
--> about no exec partitions.
Syzop wrote:(<- security expert here)
Safer? Yes.
MUCH safer / Impossible? No. That's really just an illusion, while noexec is good security practice (like, to start with, it will often break automated rooters), you should really not expect too much of it.. There are tons of local programs that can be abused, "security holes" that are otherwise "unimportant" (non-suid binary apps). It's a bit like the ""restricted shell"" type of thingy :P.
Your story has a lot of good but also bad arguments. The point about breaking stuff is really the cause of the administrator, no one else. It doesn't break per facto, only if you're not fully familiar with the things you're doing. As for abusing local programs; that is true but in most if not all cases people need to have some sort of 'foothold' in order to have the option to actually abuse those. And that is once again in most cases another result of sloppy housekeeping.

Making things safer is what this is all about. Nothing makes your system MUCH safer, thats the job of the administrator who puts the several options he has together. Nothing will make your box MUCH safer, thats an utopia.

Still, noexec is an invaluable addition to the options one has to make things safer.
Unfortunatly hardlinking won't be the solution to the problem since most (if not all) *nix environments won't allow it. And on the ones which do you'll risk some major filesystem corruption since you're basicly using an hack.
Huh? What a nonsense... hardlinking is a normal thing in *NIX, as long as it's on the same filesystem, which is normally the case for our purposes.
I was talking about getting around the problem to let Unreal dump its data on a partion which has been mounted noexec, thus hardlinking is not the solution. And you can't bypass 'noexec' on the same partition.

--->about chroot
That said, even if you have process fully chrooted, prevent any files from being created, then it is still possible to execute a program what your want[1] such as a nice DDoS client or ... knows what, sometimes even getting root access[2] and breaking out the chroot is possible.
That heavily depends on many factors. Thats also why I explicitly mentioned that the root privileges need to be dropped and why "just using chroot" is not enough. Breaking out of a chroot is peanuts. However, the moment you make sure that root privileges are dropped (best way to make sure is to change chroot itself and force it to do a setuid()), make sure that the partiton you're using is also mounted nodev, and create a safe environment (not that rubbish about 'makejail' or even worse <shiver> 'debootstrap') then its getting nearly impossible to break out. There is no (virtual) root access to abuse, /dev is unreachable nor are there any programs (like a shell, ls, etc.) to abuse.

Alas, we're getting really offtopic now. This could be an interesting discussion in a *nix forum IMO 8)

Anyway, its really refreshing to see that even despite of this (IMO) uncommon behaviour there's a good way to work around it.

ps: small modification of my post: I forgot the '*nix' part in my comment about the discussion being interesting.

Posted: Thu Feb 17, 2005 6:35 am
by Stealth
From my understanding, Unreal only reads the modules from the tmp dir, so "hacking" them wouldn't do much good. Here is how I have learned it works (correct me if I am wrong):

Startup:
1. Unreal reads the conf
2. Unreal copies the modules the the tmp folder
3. Unreal reads the modules to load them.

Rehash:
1. Unreal gets the rehash signal/command
2. Unreal reads the conf
3. Unreal copies the modules
4. Unreal loads the modules

So securing this would be kinda pointless, because even though they are there, it would take a rehash to reload them if edited, but the changes will be undone when it rehashes, as the modules are overritten with the original module.

Posted: Thu Feb 17, 2005 2:09 pm
by Syzop
That's true Stealth :). [and assuming your configfile is non-writable]
Except of course, when you control the program, but then you could also just do [1].

That said, I think you (Shelluser) missed (and sometimes even ignored) many of my points, such as completely overrating the protection level of noexec (sounds almost like you get into trance from it ;p), you seem to completely bypass my [1] point, and in fact even [2] stating "getting nearly impossible to break out" which is still giving too much credit for chroot() + the filesystem lockdown thingies. I too agree it's harder and it helps, but it's far from nearly impossible.[3]

Just remember that I'm not saying all this to "show off" or anything, I'm trying to give some (minor) education on these things, in the hope that they will enable you (and others that read this thread) to make the right decisions.

Anyway, I think we have spoken enough now indeed. And I whish you good luck with locking down your system & unreal :)

[1] see my old post [1]
[2] see my old post [2]
[3] Note that in all my posts where I talked about chroot I assumed the ircd would continue to run as a non-root user {hence my reference to IRC_UID/IRC_GID, but also just assuming common sense}, else chroot() is useless indeed, I completely agree on that.