nexpose 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|