watobo 0.9.9.pre3 → 0.9.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. data/.yardopts +24 -0
  2. data/CHANGELOG +17 -7
  3. data/README +4 -60
  4. data/bin/nfq_server.rb +191 -0
  5. data/config/interceptor.yml +2 -6
  6. data/lib/watobo/adapters/data_store.rb +1 -1
  7. data/lib/watobo/adapters/file/file_store.rb +50 -33
  8. data/lib/watobo/ca.rb +22 -0
  9. data/lib/watobo/config.rb +6 -0
  10. data/lib/watobo/core/ca.rb +411 -0
  11. data/lib/watobo/core/cert_store.rb +56 -0
  12. data/lib/watobo/core/forwarding_proxy.rb +38 -0
  13. data/lib/watobo/core/http_socket.rb +18 -0
  14. data/lib/watobo/core/intercept_carver.rb +179 -0
  15. data/lib/watobo/core/intercept_filter.rb +257 -0
  16. data/lib/watobo/core/interceptor.rb +342 -79
  17. data/lib/watobo/core/netfilter_queue.rb +191 -0
  18. data/lib/watobo/core/project.rb +84 -138
  19. data/lib/watobo/core/proxy.rb +61 -0
  20. data/lib/watobo/core/request.rb +40 -0
  21. data/lib/watobo/core/response.rb +30 -0
  22. data/lib/watobo/core/scanner.rb +64 -58
  23. data/lib/watobo/core/session.rb +70 -77
  24. data/lib/watobo/core.rb +1 -1
  25. data/lib/watobo/framework/create_project.rb +25 -10
  26. data/lib/watobo/framework/init.rb +13 -0
  27. data/lib/watobo/gui/browser_preview.rb +5 -4
  28. data/lib/watobo/gui/checks_policy_frame.rb +1 -0
  29. data/lib/watobo/gui/client_cert_dialog.rb +11 -6
  30. data/lib/watobo/gui/conversation_table.rb +7 -4
  31. data/lib/watobo/gui/fuzzer_gui.rb +9 -11
  32. data/lib/watobo/gui/intercept_filter_dialog.rb +210 -0
  33. data/lib/watobo/gui/interceptor_gui.rb +59 -21
  34. data/lib/watobo/gui/interceptor_settings_dialog.rb +39 -5
  35. data/lib/watobo/gui/list_box.rb +2 -1
  36. data/lib/watobo/gui/log_viewer.rb +79 -5
  37. data/lib/watobo/gui/main_window.rb +159 -113
  38. data/lib/watobo/gui/manual_request_editor.rb +11 -5
  39. data/lib/watobo/gui/mixins/subscriber.rb +47 -0
  40. data/lib/watobo/gui/project_wizzard.rb +3 -3
  41. data/lib/watobo/gui/proxy_dialog.rb +17 -18
  42. data/lib/watobo/gui/request_editor.rb +1 -1
  43. data/lib/watobo/gui/rewrite_filters_dialog.rb +416 -0
  44. data/lib/watobo/gui/rewrite_rules_dialog.rb +394 -0
  45. data/lib/watobo/gui/scanner_settings_dialog.rb +9 -6
  46. data/lib/watobo/gui/session_management_dialog.rb +33 -23
  47. data/lib/watobo/gui/sites_tree.rb +5 -6
  48. data/lib/watobo/gui/status_bar.rb +101 -49
  49. data/lib/watobo/gui/table_editor.rb +1 -1
  50. data/lib/watobo/gui/templates/plugin2.rb +23 -27
  51. data/lib/watobo/gui/utils/save_default_settings.rb +9 -9
  52. data/lib/watobo/gui/utils/save_proxy_settings.rb +25 -9
  53. data/lib/watobo/gui/utils/save_scanner_settings.rb +10 -7
  54. data/lib/watobo/gui/utils/session_history.rb +1 -1
  55. data/lib/watobo/gui/www_auth_dialog.rb +25 -21
  56. data/lib/watobo/gui.rb +3 -1
  57. data/lib/watobo/mixins/httpparser.rb +47 -40
  58. data/lib/watobo/mixins/request_parser.rb +126 -41
  59. data/lib/watobo/mixins/shapers.rb +124 -15
  60. data/lib/watobo/utils/hexprint.rb +31 -0
  61. data/lib/watobo/utils/load_chat.rb +2 -0
  62. data/lib/watobo/utils/response_builder.rb +111 -0
  63. data/lib/watobo.rb +4 -1
  64. data/modules/active/discovery/http_methods.rb +6 -4
  65. data/modules/active/fileinclusion/lfi_simple.rb +3 -3
  66. data/modules/active/sqlinjection/sqli_timing.rb +6 -6
  67. data/modules/passive/redirectionz.rb +5 -6
  68. data/plugins/catalog/catalog.rb +240 -56
  69. data/plugins/catalog/db_tests +1 -6483
  70. data/plugins/catalog/db_variables +2 -29
  71. data/plugins/crawler/gui/auth_frame.rb +15 -3
  72. data/plugins/crawler/gui/crawler_gui.rb +24 -0
  73. data/plugins/crawler/gui/hooks_frame.rb +7 -2
  74. data/plugins/crawler/gui/settings_tabbook.rb +4 -0
  75. data/plugins/crawler/gui.rb +3 -3
  76. data/plugins/crawler/lib/engine.rb +1 -1
  77. data/plugins/filefinder/filefinder.rb +21 -17
  78. data/plugins/sqlmap/bin/test.rb +100 -0
  79. data/plugins/sqlmap/gui/main.rb +227 -0
  80. data/plugins/sqlmap/gui/options_frame.rb +119 -0
  81. data/plugins/sqlmap/gui.rb +27 -0
  82. data/plugins/sqlmap/icons/sqlmap.ico +0 -0
  83. data/plugins/sqlmap/lib/sqlmap_ctrl.rb +116 -0
  84. data/plugins/sqlmap/sqlmap.rb +26 -0
  85. data/plugins/sslchecker/gui/gui.rb +45 -30
  86. metadata +32 -9
  87. data/certificates/cert.pem +0 -19
  88. data/certificates/privkey.pem +0 -15
  89. data/certificates/watobo_dh.key +0 -5
  90. data/lib/watobo/core/simple_ca.rb +0 -393
