risu 1.4.3

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.
Files changed (47) hide show
  1. data/KNOWNISSUES.markdown +50 -0
  2. data/LICENSE +25 -0
  3. data/NEWS.markdown +112 -0
  4. data/README.markdown +126 -0
  5. data/Rakefile +37 -0
  6. data/TODO.markdown +69 -0
  7. data/bin/risu +12 -0
  8. data/lib/nessusdb.rb +38 -0
  9. data/lib/nessusdb/cli.rb +9 -0
  10. data/lib/nessusdb/cli/application.rb +402 -0
  11. data/lib/nessusdb/cli/banner.rb +25 -0
  12. data/lib/nessusdb/exceptions.rb +8 -0
  13. data/lib/nessusdb/exceptions/invaliddocument.rb +10 -0
  14. data/lib/nessusdb/listener.rb +274 -0
  15. data/lib/nessusdb/models.rb +18 -0
  16. data/lib/nessusdb/models/familyselection.rb +12 -0
  17. data/lib/nessusdb/models/host.rb +359 -0
  18. data/lib/nessusdb/models/individualpluginselection.rb +14 -0
  19. data/lib/nessusdb/models/item.rb +183 -0
  20. data/lib/nessusdb/models/plugin.rb +98 -0
  21. data/lib/nessusdb/models/pluginspreference.rb +12 -0
  22. data/lib/nessusdb/models/policy.rb +17 -0
  23. data/lib/nessusdb/models/reference.rb +13 -0
  24. data/lib/nessusdb/models/report.rb +26 -0
  25. data/lib/nessusdb/models/serverpreference.rb +13 -0
  26. data/lib/nessusdb/models/version.rb +12 -0
  27. data/lib/nessusdb/nessusdocument.rb +66 -0
  28. data/lib/nessusdb/parsers.rb +8 -0
  29. data/lib/nessusdb/prawn_templater.rb +38 -0
  30. data/lib/nessusdb/schema.rb +145 -0
  31. data/lib/nessusdb/templates/assets.rb +21 -0
  32. data/lib/nessusdb/templates/cover_sheet.rb +42 -0
  33. data/lib/nessusdb/templates/data/nessuslogo.jpg +0 -0
  34. data/lib/nessusdb/templates/exec_summary.rb +56 -0
  35. data/lib/nessusdb/templates/executive_summary.rb +182 -0
  36. data/lib/nessusdb/templates/finding_statistics.rb +23 -0
  37. data/lib/nessusdb/templates/findings_host.rb +49 -0
  38. data/lib/nessusdb/templates/findings_summary.rb +68 -0
  39. data/lib/nessusdb/templates/findings_summary_with_pluginid.rb +68 -0
  40. data/lib/nessusdb/templates/graphs.rb +33 -0
  41. data/lib/nessusdb/templates/host_summary.rb +40 -0
  42. data/lib/nessusdb/templates/ms_patch_summary.rb +37 -0
  43. data/lib/nessusdb/templates/ms_update_summary.rb +43 -0
  44. data/lib/nessusdb/templates/pci_compliance.rb +66 -0
  45. data/lib/nessusdb/templates/technical_findings.rb +116 -0
  46. data/risu.gemspec +44 -0
  47. metadata +247 -0
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+
3
+ module NessusDB
4
+ module CLI
5
+ end
6
+ end
7
+
8
+ require 'nessusdb/cli/application'
9
+ require 'nessusdb/cli/banner'
@@ -0,0 +1,402 @@
1
+ # encoding: utf-8
2
+
3
+ module NessusDB
4
+ module CLI
5
+
6
+ # Application class for NessusDB
7
+ #
8
+ # @author Jacob Hammack <jacob.hammack@hammackj.com>
9
+ class Application
10
+ attr_accessor :database
11
+
12
+ #
13
+ #
14
+ def initialize
15
+ @options = {}
16
+ @database = {}
17
+ @report = {}
18
+ @blacklist = {}
19
+
20
+ @options[:debug] = false
21
+ end
22
+
23
+ # Creates a blank config file
24
+ #
25
+ def create_config(file=CONFIG_FILE)
26
+ File.open(file, 'w+') do |f|
27
+ f.write("report:\n")
28
+ f.write(" author: \n")
29
+ f.write(" title: \n")
30
+ f.write(" company: \n")
31
+ f.write(" classification: \n\n")
32
+ f.write("database:\n")
33
+ f.write(" adapter: \n")
34
+ f.write(" host: \n")
35
+ f.write(" port: \n")
36
+ f.write(" database: \n")
37
+ f.write(" username: \n")
38
+ f.write(" password: \n")
39
+ f.write(" timeout: \n\n")
40
+ #TODO blacklisting
41
+ #f.write("blacklist:\n")
42
+ #f.write(" ips: \n")
43
+ #f.write(" macs: \n")
44
+ #f.write(" plugins: \n\n")
45
+ end
46
+ end
47
+
48
+ # Loads the configuration file
49
+ #
50
+ def load_config(file=CONFIG_FILE, in_memory_config=false)
51
+ if File.exists?(file) == true or in_memory_config == true
52
+ begin
53
+ if in_memory_config
54
+ yaml = YAML::load(file)
55
+ else
56
+ yaml = YAML::load(File.open(file))
57
+ end
58
+
59
+ @database = yaml["database"]
60
+ @report = yaml["report"]
61
+
62
+ puts @database.inspect if @options[:debug]
63
+
64
+ #If no values were entered put a default value in
65
+ @report.each do |k, v|
66
+ if v == nil
67
+ @report[k] = "No #{k}"
68
+ end
69
+ end
70
+
71
+ #@blacklist = yaml["blacklist"]
72
+ rescue => e
73
+ puts "[!] Error loading config! - #{e.message}"
74
+ exit
75
+ end
76
+ else
77
+ puts "[!] Config file does not exist!"
78
+ exit
79
+ end
80
+ end
81
+
82
+ # Initiator for [ActiveRecord] migrations.
83
+ #
84
+ def migrate(direction)
85
+ begin
86
+ if @database["adapter"] == nil
87
+ return false, "[!] Invalid database adapter, please check your config file"
88
+ end
89
+
90
+ ActiveRecord::Base.establish_connection(@database)
91
+ require 'nessusdb/schema'
92
+ Schema.migrate(direction)
93
+
94
+ if direction == :up
95
+ ver = Version.create
96
+ ver.version = NessusDB::VERSION
97
+ ver.save
98
+ end
99
+
100
+ rescue ActiveRecord::AdapterNotSpecified => ans
101
+ puts "[!] Database adapter not found, please check your config file"
102
+ puts "#{ans.message}\n #{ans.backtrace}" if @options[:debug]
103
+
104
+ exit
105
+ rescue ActiveRecord::AdapterNotFound => anf
106
+ puts "[!] Database adapter not found, please check your config file"
107
+ puts "#{ans.message}\n #{ans.backtrace}" if @options[:debug]
108
+
109
+ exit
110
+ rescue => e
111
+ puts "[!] Exception! #{e.message}\n#{e.backtrace}"
112
+ exit
113
+ end
114
+ end
115
+
116
+ #
117
+ #
118
+ def db_connect
119
+ begin
120
+ if @database["adapter"] == nil
121
+ puts "[!] #{@database['adapter']}" if @options[:debug]
122
+
123
+ return false, "[!] Invalid database adapter, please check your config file"
124
+ end
125
+
126
+ ActiveRecord::Base.establish_connection(@database)
127
+ ActiveRecord::Base.connection
128
+
129
+ rescue ActiveRecord::AdapterNotSpecified => ans
130
+ puts "[!] Database adapter not found, please check your config file"
131
+
132
+ puts "#{ans.message}\n #{ans.backtrace}" if @options[:debug]
133
+
134
+ exit
135
+ rescue ActiveRecord::AdapterNotFound => anf
136
+ puts "[!] Database adapter not found, please check your config file"
137
+
138
+ puts "#{anf.message}\n #{anf.backtrace}" if @options[:debug]
139
+
140
+ exit
141
+ rescue => e
142
+ puts "[!] Exception! #{e.message}\n #{e.backtrace}"
143
+ end
144
+ end
145
+
146
+ #
147
+ #
148
+ def test_connection?
149
+ begin
150
+
151
+ db_connect
152
+
153
+ if ActiveRecord::Base.connected? == true
154
+ return true, "[*] Connection Test Successful"
155
+ else
156
+ return false, "[!] Connection Test Failed"
157
+ end
158
+ rescue => e
159
+ puts "[!] Exception! #{e.message}\n #{e.backtrace}"
160
+ end
161
+ end
162
+
163
+ # Starts a console and executes anything in a block sent to it
164
+ #
165
+ def consolize &block
166
+
167
+ yield
168
+
169
+ IRB.setup(nil)
170
+ IRB.conf[:USE_READLINE] = true
171
+ IRB.conf[:PROMPT_MODE] = :SIMPLE
172
+
173
+ irb = IRB::Irb.new
174
+ IRB.conf[:MAIN_CONTEXT] = irb.context
175
+
176
+ irb.context.evaluate("require 'irb/completion'", 0)
177
+
178
+ trap("SIGINT") do
179
+ irb.signal_handle
180
+ end
181
+ catch(:IRB_EXIT) do
182
+ irb.eval_input
183
+ end
184
+ end
185
+
186
+ # Parses all the command line
187
+ #
188
+ def parse_options
189
+ begin
190
+ opts = OptionParser.new do |opt|
191
+ opt.banner = "#{APP_NAME} v#{VERSION}\nJacob Hammack\nhttp://www.hammackj.com\n\n"
192
+ opt.banner << "Usage: #{APP_NAME} [options] [files_to_parse]"
193
+ opt.separator('')
194
+ opt.separator("Reporting Options")
195
+
196
+ opt.on('-t','--template FILE','The filename of the template to use') do |option|
197
+ @options[:template] = option
198
+ end
199
+
200
+ opt.on('-o','--output-file FILE','The filename to output the generated report to') do |option|
201
+ @options[:output_file] = option
202
+ end
203
+
204
+ opt.separator('')
205
+ opt.separator('Configuration Options')
206
+
207
+ opt.on('--config-file FILE', "Loads configuration settings for the specified file. By default #{APP_NAME} loads #{CONFIG_FILE}") do |option|
208
+ if File.exists?(option) == true
209
+ @options[:config_file] = option
210
+ else
211
+ puts "[!] Specified config file does not exist. Please specify a file that exists."
212
+ exit
213
+ end
214
+ end
215
+
216
+ opt.on('--create-config-file [FILE]',"Creates a config file in the current directory with the specified name, Default is #{CONFIG_FILE}") do |option|
217
+ if option == nil
218
+ option = CONFIG_FILE
219
+ end
220
+
221
+ if File.exists?(option) == true
222
+ puts "[!] Config file already exists; If you wish to over-write this file please delete it."
223
+ else
224
+ if option == nil
225
+ create_config
226
+ else
227
+ create_config option
228
+ end
229
+
230
+ exit
231
+ end
232
+ end
233
+
234
+ opt.separator('')
235
+ opt.separator('Database Options')
236
+
237
+ opt.on('--test-connection','Tests the database connection settings') do |option|
238
+ @options[:test_connection] = option
239
+ end
240
+
241
+ opt.on('--create-tables','Creates the tables required for NessusDB') do |option|
242
+ @options[:create_tables] = option
243
+ end
244
+
245
+ opt.on('--drop-tables','Deletes the tables and data from NessusDB') do |option|
246
+ @options[:drop_tables] = option
247
+ end
248
+
249
+ opt.separator ''
250
+ opt.separator 'Other Options'
251
+
252
+ opt.on_tail('-v', '--version', "Shows application version information") do
253
+ puts "#{APP_NAME} - #{VERSION}"
254
+ exit
255
+ end
256
+
257
+ opt.on('-d','--debug','Enable Debug Mode (More verbose output)') do |option|
258
+ @options[:debug] = true
259
+ end
260
+
261
+ opt.on('--console', 'Starts an ActiveRecord console into the configured database') do |option|
262
+ @options[:console] = option
263
+ end
264
+
265
+ opt.on_tail("-?", "--help", "Show this message") do
266
+ puts opt.to_s + "\n"
267
+ exit
268
+ end
269
+ end
270
+
271
+ if ARGV.length != 0
272
+ opts.parse!
273
+ else
274
+ puts opts.to_s + "\n"
275
+ exit
276
+ end
277
+ rescue OptionParser::MissingArgument => m
278
+ puts opts.to_s + "\n"
279
+ exit
280
+ rescue OptionParser::InvalidOption => i
281
+ puts opts.to_s + "\n"
282
+ exit
283
+ end
284
+ end
285
+
286
+ #
287
+ #
288
+ def run
289
+ parse_options
290
+
291
+ if @options[:debug] == true
292
+ puts "[*] Enabling Debug Mode"
293
+ end
294
+
295
+ if @options[:config_file] != nil
296
+ load_config @options[:config_file]
297
+ else
298
+ load_config
299
+ end
300
+
301
+ db_connect
302
+
303
+ if @options[:console] != nil
304
+ consolize do
305
+ puts NessusDB::CLI::Banner
306
+ puts "NessusDB Console v#{VERSION}"
307
+ end
308
+ exit
309
+ end
310
+
311
+ if @options[:test_connection] != nil
312
+ result = test_connection?
313
+
314
+ puts "#{result[1]}"
315
+ exit
316
+ end
317
+
318
+ if @options[:create_tables] != nil
319
+ migrate(:up)
320
+ exit
321
+ end
322
+
323
+ if @options[:drop_tables] != nil
324
+ migrate(:down)
325
+ exit
326
+ end
327
+
328
+ if @options[:template] != nil and @options[:output_file] != nil
329
+ if File.exists?(@options[:template]) == false
330
+ puts "[!] Template \"#{@options[:template]}\" does not exist. Please check the filename"
331
+ exit
332
+ end
333
+
334
+ @findings = Report
335
+
336
+ @findings.author = @report["author"]
337
+ @findings.title = @report["title"]
338
+ @findings.company = @report["company"]
339
+ @findings.classification = @report["classification"]
340
+
341
+ template = PrawnTemplater.new(@options[:template], @findings, @options[:output_file])
342
+ template.generate
343
+ end
344
+
345
+ ARGV.each do |file|
346
+ begin
347
+ parse_file file
348
+
349
+ rescue NessusDB::Exceptions::InvalidDocument => id
350
+ puts "[!] #{id.message}"
351
+ next
352
+ rescue ActiveRecord::StatementInvalid => si
353
+ puts "[!] Please run nessusdb --create-tables, to create the required database schema!"
354
+ exit
355
+ rescue => e
356
+ puts e.inspect
357
+ puts "[!] Error: #{file}"
358
+ next
359
+ end
360
+ end
361
+ end
362
+
363
+ # Handles the parsing of a single file
364
+ #
365
+ def parse_file file
366
+ begin
367
+ puts "[*] Parsing #{file}..."
368
+ tstart = Time.new
369
+
370
+ if File.exists?(file) == false
371
+ raise NessusDB::Exceptions::InvalidDocument, "[!] Document does not exist - #{file}"
372
+ end
373
+
374
+ doc = NessusDocument.new file
375
+ if doc.valid? == true
376
+ doc.parse
377
+
378
+ puts "[*] Fixing IP Address field"
379
+
380
+ doc.fix_ips
381
+
382
+ else
383
+ raise NessusDB::Exceptions::InvalidDocument, "[!] Invalid Document - #{file}"
384
+ end
385
+
386
+ printf "[*] Finished parsing %s. Parse took %.02f seconds\n", file, Time.now - tstart
387
+ rescue Interrupt => i
388
+ puts "[!] Parse cancelled!"
389
+ exit(1)
390
+ rescue Mysql::Error => m
391
+ if m.errno == 1146
392
+ puts "[!] Error: Tables were not created. Please run nessusdb --create-tables"
393
+ exit(1)
394
+ end
395
+ rescue => e
396
+ puts "[!] #{e.message}\n #{e.backtrace.join("\n")}\n"
397
+ exit(1)
398
+ end
399
+ end
400
+ end
401
+ end
402
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ #Cool random banner stuff for the cli, based on the metasploit random banner stuff
4
+
5
+ module NessusDB
6
+ module CLI
7
+ module Banner
8
+ Banners =
9
+ [
10
+ '
11
+ _ _
12
+ _ __ ___ ___ ___ _ _ ___ __| | |__
13
+ | \'_ \ / _ \/ __/ __| | | / __|/ _` | \'_ \
14
+ | | | | __/\__ \__ \ |_| \__ \ (_| | |_) |
15
+ |_| |_|\___||___/___/\__,_|___/\__,_|_.__/
16
+
17
+ '
18
+ ]
19
+
20
+ def self.to_s
21
+ Banners[rand(Banners.length)]
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+
3
+ module NessusDB
4
+ module Exceptions
5
+ end
6
+ end
7
+
8
+ require 'nessusdb/exceptions/invaliddocument'
@@ -0,0 +1,10 @@
1
+
2
+ # encoding: utf-8
3
+
4
+ module NessusDB
5
+ module Exceptions
6
+ class InvalidDocument < StandardError
7
+
8
+ end
9
+ end
10
+ end