Solaris ld.so buffer overflow vulnerability

Overview

There is a buffer overflow vulnerability in the Solaris runtime linker, /lib/ld.so.1. A local user can gain elevated privileges if there are any dynamically linked, executable SUID/SGID programs in the filesystem.

On a typical Solaris installation most or all SUID/SGID programs are dynamically linked. The trend has been to completely move towards dynamically linked binaries due to Sun’s recommendation. Support for static binaries will be removed in Solaris 10.

Details

The environment variable LD_PRELOAD is used to force ld.so.1 to load the specified library during runtime linking. If a setuid or setgid program is being loaded, the value of this variable is checked to prevent a potential malicious user-defined library to be linked in. In this case the linker only accepts libraries located under certain trusted directories. The code doing this evaluation is most likely the point containing the “unchecked buffer”.

The buffer overflow happens if the LD_PRELOAD value starts and ends with a slash and contains about 1200 characters. An exploit won’t be presented here, but the existance of the vulnerability can be tested like this:

  $ LD_PRELOAD=/`perl -e 'print "A"x2000'`/ passwd
  ld.so.1: passwd: warning /AAAAAAA ... AAAAA/: open failed: illegal 
  insecure pathname
  Segmentation Fault (core dumped)

My test exploit for Solaris 9 / SPARC gets a root shell by setting the variable and starting /usr/bin/passwd. The exploit builds a fake stack frame and causes the linker to return to libc in order to defeat the nonexecutable stack protection. I haven’t produced an exploit for Intel platform, but according to Sun the vulnerability exists on both platforms.

Solution

Sun Microsystems was contacted on June 1st, 2003 and has released a fix for the flaw. A complete list of vulnerable Solaris versions and the fix can be found here:

   http://sunsolve.sun.com/pub-cgi/retrieve.pl?doc=fsalert/55680

Credits

The vulnerability was discovered by Jouko Pynnönen, Finland.