The Visual C .NET GS Option

The Visual C++ .NET /GS Option

The Visual C++ .NET /GS option is a cool new compiler setting that sets up a canary between any variables declared on the stack and the EBP pointer, return address pointer, and the function-specific exception handler. What the /GS option does is prevent simple stack overruns from becoming exploitable.

NOTE
The /GS option is similar to StackGuard, created by Crispin Cowan (and others), which is available at http://www.immunix.org. StackGuard was designed to protect apps compiled with gcc. The /GS option isn't a port of StackGuard; the two were developed independently.

Wow that's fairly cool. Does this mean we can just buy Visual C++ .NET, happily compile with /GS, and never have to worry about overflows ever again? No. There are a number of attacks that neither /GS nor StackGuard will stop. Let's take a look at several of the ways that an overflow can be used to change program execution. (This text is taken from an excellent internal document by the Microsoft Office security team.)

  • Stack smashing

    The standard method of overflowing a buffer to change a function's return address this one is stopped cold by /GS.

  • Pointer subterfuge

    Overwriting a local pointer in order to later place data at a specific location /GS can't stop this, unless the specific location is a return address.

  • Register attack

    Overwriting the stored value of a register (such as ebp) so as to later gain control might be stopped some of the time.

  • VTable hijacking

    Changing a local object pointer such that a Vtable call launches a payload /GS typically will not help with this. One interesting aspect of /GS is that it can rearrange the order in which variables are declared on the stack to make the more dangerous arrays appear next to the canary value, thereby preventing some attacks of this nature. Note that VTable hijacking can also occur because of other types of overflows.

  • Exception handler clobbering

    Overwriting an exception record to divert the handler to your payload /GS also won't help with this one, although it will in future versions.

  • Index out of range

    Taking advantage of an array index that is not range-checked unless you choose to modify a return address, /GS won't help you here.

  • Heap overruns

    Getting the heap manager to do your evil bidding /GS won't save you from this, either.

So, if /GS won't help you with all of these problems, what good is it? Stack integrity checking is only meant to stop problems that directly affect the integrity of the stack and, in particular, the return address information that would be pushed into the EIP and EBP registers. It does a fine job stopping exactly the problems it was designed to stop. It doesn't do very well with problems it was not designed to stop. Likewise, I can come up with convoluted examples involving multistage attacks to overcome /GS (or any stack protection scheme). I'm not especially worried about trying to stop problems in convoluted examples. I'm worried about trying to stop problems in real-world code.

Some of the problems that stack checking does stop are the most common. Take, for example, the off-by-one demonstration app earlier in this chapter. Any of us could have written that code on a bad day. The best argument I can make is documented by Crispin Cowan at http://immunix.org/stackguard.html in the several references cited at the bottom of the page. These papers show large numbers of real-world bugs that are stopped by a mere recompile.

Greg Hoglund argued on NTBUGTRAQ that we shouldn't allow ourselves to be sloppy just because we set /GS, and he's right. But let's take a look at the available resources we have to stop the problems:

  • Ban unsafe function calls

    Great step, but people still find ways to screw up, as I've outlined above.

  • Code reviews

    Another great step that finds lots of bugs, but the person who wrote the code isn't perfect and neither is the reviewer. The quality of a code review varies with the experience level of the reviewer and the amount of sleep she's had. There's also some degree of chance. A code sample Michael wrote had an off-by-one error that I caught. The code sample had already been run past several programmers who I know to be very sharp Michael included! and no one else had caught it.

  • Thorough testing

    Yet another great tool, but who among us has a perfect test plan?

  • Source code scanning tools

    These tools are in their infancy. The best part is that they are consistent and can review millions of lines of code quickly. The worst code-scanning tools aren't any better than grep strcpy *.c. Anyone good with Perl can do better than some of them. The best tools still miss a lot of problems. This is an area of active research and I fully expect the next generations to be much better, but it's a very hard problem, so don't expect too much any time soon.

I look at it like seat belts in a car. I try to keep my car well-maintained, keep its tires inflated, drive carefully, and use airbags and ABS brakes to help keep me safe. Just because I wear my seat belt doesn't mean I should go driving around like some maniac. The seat belt won't save me if I go plummeting off a 2000-foot cliff. But if, despite my best efforts, everything goes wrong one day, that seat belt just might keep me alive. Use the /GS switch the same way. Eliminate those unsafe calls, review your code, test your code, and use good code-scanning tools. Do all of that, and then set /GS to save you when all else has failed.

One other benefit that I've personally taken advantage of is that /GS causes certain types of problems to show up immediately. When used in conjunction with a solid test plan particularly with network applications stack checking can make the difference between spending hours chasing random, intermittent bugs and going right to the problem.

IMPORTANT
/GS is a small insurance policy and nothing more. It is no replacement for good, quality code.



Writing Secure Code
Writing Secure Code, Second Edition
ISBN: 0735617228
EAN: 2147483647
Year: 2001
Pages: 286

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