 With the University of Southern Mississippi and the anti-child porn organization now incorporated. At this point I'll probably have to say that University of Southern Mississippi has the greatest IT department computer science program. I have to say that now. Can you hear me? All righty. Again, my name is Tim Lawless with the University of Southern Mississippi and anti-child porn organization. I'm here to talk about a little project I've been working on in St. Jude where we're trying to detect improper root transitions. Come on. Wake up. There we go. Of course, the computer thinks it's a Monday too. Actually, no, Star Office. Really, really heck with this person. This is my email address and we'll be dropping this presentation plus other information out on this URL a little bit later on today. St. Jude really came about because in our institution we have to allow clear text passwords on a lot of systems, which as you know is the most evil thing that one can do. Once you get in, they pretty much, it's just a matter of time. So we started looking for a way to save ourselves a lot of time from sleeping on the floor. One thing led to another. Guy put forth an idea back in October, I believe, of 97 in a system in magazine about actually trying to detect the transitions into the root user by monitoring audit trails under Solaris. That's really where we got the beginning of this and has come forward. The reason why we had to go and start looking at things like this is because our firewalls really would not protect us. We're also with clear text passwords coming in. Our users themselves will expose our systems. They're sometimes our best friends and our worst enemies. The misuse detection scanners like Snort and the like really would not pick up everything. We've already seen how they can be bypassed, how the systems that we're putting out on our hosts really themselves can be defeated and you will see this continually through the day. And of course, we've come to love our Unix vendors, the ones who give us new root exploits and every update that they send out. And we also, the problem also with our detections that you may go one, two days without finding it. Unfortunately, the system ends real-time on vacation. And the longer that that is, the more damage will be done to the system. But anytime that they're on the system, we can't trust anything really on the system itself. So that's where we began. When we began the project, we wanted to produce ultimately critical level IDS implementation. Our target was Solaris, but we went over to Linux because it was easier to do development. There was a little bit more information just to get the wheels going. I can't. We also wanted to try to minimize the number of false positives that we would be getting. And of course, the negatives. That was a problem with the original implementation put forth and systemed in is a heap load of false negatives. Before we would be able to really respond to anything, we wanted to reduce those false negatives and false positives to a point where we won't shoot our users, plus we'll be able to catch enough of what's really going on. So what we were doing, we used reference monitoring implementation. I believe you'll probably hear a little bit more about this later on this evening when a gentleman talks about penetrating B1 systems. We also went to a rule-based anomaly detection. Just a moment, I'll go in a little bit more about that in a model of behavior for execution after we're doing copious BSM outputs. Before we get into this, I'll go into a little bit that we're going to talk about subjects and objects. How many here have dealt with maybe trusted operating systems? Good. Excellent. So you'll follow what I'm saying. The subjects are the things that do things onto other things. Well, the objects are those which are being done too. A little bit better definition is put up there. We'll also sometimes see that our subjects will be the objects themselves. The reference monitor, it will be enforcing our policy by forcing all actions performed by the subject to actually go through it. It will act as a stop-gap to prevent things from occurring which we really do not want to occur. The rule-based anomaly IDS as opposed to our statistical anomaly IDS systems. Given a rule set, if we're looking at a chain of events, we'll start off with the beginning where we'll enter the rule set. And we'll move forward. If at some point one of the options at that point is not actually what is occurring, we have an anomaly going on. That's really what this guy's about. It was implemented at LOLNL and the Wisdom Incense and also the TIMS Project with Digital Corporation. What we're going to be doing is looking at, we take every subject or process in our case. We would classify it as being a privileged or uncrivileged process. The privileges won't be rude, but it also would be a set of root plus somebody else. This would allow us to detect transitions into, say, oracle users or other damage that we're running within the system. Unprivileged subjects, just normal user processes, will transition up, like we know, through execution of the set UAD binaries. And doing so, we then have to catch them and determine how they're beginning, where they're beginning, and the chain of events that may then occur. The privileged subjects, the processes, will drop their privileges through one of, and one of these three calls. I believe under Salish, we'll be dealing with a fourth one. Given the subject with privilege, and this is really where the decision is made, they may execute any other following system to exceed. Only if the subject first drops its privileges through one of the means we just talked about before, and the object is within the restriction list, within the rule base. A subject without privilege may execute any object. Just a normal user may go about his daily life. As long as they do not transition up into a privileged state, we're going to be perfect if they can't allow them to do what they want. Now upon execution, we're going to have to do some stuff and juggle around, change our states, where once upon execution, the new subjects restriction list will be updated based upon the subjects prior state and the objects executed. I'll show you in a moment where we go through and have to serve running and binary. He calls another function and he's okay to execute. We've already passed it on. The binary will then find the best rule and we have to ensure that the next rule for what the next guy, this about to run, can do is a subset of the current processes rule. Otherwise, we could gain privileges just merely by executing a certain path of applications. And finally, a subject's update restriction must be subject to our restriction list in a minute or two. This is currently where we're standing right now. We've got a Slurs Perl implementation. It'll run currently under Slurs 251 through 8. It has some problems with its arguments where it will not give those out to us in the BSM. It's not yet been fixed by some microsystems. And the current Linux implementation is running at this time not a multiprocessor system. We do not use argv's for context in the Perl module at this point, but under Slurs, under the Linux kernel, we are using the arguments to decide a context. The reason this being is some applications will make a call system, for example, which goes out there and will run slash bin slash sh with v dash minus c, and then the argument passed the system as the third argv. Without being able to look at our argv's for the context of what we wanted to do, we would then just have to allow these programs that are executing a system call to then just go merely out and run in the shell, which is something bad. We're hoping to have an internal slurs implementation out and around Christmas of this year. This year, maybe early 2001 at worst, probably in the I-277 point, Slurs 7 kernel 80 at worst. I'm just going to show you. I'll switch the slides, I'm sorry. Externally, internal versus external, inside or outside the kernel. When we implement, when we would do this, to be able to really stop the things before they occur, we would have to do it within the kernel to cramp them. However, when we go into the kernel, some things change. Externally, when we get them up through our audit trails, each event is a discrete instance. In one line is one event. We have all the information about what's going on while inside the kernel. We're watching it as it's actually going on. Sometimes we have to wait until another event occurs before we can really determine what happened with the prior event. For example, with the execution of a set UID binary, the execution code down in the file system objects in the Linux kernel will actually set the UID and the effective user ID to zero during the execution phase. However, since exec never returns, we never really know that a set UID binary has in fact been executed until another event occurs and we can really see, we can infer from what has changed in the state of the system that it was in fact a set UID binary that went forth and then we build our trees from there. Externally, the detection is delayed. In the Solare implementation, we're seeing about two, three seconds on a single processor system, a little bit less on a multiple processor system, but at that point we begin racing to see who can kill whom first. Also, externally, it is easy within those two seconds, two, three seconds to strip a kill of the external monitor. Within the kernel, it's a little bit harder. You would have to do it before actually doing an exec, which would require you to have the code within the module itself. For example, this little application will execute a bash shell. If it set UID root, it would give us root normally. Over here for a second. Normally, we're running this. We've dropped out to a root shell upon execution of the binary. However, going through the syncing model. The font? Yes, sir. Just a second, please. I'm sorry. Let me find a nice... This has been with the font. Maybe that'll work. Whoa. It did get big. Well... Okay, let's try this one again. Normally, we'd be dropped out to a root shell. Possibly. Hi, sir. Normally, at this point, your friendly administrator will spend the next evening. Instead of with his wife and kids, we're building a system. What we want to do... What we want to do, I'm sorry, let me just... I'm going to go in here and load up the module. And then it catches the exec just as it begins. It kills it at the exec process, and... We just dropped out a message to our KLOG. There are some... This would catch the buffer overflows. We tried it with several buffer... We pretty much saw the buffer overflows. We could. I try not to keep many buffer overflow vulnerabilities on my laptop. I apologize. I'm nervous. You can tell. Let's see if I can just minimize this guy. Right now, there's no other tracing. We're playing into kernel. Well, we're not outputting any tracing. There's some extra tracing in there depending on the compile time defines you do. But right now, the minimal ones will just make a hard drive rattle for several hours for just running an LS. It is feasible to add in additional tracing into the system. Just modifying the source code of the main app. Let's see if I'll... I'll get into the source code in just a minute. Let me find the window. I want to... I'm going to have to fast forward through these again probably. Unfortunately, some things in Unix are not quite as good as they are in Windows yet. Pay attention to... I feel like I'm doing patches right now. Unfortunately, right now, there's no silver bullet. Not even this guy can really stop everything. He would be just another layer in there. For example, with the buffer overflow, the buffer overflow actually does occur. The shell code does get executed. However, just at that execute is where it's caught and it stopped. That's why I'm referring to... That's what it's referred to as the last ditch effort right before Hellfire and Bromstone falls down upon us. Also, the restriction rules must be written. There are some applications, for example, I discovered when I came here, I have been spoiled all my life and have not used PPP yet, that the using that CTL script causes that module to go really wild. So you have to go through and write out the rules in the script before it will not catch those and actually let them pass. Also, there's the additional overhead. As we're playing around with the kernel, just doing the extra stuff and lunging the data, it costs a little bit. Just executing user processes without going through having to do any of the checks. We're seeing less than 1% slowdown. However, let's say we're root and we're compiling a kernel. See almost a 5% slowdown at that point. And it's really spending it in system time now because we're having to update all of our checklists. There's really no optimizations in at this time. We do have some inline functions, but that's it. Now, the rule sense that I spoke of, that's the end of the slide presentation. No network connection right now. Oh yeah, well, we'll just hit that right here. Well, unfortunately it's not PowerPoint, but religious reasons prevent me from using that. That's the contact information once again. Probably by 1 or 2 o'clock this afternoon, we'll probably have this PowerPoint out there along with the source code. The source code is available on PacketStorm at this time. I sent out an update last night. You got it? Good? Okay. Now, let's try to get this a little bit smaller. Much better. Can you read? Whoa. For example, right down here are the general rules that we've, the rule sense, and unfortunately we're having to compel them in by hand right now not reading them at low time. We do want to be able to go to root sometimes, and so we're going to have some guys that really have to be granted an IA pardon. SU and Pseudo, by the way Pseudo is bad, you should never use it, are in there. Gene Mixer was one that just had to go in there because it will execute mod probe through system as root. Otherwise, sound gets really loud and you can't, or you can't turn it off. Are there any questions? Yes? Pardon? No. A set UAD process may execute. However, it may not execute other processes by default. The default rule down here is actually rule zero, which is nine, you can really go through and execute nothing else, but that set UAD process itself may execute. By granting all privileges it may, it has carte blanche in your system. SU and Pseudo, of course, would be applicable, we'd want to do that. I don't think there would be anything else we'd want to do that for. Some of the testing that we did, just with a couple things, gets really long. Unfortunately, that's the nature of the beast right now for this guy. We're wanting to add in later support for just loading it in from a configuration file. Yes, right now I can. There is the option in there commented out for debugging purposes to prevent the loading of the unloading options. We just replaced the load and the clear module syscalls in there. Now it is still possible to attack it through KMM. However, personally using lids to prevent that may be something put in this guy later on in the future. Policy such as what we're looking at, what we're just looking at. Initially, what we'd have to go do is go through a learning phase where we just run through the system normally in a safe environment. Not plugged into the network, we just hope we know what we're going to run on the system beforehand. After determining from the output of the learning process, which is, does everything, but still permits it to actually execute. It just gives us the error message and from those we then would be able to write these rules. Once that these rules are populated, you've recompiled without the learning option enabled, you'd load that in and go from there. When you make changes to the system which may require these root execute features, you'd have to modify and reload from there. Not through this guy. He wraps himself around the kernel at this point. In fact, let me just go into... Also, since we can't link when we build the module to make it manageable, we've done includes my C professor shit when he saw this. I think I committed a sin. And loading the module, this is just handling the execs since... I point you to the stuff by pragmatic of THC for how to handle execs. We're going down here, what we do is we're saving the original CIS call to a pointer, replacing it with our wrapper. And within that wrapper, we're going to make a call to that original CIS call. So we just wrap ourselves around the kernel. We're not actually being invasive. And that's why we can actually pull ourselves out without much problem. That would be possible. Would not be part of the module itself because it would be such an expensive process to do. Probably through a proc file system interface with a monitoring daemon running. That you would be able to do that. I'm sorry. It was asked whether we would be able to, at some later point, modify this so that it would communicate or be able to attack the offending processes, offending users' processes and pretty much retaliate against the login instance that may be perpetrating this. Would I be correct in saying that? Basically be able to take a dump of memory and just... That would be something we'd be doing in an external monitoring application. The dumping of memory and gathering of further information about the offending processes. Yeah, during the execs, forks, and to a much lesser extent, the set UIDs and exits. Yeah, I could see how it would be much easier to do it in user space versus kernel space since a lot of the fun with viewing it in kernel spaces, you've got your set right here and you're limited in what you can do. A lot of just string calls. You're going to have to write them yourself since you cannot call external libraries while in kernel space. Plus, if you core dump in kernel space, that's a bad thing. Yes, we lost exec many times. Everything keeps running, nothing else will. But after we load the functions and wrapper cells, it just goes on. Right now we're allowed to clean up a module, we free our memory and go on. What normally we do to prevent you from cleaning up or loading in other modules is we just replace those with an error message of either for loading no memory or for clean up module, module not found. It just errors out and blocks any attempts to add or remove because those syscalls can be called from within, for example, buffer overflow. Apache runs as nobody, so really you'd be hitting just running in user space at that point. If you're just without privilege, just not root, we branch out just into the wrapper and go straight to the syscall itself, so it's practically no expense if you're just doing user stuff. Name D, let's say you're not running name D as root. Just a moment on that, but let's say you're running name D as root and that guy was cracked. If you had no, he could not really execute anything else after that. Maybe name DX for it would be the only thing he would be allowed to run. It would catch that with one caveat. We still have a lot of the stuff that starts up at the beginning. We're still generating rules for that and we're working on handling a login because login will sometimes transition over, be logged in root on console or login user. We're playing with how we would handle that guy right now. That would be one thing that would come out within the next two conversions. The question would be to load with an Apache web server. Other web servers, I have run this with Roxxon without any problems. Just running regular CGIs. Unless I shoot myself in the foot by making an error in my logic. We can go with all, with a set of privileges, which root will always be the superset. Easier for just development, right now it's been root. That's been the part where my headache personally came from which caused me to really want to do this. I don't like sleeping on machine room floors. I asked why are we just limiting this to root transitions. Also transitioning from user to user until you transition into that root user. You can have your other IDS utilities running out there as root with more privilege than that user. Monitoring them, T2I Snoop, other applications, watching logs. But once they actually acquire that root privilege in their ended system, you can no longer trust that stuff. So the only thing that has more privilege than root is kernel. Anything? Pardon? Issue, well right now because the root... The question is, if you're using SU, is there anything to help? I'm not quite sure if I fully understand what you're... Unfortunately right now, SU is a trusted binary. To keep it more secure. If SU is... If you can root SU, especially on the Linux box, congratulations man, don't let anyone find out about it. You could own the world, literally. But yeah, SUTO, I do it for convenience, but really, SU would be the only one you really should have in there. I hope SU is secure. I hope people have been hacking on it, trying to get it not to be secure enough. Yes sir, back in the back. I'm storing the argument itself, not the inode. So moving around files on the file system would not affect it. It's a little bit... I think you were probably going towards the lids project in that question. We're really not doing ACLs at any point in here. If flush bin is SU, it could be replaced, yes. However, I hope the file system is set up properly. It should not be easily replaced without already having the privilege which we're trying to acquire. And then again, if they have physical access to your machine, you might as well just pack it up and go home. Pardon sir? Copy a set UID binary. No, because we're actually looking at the file name as it's coming in through the exec, which is the fully qualified path name, not the arg-via-0. The guy we were asking if, for example, you created a user bin under your home directory and would run SU under that, would that be it? Which I think you were trying to get if we're checking slash arg-via-0, you'd have relative path issues. I see each route. Actually, I don't know. I'd have to try that back in the hotel room. That would be correct. You would not be able to give it, set UID route privileges. You'd have to have a collaborating administrator or a negligent one. Right now, pretty much within a group, just the guys have been beating on it. A few other people would like to see what people could do to it. Yes, sir, right in the back. The question was if NARC was loaded prior to this module actually being loaded onto this system, would it be able to detect the route transitions? If you tried to execute something, like let's say an LS, or just a command through the system, it would catch that. If just any Trojan binary that you would just say anything, just not even that guy, if he did not have to call exec up to that point, it would not go through the reference monitor to be stopped or permitted through it. Yes, ma'am. Right now, well, the question is why, why is a symmetrical multiple processor box has been exceeded at this point? At this point, we are not handling spin locks within the code, so race conditions probably would occur. That is something else to be going into. First need to get a good S&P box that I can crash. Yes, ma'am? Could you repeat that a little bit louder? We're not using, let me just go into that and I'll show you. Where is that? This question, if you modified RGV of 0 to point to a legitimate file, would it be able to bypass it? No, that was one that actually came up earlier on in the testing. What is it? Try S calls. We're not using the file name that actually comes in through the exec statement, which is really what is executed. That's what we're using for it to figure out what you're going to run out. Run, yeah. Yes, sir? Well, if it is a buffer overflow. That is, this guy, sorry. Is there a Sean Hedges in this room? Sean Hedges? Okay. Sorry, could you repeat for me? The memory that's been overwritten is not in kernel space. The memory that's overwritten is on the stack at that point in time. You're not in the kernel memory at that point. You're still actually in user space. We try to terminate the process at that point, exit the process, literally just destroying the fending application because after that buffer overflow and we deny the exec, it's not deterministic what will happen. The shell code will execute on the buffer overflow. It stops it at the exec itself. You call the syscalls. Yes. In normal production, you would not have the unloading of the module. We would be overriding actually replacing the syscalls for loading and unloading the module where you would have to go through an attack came down at that point. Yes, sir? To run the actual shell, not the exec calls. The question is if you could actually just write a shell in the buffer. That was actually not the attack that we have recently been actually looking at, such as not so much writing a shell, but writing what you want to occur within the attack, within it, for say, just to give you an example, one that we're trying to work on now is handling, you call open, open ecc password and write mode, write out a new line, close the file. Probably even take up less space than what you're probably shooting at. At which point that's where you bring in other applications, not a silver bullet. Things like lids, we actually be watching and protecting these files. Yes, sir? That would be something that we'd be doing actually in an external application. I'm sorry. Pardon? Actually, you would have to copy the binary over. Yes. You would be wanting to, using applications like lids where you would be protecting the files themselves, your read file systems, yes. And with, it is 1046. So if there are any other questions, thank you for coming.