Section 6.10 Stopping Buffer Overflows with Libsafe

   


6.10 Stopping Buffer Overflows with Libsafe

graphics/fivedangerlevel.gif

Libsafe is an innovative solution to prevent crackers from breaking into your system by using buffer overflow attacks. Its greatest innovation might be its extreme ease of installation and use. Rather than recompiling every program on your system, you simply install the Libsafe dynamic library file and either define the environment variable $LD_PRELOAD to specify it or list it in /etc/ld.so.preload. Executable files do not need to be altered in any way.

According to Libsafe's authors, researchers at the Murray Hill Bell Labs facility where UNIX was invented, for each of the years 1997 through 1999, half of the reported CERT Security advisories were due to buffer overflow problems. Libsafe will stop the vast majority of these that are due to buffer overflows on the stack in dynamically linked programs. Unlike most other solutions to security problems, Libsafe will work on unknown problems; you do not need to worry about which programs need Libsafe's help. It will help all with a performance hit of only a few percent and sometimes with no performance loss at all due to its more efficient way of doing things.

Libsafe works by arranging to be called instead of common unsafe C functions that include gets(), strcpy(), getwd(), scanf(), and sprintf(). It determines whether the destination is on the stack and if any of the addresses to be written would overwrite beyond the current stack frame. If so, the operation is blocked. It is under the GNU Library General Public License and is available on the companion CD-ROM and

www.research.avayalabs.com/project/libsafe

Some alternatives to Libsafe include StackGuard, Janus, and configuring a nonexecutable stack. Although these will catch some problems that Libsafe does not, they are substantially harder to set up and to use. No combination of them will stop all buffer overflow attacks; there are no silver bullets in computer security or any other part of system administration or programming. There is no substitute to keeping up-to-date on exploits and defenses; see Appendix A for Web resources to keep up-to-date. Their URLs are listed here.

www.cse.ogi.edu/DISC/projects/immunix/StackGuard/linux.html

www.linuxhq.com/patch/20-p0491.html

or

www.openwall.com/linux/

Why are gets() and friends unsafe? Unlike some other programming languages, C does what the programmer tells it to. Although this yields much higher performance, it has consequences for careless programmers. Let us consider imapd, the daemon that lets a user download her mail onto her laptop system. It must run as root so that it has access to each user's mailbox. It prompts the client program for an account name and reads it from standard input into memory using gets().

The gets() function takes a single argument that is the address of the buffer to read a line of characters into. These characters are read from standard input, which will be the TCP connection to the client system. Because account names are "only" up to "eight" characters, imapd declares its buffer to be 20 bytes long, for some padding. It then calls gets(), which will read characters into the buffer until a newline is received.

What happens when a cracker enters more than 20 characters? They will be written into memory following the end of the 20-byte buffer. Shortly beyond the end of the buffer is the return address of the function that called gets(). A cracker merely writes instructions into the buffer to take over and then puts the address of this buffer into the memory where the return address is stored. When gets() returns, the cracker "owns" the machine. (Although it takes a lot of talent to write an exploit, frequently they fall into the hands of script kiddies who proceed to run them against thousands of random systems.)

These functions are considered unsafe because there is no way for a programmer to tell them the size of the buffer so that they will not exceed this size. A clever cracker will be able to determine exactly what values to put in those bytes past the end of the buffer to alter the program's execution to give the cracker root access. The result is a buffer overflow, sometimes called a buffer overrun. For each of these functions, there is a safe alternative that should be used, such as fgets() instead of gets(), and strncpy() instead of strcpy().

Approximately half of the recent types of Linux and UNIX intrusions were done with buffer overflows in this manner. These include the named break-in that first was seen in late 1999 and the famous Morris Internet worm that crippled 10 percent of all Internet-connected computers in 1988.



       
    Top


    Real World Linux Security Prentice Hall Ptr Open Source Technology Series
    Real World Linux Security Prentice Hall Ptr Open Source Technology Series
    ISBN: N/A
    EAN: N/A
    Year: 2002
    Pages: 260

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net