nexpose 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/nexpose.rb +1 -0
- data/lib/nexpose/common.rb +11 -0
- data/lib/nexpose/creds.rb +63 -0
- data/lib/nexpose/scan.rb +15 -1
- data/lib/nexpose/shared_cred.rb +209 -0
- data/lib/nexpose/site.rb +4 -6
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 584499f88ee81a2448cdfeb678b7c3558547af44
|
4
|
+
data.tar.gz: 12b0b5b05463523515453d095dd4aa68fd5c989c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d91c67f78e7e1201b254d0ca9028697da033aea3e736a490462a24acebbbf8736b758f28e721baadc31b888585e79eaff8dc2d92a68b0fce0bec6f31905843c5
|
7
|
+
data.tar.gz: 6d03e8f451ba644ce2779e98712e9acb488438a028ebd7ccf717dec7a93c52dd8179425f73bfd5b5337e71f4ba0211cfd27574c61f4fef9ab40cfdb95320add9
|
data/lib/nexpose.rb
CHANGED
data/lib/nexpose/common.rb
CHANGED
@@ -143,5 +143,16 @@ module Nexpose
|
|
143
143
|
schedule.repeater_type = xml.attributes['repeaterType'] if xml.attributes['repeaterType']
|
144
144
|
schedule
|
145
145
|
end
|
146
|
+
|
147
|
+
# Recurring schedule type constants. These are all the possible values which
|
148
|
+
# may be used to create a Schedule.
|
149
|
+
#
|
150
|
+
module Type
|
151
|
+
DAILY = 'daily'
|
152
|
+
HOURLY = 'hourly'
|
153
|
+
WEEKLY = 'weekly'
|
154
|
+
MONTHLY_DATE = 'monthly-date'
|
155
|
+
MONTHLY_DAY = 'monthly-day'
|
156
|
+
end
|
146
157
|
end
|
147
158
|
end
|
data/lib/nexpose/creds.rb
CHANGED
@@ -54,6 +54,15 @@ module Nexpose
|
|
54
54
|
@priv_password = password
|
55
55
|
end
|
56
56
|
|
57
|
+
def self.parse(xml)
|
58
|
+
cred = new
|
59
|
+
cred.service = xml.attributes['service']
|
60
|
+
cred.host = xml.attributes['host']
|
61
|
+
cred.port = xml.attributes['port']
|
62
|
+
cred.blob = xml.get_text
|
63
|
+
cred
|
64
|
+
end
|
65
|
+
|
57
66
|
def to_xml
|
58
67
|
to_xml_elem.to_s
|
59
68
|
end
|
@@ -91,6 +100,60 @@ module Nexpose
|
|
91
100
|
def hash
|
92
101
|
to_xml.hash
|
93
102
|
end
|
103
|
+
|
104
|
+
# Credential type options.
|
105
|
+
#
|
106
|
+
module Type
|
107
|
+
|
108
|
+
# Concurrent Versioning System (CVS)
|
109
|
+
CVS = 'cvs'
|
110
|
+
# File Transfer Protocol (FTP)
|
111
|
+
FTP = 'ftp'
|
112
|
+
# Web Site HTTP Authentication
|
113
|
+
HTTP = 'http'
|
114
|
+
# IBM AS/400
|
115
|
+
AS400 = 'as400'
|
116
|
+
# Lotus Notes/Domino
|
117
|
+
NOTES = 'notes'
|
118
|
+
# Microsoft SQL Server
|
119
|
+
TDS = 'tds'
|
120
|
+
# Sybase SQL Server
|
121
|
+
SYBASE = 'sybase'
|
122
|
+
# Microsoft Windows/Samba (SMB/CIFS)
|
123
|
+
CIFS = 'cifs'
|
124
|
+
# Microsoft Windows/Samba LM/NTLM Hash (SMB/CIFS)
|
125
|
+
CIFSHASH = 'cifshash'
|
126
|
+
# Oracle
|
127
|
+
ORACLE = 'oracle'
|
128
|
+
# Post Office Protocol (POP)
|
129
|
+
POP = 'pop'
|
130
|
+
# PostgreSQL
|
131
|
+
POSTGRESQL = 'postgresql'
|
132
|
+
# Remote Execution
|
133
|
+
REMOTE_EXECUTION = 'remote execution'
|
134
|
+
# Simple Network Management Protocol
|
135
|
+
SNMP = 'snmp'
|
136
|
+
# Secure Shell (SSH)
|
137
|
+
SSH = 'ssh'
|
138
|
+
# Secure Shell (SSH) Public Key
|
139
|
+
SSH_KEY = 'ssh-key'
|
140
|
+
# TELNET
|
141
|
+
TELNET = 'telnet'
|
142
|
+
# MySQL Server
|
143
|
+
MYSQL = 'mysql'
|
144
|
+
# DB2
|
145
|
+
DB2 = 'db2'
|
146
|
+
end
|
147
|
+
|
148
|
+
# Permission Elevation Types
|
149
|
+
#
|
150
|
+
module ElevationType
|
151
|
+
|
152
|
+
NONE = 'NONE'
|
153
|
+
SUDO = 'SUDO'
|
154
|
+
SUDOSU = 'SUDOSU'
|
155
|
+
SU = 'SU'
|
156
|
+
end
|
94
157
|
end
|
95
158
|
|
96
159
|
# Object that represents Header name-value pairs, associated with Web Session Authentication.
|
data/lib/nexpose/scan.rb
CHANGED
@@ -152,7 +152,7 @@ module Nexpose
|
|
152
152
|
# Retrieve the status of a scan.
|
153
153
|
#
|
154
154
|
# @param [Fixnum] scan_id The scan ID.
|
155
|
-
# @return [String] Current status of the scan.
|
155
|
+
# @return [String] Current status of the scan. See Nexpose::Scan::Status.
|
156
156
|
#
|
157
157
|
def scan_status(scan_id)
|
158
158
|
r = execute(make_xml('ScanStatusRequest', { 'scan-id' => scan_id }))
|
@@ -425,5 +425,19 @@ module Nexpose
|
|
425
425
|
scan.attributes['engine-id'].to_i)
|
426
426
|
end
|
427
427
|
end
|
428
|
+
|
429
|
+
# Scan status constants. These are all the possible values which may be
|
430
|
+
# returned by a #scan_status call.
|
431
|
+
#
|
432
|
+
module Status
|
433
|
+
RUNNING = 'running'
|
434
|
+
FINISHED = 'finished'
|
435
|
+
ABORTED = 'aborted'
|
436
|
+
STOPPED = 'stopped'
|
437
|
+
ERROR = 'error'
|
438
|
+
PAUSED = 'paused'
|
439
|
+
DISPATCHED = 'dispatched'
|
440
|
+
UNKNOWN = 'unknown'
|
441
|
+
end
|
428
442
|
end
|
429
443
|
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
module Nexpose
|
2
|
+
|
3
|
+
module NexposeAPI
|
4
|
+
|
5
|
+
def list_shared_credentials
|
6
|
+
creds = DataTable._get_json_table(self,
|
7
|
+
'/data/credential/shared/listing',
|
8
|
+
{ 'sort' => -1,
|
9
|
+
'table-id' => 'credential-listing' })
|
10
|
+
creds.map { |c| SharedCredentialSummary.from_json(c) }
|
11
|
+
end
|
12
|
+
|
13
|
+
alias_method :list_shared_creds, :list_shared_credentials
|
14
|
+
alias_method :shared_credentials, :list_shared_credentials
|
15
|
+
alias_method :shared_creds, :list_shared_credentials
|
16
|
+
|
17
|
+
def delete_shared_credential(id)
|
18
|
+
AJAX.post(self, "/data/credential/shared/delete?credid=#{id}")
|
19
|
+
end
|
20
|
+
|
21
|
+
alias_method :delete_shared_cred, :delete_shared_credential
|
22
|
+
end
|
23
|
+
|
24
|
+
class SharedCredentialSummary
|
25
|
+
|
26
|
+
# Unique ID assigned to this credential by Nexpose.
|
27
|
+
attr_accessor :id
|
28
|
+
# Name to identify this credential.
|
29
|
+
attr_accessor :name
|
30
|
+
# The credential type. See Nexpose::Credential::Type.
|
31
|
+
attr_accessor :type
|
32
|
+
# Domain or realm.
|
33
|
+
attr_accessor :domain
|
34
|
+
# User name.
|
35
|
+
attr_accessor :username
|
36
|
+
# User name to use when elevating permissions (e.g., sudo).
|
37
|
+
attr_accessor :privilege_username
|
38
|
+
# Boolean to indicate whether this credential applies to all sites.
|
39
|
+
attr_accessor :all_sites
|
40
|
+
# When this credential was last modified.
|
41
|
+
attr_accessor :last_modified
|
42
|
+
|
43
|
+
def self.from_json(json)
|
44
|
+
cred = new
|
45
|
+
cred.id = json['credentialID']['ID']
|
46
|
+
cred.name = json['name']
|
47
|
+
cred.type = json['service']
|
48
|
+
cred.domain = json['domain']
|
49
|
+
cred.username = json['username']
|
50
|
+
cred.privilege_username = json['privilegeElevationUsername']
|
51
|
+
cred.all_sites = json['scope'] == 'ALL_SITES_ENABLED_DEFAULT'
|
52
|
+
cred.last_modified = Time.at(json['lastModified']['time'] / 1000)
|
53
|
+
cred
|
54
|
+
end
|
55
|
+
|
56
|
+
# Delete this credential from the security console.
|
57
|
+
#
|
58
|
+
# @param [Connection] nsc An active connection to the security console.
|
59
|
+
#
|
60
|
+
def delete(nsc)
|
61
|
+
nsc.delete_shared_credential(@id)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class SharedCredential < SharedCredentialSummary
|
66
|
+
|
67
|
+
# Optional description of this credential.
|
68
|
+
attr_accessor :description
|
69
|
+
|
70
|
+
# Database or SID.
|
71
|
+
attr_accessor :database
|
72
|
+
# Windows/Samba LM/NTLM Hash.
|
73
|
+
attr_accessor :ntlm_hash
|
74
|
+
# Password or SNMP community name.
|
75
|
+
attr_accessor :password
|
76
|
+
# PEM-format private key.
|
77
|
+
attr_accessor :pem_key
|
78
|
+
# Password to use when elevating permissions (e.g., sudo).
|
79
|
+
attr_accessor :privilege_password
|
80
|
+
# Permission elevation type. See Nexpose::Credential::ElevationType.
|
81
|
+
attr_accessor :privilege_type
|
82
|
+
|
83
|
+
# IP address or host name to restrict this credential to.
|
84
|
+
attr_accessor :host
|
85
|
+
# Single port to restrict this credential to.
|
86
|
+
attr_accessor :port
|
87
|
+
|
88
|
+
# Array of site IDs that this credential is restricted to.
|
89
|
+
attr_accessor :sites
|
90
|
+
# Array of sites where this credential has been temporarily disabled.
|
91
|
+
attr_accessor :disabled
|
92
|
+
|
93
|
+
def initialize(name, id = -1)
|
94
|
+
@name, @id = name, id.to_i
|
95
|
+
@sites = []
|
96
|
+
@disabled = []
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.load(nsc, id)
|
100
|
+
response = AJAX.get(nsc, "/data/credential/shared/get?credid=#{id}")
|
101
|
+
parse(response)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Save this credential to the security console.
|
105
|
+
#
|
106
|
+
# @param [Connection] nsc An active connection to a Nexpose console.
|
107
|
+
# @return [Boolean] Whether the save succeeded.
|
108
|
+
#
|
109
|
+
def save(nsc)
|
110
|
+
response = AJAX.post(nsc, '/data/credential/shared/save', to_xml)
|
111
|
+
!!(response =~ /success="1"/)
|
112
|
+
end
|
113
|
+
|
114
|
+
def to_xml
|
115
|
+
xml = '<Credential '
|
116
|
+
xml << %( id="#{@id}">)
|
117
|
+
|
118
|
+
xml << %(<Name>#{@name}</Name>)
|
119
|
+
xml << %(<Description>#{@description}</Description>)
|
120
|
+
|
121
|
+
xml << %(<Services><Service type="#{@type}"></Service></Services>)
|
122
|
+
|
123
|
+
xml << '<Account type="nexpose">'
|
124
|
+
xml << %(<Field name="database">#{@database}</Field>)
|
125
|
+
xml << %(<Field name="domain">#{@domain}</Field>)
|
126
|
+
xml << %(<Field name="username">#{@username}</Field>)
|
127
|
+
xml << %(<Field name="ntlmhash">#{@ntlm_hash}</Field>) if @ntlm_hash
|
128
|
+
xml << %(<Field name="password">#{@password}</Field>) if @password
|
129
|
+
xml << %(<Field name="pemkey">#{@pem_key}</Field>) if @pem_key
|
130
|
+
xml << %(<Field name="privilegeelevationusername">#{@privilege_username}</Field>)
|
131
|
+
xml << %(<Field name="privilegeelevationpassword">#{@privilege_password}</Field>) if @privilege_password
|
132
|
+
xml << %(<Field name="privilegeelevationtype">#{@privilege_type}</Field>) if @privilege_type
|
133
|
+
xml << '</Account>'
|
134
|
+
|
135
|
+
xml << '<Restrictions>'
|
136
|
+
xml << %(<Restriction type="host">#{@host}</Restriction>) if @host
|
137
|
+
xml << %(<Restriction type="port">#{@port}</Restriction>) if @port
|
138
|
+
xml << '</Restrictions>'
|
139
|
+
|
140
|
+
xml << %(<Sites all="#{@all_sites ? 1 : 0}">)
|
141
|
+
@sites.each do |site|
|
142
|
+
xml << %(<Site id="#{site}")
|
143
|
+
xml << ' enabled="0"' if @disabled.member? site
|
144
|
+
xml << '></Site>'
|
145
|
+
end
|
146
|
+
if @sites.empty?
|
147
|
+
@disabled.each do |site|
|
148
|
+
xml << %(<Site id="#{site}" enabled="0"></Site>)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
xml << '</Sites>'
|
152
|
+
|
153
|
+
xml << '</Credential>'
|
154
|
+
end
|
155
|
+
|
156
|
+
def self.parse(xml)
|
157
|
+
rexml = REXML::Document.new(xml)
|
158
|
+
rexml.elements.each('Credential') do |c|
|
159
|
+
cred = new(c.elements['Name'].text, c.attributes['id'].to_i)
|
160
|
+
|
161
|
+
desc = c.elements['Description']
|
162
|
+
cred.description = desc.text if desc
|
163
|
+
|
164
|
+
c.elements.each('Account/Field') do |field|
|
165
|
+
case field.attributes['name']
|
166
|
+
when 'database'
|
167
|
+
cred.database = field.text
|
168
|
+
when 'domain'
|
169
|
+
cred.domain = field.text
|
170
|
+
when 'username'
|
171
|
+
cred.username = field.text
|
172
|
+
when 'password'
|
173
|
+
cred.password = field.text
|
174
|
+
when 'ntlmhash'
|
175
|
+
cred.ntlm_hash = field.text
|
176
|
+
when 'pemkey'
|
177
|
+
cred.pem_key = field.text
|
178
|
+
when 'privilegeelevationusername'
|
179
|
+
cred.privilege_username = field.text
|
180
|
+
when 'privilegeelevationpassword'
|
181
|
+
cred.privilege_password = field.text
|
182
|
+
when 'privilegeelevationtype'
|
183
|
+
cred.privilege_type = field.text
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
service = REXML::XPath.first(c, 'Services/Service')
|
188
|
+
cred.type = service.attributes['type']
|
189
|
+
|
190
|
+
c.elements.each('Restrictions/Restriction') do |r|
|
191
|
+
cred.host = r.text if r.attributes['type'] == 'host'
|
192
|
+
cred.port = r.text.to_i if r.attributes['type'] == 'port'
|
193
|
+
end
|
194
|
+
|
195
|
+
sites = REXML::XPath.first(c, 'Sites')
|
196
|
+
cred.all_sites = sites.attributes['all'] == '1'
|
197
|
+
|
198
|
+
sites.elements.each('Site') do |site|
|
199
|
+
site_id = site.attributes['id'].to_i
|
200
|
+
cred.sites << site_id unless cred.all_sites
|
201
|
+
cred.disabled << site_id if site.attributes['enabled'] == '0'
|
202
|
+
end
|
203
|
+
|
204
|
+
return cred
|
205
|
+
end
|
206
|
+
nil
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
data/lib/nexpose/site.rb
CHANGED
@@ -101,7 +101,8 @@ module Nexpose
|
|
101
101
|
# The risk factor associated with this site. Default: 1.0
|
102
102
|
attr_accessor :risk_factor
|
103
103
|
|
104
|
-
# [Array] Collection of credentials associated with this site.
|
104
|
+
# [Array] Collection of credentials associated with this site. Does not
|
105
|
+
# include shared credentials.
|
105
106
|
attr_accessor :credentials
|
106
107
|
|
107
108
|
# [Array] Collection of real-time alerts.
|
@@ -321,11 +322,8 @@ module Nexpose
|
|
321
322
|
site.exclude << HostName.new(host.text)
|
322
323
|
end
|
323
324
|
|
324
|
-
s.elements.each('Credentials/adminCredentials') do |
|
325
|
-
|
326
|
-
cred.service = credconf.attributes['service']
|
327
|
-
cred.set_blob(credconf.get_text)
|
328
|
-
site.credentials << cred
|
325
|
+
s.elements.each('Credentials/adminCredentials') do |cred|
|
326
|
+
site.credentials << Credential.parse(cred)
|
329
327
|
end
|
330
328
|
|
331
329
|
s.elements.each('ScanConfig') do |scan_config|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nexpose
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- HD Moore
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-09-
|
13
|
+
date: 2013-09-16 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: librex
|
@@ -78,6 +78,7 @@ files:
|
|
78
78
|
- lib/nexpose/alert.rb
|
79
79
|
- lib/nexpose/silo.rb
|
80
80
|
- lib/nexpose/vuln_exception.rb
|
81
|
+
- lib/nexpose/shared_cred.rb
|
81
82
|
- lib/nexpose/user.rb
|
82
83
|
- lib/nexpose/tags
|
83
84
|
- lib/nexpose/connection.rb
|