Nessus6 0.2.0 → 0.3.0

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: f946afee24ef43e6b6628db34f17781d12d4ee9c
4
- data.tar.gz: d143fca91c08c8cf0180f51410dc6e7fce95ffcf
3
+ metadata.gz: dcbf03fa0718601cfb9d3780f862eead39111c50
4
+ data.tar.gz: 3fd45dd455a363b77bfde3095048f123221c8686
5
5
  SHA512:
6
- metadata.gz: f79d967ef973421555e7bb5b6a0ca06bf342480f44de6a3c5b8c8943076f90f96aeacc143ba59599d094cf1387455b6b60cf7bc3b6f9ce0161e0b4ce12b90630
7
- data.tar.gz: 517c90f4d10b8b2fabc6050143b36c8a9acb974e58ccca8c604c79a25da353599758eda73355a6df880544da35350ba28e5064ddcbd065278ee16e7e05d647a6
6
+ metadata.gz: bfac592a8a198defceb5eaa15aaa1dfcbb18ec18390f81b2b9a55a9ac60f08e5185df79ed0b0900800ea872708f7bdc3eb3d635715972ccb602d2f79dd29b103
7
+ data.tar.gz: 16c0e2df32c239416b89ccd48676eb6a88757d619e495f7405b8dd9b1d8b875f22595b093c97125e5300b586534e973151b00457e809d2351eda04ac68600776
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'Nessus6'
4
+ require 'fileutils'
5
+ require 'logger'
6
+ require 'sqlite3'
7
+ require 'json'
8
+
9
+ # Global variables for the script / binary
10
+ @base_directory = '/opt/scanner'
11
+ @results_directory = "#{@base_directory}/results"
12
+ @send_mail = '/usr/lib/sendmail -t'
13
+
14
+ credentials = {
15
+ access_key: 'NA',
16
+ secret_key: 'NA'
17
+ }
18
+
19
+ nessus_location = {
20
+ ip: 'localhost',
21
+ port: '8834'
22
+ }
23
+
24
+ @append_results = "x-scanner|#{nessus_location[:ip]}"
25
+
26
+ # Prep work
27
+ @logger = Logger.new(STDOUT)
28
+ @logger.level = Logger::INFO
29
+
30
+ # Begin the main portion of the app
31
+ @logger.debug 'Creating Nessus API Client'
32
+ @client = Nessus6::Client.new credentials, nessus_location
33
+
34
+ @db = SQLite3::Database.new '/home/scripts/launched_nessus_scans.db'
35
+ @db.execute 'SELECT * FROM active_scans' do |row|
36
+ mapped_row = {
37
+ request_id: row[0],
38
+ method: row[1],
39
+ scan_uuid: row[2],
40
+ scan_id: row[3]
41
+ }
42
+ opts = { format: :csv }
43
+ mapped_row[:file_id] = @client.scan.export mapped_row[:scan_id], opts
44
+
45
+ # Lock it in a closure so we don't have to have a huge one liner
46
+ export_status = Proc.new { @client.scan.export_status mapped_row[:scan_id], mapped_row[:file_id] }
47
+ ready_status = { 'status' => 'ready' }
48
+ @logger.debug 'Waiting...' while export_status.call != ready_status
49
+
50
+ file = @client.scan.download mapped_row[:scan_id],
51
+ mapped_row[:file_id],
52
+ "#{@results_directory}/#{mapped_row[:request_id].csv}"
53
+
54
+ puts file
55
+ end
@@ -3,6 +3,29 @@
3
3
  require 'Nessus6'
4
4
  require 'fileutils'
5
5
  require 'logger'
6
+ require 'sqlite3'
7
+ require 'json'
8
+
9
+ def create_scan(scan_id_to_copy, opts)
10
+ @client.scan.copy scan_id_to_copy, opts
11
+ end
12
+
13
+ def launch_scan(target_scan_id, target_ip_addresses)
14
+ @logger.info 'Attempting to launch scan.'
15
+ begin
16
+ result = @client.scan.launch target_scan_id, target_ip_addresses
17
+ if result.key? 'scan_uuid'
18
+ @logger.info "Scan launched successfully. Scan has been assigned a UUID of #{result['scan_uuid']}."
19
+ result
20
+ else
21
+ @logger.info 'Failed to launch scan due to an unknown reason..'
22
+ false
23
+ end
24
+ rescue Nessus6::Error::InternalServerError
25
+ @logger.error 'Failed to launch scan. A scan is already running.'
26
+ false
27
+ end
28
+ end
6
29
 
7
30
  # Global variables for the script / binary
8
31
  @base_directory = '/opt/scanner'
@@ -21,34 +44,101 @@ nessus_location = {
21
44
  port: '8834'
22
45
  }
23
46
 
47
+ scan_templates = {
48
+ allportsnoping: 62,
49
+ allportswithping: 63,
50
+ atomic: 64,
51
+ default: 61,
52
+ pci: 60
53
+ }
54
+
24
55
  @append_results = "x-scanner|#{nessus_location[:ip]}"
25
56
 
