Re: Solaris libc exploit

From: Casper Dik (casperat_private)
Date: Mon May 24 1999 - 13:29:49 PDT

  • Next message: aleph1at_private: "New Allaire Security Zone Bulletins and KB Articles"

    >Several people have posted stating that turning off executing on the
    >stack solves the problem. Folks, just because it stops this exploit
    >does not mean it stops all exploits. Clever ones will work around
    >the stack execution issue.
    >
    >In any case some protection is better than none. So to turn off execution
    >on the stack in Solaris 2.6 and 7 add the following lines to /etc/system
    >and restart the system:
    >
    >* Turn off executable stacks (doesn't work on Solaris x86)
    >set noexec_user_stack = 1
    >set noexec_user_stack_log = 1
    
    
    If you don't scare easily, you may try hacking libc with adb.
    
    
    THIS IS NOT A SUN SUPPORTED SOLUTION; USE AT YOUR OWN RISK
    YOUR SYSTEM MAY BE RENDEDERED INOPERABLE BY FOLLOWING THE INSTRUCTIONS
    BELOW
    
    
    No 100% guarantee either, it seems to work around the problem.
    
    This is a SPARC only solution; perhaps someone can come up with similar
    code for IA32.
    
    Before we start to alter the system C library with libc make sure
    you have SUNWsutl installed:
    
    	$ pkginfo SUNWsutl; ls -l /usr/sbin/static
    	system      SUNWsutl       Static Utilities
    	total 4272
    	-r-xr-xr-x   3 root     bin       213908 Mar 17 22:56 cp
    	-r-xr-xr-x   3 root     bin       213908 Mar 17 22:56 ln
    	-r-xr-xr-x   3 root     bin       213908 Mar 17 22:56 mv
    	-r-sr-xr-x   1 root     bin       712652 Mar 17 22:58 rcp
    	-r-xr-xr-x   1 root     bin       762108 Mar 17 23:00 tar
    
    
    On quick examination, there appear to be two functions that overflow a
    buffer:
    
    	_real_setlocale
    	load_all_locales
    
    (You're advised to use a different working copy of libc and only replace
    libc carefully when you've tested the resutl using LD_LIBRARY_PATH)
    
    adb -w /lib/libc.so.1
    
    _real_setlocale,100?a^i
    
    (lot of output)
    
    you'll find for other library calls in quick quick succession):
    
    _real_setlocale+0x290:          cmp     %i0, 0x5
    _real_setlocale+0x294:          bne,a   _real_setlocale+0x324
    _real_setlocale+0x298:          ld      [%i2 + 0x9b0], %o0
    _real_setlocale+0x29c:          add     %fp, -0x6b8, %o0
    _real_setlocale+0x2a0:          call    _PROCEDURE_LINKAGE_TABLE_+0x2b8	******
    _real_setlocale+0x2a4:          ld      [%i2 + 0x9cc], %o1
    _real_setlocale+0x2a8:          add     %fp, -0x6b8, %o0
    _real_setlocale+0x2ac:          call    _PROCEDURE_LINKAGE_TABLE_+0x660 ******
    _real_setlocale+0x2b0:          mov     %l0, %o1
    _real_setlocale+0x2b4:          add     %fp, -0x6b8, %o0
    _real_setlocale+0x2b8:          call    _PROCEDURE_LINKAGE_TABLE_+0x660 ******
    _real_setlocale+0x2bc:          ld      [%i2 + 0x9d0], %o1
    _real_setlocale+0x2c0:          add     %fp, -0x6b8, %o0
    _real_setlocale+0x2c4:          call    _PROCEDURE_LINKAGE_TABLE_+0x264 ******
    _real_setlocale+0x2c8:          add     %fp, -0x750, %o1
    _real_setlocale+0x2cc:          orcc    %g0, %o0, %g0
    
    Change the second call to a nop (a 1 with six 0s):
    
    _real_setlocale+0x2ac?W1000000
    
    Check for nop:
    
    _real_setlocale+0x2ac?i
    _real_setlocale+0x2ac:          nop
    
    Similar for load_all_locales:
    
    load_all_locales+0x32c:         st      %o0, [%l0 + 0x4]
    load_all_locales+0x330:         ld      [%fp - 0x4c], %o0
    load_all_locales+0x334:         cmp     %l2, %o0
    load_all_locales+0x338:         bne     load_all_locales+0x3e4
    load_all_locales+0x33c:         add     %fp, -0x464, %o0
    load_all_locales+0x340:         call    _PROCEDURE_LINKAGE_TABLE_+0x2b8
    load_all_locales+0x344:         ld      [%i4 + 0x9d4], %o1
    load_all_locales+0x348:         add     %fp, -0x464, %o0
    load_all_locales+0x34c:         call    _PROCEDURE_LINKAGE_TABLE_+0x660
    load_all_locales+0x350:         ld      [%fp - 0x4], %o1
    load_all_locales+0x354:         add     %fp, -0x464, %o0
    load_all_locales+0x358:         call    _PROCEDURE_LINKAGE_TABLE_+0x660
    load_all_locales+0x35c:         ld      [%i4 + 0x9d8], %o1
    load_all_locales+0x360:         add     %fp, -0x464, %o0
    load_all_locales+0x364:         call    _PROCEDURE_LINKAGE_TABLE_+0x264
    load_all_locales+0x368:         add     %fp, -0x500, %o1
    load_all_locales+0x36c:         orcc    %g0, %o0, %g0
    load_all_locales+0x370:         bne     load_all_locales+0x390
    
    Nop the second call:
    
    load_all_locales+0x34c?W1000000
    load_all_locales+0x34c:         0x40011520      =       0x1000000
    ?i
    load_all_locales+0x34c:         nop
    
    
    These addresses apply to Solaris 7/SPARC (unpatched), 32 bit libc.
    
    
    The latest Solaris 2.6/SPARC libc patch differs only a little bit
    _real_setlocale+0x2b8, load_all_locales+0x34c
    
    Make sure to test the library before installing it and verify the addresses
    accordingly.
    
    To safely replace a library, do this:
    
    
    	cp modifiedlibc.so.1 /usr/lib/libc.so.1.new
    	cd /usr/lib
    	ln libc.so.1 libc.so.1.old
    	ln libc.so.1.new libc.so.1
    
    Make sure to remove libc.so.1.old or place it outside usr/lib as the runtime
    linker can accept it as LD_PRELOAD in which case you'd be back at sq 1.
    
    
    Casper
    



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