|
Beneath the surface, computer programs (applications) are made up of many subprograms known as subroutines. Subroutines allow programmers to divide into many smaller tasks the task a program is to perform. Designing big or small programs without subroutines would be impossible.
 | Whenever a program calls a subroutine, or a subroutine calls a subroutine, information can be passed between the two via the stack. A stack is like a can of tennis balls: The first ball pushed into the can is the last one taken out. This type of stack is called first-in-last-out. (Other variations are possible, such as first-in-first-out.) Stacks turn out to be quite efficient for transferring information: Memory is consumed when transferring information to a subroutine and then automatically released when the subroutine finishes. Stacks are also referred to as buffers and queues. |
Although stacks make programming with subroutines efficient, they're vulnerable to a hacking technique called buffer overflows (or stack-smashing). Overflowing a buffer is one of the most popular methods hackers use to break into computers. The idea is to feed seemingly crazy streams of code, in binary form, to a program in order to make them behave in ways their designers never intended.
Here's how buffer overflows work: 1. The character stream overflows the intended boundaries of the subroutine's buffer. 2. When the subroutine finishes, it reads the return address of the calling program or subroutine off the stack. 3. But the false return address executes the malicious hacker code — and you have been hacked!
A little more has to happen for the hacker to be successful, but you get the idea. When a hacker finds and exploits a vulnerable program, he gains access to your computer. Sometimes that access comes in the form of superuser (root) access! Yikes!
Here are some simple techniques you can use to minimize buffer overflows:
- Your first line of defense is simply to minimize the number of services you run. You run zero risk of compromise from a buffer-overflow vulnerability in any particular service if you don't run that service.
For example, the Lion worm wreaked havoc in Spring 2001. Lion took advantage of a vulnerability in the Linux sendmail and Lpd printer services. Computers that didn't run those services weren't vulnerable to the Lion worm.
- Your second defense is to update your Fedora Core computer as often as possible. Fedora Core posts package updates (as they become available) that fix vulnerabilities. Buffer overflow fixes comprise many of the package updates. Updating your system fixes many buffer overflow vulnerabilities.
Click the red exclamation button on the GNOME Panel to start the up2date service. You can also run the command yum update to accomplish the same function.
- Your last defense is the new stack-protection system named ExecShield. ExecShield places a canary in the stack. A canary is a number that, if overwritten by a buffer overflow, creates an invalid state for the calling software. The software that called the compromised subroutine sees the invalid state, and can decide to exit before any damage is done.
ExecShield is included in the Fedora Core kernel. When ExecShield is enabled, it prevents sections of a program, including its stack, from executing code or other programs. Some sections of a program (such as data) shouldn't be executable — and that includes the stack, of course.
ExecShield provides three modes of operation:
- Disabled: ExecShield is disabled and doesn't affect your computer's operation.
You manually configure Linux to disable ExecShield by logging in as root, starting the GNOME Terminal, and running this command:
echo 0 > /proc/sys/kernel/exec-shield
Alternatively, you can add the following option to the /etc/sysctl.conf configuration file to turn ExecShield off at boot time:
kernel.exec-shield = 0
- Enabled for marked binaries only: This mode, the default, enables only enabled programs (binaries) to work with ExecShield. You may want to use this mode with, for example, a Web server. You would protect your most vulnerable services with ExecShield and not worry about, for example, your Mozilla browser.
This mode of operation is the default for ExecShield. However, if you have changed to another mode, you can reset this mode by logging in as root, starting the GNOME Terminal, and running this command:
echo 1 > /proc/sys/kernel/exec-shield
- Enabled for all binaries: In this mode, all programs on your computer use ExecShield. Because ExecShield is relatively new, this mode is recommended only for experimenting.
You can manually configure Linux to use this higher level of security by logging in as root, starting the GNOME Terminal, and running the command echo 2 > /proc/sys/kernel/exec-shield. Alternatively, you can add the option kernel.exec-shield = 2 to the /etc/sysctl.conf configuration file to set ExecShield to its maximum level at boot time.
 | You can find out whether a program is compatible with ExecShield. Use the program execstack to query and set programs to use ExecShield. For example, enter the command execstack -q / sbin/* and you see that a few files, such as GRUB, are compatible; the capital X in the first column indicates that the file has been compiled with the ExecShield hooks. You can set GRUB to use ExecShield by typing execstack -s /sbin/grub. You should eventually see more programs become ExecShield-compatible. |
ExecShield can also randomize the location where programs are loaded into your computer's virtual memory. A hacker can exploit the knowledge of where a program is loaded into your computer's memory. Linux loads programs at fairly predictable locations, but ExecShield mostly fixes the problem.
ExecShield randomizes Linux memory by default. Woo-hoo! You can manually configure the ExecShield random function: Log in as root, start the GNOME Terminal, and run the command echo 1 > /proc/sys/kernel/exec-shield-randomize. Alternatively, you can add the line kernel.exec-shield-randomize = 1 (or 0) to /etc/sysctl.conf to automate the process at boot time.
|