Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/scanner/nexpose/nexpose_api_login.rb
28052 views
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
)
31
end
32
33
def run_host(ip)
34
begin
35
res = send_request_cgi({
36
'uri' => datastore['URI'],
37
'method' => 'GET'
38
}, 25)
39
http_fingerprint({ :response => res })
40
rescue ::Rex::ConnectionError => e
41
vprint_error("#{datastore['URI']} - #{e.to_s}")
42
return
43
end
44
45
if not res
46
vprint_error("#{datastore['URI']} - No response")
47
return
48
end
49
if res.code != 200
50
vprint_error("Did not get 200 for API XML interface")
51
return
52
end
53
54
each_user_pass do |user, pass|
55
do_login(user, pass)
56
end
57
end
58
59
def report_cred(opts)
60
service_data = {
61
address: opts[:ip],
62
port: opts[:port],
63
service_name: opts[:service_name],
64
protocol: 'tcp',
65
workspace_id: myworkspace_id
66
}
67
68
credential_data = {
69
origin_type: :service,
70
module_fullname: fullname,
71
username: opts[:user],
72
private_data: opts[:password],
73
private_type: :password
74
}.merge(service_data)
75
76
login_data = {
77
last_attempted_at: Time.now,
78
core: create_credential(credential_data),
79
status: Metasploit::Model::Login::Status::SUCCESSFUL,
80
proof: opts[:proof]
81
}.merge(service_data)
82
83
create_credential_login(login_data)
84
end
85
86
def do_login(user = 'nxadmin', pass = 'nxadmin')
87
vprint_status("Trying username:'#{user}' with password:'#{pass}'")
88
headers = {
89
'Content-Type' => 'text/xml'
90
}
91
data = '<?xml version="1.0" encoding="UTF-8"?><LoginRequest sync-id="1" user-id="' << user << '" password="' << pass << '"></LoginRequest>'
92
begin
93
res = send_request_cgi({
94
'encode' => true,
95
'uri' => datastore['URI'],
96
'method' => 'POST',
97
'headers' => headers,
98
'data' => data
99
}, 25)
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