 Okay. Hi. I'm Anthony Martinez. This is Thomas Bowen. We're here to talk about Toaster Kit. It's a root kit designed for NetBSD. And the reason we pick NetBSD is it's portable. It runs on everything from, you know, your desktop machine to big, scary hardware like the Vax. Do a toaster. A little gum stick board, someone put in a toaster. There's, you know, new additions to the Unix ideas. It's also fun. Messing with the kernel lets you control the machine. So as for root kits, on NetBSD there pretty much is none. There are none. There haven't been any that we've been able to find. And in addition, Czech root kit hasn't been updated for NetBSD for a very, very, very long time. And so this is possibly the first root kit for NetBSD. So NetBSD architecture, there's a lot of different things to it. One thing to it is that there's loadable kernel modules, which allow you to, at runtime, add new system calls to kernel space. Also there's a very good, very clean design in the code as well as very portable design. And the way that they do portable design is just basically you have a lot of abstraction from the architecture so you abstract from the architecture so that you do not have to deal with... There's a lot of functions out there in kernel space that make it so you don't have to deal with any of the architecture-specific pieces of code. You just deal with generic functions and it's very easy to deal with. There's process security. If you've ever used the Windows security tokens, privileges, Linux capabilities, it's a similar idea. We get away from the all or nothing, are you root? And they also let you load in different security models. So we've got to take that into account when we're breaking the security. So how are we broken the security? We do a few standard root kit tricks, provide a system call to make whoever asks the root user. We hide processes like say you're running a password cracker. You don't want that to show up in the list. Say you're sending those crack passwords home. We can hide the network socket. And we can also hide the loadable modules that we're using so that it's not obvious that there's a root kit installed. So the code that we used, we just basically ended up using sample... There were a lot of sample code skeletons inside as part of the NetBSD kernel. They gave you a lot of information on how to create system calls in loadable kernel modules. It was very simple to modify those so that instead of adding a new system call we could create system call hooks and things like that. It was very, very easy. Just as little as three lines of code modification to be able to make a code that they already gave us into a system call hook. So that was very easy. So system call hooks. Basically there's a master table inside in the kernel space which is called sysent. It's a sysent array. Basically that table is a table mapping system call numbers to the system call functions in kernel space. And so to create a system call hook all you do is go through that table, find the number you want to modify and change the function pointer in there and ta-da, you have a system call hook. It's very, very easy. Now the modules that ship, they can do lots of neat stuff. Load executable formats, load file system types. But we only concern ourselves with two kinds. A miscellaneous module which doesn't do anything by itself when it's loaded. We have to tell it what to do. And a system call module, those go through and pick the next unused system call, load ours in there. We get to be extra lazy because the NetBSD people did all the work. We just use their functions. The module systems control through a file on the file system. It's their unix. Everything's a file mentality. It kind of comes back later when we're dealing with hiding the modules. The first module we did goes through and gives you root. It doesn't really, it doesn't give you root so much as it copies the credentials out of init. And since init has all sorts of responsibilities, it's the first process to start up. So it needs to do lots of things. So we use the interface provided by kAuth to steal its credentials and plug them in to our ASCs. Once we get more complicated than that, we start running into some of the things we want to modify are locked. They can't be written to, trying to set them equal, trying to use the equal assignment operator in C. We just crash system. So there's functions for the memory manager, UVM map protect, and it says that it goes through and it'll remove write protection, but it doesn't actually work against kernel, kernel memory. So we went through the memory manager code and it turns out that for supporting the debugger, they had a function that actually does what we want. So we just kind of copied it because we're lazy. So, wrong slide. So once we got that finished, we could hide modules. So if we go through and type modstat and there's a bunch of modules labeled rootkit, that's a dead giveaway. So the devLKM file, which is where module information comes from, is on the file system. And if we delete that, you know, another dead giveaway. So we go through and there's a function that provides the information, and we just hook it in a similar way to doing the system call. And when it's asked about modules whose name contains rootkit, it says they don't exist. So after we've... now we already have a module that will give you root and then we also have a module that will hide any modules you have in there. Another thing we maybe want to do is hide ports. Maybe we want to have something like an open SSH running that we don't want anybody to know. So we can hide that, but to be able to hide that, it turns out netstat uses the ctl tree. So ctl is basically a tree structure in kernel space that all of the leaves contain information or configuration options for the kernel that you can modify. It also turns out that it contains all of the port information that netstat looks through. So to be able to modify... to be able to hide ports from netstat, we had to hook a ctl helper function, the TCP helper function. And one notable thing about ctl is the API really, really, really sucks. It was very difficult to get any information out of it to help us in messing with the ctl structure. So, yeah. So actually hiding the port, basically we needed to find the TCP helper function node inside the ctl tree. As soon as we find that, we can modify that helper function, basically create a new hook just like we would do for a system call hook. So once we traverse it, get to that and hook that function, basically our hook function will call the original helper function and modify the results that function returns so that we're hiding certain ports that we don't want it to actually be displaying to netstat and then return back to netstat or whoever's calling... anybody that's calling the function, it's basically just hiding from anybody. And our next step was hiding some processes. We could do that with ctl, but like we said, using the ctl API kind of sucks. Instead we go through, there's a master list of processes in memory that's pretty much only used by PS. And we go through and when we're asked we remove the process we want to hide from the list. And you would think that'd be a bad idea because the process wouldn't continue to execute, but that's not actually the case. The scheduler doesn't work with processes anymore. It works on threads. We've got a quick demo cooked up. We did development on Intel i386 machines. We also worked on a PowerPC machine and we tested it on a Vax. I could have brought some actual Vax hardware, but it's a little easier to use the emulated one, which is not working. Okay, can we all see that? Okay, so as we can see we're running NetBSC 4.0 on the Vax. We've got our main module, our port hiding module and our process hiding module loaded, and later on we'll load the hiding and the detection modules. And currently we're unprivileged, but we can change that. This is a little C program that just makes our system call and then runs ID. You could do that and then run a shell. So here's our current process list. One of them is SSHD. So like Thomas was saying, we can hide the SSHD socket. Currently we only work on TCP4. It's not hiding the IPv6, but we can easily fix it so that it also hides the IPv6. Okay, and now we show the mouse. Now we show that we don't see the SSHD anymore. It's out of the list, but it's still running. So we'll log out of our unprivileged account, come into root, load the hiding module. Vaxes are a little slow. And that's a bunch of garbage. The considering stuff is our debugging output, but it doesn't show any of the modules listed. So now we can show that we can detect our root kit. Again, the Vax is not the speediest machine on the earth. Okay, so there's sys exit mismatch because we hook exit. These get GID, get PID, and get UID. Those system calls don't actually match up to their functions to begin with. There's a reason for that. I don't recall at the moment. And here we show that we are not showing the true module status because these functions differ. And then we return error because we don't actually need to load permanently. We just go into the kernel space to check. We don't hide files at the moment, but that's the next step. So how do you do protection? Basically, you have to detect these hooks. Our current root kit just does a lot of simple hooks. So for the simple case, it's very easy to detect hooks like this because you're modifying some sort of table somewhere or a tree somewhere where there's basically a pointer in there which is supposed to be pointing to your actual system call or your helper function like in the CTL tree. And while you're in kernel space, you can see both that table and your actual function. And so you can compare the memory addresses of those two and if they're different, then that's how you detect hooks. However, it's an arms race with root kits because they are now mostly starting to do a lot of hot patching in kernel. Basically, you strip out all of your code from the original function that you're hooking and move that somewhere else in memory and then replace it with your hook function and run it like that. And so that is a bit more difficult to detect. So detecting KOF is pretty difficult because what we did with KOF is it's just doing a simple duplicate function that many other kernel functions use. An example is fork uses it very often. And we're not doing anything special with it. We're just basically calling it as if we're calling it normally. So it would be very difficult to be able to detect what we're doing with that because it just looks normal. And detecting memory unprotection is difficult as well because at least on NetBSD currently because there is no utilities to really do that because there are no root kits that we've been able to find, public root kits for NetBSD. So there's just no need for the tools currently. And preventing this sort of attack is another arms race. The first step is don't build your kernel with modules available. Now that works against a script kitty installing a root kit on a machine because there's also tools to force in a module through directly writing a memory. And sometimes you've got to have a module for a hardware device or a file system that you can't build in the kernel. The other option is the security levels which originated in BSD but that messes with your ability to run X windows. It keeps you from being able to patch your system easily because you've got to take it all the way down to a single user to get insecure again. And the popular architectures ship by default as insecure because it's a trade-off between annoying your users and being able to use your machine. Plus there's always a point where the secure level's low enough at boot time so someone can go in and modify your boot up scripts and load the modules in there. We ran really, really short of any questions. He's asking if we do anything to avoid things like top and free from seeing our hidden processes. Those also use the all-proc list that we modify. So yes, that works against those. We do not hide our network sockets from LSOF because what LSOF does is it goes through, it actually reads kernel memory. They're trying to get away from processes reading kernel memory because then they are hard-coded in and it's difficult to upgrade past that. I'm sorry? If you're on Netstat, it will not show because we hide from Netstat, but we do not hide from LSOF. The little stub functions that we wrote that actually make the system calls, those are really short. It just makes system call and then runs ID. This is the one we use to hide a process and this is the one we use to hide network sockets. You hand it the process name or the port number. I'm sorry? We are not affiliated with the NetBSD project. This is a typical root kit. There's nothing special we've done. There's lots of books about designing root kits. The most innovative thing we've done from what I can tell is we messed this CTL, which I haven't seen any other kit that deals with that. Any other questions? We've tried this on three architectures, the PPC, the Intel 386, and the Vax. We can run through the module code. The code is going to be released in a Google Code project. The group name is Toaster Kit. This is the main module, the first one. It goes through, it finds init, copies the credentials in, and puts them in the current process. That was the easiest thing to do. This is the function that we pulled from the memory manager that allows us to unprotect the memory. It goes through various dances to find the physical addresses and forcefully put the protection in. This is possibly our worst module. This doesn't 100% work on the PowerPC for some reason. I am not entirely sure why that is, but it started out with... We make the original call. We check for some errors. Then we go through and copy the useful information back out and hide the port we're looking for. As released, it has a bunch of debugging information. It's not particularly stealthy. It's more of a proof of concept. It's all licensed under the BSD license, of course. This one goes through, looks at the process list, and removes it out of the list. Simple link list style. We could do some more thorough hiding later on, but proof of concept. The detection is sort of interesting. We generate... At compile time, we generate a C file that includes... We just include into the module, and it goes through, performs all the F checks and warns on the errors. For the checking if we're hooking module listing, we just do a single lift check. For hiding the modules, it's the same sort of... We wrap the old function, and we lie about the original data, say it is not an entry, does not exist. Not in the base system. He was asking if there's any tools that show the thread list. PS does not read the thread list, it reads the all-proc list. Any further questions? If there's no further questions, I suppose we'll be in the Q&A room for Track 2. Thank you.