Weve all heard of exploitable buffer overrunsprogramming errors that let people write programs full of strange strings that cause your application to suddenly do anything an attacker wants. This simple vulnerability accounts for most exploitable security issues, and even though security experts have known about this problem for a long time, new instances crop up all the time. Errors in handling strings account for most of the problem, though not all of the time. (For more information about string handling, see my previous article, "Avoiding Buffer Overruns with String Safety<.")
Although several explanations of buffer overruns exist on the Web (see the sidebar, "Buffer Overrun References"), most tend to be very technical and often show you how to exploit a particular application. Some of these articles come complete with code that lets attackers do something they consider useful. Instead of going into that much depth, Im going to demonstrate the problem with an example program that you can step through to see how it works. This article isn't meant to teach you how to attack people, but instead to teach you how an attack works and what the consequences are of writing insecure code.
Consider the code in Listing 1. Start by looking at main. Notice that the example uses an unsafe call to fill a static buffer, which means that two possible overruns might occur in this application. Ill leave the task of exploiting the second one as an exercise for you. The reason I left in this unsafe call was because I needed some odd characters in my input stream to get the example to work, and feeding a file to the application via stdin was easier than typing possibly unprintable characters at the command line (although a Perl script could have overcome this problem). Typically, you never want to use gets()fgets() is much safer and wont overflow your buffer. . . .