Re: Defeating Solar Designer non-executable stack patch

From: der Mouse (mouseat_private)
Date: Wed Feb 04 1998 - 12:10:08 PST

  • Next message: Andy Church: "Re: Defeating Solar Designer non-executable stack patch"

    I've just read over Rafal Wojtczuk's most informative and clever little
    article about how to leverage a buffer overrun even on a system
    protected by Solar Designer's patch to remove the execute bits from the
    stack.
    
    The first thing I'd like to say is to thank him(?) for this article.
    Clever and thought-provoking.
    
    The next thing I'd like to say is to observe the elaborateness
    involved.  An attack such as described involves quite a lot of
    investigation on the target system and several addresses that must be
    gotten exactly right and must not happen to contain NUL bytes.  This
    means that - even though it is not a perfect defense - Solar Designer's
    patch *does* harden a system significantly and is still worth applying
    (at least for systems for which it ever was considered worth applying;
    all its downsides are still there, of course).  (In all fairness, Rafal
    did realize and mention the precision required.)
    
    >   Section X. Any solutions - continued
    >   Well, if
    >      a) we can protect data segments from being executed
    >      b) we force LD_BIND_NOW - like dynamic linking, which enables us to
    >         mprotect GOT non-writable
    > both exploits will fail.
    
    True.  And if you're willing to pay the price of two more syscalls per
    dynamic-linker resolution, you can get lazy binding *and* have all the
    security benefits of (b).  All you need is for the dynamic linker to
    leave the GOT read-only, then use mprotect to re-protect it just before
    and after it snaps the pointer to the real routine.  This would make it
    (almost) impossible to attack through the GOT, since it's not
    modifiable except for a very brief time deep within the guts of the
    dynamic linker.  (Sure, if you can get your code executed, you can
    re-mprotect it - but if you can do that, you're home free anyway.)
    
    >   The best solution would be to mmap text segment ( accompanied by
    > PLT and GOT ) under 16MB boundary.  But it's impossible, right ?
    > Code of applications is not position independent.
    
    This would mean a linker change, so that user-land programs get linked
    with the text segment in low memory.  If the linker is careful to link
    the PLT and GOT early (eg, right after crt0), you can ensure *it* is
    below 16M even if the text segment is over 16M.
    
    An idea which should stop these scribbling attacks cold is this: put
    guard bytes above and below the return address on the stack - and use
    0x00 as the guard bytes.  Then the function epilogue/return code checks
    for these 0x00 bytes and if it doesn't find them it does something
    appropriate for a garbaged return address - a deliberate segfault,
    perhaps, or a halt-cpu instruction (which certainly ought to be
    sufficiently illegal for user-land code!).  The point, of course, is
    that you would have to find a way to overwrite the return address
    without disturbing the NULs, which is very hard when using routines
    like strcpy or sprintf, the favorites of smash-the-stack attacks, since
    they stop at NULs.
    
    Does anyone know of any common routine which (a) has an unlimited-size
    interface and (b) is capable of writing user-supplied data containing
    NULs into the target area?  (Even if such a routine is found, merely
    getting the exploit string to it intact is nontrivial, since NULs also
    cannot be present in things like environment variables.)
    
                                            der Mouse
    
                                   mouseat_private
                         7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 13:41:38 PDT