Path: blob/master/modules/auxiliary/scanner/portscan/ftpbounce.rb
21367 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary67# Order is important here8include Msf::Auxiliary::Report9include Msf::Auxiliary::Scanner10include Msf::Exploit::Remote::Ftp1112def initialize13super(14'Name' => 'FTP Bounce Port Scanner',15'Description' => %q{16Enumerate TCP services via the FTP bounce PORT/LIST17method.18},19'Author' => 'kris katterjohn',20'License' => MSF_LICENSE21)2223register_options([24OptString.new('PORTS', [true, "Ports to scan (e.g. 22-25,80,110-900)", "1-10000"]),25OptAddress.new('BOUNCEHOST', [true, "FTP relay host"]),26OptPort.new('BOUNCEPORT', [true, "FTP relay port", 21]),27OptInt.new('DELAY', [true, "The delay between connections, per thread, in milliseconds", 0]),28OptInt.new('JITTER', [true, "The delay jitter factor (maximum value by which to +/- DELAY) in milliseconds.", 0])29])3031deregister_options('RPORT')32end3334# No IPv6 support yet35def support_ipv6?36false37end3839def rhost40datastore['BOUNCEHOST']41end4243def rport44datastore['BOUNCEPORT']45end4647def run_host(ip)48ports = Rex::Socket.portspec_crack(datastore['PORTS'])49if ports.empty?50raise Msf::OptionValidateError.new(['PORTS'])51end5253jitter_value = datastore['JITTER'].to_i54if jitter_value < 055raise Msf::OptionValidateError.new(['JITTER'])56end5758delay_value = datastore['DELAY'].to_i59if delay_value < 060raise Msf::OptionValidateError.new(['DELAY'])61end6263return if not connect_login6465ports.each do |port|66# Clear out the receive buffer since we're heavily dependent67# on the response codes. We need to do this between every68# port scan attempt unfortunately.69while true70r = sock.get_once(-1, 0.25)71break if not r or r.empty?72end7374begin75# Add the delay based on JITTER and DELAY if needs be76add_delay_jitter(delay_value, jitter_value)7778host = (ip.split('.') + [port / 256, port % 256]).join(',')79resp = send_cmd(["PORT", host])8081if resp =~ /^5/82# print_error("Got error from PORT to #{ip}:#{port}")83next84elsif not resp85next86end8788resp = send_cmd(["LIST"])8990if resp =~ /^[12]/91print_good(" TCP OPEN #{ip}:#{port}")92report_service(:host => ip, :port => port)93end94rescue ::Exception95print_error("Unknown error: #{$!}")96end97end98end99end100101102