CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/scanner/ftp/ftp_login.rb
Views: 1904
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
require 'metasploit/framework/credential_collection'
7
require 'metasploit/framework/login_scanner/ftp'
8
9
class MetasploitModule < Msf::Auxiliary
10
include Msf::Exploit::Remote::Ftp
11
include Msf::Auxiliary::Scanner
12
include Msf::Auxiliary::Report
13
include Msf::Auxiliary::AuthBrute
14
15
def proto
16
'ftp'
17
end
18
19
def initialize
20
super(
21
'Name' => 'FTP Authentication Scanner',
22
'Description' => %q{
23
This module will test FTP logins on a range of machines and
24
report successful logins. If you have loaded a database plugin
25
and connected to a database this module will record successful
26
logins and hosts so you can track your access.
27
},
28
'Author' => 'todb',
29
'References' =>
30
[
31
[ 'CVE', '1999-0502'] # Weak password
32
],
33
'License' => MSF_LICENSE,
34
'DefaultOptions' => {
35
'ConnectTimeout' => 30
36
}
37
)
38
39
register_options(
40
[
41
Opt::Proxies,
42
Opt::RPORT(21),
43
OptBool.new('RECORD_GUEST', [ false, "Record anonymous/guest logins to the database", false])
44
])
45
46
register_advanced_options(
47
[
48
OptBool.new('SINGLE_SESSION', [ false, 'Disconnect after every login attempt', false]),
49
]
50
)
51
52
deregister_options('FTPUSER','FTPPASS') # Can use these, but should use 'username' and 'password'
53
@accepts_all_logins = {}
54
end
55
56
57
def run_host(ip)
58
print_status("#{ip}:#{rport} - Starting FTP login sweep")
59
60
cred_collection = build_credential_collection(
61
username: datastore['USERNAME'],
62
password: datastore['PASSWORD'],
63
prepended_creds: anonymous_creds
64
)
65
66
scanner = Metasploit::Framework::LoginScanner::FTP.new(
67
configure_login_scanner(
68
host: ip,
69
port: rport,
70
proxies: datastore['PROXIES'],
71
cred_details: cred_collection,
72
stop_on_success: datastore['STOP_ON_SUCCESS'],
73
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
74
max_send_size: datastore['TCP::max_send_size'],
75
send_delay: datastore['TCP::send_delay'],
76
connection_timeout: datastore['ConnectTimeout'],
77
ftp_timeout: datastore['FTPTimeout'],
78
framework: framework,
79
framework_module: self,
80
ssl: datastore['SSL'],
81
ssl_version: datastore['SSLVersion'],
82
ssl_verify_mode: datastore['SSLVerifyMode'],
83
ssl_cipher: datastore['SSLCipher'],
84
local_port: datastore['CPORT'],
85
local_host: datastore['CHOST']
86
)
87
)
88
89
scanner.scan! do |result|
90
credential_data = result.to_h
91
credential_data.merge!(
92
module_fullname: self.fullname,
93
workspace_id: myworkspace_id
94
)
95
if result.success?
96
credential_data[:private_type] = :password
97
credential_core = create_credential(credential_data)
98
credential_data[:core] = credential_core
99
create_credential_login(credential_data)
100
101
print_good "#{ip}:#{rport} - Login Successful: #{result.credential}"
102
else
103
invalidate_login(credential_data)
104
vprint_error "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status}: #{result.proof})"
105
end
106
end
107
108
end
109
110
111
# Always check for anonymous access by pretending to be a browser.
112
def anonymous_creds
113
anon_creds = [ ]
114
if datastore['RECORD_GUEST']
115
['IEUser@', 'User@', '[email protected]', '[email protected]' ].each do |password|
116
anon_creds << Metasploit::Framework::Credential.new(public: 'anonymous', private: password)
117
end
118
end
119
anon_creds
120
end
121
122
def test_ftp_access(user,scanner)
123
dir = Rex::Text.rand_text_alpha(8)
124
write_check = scanner.send_cmd(['MKD', dir], true)
125
if write_check and write_check =~ /^2/
126
scanner.send_cmd(['RMD',dir], true)
127
print_status("#{rhost}:#{rport} - User '#{user}' has READ/WRITE access")
128
return 'Read/Write'
129
else
130
print_status("#{rhost}:#{rport} - User '#{user}' has READ access")
131
return 'Read-only'
132
end
133
end
134
135
136
end
137
138