* Crispin Cowan ([EMAIL PROTECTED]) [990830 19:47]:

First, I want to make clear that I'm not involved in the development
of Stack Shield. Anyway, I wrote a very similar tool some time ago,
but stopped the development because of some very nasty problems. I
will comment on these problems, that are present in Stack Shield, too. 

> [...]

> Similar to StackGuard, Stack Shield hacks the prolog and epilog
> functions to implement the defense, but instead of the StackGuard
> mechanism of instrumenting the main stack, Stack Shield copies the
> return addresses to the secondary stack.  Upon return, the hacked
> epilog compares the return address on the secondary stack to that on
> the main stack.  If they match, the return proceeds normally, and if
> they don't match, Stack Shield patches the main stack with the
> (presumably safe) return address from the secondary stack.

This, of course, is a design flaw. The assumption, that a program
while survive a stack smashing attack by just correcting the return
address is somewhat optimistic. Therefore, one should use the
StackGuard approach and abort the program (with some cool logging).

> [...]

> Perhaps I don't see your point. How is this more secure than StackGuard?

You're right. StackGuard is at least as secure as Stack Shield. In
some very rare cases, StackGuard is more secure, since it can detect
buffer overflow attacks that don't change the return address, but only
the state of the program! This type of attack goes undetected when
using Stack Shield.

> On some other not-quite-security issues:
> 
>    * Compatability:
>         o Stack Shield has a fixed size buffer for the secondary stack.
>           Deeply recursive programs will bust this buffer.

This is the first nasty problem. I was about to implement a second
stack that grows automatically. This is not really hard to implement,
but is operating system dependent and some work to get it right. 

> [...]

>         o Stack Shield is an outboard post-processor.  This would be a
>           HUGE compatability advantage, except that it appears to be a
>           post-processor for assembly source files.  Thus, you still
>           need to have source code for the program to be protected.  You
>           also have to extensively hack make files to insert Stack
>           Shield in the middle of compiling each file.  The path of .c
>           -> .o -> executable becomes .c -> .s -> stack shield -> .o ->
>           executable.  From our experience re-building all of Red Hat
>           Linux with StackGuard, you can trust me that this will become
>           an issue :-)

This can be avoided if one hacks the compiler instead of supplying a
new post-processor. I used this approach. Although I have not finished
the hack to work in every possible optimization mode (though it's not
hard to do), it works fine in most cases. The hack itself is very
short (less than 100 lines of code) and it took me about 3 hours to
locate the right spot in the gcc code, change, compile and test it.

> [...]

>    * Performance:  Stack Shield does a copy to the secondary stack and
>      an increment in the prolog, and a compare and decrement in the
>      epilog.  This is essentially similar to the workload imposed by
>      StackGuard using the "Random Canary" defense, where we have an
>      outboard table of 128 random numbers that are statically
>      modulo-mapped to functions.  StackGuard in "Terminator Canary" mode
>      (where the "canary" word is -1 (EOF), CR, LF, and 0; the set of
>      common string function terminators) is likely to be faster.

During my tests, I found that my method produces an overhead in
between of 7% and 13% in total execution time on most programs. As I
recall your paper on StackGuard [1], your figures were somewhat
larger, even though I would expect your method to be faster.

So, why would one use the approach of saving the return address on
another stack, instead of patching the stack itself, like StackGuard?
The only reason I can imagine, is that one does not want to change the 
stack layout. The benefit of not changing the stack layout, is that
you can do the change outside of the compiler. I was about to write a
binary translator, that reads an executeable, locates every function
prolog and epilog, adds the nescessary code to detect buffer
overflows, and writes a new version of the executeable. By using this
approach, one could make existing executeables safe against (most)
buffer overflows. The cost would be minimal, since the translator must 
only run once and the overhead of the proposed method is about 10% on
average. (The reason for me to change the compiler was to check
whether the approach works and to measure the induced overhead).

Writing such a translator is possible, since there are examples of
working tools that do similar things (Purify [2], Etch [3], ...). 
Anyway, doing this is a lot of work, therefore, I'm currently trying
to find a skeleton for the translator, instead of writing one from
scratch. If someone has a working translator on hand, I'm very
interested in getting the source code to continue on this project.


References
----------

[1] Crispin Cowan, Calton Pu, Dave Maier, Hether Hinton, Jonathan
Walpole, Peat Bakke, Steve Battie, Aaron Grier, Perry Wagle, Qian
Zhang, "StackGuard: Automatic Adaptive Detection and Prevention of
Buffer-Overflow Attacks", Proceedings of the 7th USENIX Security
Conference, January 1998

[2] Reed Hastings, Bob Joyce, "Purify: Fast Detection of Memory Leaks
and Access Errors", Proceedings of the Winter 1992 USENIX Conference,
pp. 125-136, January 1992

[3] Ted Romer, Geoff Voelker, Dennis Lee, Alec Wolman, Wayne Wonk,
Hank Levy, Brian Bershad, Brad Chen, "Instrumentation and Optimization
of Win32/Intel Executeables Using Etch", Proceedings of the USENIX
Windows NT Workshop.  pp. 1-7.  August 1997


Ciao,

Tobias

-- 
Dipl. Inform. Tobias Haustein

Department of Computer Science IV, Aachen University of Technology
Ahornstr. 55, D-52056 Aachen
Phone +49 (241) 80-21417, Fax +49 (241) 8888-220
E-Mail [EMAIL PROTECTED]
Web http://www-i4.informatik.rwth-aachen.de/~haustein/

PGP signature

Reply via email to