@@ -22,8 +22,6 @@
22
22
  module Watobo
23
23
  module Modules
24
24
  module Passive
25
-
26
-
27
25
  class Redirectionz < Watobo::PassiveCheck
28
26
 
29
27
  def initialize(project)
@@ -67,10 +65,11 @@ module Watobo
67
65
  end
68
66
  end
69
67
  end
68
+ end
70
69
  #puts ""
71
- chat.request.post_parm_names.each do |parm|
72
- parm_value=chat.request.post_parm_value(parm)
73
- if parm_value.length > 5 then # check for minimum parameter length (False Positive Reduction)
70
+ chat.request.post_parm_names.each do |parm|
71
+ parm_value=chat.request.post_parm_value(parm)
72
+ if parm_value.length > 5 then # check for minimum parameter length (False Positive Reduction)
74
73
  chat.response.headers.each do |header|
75
74
  if header =~ /Location.*#{parm_value}.*/i then
76
75
  addFinding(
@@ -83,7 +82,7 @@ module Watobo
83
82
  end
84
83
  end
85
84
  end
86
- end
85
+
87
86
  rescue => bang
88
87
  # raise
89
88
  showError(chat.id, bang)
@@ -23,6 +23,30 @@ module Watobo
23
23
  module Plugin
24
24
  module Catalog
25
25
 
26
+ class About < FXDialogBox
27
+ def initialize(owner, text)
28
+ super(owner, "About Catalog-Scanner", :opts => DECOR_TITLE|DECOR_BORDER|DECOR_CLOSE|DECOR_RESIZE,:width=>400, :height=>300)
29
+ self.icon = Watobo::Gui::Icons::ICON_WATOBO
30
+
31
+ main = FXVerticalFrame.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_GROOVE, :padding => 0)
32
+ main.backColor = FXColor::White
33
+
34
+ about_txt = FXText.new(main, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
35
+ about_txt.editable = false
36
+
37
+ about_txt.disable
38
+ about_txt.setText text
39
+ about_txt.font = FXFont.new(getApp(), "courier", 12, FONTWEIGHT_BOLD)
40
+ about_txt.backColor = FXColor::White
41
+
42
+ bottom = FXHorizontalFrame.new(main, :opts => LAYOUT_FILL_X)
43
+ FXButton.new(bottom, "OK" ,
44
+ :target => self, :selector => FXDialogBox::ID_ACCEPT,
45
+ :opts => BUTTON_NORMAL|LAYOUT_RIGHT)
46
+
47
+ end
48
+ end
49
+
26
50
  class Check < Watobo::ActiveCheck
27
51
  attr_writer :db_files
28
52
  attr_writer :var_files
@@ -237,9 +261,15 @@ module Watobo
237
261
 
238
262
  if @project then
239
263
  @sites_combo.appendItem("no site selected", nil)
240
- @project.listSites(:in_scope => @scope_only_cb.checked? ).each do |site|
264
+ @project.listSites(:in_scope => Watobo.project.has_scope? ).each do |site|
241
265
  #puts "Site: #{site}"
242
- @sites_combo.appendItem(site.slice(0..35), site)
266
+ site_string = site
267
+ if site.length > 60
268
+ site_string = site.slice(0..55)
269
+ site_string << "...:"
270
+ site_string << site.gsub(/.*:/,'')
271
+ end
272
+ @sites_combo.appendItem(site_string, site)
243
273
  end
244
274
  @sites_combo.numVisible = @sites_combo.numItems >= 20 ? 20 : @sites_combo.numItems
245
275
  @sites_combo.setCurrentItem(0) if @sites_combo.numItems > 0
@@ -263,25 +293,33 @@ module Watobo
263
293
  end
264
294
 
265
295
  def initialize(owner, project)
296
+
266
297
  super(owner, "Catalog Scanner", project, :opts => DECOR_ALL, :width=>800, :height=>400)
267
- load_icon(__FILE__)
298
+ menu_bar = FXMenuBar.new(self, :opts => LAYOUT_SIDE_TOP|LAYOUT_FILL_X|FRAME_GROOVE)
299
+ menu_pane = FXMenuPane.new(self)
300
+
301
+ text = "Catalog-Scanner will test the web application for known directories and/or files.\nYou need two files (db_tests and db_variables) in the DB folder. "
302
+ text << "These files must have the same format as nikto DB files (http://cirt.net/nikto2).\nSo, if you have your own DB files, you"
303
+ text << " can use them with this plugin."
304
+
305
+ load_icon(__FILE__)
306
+
307
+ FXMenuTitle.new(menu_bar, "Help" , :popupMenu => menu_pane)
308
+ menu = FXMenuCommand.new(menu_pane, "About" )
309
+ menu.connect(SEL_COMMAND) {
310
+ dlg = Watobo::Plugin::Catalog::About.new(self, text)
311
+ dlg.execute
312
+ }
313
+
268
314
  self.connect(SEL_CLOSE, method(:onClose))
269
315
 
270
316
  @event_dispatcher_listeners = Hash.new
271
317
  @scanner = nil
272
318
  @plugin_name = "Catalog-Scan"
273
319
  @project = project
274
- @path = File.expand_path(File.dirname(__FILE__))
275
- catalog_ready = true
276
- db_files = %w( db_tests db_variables )
277
- db_files.each do |file|
278
- fname = File.join( @path, file)
279
- if not File.exists?(fname)
280
- catalog_ready = false
281
- puts "WARNING: Missing catalog db file: #{fname}"
282
- end
283
- end
284
-
320
+
321
+
322
+
285
323
  @site = nil
286
324
  @dir = nil
287
325
 
@@ -300,13 +338,20 @@ load_icon(__FILE__)
300
338
 
301
339
  mr_splitter = FXSplitter.new(self, LAYOUT_FILL_X|LAYOUT_FILL_Y|SPLITTER_VERTICAL|SPLITTER_REVERSED|SPLITTER_TRACKING)
302
340
  # top = FXHorizontalFrame.new(mr_splitter, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_SIDE_BOTTOM)
303
- top_frame = FXVerticalFrame.new(mr_splitter, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y||LAYOUT_FIX_HEIGHT|LAYOUT_BOTTOM,:height => 500)
341
+ top_frame = FXVerticalFrame.new(mr_splitter, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FIX_HEIGHT|LAYOUT_BOTTOM, :height => 500)
342
+ # info_frame = FXGroupBox.new(top_frame, "Info", LAYOUT_SIDE_TOP|FRAME_GROOVE|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0, 0, 0, 0)
343
+ # info = FXText.new(info_frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
344
+ # info.setText text
345
+ # info.backColor = info.parent.backColor
346
+ # info.disable
304
347
  top_splitter = FXSplitter.new(top_frame, LAYOUT_FILL_X|SPLITTER_HORIZONTAL|LAYOUT_FILL_Y|SPLITTER_TRACKING)
305
348
  log_frame = FXVerticalFrame.new(mr_splitter, :opts => LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM,:height => 100)
306
349
 
307
- @settings_frame = FXVerticalFrame.new(top_splitter, :opts => LAYOUT_FILL_Y)
308
- result_frame = FXVerticalFrame.new(top_splitter, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
309
- @requestCombo = FXComboBox.new(result_frame, 5, nil, 0,
350
+ @settings_frame = FXVerticalFrame.new(top_splitter, :opts => LAYOUT_FILL_Y, :padding => 0)
351
+ #request_frame = FXVerticalFrame.new(top_splitter, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
352
+ request_frame = FXGroupBox.new(top_splitter, "Request Template", LAYOUT_SIDE_TOP|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
353
+ FXLabel.new(request_frame, "Select a request template from drop-down list or enter manually.")
354
+ @requestCombo = FXComboBox.new(request_frame, 5, nil, 0,
310
355
  COMBOBOX_STATIC|FRAME_SUNKEN|FRAME_THICK|LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
311
356
  #@filterCombo.width =200
312
357
 
@@ -315,21 +360,22 @@ load_icon(__FILE__)
315
360
  @requestCombo.editable = false
316
361
  @requestCombo.connect(SEL_COMMAND, method(:onSelectRequest))
317
362
 
318
- log_text_frame = FXVerticalFrame.new(result_frame, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, :padding=>0)
363
+ #log_text_frame = FXVerticalFrame.new(request_frame, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, :padding=>0)
319
364
  # @request_box = FXText.new(log_text_frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
320
365
  # @request_box.styled = true
321
366
  # Set the styles
322
367
  # @request_box.hiliteStyles = [ hs_green, hs_red]
323
368
 
324
- @request_editor = RequestEditor.new(log_text_frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
369
+ @request_editor = RequestEditor.new(request_frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, :padding=>0)
325
370
 
326
- FXLabel.new(@settings_frame, "Select Site:")
371
+ # FXLabel.new(@settings_frame, "Select Site:")
372
+ ts_frame = FXGroupBox.new(@settings_frame, "Scan Settings", LAYOUT_SIDE_TOP|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
327
373
 
328
- @scope_only_cb = FXCheckButton.new(@settings_frame, "target scope only", nil, 0, ICON_BEFORE_TEXT|LAYOUT_SIDE_LEFT)
329
- @scope_only_cb.setCheck(false)
330
- @scope_only_cb.connect(SEL_COMMAND) { updateView() }
374
+ # @scope_only_cb = FXCheckButton.new(@settings_frame, "target scope only", nil, 0, ICON_BEFORE_TEXT|LAYOUT_SIDE_LEFT)
375
+ # @scope_only_cb.setCheck(false)
376
+ # @scope_only_cb.connect(SEL_COMMAND) { updateView() }
331
377
 
332
- @sites_combo = FXComboBox.new(@settings_frame, 5, nil, 0,
378
+ @sites_combo = FXComboBox.new(ts_frame, 5, nil, 0,
333
379
  COMBOBOX_STATIC|FRAME_SUNKEN|FRAME_THICK|LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
334
380
  #@filterCombo.width =200
335
381
 
@@ -338,15 +384,15 @@ load_icon(__FILE__)
338
384
  @sites_combo.editable = false
339
385
  @sites_combo.connect(SEL_COMMAND, method(:onSiteSelect))
340
386
 
341
- FXLabel.new(@settings_frame, "Root Directory:")
342
- @dir_combo = FXComboBox.new(@settings_frame, 5, nil, 0,
387
+ FXLabel.new(ts_frame, "Root Directory:")
388
+ @dir_combo = FXComboBox.new(ts_frame, 5, nil, 0,
343
389
  COMBOBOX_STATIC|FRAME_SUNKEN|FRAME_THICK|LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
344
390
  @dir_combo.numVisible = 20
345
391
  @dir_combo.numColumns = 35
346
392
  @dir_combo.editable = false
347
393
  @dir_combo.connect(SEL_COMMAND, method(:onDirSelect))
348
394
 
349
- @test_all_dirs = FXCheckButton.new(@settings_frame, "test all sub-directories", nil, 0, ICON_BEFORE_TEXT|LAYOUT_SIDE_LEFT)
395
+ @test_all_dirs = FXCheckButton.new(ts_frame, "test all sub-directories", nil, 0, ICON_BEFORE_TEXT|LAYOUT_SIDE_LEFT)
350
396
  @test_all_dirs.setCheck(false)
351
397
 
352
398
  # @use_ssl = FXCheckButton.new(@settings_frame, "use SSL", nil, 0, ICON_BEFORE_TEXT|LAYOUT_SIDE_LEFT)
@@ -355,32 +401,100 @@ load_icon(__FILE__)
355
401
  # @run_passive_checks.setCheck(false)
356
402
 
357
403
  frame = FXGroupBox.new(@settings_frame, "Logging", LAYOUT_SIDE_TOP|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
358
- @logScanChats = FXCheckButton.new(frame, "Log Scan", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
404
+ @logScanChats = FXCheckButton.new(frame, "enable", nil, 0, JUSTIFY_LEFT|JUSTIFY_TOP|ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP)
359
405
  @logScanChats.checkState = false
360
406
 
361
407
  @logScanChats.connect(SEL_COMMAND) do |sender, sel, item|
362
408
  if @logScanChats.checked? then
363
409
  @scanlog_dir_text.enabled = true
364
- @scanlog_dir_label.enabled = true
365
- @scanlog_dir_btn.enable
410
+ @scanlog_dir_text.backColor = FXColor::White
411
+ # @scanlog_dir_label.enabled = true
412
+ # @scanlog_dir_btn.enable
366
413
  else
367
414
  @scanlog_dir_text.enabled = false
368
- @scanlog_dir_label.enabled = false
369
- @scanlog_dir_btn.disable
415
+ @scanlog_dir_text.backColor = @scanlog_dir_text.parent.backColor
416
+ # @scanlog_dir_label.enabled = false
417
+ # @scanlog_dir_btn.disable
370
418
  end
371
419
  end
372
420
 
373
421
  @scanlog_dir_dt = FXDataTarget.new('')
374
422
  # @scanlog_dir_dt.value = @project.scanLogDirectory() if File.exist?(@project.scanLogDirectory())
375
- @scanlog_dir_label = FXLabel.new(frame, "Scan-Log Directory:" )
423
+ @scanlog_dir_label = FXLabel.new(frame, "Scan Name:" )
376
424
  scanlog_frame = FXHorizontalFrame.new(frame,:opts => LAYOUT_FILL_X|LAYOUT_SIDE_TOP)
377
425
  @scanlog_dir_text = FXTextField.new(scanlog_frame, 20,
378
426
  :target => @scanlog_dir_dt, :selector => FXDataTarget::ID_VALUE,
379
427
  :opts => TEXTFIELD_NORMAL|LAYOUT_FILL_COLUMN|LAYOUT_FILL_X)
380
428
  @scanlog_dir_text.handle(self, FXSEL(SEL_UPDATE, 0), nil)
381
- @scanlog_dir_btn = FXButton.new(scanlog_frame, "Change")
429
+ unless @logScanChats.checked?
430
+ @scanlog_dir_text.enabled = false
431
+ @scanlog_dir_text.backColor = @scanlog_dir_text.parent.backColor
432
+ end
433
+ #@scanlog_dir_btn = FXButton.new(scanlog_frame, "Change")
382
434
  # @scanlog_dir_btn.connect(SEL_COMMAND, method(:selectScanlogDirectory))
383
-
435
+
436
+
437
+ @db_files = %w( db_tests db_variables )
438
+
439
+ @path = File.expand_path(File.dirname(__FILE__))
440
+
441
+
442
+ @known_db_paths = [
443
+ # File.expand_path(File.dirname(__FILE__)),
444
+ # "/pentest/web/nikto/plugins" # BackTrack
445
+ @path
446
+ ]
447
+ config = load_config
448
+ unless config.nil?
449
+ if config.has_key? :path_history
450
+ begin
451
+ config[:path_history].each do |p|
452
+ @known_db_paths << p unless @known_db_paths.include? p
453
+ end
454
+ rescue => bang
455
+ puts "!Broken Path History"
456
+ end
457
+ end
458
+ @path = config[:db_path] if config.has_key? :db_path
459
+
460
+ end
461
+
462
+ frame = FXGroupBox.new(@settings_frame, "DB Path", LAYOUT_SIDE_TOP|FRAME_GROOVE|LAYOUT_FILL_X, 0, 0, 0, 0)
463
+ #FXLabel.new(frame, "Path:" )
464
+ db_frame = FXHorizontalFrame.new(frame,:opts => LAYOUT_FILL_X|LAYOUT_SIDE_TOP)
465
+ @db_path_combo = FXComboBox.new(db_frame, 5, nil, 0,
466
+ COMBOBOX_STATIC|FRAME_SUNKEN|FRAME_THICK|LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
467
+
468
+ @db_path_combo.numVisible = 3
469
+ @db_path_combo.numColumns = 8
470
+
471
+ @db_path_combo.editable = false
472
+ @db_path_combo.connect(SEL_COMMAND){
473
+ path = @db_path_combo.getItemData(@db_path_combo.currentItem)
474
+ set_db_path path
475
+ }
476
+ # @db_path_txt = FXTextField.new(db_frame, 20, nil, 0, :opts => TEXTFIELD_NORMAL|LAYOUT_FILL_COLUMN|LAYOUT_FILL_X)
477
+ # @db_path_txt.text = @path
478
+ # @db_path_txt.handle(self, FXSEL(SEL_UPDATE, 0), nil)
479
+ @db_path_btn = FXButton.new(db_frame, "add")
480
+ @db_path_btn.connect(SEL_COMMAND){
481
+ select_db_path
482
+ # @db_path_txt.text = @path
483
+ }
484
+ #@check_buttons = Hash.new
485
+
486
+
487
+ path_index = 0
488
+ @known_db_paths.each_with_index do |dbp,i|
489
+ if File.exist? dbp
490
+ item = @db_path_combo.appendItem(dbp)
491
+ @db_path_combo.setItemData(item, dbp)
492
+ path_index = i if dbp == @path
493
+ end
494
+ end
495
+
496
+ @db_path_combo.currentItem = path_index if @db_path_combo.numItems > 0
497
+
384
498
  @pbar = FXProgressBar.new(@settings_frame, nil, 0, LAYOUT_FILL_X|FRAME_SUNKEN|FRAME_THICK|PROGRESSBAR_HORIZONTAL)
385
499
  @pbar.progress = 0
386
500
  @pbar.total = 0
@@ -393,16 +507,16 @@ load_icon(__FILE__)
393
507
  @start_button.connect(SEL_COMMAND, method(:start))
394
508
  @start_button.disable
395
509
 
396
- gbox = FXGroupBox.new(@settings_frame, "Info", LAYOUT_SIDE_LEFT|FRAME_GROOVE|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0, 0, 0, 150)
397
- gbframe = FXVerticalFrame.new(gbox, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0)
398
- fxtext = FXText.new(gbframe, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
399
- fxtext.backColor = fxtext.parent.backColor
400
- fxtext.disable
401
- text = "Catalog-Scanner will test the web application for known directories and/or files. There must be two files in the appropriate plugin folder:\n"
402
- text << "- db_tests\n- db_variables\n\nThe format of these files is very similar to the format nikto (http://cirt.net/nikto2) is using. So if you have your own nikto.db-files, you"
403
- text << " can use them with this plugin."
404
- text << "\n\nCatalog Directory:\n#{File.dirname(__FILE__)}"
405
- fxtext.setText(text)
510
+ # gbox = FXGroupBox.new(@settings_frame, "Info", LAYOUT_SIDE_LEFT|FRAME_GROOVE|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0, 0, 0, 150)
511
+ # gbframe = FXVerticalFrame.new(gbox, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y, :padding => 0)
512
+ # fxtext = FXText.new(gbframe, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP)
513
+ # fxtext.backColor = fxtext.parent.backColor
514
+ # fxtext.disable
515
+ # text = "Catalog-Scanner will test the web application for known directories and/or files. There must be two files in the appropriate plugin folder:\n"
516
+ # text << "- db_tests\n- db_variables\n\nThe format of these files is very similar to the format nikto (http://cirt.net/nikto2) is using. So if you have your own nikto.db-files, you"
517
+ # text << " can use them with this plugin."
518
+ # text << "\n\nCatalog Directory:\n#{File.dirname(__FILE__)}"
519
+ # fxtext.setText(text)
406
520
 
407
521
  @check = nil
408
522
 
@@ -411,8 +525,8 @@ load_icon(__FILE__)
411
525
 
412
526
  #log_text_frame = FXHorizontalFrame.new(bottom_frame, :opts => LAYOUT_FILL_X|FRAME_SUNKEN|LAYOUT_BOTTOM)
413
527
  log_text_frame = FXVerticalFrame.new(log_frame, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, :padding=>0)
414
- @log_viewer = LogViewer.new(log_text_frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
415
-
528
+ @log_viewer = LogViewer.new(log_text_frame, nil, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
529
+
416
530
  updateView()
417
531
  rescue => bang
418
532
  puts bang
@@ -421,19 +535,21 @@ load_icon(__FILE__)
421
535
  end
422
536
 
423
537
  def create
424
- @log_viewer.purge
538
+ super # Create the windows
539
+ @log_viewer.purge_logs
425
540
  @request_editor.setText('')
426
541
  @requestCombo.clearItems()
427
542
 
428
543
  @start_button.text = "Start"
429
- super # Create the windows
544
+
430
545
  show(PLACEMENT_SCREEN) # Make the main window appear
431
546
  disableOptions()
547
+ @start_button.disable
432
548
  end
433
549
 
434
-
435
-
550
+
436
551
  private
552
+
437
553
 
438
554
  def updateRequestEditor(chat=nil)
439
555
  @request_editor.setText('')
@@ -447,8 +563,8 @@ load_icon(__FILE__)
447
563
 
448
564
  def createChat()
449
565
  request = @request_editor.parseRequest()
450
- puts "[#{self}] - createChat:"
451
- puts request
566
+ # puts "[#{self}] - createChat:"
567
+ # puts request
452
568
  chat = Watobo::Chat.new(request, [], :id => 0)
453
569
  end
454
570
 
@@ -466,7 +582,7 @@ load_icon(__FILE__)
466
582
  @requestCombo.clearItems()
467
583
  chat_list.each do |chat|
468
584
  text = "[#{chat.id}] #{chat.request.url}"
469
- @requestCombo.appendItem(text.slice(0..60), chat)
585
+ @requestCombo.appendItem(text, chat)
470
586
  end
471
587
  if @requestCombo.numItems > 0 then
472
588
  if @requestCombo.numItems < 10 then
@@ -497,7 +613,7 @@ load_icon(__FILE__)
497
613
  updateRequestEditor(chats.first)
498
614
  if @project then
499
615
  @project.listDirs(@site) do |dir|
500
- text = "/" + dir.slice(0..35)
616
+ text = "/" + dir #.slice(0..35)
501
617
  text.gsub!(/\/+/, '/')
502
618
  @dir_combo.appendItem(text, dir)
503
619
  end
@@ -536,6 +652,34 @@ load_icon(__FILE__)
536
652
  end
537
653
  end
538
654
  end
655
+
656
+ def select_db_path(start_path = nil)
657
+ s_path = start_path.nil? ? @path : start_path
658
+ path = FXFileDialog.getOpenDirectory(self, "Select DB Path", s_path)
659
+ unless path.empty?
660
+ set_db_path(path)
661
+ end
662
+ end
663
+
664
+ def set_db_path(path)
665
+ if db_path?(path)
666
+ puts "New DB Path >> #{path}"
667
+ @path = path
668
+ @known_db_paths << @path unless @known_db_paths.include? @path
669
+ @start_button.enable
670
+ unless @db_path_combo.findItemByData(@path)
671
+ item = @db_path_combo.appendItem(dbp)
672
+ @db_path_combo.setItemData(item, @path)
673
+ @db_path_combo.currentItem = @db_path_combo.numItems - 1
674
+
675
+ end
676
+
677
+ save_config
678
+ else
679
+ @catalog_ready = false
680
+ @start_button.disable
681
+ end
682
+ end
539
683
 
540
684
  def enableOptions()
541
685
  # @use_ssl.enable
@@ -568,6 +712,46 @@ load_icon(__FILE__)
568
712
  self.destroy
569
713
 
570
714
  end
715
+
716
+ def db_path?(path)
717
+ @db_files.each do |file|
718
+ fname = File.join( path, file)
719
+ unless File.exists?(fname)
720
+ puts "WARNING: Missing catalog db file: #{fname}"
721
+ return false
722
+ end
723
+
724
+ end
725
+
726
+ return true
727
+ end
728
+
729
+ def save_config()
730
+ wd = Watobo.working_directory
731
+
732
+ dir_name = Watobo::Utils.snakecase self.class.to_s.gsub(/.*::/,'')
733
+ path = File.join(wd, "conf", "plugins")
734
+ Dir.mkdir path unless File.exist? path
735
+ conf_dir = File.join(path, dir_name)
736
+ Dir.mkdir conf_dir unless File.exist? conf_dir
737
+ file = File.join(conf_dir, dir_name + "_config.yml")
738
+ config = {
739
+ :db_path => @path,
740
+ :path_history => @known_db_paths
741
+ }
742
+ Watobo::Utils.save_settings(file, config)
743
+ end
744
+
745
+ def load_config()
746
+ wd = Watobo.working_directory
747
+ dir_name = Watobo::Utils.snakecase self.class.to_s.gsub(/.*::/,'')
748
+ path = File.join(wd, "conf", "plugins")
749
+ Dir.mkdir path unless File.exist? path
750
+ conf_dir = File.join(path, dir_name)
751
+ Dir.mkdir conf_dir unless File.exist? conf_dir
752
+ file = File.join(conf_dir, dir_name + "_config.yml")
753
+ config = Watobo::Utils.load_settings(file)
754
+ end
571
755
 
572
756
  def start(sender, sel, item)
573
757
  if @start_button.text =~ /cancel/i then