Re: A way to prevent buffer overflow exploits? (was: "Any user can

From: Crispin Cowan (crispinat_private)
Date: Fri Aug 07 1998 - 11:21:05 PDT

  • Next message: Casper Dik: "Re: Solaris 2.5.1/2.6 fingerd bug"

    Kragen wrote:
    
    > On Wed, 5 Aug 1998, Crispin Cowan wrote:
    > > <randomizing stack locations>
    > > It is also faster than the StackGuard approach, but probably not as effective.
    > > In particular, if the attacker uses the technique mentioned above, then they
    > > don't have to point the return address at a fixed point within the stack.
    > > StackGuard, on the other hand, will detect any buffer overflow that corrupts
    > > the return address.
    > As has occasionally been pointed out before, buffer overflows don't
    > need to overwrite a return address to be dangerous.  If you can
    > overwrite a pointer to a function, a pointer to a structure containing
    > a pointer to a function, etc., you can still execute arbitrary code.
    
    We're working on an extension to StackGuard to address that problem.  The idea is
    to place canaries next to other data structures that you care about.  This is hard,
    because you have to mess with the compiler's type system, but we're part-way
    through doing it.
    
    > Randomizing stack locations can make all of these a little more difficult.
    
    Depending on the flavor of stack randomization, it might.  The original proposal
    here is to start the stack at a random location, and otherwise leave it alone.
    That's easy to do, but will do absolutely nothing to prevent an overflow that, say,
    changes credential information.  It mostly makes it hard to aim code pointers at
    injected code fragments, because you don't know their absolute address.  If you can
    inject a BIG overflow, then you can use Aleph's NOP hack to partially overcome that
    problem.  You can also inject your attack code into a static buffer and aim your
    code pointer at that.
    
    There's multiple parts to this problem, and each technique treats one or more parts
    of the problem:
    
       * array bounds:  if you can prevent buffer overflows, you stop the problem at
         the source
       * critical data structures: if you can prevent or detect corruption of critical
         data structures (i.e. code pointers such as the stack return address, function
         pointers, longjmp buffers, etc., and other critical structures such as
         credential information, file paths, etc.) then you can prevent the attack from
         being exploited
       * injectable code:  the attacker can inject code into ANY buffer without
         overflowing it.  If you can make the absolute address of all such buffers hard
         to find, then it is hard for the attacker to point code pointers at the buffer
         with the attack code
       * resident code: the attacker doesn't necessarily have to inject code if the
         right code is already resident in the victim program.  For instance, if the
         program already does "exec(mumble)" somewhere in there, then there is code in
         there that calls the exec() system call.  The attacker can alter data and then
         jump to that resident code.
    
    > The bounds-checking folks are optimistic that bounds-checking can be
    > made much faster.  ATM, it's 50%-80% overhead in general.
    
    That's interesting.  Why do they think they can make such huge strides in the cost
    of bounds checking?
    
    I'd be impressed if they could make huge strides in stability, so that a
    bounds-checking C compiler could actually compile and run a sophisticated program.
    I have been unable to reproduce the BIND experiment where a bounds-checked BIND was
    said to run, but very slowly.  Our experience with the Jones & Kelly
    bounds-checking compiler is that non-trivial programs compiled with it just die.  I
    would be very happy to be pointed to a bounds-checking compiler that is stable.  I
    mean no disrespect to Jones & Kelly, as I understand that bounds-checking is
    VERY difficult in C, and I'm impressed with how far they got with it.
    
    Crispin
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:11:44 PDT