26
- # Prep work
27
- FileUtils.mkdir_p @temp_directory
28
- @logger = Logger.new(STDOUT)
29
- @logger.level = Logger::INFO
57
+ begin
58
+ # Prep work
59
+ @logger = Logger.new(STDOUT)
60
+ @logger.level = Logger::INFO
61
+
62
+ @logger.info "Creating temporary directory: #{@temp_directory}"
63
+ FileUtils.mkdir_p @temp_directory
64
+
65
+ # Begin the main portion of the app
66
+ @logger.debug 'Creating Nessus API Client'
67
+ @client = Nessus6::Client.new credentials, nessus_location
68
+
69
+ # Loop through the directory and process each file in it.
70
+ Dir.foreach(@incoming_directory) do |file|
71
+ @logger.debug "Processing #{@incoming_directory}/#{file}"
72
+ next if file == '.' || file == '..' # skip current / parent directory opts
73
+
74
+ @logger.info "Archiving #{@incoming_directory}/#{file} to " \
75
+ "#{@base_directory}/targets/archive/#{file}."
76
+ FileUtils.copy "#{@incoming_directory}/#{file}",
77
+ "#{@base_directory}/targets/archive/#{file}"
78
+
79
+ @logger.info "Moving #{@incoming_directory}/#{file} to " \
80
+ "#{@temp_directory}/#{file}"
81
+ FileUtils.move "#{@incoming_directory}/#{file}",
82
+ "#{@temp_directory}/#{file}"
83
+
84
+ @logger.info 'Finding the target scan details (id, method, target ip).'
85
+ file_contents = File.open("#{@temp_directory}/#{file}") { |file| file.read }
86
+
87
+ # Take the request file and process each line individually
88
+ file_array = file_contents.split("\n")
89
+
90
+ request_id = []
91
+ method = []
92
+ ips = []
93
+
94
+ # Process the request file and find the Request ID, Method, and IP Addresses
95
+ file_array.each do |line|
96
+ if line =~ /requestid\:\t(?<request_id>\d+)/
97
+ request_id.push line[11..-1]
98
+ next
99
+ end
100
+ if line =~ /method\:\t(?<method>.+)/
101
+ method.push line[8..-1]
102
+ next
103
+ end
104
+ ips.push line[0..-3] if line =~ /^(?<ip>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\/\d$/
105
+ ips.push line[0..-4] if line =~ /^(?<ip>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\/\d\d$/
106
+ next
107
+ end
108
+
109
+ @logger.info "Found Request ID #{request_id[0]}; Found Method #{method[0]}; Found IP's #{ips}"
110
+
111
+ # Take the scan method and find the scan template UUID for it.
112
+ scan_template_id = scan_templates[method[0].to_sym]
113
+ scan_opts = { name: "Requested Scan ##{request_id[0]}", folder_id: 65,
114
+ history: 'false' }
115
+ scan = create_scan scan_template_id, scan_opts
116
+
117
+ # Attempt to launch a scan. If it fails, wait 30 seconds then repeat.
118
+ @result = launch_scan(scan['id'], ips)
119
+ while @result == false
120
+ sleep 30
121
+ @result = launch_scan(scan_id_to_launch, ips)
122
+ end
123
+
124
+ @logger.info 'Attempting to connect to database'
125
+
126
+ db = SQLite3::Database.new '/home/scripts/launched_nessus_scans.db'
30
127
 
31
- # Begin the main portion of the app
32
- @logger.debug 'Creating Nessus API Client'
33
- @client = Nessus6::Client.new credentials, nessus_location
128
+ @logger.debug "Create new db with: require 'sqlite3'; db = SQLite3::Database.new '/home/scripts/launched_nessus_scans.db'; rows = db.execute 'create table active_scans (request_id bigint, method varchar(200), scan_uuid varchar(250), scan_id integer);'"
34
129
 
35
- Dir.foreach(@incoming_directory) do |file|
36
- @logger.debug "Processing #{@incoming_directory}/#{file}"
37
- next if file == '.' || file == '..' # skip current / parent directory opts
130
+ @logger.info "Inserting scan UUID with 'INSERT INTO active_scans (request_id, method, scan_uuid, scan_id) VALUES (?, ?, ?, ?)', "\
131
+ "[#{request_id[0]}, #{method[0]}, #{@result['scan_uuid']}, #{scan['id']}]'"
38
132
 
39
- @logger.info "Archiving #{@incoming_directory}/#{file} to " \
40
- "#{@base_directory}/targets/archive/#{file}."
41
- # FileUtils.copy "#{@incoming_directory}/#{file}",
42
- # "#{@base_directory}/targets/archive/#{file}"
133
+ db.execute 'INSERT INTO active_scans (request_id, method, scan_uuid, scan_id) VALUES (?, ?, ?, ?)',
134
+ [request_id[0], method[0], @result['scan_uuid'], scan['id']]
43
135
 
44
- @logger.info "Moving #{@incoming_directory}/#{file} to " \
45
- "#{@temp_directory}/#{file}"
46
- # FileUtils.move "#{@incoming_directory}/#{file}",
47
- # "#{@temp_directory}/#{file}"
136
+ @logger.info 'Scan UUID saved successfully.'
48
137
 
49
- @logger.info 'Finding the request ID in the file.'
50
- request_id = File.readlines("#{@incoming_directory}/#{file}").select do |line|
51
- line =~ /^requestid.*$/
138
+ @logger.info "Removing the temporary scan file #{@temp_directory}/#{file}"
139
+ FileUtils.rm "#{@temp_directory}/#{file}"
52
140
  end
53
- puts request_id
141
+ ensure
142
+ @logger.info "Removing temp directory: #{@temp_directory}"
143
+ FileUtils.rm_rf "#{@temp_directory}"
54
144
  end
@@ -11,10 +11,9 @@ RESULTSDIR=${BASEDIR}/results
11
11
  SENDMAIL="/usr/lib/sendmail -t"
12
12
 
13
13
  NESSUSBIN=/opt/nessus/bin/nessus
14
- NESSUSUSER=scripts
14
+ NESSUSUSER=xxxx
15
15
  NESSUSPASSWORD=XXXXXXXXXXXXXXX
16
16
 
17
- IPADDR="153.39.86.90"
18
17
  APPENDRESULTS="x-scanner|${IPADDR}"
19
18
 
20
19
  mkdir -p ${TEMPDIR}
@@ -28,7 +28,7 @@ module Nessus6
28
28
  # @param scan_id [String, Fixnum] The id of the scan to export.
29
29
  # @param query_params [Hash] Includes:
30
30
  # :folder_id [String, Fixnum] - The id of the destination folder.
31
- # :history [TrueClass, FalseClass, String] - If true, the history for
31
+ # :history [String] - If true, the history for
32
32
  # the scan will be copied
33
33
  # :name [String] - The name of the copied scan
34
34
  # @return [Hash]
@@ -124,6 +124,17 @@ module Nessus6
124
124
  not_found: "Scan ID #{scan_id} could not be found. Please try again"
125
125
  end
126
126
 
127
+ # Check the file status of an exported scan.
128
+ # This request requires can view scan permissions.
129
+ #
130
+ # @param scan_id [String, Fixnum] The id of the scan to export
131
+ # @param file_id [String, Fixnum] The id of the file to poll (Included in response from /scans/{scan_id}/export).
132
+ def export_status(scan_id, file_id)
133
+ response = @client.get "scans/#{scan_id}/export/#{file_id}/status"
134
+ verify response,
135
+ not_found: "Scan ID #{scan_id} could not be found. Please try again"
136
+ end
137
+
127
138
  # Launches a scan.
128
139
  #
129
140
  # @param scan_id [String, Fixnum] The id of the scan to launch.
@@ -19,20 +19,20 @@ module Nessus6
19
19
  when 200
20
20
  return JSON.parse response.body
21
21
  when 400
22
- fail Nessus6::Error::BadRequestError, "#{message[:bad_request]}"
22
+ fail Nessus6::Error::BadRequestError, "#{message[:bad_request]} | Response: #{response.body}"
23
23
  when 401
24
- fail Nessus6::Error::UnauthorizedError, "#{message[:unauthorized]}"
24
+ fail Nessus6::Error::UnauthorizedError, "#{message[:unauthorized]} | Response: #{response.body}"
25
25
  when 403
26
- fail Nessus6::Error::ForbiddenError, "#{message[:forbidden]}"
26
+ fail Nessus6::Error::ForbiddenError, "#{message[:forbidden]} | Response: #{response.body}"
27
27
  when 404
28
- fail Nessus6::Error::NotFoundError, "#{message[:not_found]}"
28
+ fail Nessus6::Error::NotFoundError, "#{message[:not_found]} | Response: #{response.body}"
29
29
  when 405
30
- fail Nessus6::Error::MethodNotAllowedError, "#{message[:not_allowed]}"
30
+ fail Nessus6::Error::MethodNotAllowedError, "#{message[:not_allowed]} | Response: #{response.body}"
31
31
  when 409
32
- fail Nessus6::Error::ConflictError, "#{message[:conflict]}"
32
+ fail Nessus6::Error::ConflictError, "#{message[:conflict]} | Response: #{response.body}"
33
33
  when 500
34
34
  fail Nessus6::Error::InternalServerError,
35
- "#{message[:internal_server_error]}"
35
+ "#{message[:internal_server_error]} | Response: #{response.body}"
36
36
  else
37
37
  fail Nessus6::Error::UnknownError, 'An unknown error occurred. ' \
38
38
  'Please consult Nessus for further details.'
@@ -1,5 +1,5 @@
1
1
  # The Nessus6 module is used to interact with Nessus version 6 servers.
2
2
  module Nessus6
3
3
  # VERSION is the current version of the Nessus6 gem
4
- VERSION = '0.2.0'
4
+ VERSION = '0.3.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: Nessus6
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Kirsche
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-10-02 00:00:00.000000000 Z
11
+ date: 2015-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -110,6 +110,7 @@ files:
110
110
  - README.md
111
111
  - Rakefile
112
112
  - bin/console
113
+ - bin/export_nessus_results
113
114
  - bin/launch_incoming_scans
114
115
  - bin/launch_incoming_scans.sh
115
116
  - bin/setup