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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 096649e7275b4dd061fab3b7331e93f66fdec709
4
- data.tar.gz: 483e8f15738e9b4297a702ee07c78b9f75381f6a
3
+ metadata.gz: 584499f88ee81a2448cdfeb678b7c3558547af44
4
+ data.tar.gz: 12b0b5b05463523515453d095dd4aa68fd5c989c
5
5
  SHA512:
6
- metadata.gz: 368763434ec2b93e957cbf596b36eeeddad7728170234dee6eaa72155e30f11d3826bc7503e22952005f2f10b6bc9cce0ad39769355cd1aeff59082d107db335
7
- data.tar.gz: a02679981f17023624c99887fd2c9677678c6e1148a302c0aa7e0b1ce17c292bad83810c6a56da2e4614853fd009702a740f5d87fb41eb935a18359592a233ad
6
+ metadata.gz: d91c67f78e7e1201b254d0ca9028697da033aea3e736a490462a24acebbbf8736b758f28e721baadc31b888585e79eaff8dc2d92a68b0fce0bec6f31905843c5
7
+ data.tar.gz: 6d03e8f451ba644ce2779e98712e9acb488438a028ebd7ccf717dec7a93c52dd8179425f73bfd5b5337e71f4ba0211cfd27574c61f4fef9ab40cfdb95320add9
data/lib/nexpose.rb CHANGED
@@ -62,6 +62,7 @@ require 'nexpose/ajax'
62
62
  require 'nexpose/api_request'
63
63
  require 'nexpose/common'
64
64
  require 'nexpose/creds'
65
+ require 'nexpose/shared_cred'
65
66
  require 'nexpose/data_table'
66
67
  require 'nexpose/device'
67
68
  require 'nexpose/engine'
@@ -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 |credconf|
325
- cred = Credential.new
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.0
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-12 00:00:00.000000000 Z
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