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 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