Now, this all seems very nice and handy. But, I want to show you some of the security problems that can arise. If you're not careful and I should add these are all very well known. If they are not fixed on your system, you have much more serious things to worry about than Secure Programming. Let's go to the next slide. This was called Shellshock and it created quite a stir when it was released. This is peculiar to the bash shell. As I mentioned earlier, it accepts definitions in environment variables. For example, here gleep is a function that will simply print OOPS. In your environment variable list, you define gleep as is shown there. () { echo OOPS; } Then you type export-F gleep to make it available to the environment. When you type gleep, it will simply print OOPS because that's what the function tells it to do. But it turns out the next slide describes a very bad bug and bash. On startup, it loads all environment variables which are defined in a startup file typically but may also be defined elsewhere. Then it looks for things that look like functions, and then it interprets functions in that way. It evaluates the value, the whole value. In this case, the export, the line that begins with export shows the definition of gleep that also has Gotcha after it. If you'll notice that. When you execute gleep, it first evaluates the whole line and says, "Okay, the echo "Gotcha!" I print gotcha." Then, I will go ahead and execute the function which is OOPS. It does what follows the definition before it executes the function. Yeah and that's problem. It turns out by appropriately setting the second part- the instead of saying echo "Gotcha!" By setting it to other things. You can cause the shell to do things that's not expected when some poor innocent victim executes F function. This is similar to changing the value of a variable from something that's expected to something that's not. The next slide shows a much more direct example of this. Essentially, what you do as an attacker, or what an attacker will do is say, "Well, what does the program expect?" Then, if I give it something else, what happens? Here's a very good example of it. You'll notice here that PATH is set with dot as the first element- first value. PATH here has four directories in its list when its value..:/ bin/usr/bin:/etc; and they're separated by colons. In some shells, notably the seashell, it would simply have these as a list with spaces between them but bash SH and other shells use colons. The export says, "Make these available to sub-commands." I think create a file called Mail. In this file called mail, I simply have it copy the shell to have that file known as.xxx. Then, the chmod changes the protection mode so that anyone can execute it. It sets your ID to me. Which if you recall from our earlier discussion, means that whoever executes that program, it will run with my rights. Now, when I execute the program mail, it will run my version of the program. What will happen is, it will go ahead and create this privileged command environment. Now the trick here is to place this somewhere where an administrative user would normally look and have them and check to be sure that their environment variable path begins with a dot. In that case, I'll get a command interpreter that gives me their privileges. By the way, an interesting variant of this is simply to misspell the name. The reason that works is that dot is often put in this path but at the end. On the theory that, if I put a program like this mail into the current directory and the administrator is in that directory. If the administrator types mail, they'll get the system version rather than mine. But suppose the administrator is a lousy typist and switches the I and the L, so it comes out M-A-L-I. If I happen to have that program, instead of saying no such program, it'll go ahead and execute mine. LS is the one that is most commonly done for because that's the easy one to mistype this SL. You can also ask well, "What is the interesting variables?" Here's a good one for X windowing environment. For example, norm uses it anything that uses X11. The value of display is the name of the display that X will do its magic on. That it will draw windows on and accept commands from. Now, the way it's used is typically you'll read a value into that display. You'll set it. Then, you'll export it and run the X program and the X program in this case, xload which shows you the load average of the system, would simply write its output to whatever display was set to. This is often used in remote execution where you supply the display and the program will then execute. But instead of just supplying a display, let's supply something a little more interesting and useful. If you'll notice what the line with DISPLAY= is set to, if first of all it would set the displayed to zero and then execute the command mail me@remote copy of your.rhosts file or.shosts file or whatever file. In any case, what happens is, when the X environment loads display, if it executes- if it's going to put that into a command line which it typically doesn't then execute the program, I'll get a copy of the file you named. With.rhosts or.shosts now we know which hosts you trust, and if I can impersonate them, I would get in. Now, the next slide points out an interesting quirk of environment variables and how they're handled. Let's say you have two environment variables with the same name. In other words, path occurs twice in the environment variable list with two different values. I'll show you how to do this in a moment. But let's just say for the moment that's done, which one does the shell use when it looks for commands? The first one or the last one? That's an interesting question. Again, we'll get back to that in a moment. But basically difference in command interpreters. Some go from the front and get the first one, others go from the back and get the last one. Now, how do you do this? If you try to do it from the command interpreter, when you enter the new value, it'll wipe out the old value. So, that doesn't work. But what you can do is write a program and set the environment variables that way. Now, if you use getenv, you're going to have the same problem. It'll wipe out the previous value. But what you can do is use one of the exact family of functions system calls, and that allows you to specify the environment variable list. So, when you specify that list, put the same variable name in there twice and just give them different values. That's what this slide does suggest. The next slide shows exactly what the problem is. Some shells use the last value. So, if you scan from the beginning and stop at the first match, you may think value uses one thing, but the command interpreter may use the value for something else. So, again, the confusion here sometimes allows you to insert bad values for environment variables and depending on which shell or which program you look at, you may not see it. Now, how do you use environment variables? Well, here's a fun little attack that was launched I think in the '80s, but anyway, it's rather fun. Vi is an old version of them. It's actually the ancestor to them. It had a very nice feature. If you were editing a file and the line dropped, in other words, for example you disconnected from the network session in which you were doing the editing or in those days, if you connected over the phone lines and sometimes phone lines just disconnected, well, vi would say, "Well, I don't want you to lose your work. So, what I'm gonna do is save it in a buffer that you can later recover from." So, it would run a privilege program called expreserve that would grab the contents of the buffer you were editing and save it in a protected area that only the administrator could access. It would then run the mail program and send you a letter which said in essence, "Hi. I'm your friendly vi editor. You disconnected or something went wrong. But don't worry, I've saved everything you've done and to recover it, type vi dash r and then the name of the"- it'll give you the buffer name. So, that was a good thing. Well, a couple of us ask, "Where's the privilege?" The editor is not setuid to root. So, the editor runs with your privileges not the administrator's, and a fun question to think about is, why? What would happen if the editor ran with the administrator's privilege? It doesn't. No editor does unless the administrator is running it, of course. So, in order to write the buffer to that protected area, expreserve had to be privileged. It had to be setuid to root and mail is run by expreserve. So, if you remember from the previous lesson, unless expreserve reset its ids, mail runs also with root privileges. So, on the next slide, we show the first attack. You create as earlier, a program called mail in the current working directory. In this case, we copied the command interpreter and then made it privileged so that it would run setuid to the owner. Then what we did was we made the mail file executable and put dot at the beginning of the path, made that available to the command interpreter, and then we ran vi and disconnected. So what happens? Expreserve fires up and it saves the file that we had been editing in the buffer area in the protected area, and then it executes the mail program. Well, since dot is the first thing in the path, unless expreserve resets that path, it's going to get the mail file we just created. The mail file copies the shell into the local area and makes it setuid to the owner. Well, expreserve is running as the administrator, so mail will run as the administrator so that shell will be copied by the administrator and owned by the administrator. So, the second line in that mail program, the third line rather, will make the shell setuid to root so now I have administrator privileges. Not a good thing to do. So, the way we fixed it initially was, we went into the source code for vi and found the line, went to expreserve rather, not vi, and found the line where it actually issued the mail command, and that was the popen one shown on the next slide here. Now, if you'll notice, the first argument to popen is simply mail user. Well, that gets given to the shell so it looks for mail using the path. So, if you change it to bin mail with the slashes, that causes the shell to ignore the path and it will go ahead and execute the system mail program. Done. Not quite. It still uses the Bourne shell to do this. So, the next thing we asked was, well, can we change the meaning of that string, bin mail, so it means something else? And we looked and we found an environment variable called IFS which stands for Internal Field Separator. The basic idea there of IFS is to make P programmers' lives easier. For example, if you're reading a file where the fields are separated by colons and it's sometimes much easier to work with blanks as separators rather than colons, you can set IFS to be colon. Then when you read the various fields one at a time or you read the words of that line one at a time, instead of giving you everything up to the next blank, it'll give you everything up to the next colon. So, in essence, it's a word separator. It separates words on a command line. Well, that seems tailor-made for this. What happens if you put IFS equal to slash as well as space, newline, and so forth? Well, the next slide shows exactly what we did. Same program as before, but instead of calling it mail, we called it b. What we then did was set IFS to be slash i, then tab, new line, and blank, and saved. Then, we made sure path had dot as the first thing in the path. So, now when you run vi and hang up, it calls expreserve, expreserve calls mail using the string slash bin slash mail. But slash is now treated as a word separator and i is as well. So, that's seen as b, the command b followed by nma, and the next i separates the word, and so the third one is l. When the expreserve runs to save the buffer and send me mail, it of course gets my program b. So, let's move on here to another type of attack that caused a major change to many of the kernels but it will show you exactly what happens when you're not careful.