Next step is how do you find these problems in your programs. So when you write your program you can come back a little bit later and check and see whether or not you made these mistakes. There are two basic tricks here. The first one is, look at the environmental condition. Find places where untrusted users can alter files and then look to see if your program refers to any of those or find all if path names your program refers to and see whether or not untrusted users can alter them. Any directory in that path that's world writable is when you need to worry about. On some systems, you can set SGID bit directory which prevents people from deleting files that exist. So if you're opening an existing file, then you're fine, but if you're creating a file, then you're not. Also, if it's a world writable, any subdirectory is vulnerable as well because they can just switch in subdirectories, and don't forget to consider group permissions as well. Remember, trust is not just a function of the user. In the UID, it's also a function of the group IDs. So I mentioned the quick and dirty method for finding programming conditions earlier. When we started doing this work back in the 90s, it turned out we had a lot of success immediately and I'm going to pick on sendmail again. The student had never written a pro-script. He learned pro and wrote it in an afternoon and he did exactly what the quick and dirty method did. It just grabbed a function, had a list of system calls that were checks, and the list that we're uses and it just tried to do a match to see if he use follow the check, that was it. We got 24 hits. Nineteen of these when we looked at them were clearly false positives, but a lot of them were because we didn't do any macro pre-processing, and the check in the use we're [inaudible]. So you either check or the use, so it was false positive. We also found for race conditions but the environmental condition didn't hold. So the programming condition held but not the environmental condition because two of them were allowing a redefinition of something in the configuration file. But that file is in a protected area and it's only readable and writable by root, at least in those days so we couldn't exploit it. Similarly, with the sendmail queue files or cued up waiting to go. There again was a programming condition there that would allow us to switch things, but the spool directory of course, was owned by readable and writable only by roots, so we couldn't do that access. The 24th thing we found though was interesting. It turns out that there was a race condition. The programming condition involved the use was changing protection modes and it checked to see whether or not you own the file using access and then allows you to change the mode, and the specific file involved was called dead letter. Dead letter was where mail would be put if it couldn't be delivered. In order for this to work though, dead letter had to be in an untrustworthy directory. Since this would be a normal state of affairs if the real user couldn't be identified. So that is a race condition and it's exploitable. However, what will happen was rather amusing because we were getting ready to report it to Eric Allman, the author of sendmail, and just before we did, we went to the website and looked up the list of bug reports and such, because we didn't want to report this if it had already been found. It turned out an analyst named Hobbit found it 10 minutes before we were going to report it and he reported it. So in essence, we had a race condition here between analysts. So in any case, it was reported but long been fixed. After we had success with sendmail, we ran it over a vendor source. We found numerous potential race conditions. We reported them to the vendor and the vendor of course fix them. We then ported the script to other vendor's systems and it turned out the hardest thing to do was actually identify these system calls that were used and the system calls that we're checking, because each vendor varied how they did the semantics of the system call slightly. But as I say, a quick and dirty approach worked real well here and so it shows that these conditions can be found fairly easily. One other thing I should mention, a common belief is that, well that window is so narrow, no one would hit it. In point of fact that's not true. The first thing you can do of course is drop the priority of the process so it's much slower. But the second thing is, this is what's called a probabilistic attack. You may not hit the first time you try it, you may not hit it the 10th time you try it, but if you keep trying you almost certainly will hit it. So you have to do this repetitively so you write a small program to do it. That's what computers are very good at.