Re: Announcing RSX - non exec stack/heap module

From: Crispin Cowan (crispinat_private)
Date: Tue Jun 12 2001 - 17:41:21 PDT

  • Next message: SNS Advisory: "[SNS Advisory No.31] Trend Micro InterScan VirusWall for Windows NT 3.51 FtpSaveC*P.dll Buffer Overflow Vulnerability"

    Paul Starzetz wrote:
    
    > Crispin Cowan wrote:
    > > > It is not very hard to mmap the libc code as non-executable are into
    > > > main memory. After the regular programm code jumps into some libc
    > > > function, we can check in the gp() handler if the gp fault resulted from
    > > > jumping into the libc area by a ret (the target address should still be
    > > > on the stack) or by a regular call/jmp instruction.
    > >
    > > That's an interesting idea, but the performance penalty will be substantial.
    > > You will pay for (at least) two system calls per library call.  In early
    > > StackGuard research, we experimented with hardware protection methods that
    > > imposed 2 syscalls per function call, and the overhead was between 500% and
    > > 10,000%, which just isn't realistic for prodution use.
    >
    > Yes and no! I have written such a code for rsx. The overhead is more
    > precisely 1x page fault and 1x general protection fault + the emulation
    > code (jmp/call/ret), which is not equal to 2x syscall + emulation, but
    > indeed of similar magnitude. However it works.
    
    I presume that what you're doing here is to mark the library pages
    non-executable, and then make them executable when you get a page fault due to
    some code trying to make a library call.  If so, how do you distinguish between
    legitmate calls into the library, and bogus calls made by a buffer overflow?
    
    
    > Note that a simpler protection (but maybe not so effective) can be done
    > by means of ld.so. What does people mean if they talk about
    > ret-into-libc?
    
    "ret-into-libc" is just a common name for the technique.  It is not technically
    precise.  The general case is to change a function return address so that it
    jumps to code that does "exec(sh)".  The intructions that do this don't have to
    be in libc, and don't have to be in a library, they can be in the program's main
    executable body.  It's just convenient for the attacker to use libc, because libc
    necessarily has "exec(sh)" in it, and most programs link to libc.
    
    Making libc non-executable is effectively another level of obscurity defense.  It
    makes existing attack scripts break, but can be bypassed in most cases if the
    attacker is willing to take the time to find the right sequence of bytes
    somewhere in the body of the victim program.
    
    
    > So now assume we doesn't link the libc-plt to the real libc location -
    
    Same effect:  you deny the attacker access to the libc code body, forcing them to
    look elsewhere for a fairly common sequence of a half dozen bytes in an
    executable page.
    
    Thanks to Solar Designer for pointing out that my previous claim that
    non-executable stacks & heaps can "always" be bypassed is inaccurate.  They can
    often be bypassed, but not always.
    
    Crispin
    
    --
    Crispin Cowan, Ph.D.
    Chief Scientist, WireX Communications, Inc. http://wirex.com
    Security Hardened Linux Distribution:       http://immunix.org
    Available for purchase: http://wirex.com/Products/Immunix/purchase.html
    



    This archive was generated by hypermail 2b30 : Wed Jun 13 2001 - 11:47:23 PDT