arachni 0.2.4 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/CHANGELOG.md +33 -0
  2. data/README.md +2 -4
  3. data/Rakefile +15 -4
  4. data/bin/arachni +0 -0
  5. data/bin/arachni_web +0 -0
  6. data/bin/arachni_web_autostart +0 -0
  7. data/bin/arachni_xmlrpc +0 -0
  8. data/bin/arachni_xmlrpcd +0 -0
  9. data/bin/arachni_xmlrpcd_monitor +0 -0
  10. data/lib/arachni.rb +1 -1
  11. data/lib/framework.rb +36 -6
  12. data/lib/http.rb +12 -5
  13. data/lib/module/auditor.rb +482 -59
  14. data/lib/module/base.rb +17 -0
  15. data/lib/module/manager.rb +26 -2
  16. data/lib/module/trainer.rb +1 -12
  17. data/lib/module/utilities.rb +12 -0
  18. data/lib/parser/auditable.rb +8 -3
  19. data/lib/parser/elements.rb +11 -0
  20. data/lib/parser/page.rb +3 -1
  21. data/lib/parser/parser.rb +130 -18
  22. data/lib/rpc/xml/server/dispatcher.rb +21 -0
  23. data/lib/spider.rb +141 -82
  24. data/lib/ui/cli/cli.rb +2 -3
  25. data/lib/ui/web/addon_manager.rb +273 -0
  26. data/lib/ui/web/addons/autodeploy.rb +172 -0
  27. data/lib/ui/web/addons/autodeploy/lib/manager.rb +291 -0
  28. data/lib/ui/web/addons/autodeploy/views/index.erb +124 -0
  29. data/lib/ui/web/addons/sample.rb +78 -0
  30. data/lib/ui/web/addons/sample/views/index.erb +4 -0
  31. data/lib/ui/web/addons/scheduler.rb +139 -0
  32. data/lib/ui/web/addons/scheduler/views/index.erb +131 -0
  33. data/lib/ui/web/addons/scheduler/views/options.erb +93 -0
  34. data/lib/ui/web/dispatcher_manager.rb +80 -13
  35. data/lib/ui/web/instance_manager.rb +87 -0
  36. data/lib/ui/web/scheduler.rb +166 -0
  37. data/lib/ui/web/server.rb +142 -202
  38. data/lib/ui/web/server/public/js/jquery-ui-timepicker.js +985 -0
  39. data/lib/ui/web/server/public/plugins/sample/style.css +0 -0
  40. data/lib/ui/web/server/public/style.css +42 -0
  41. data/lib/ui/web/server/views/addon.erb +15 -0
  42. data/lib/ui/web/server/views/addons.erb +46 -0
  43. data/lib/ui/web/server/views/dispatchers.erb +1 -1
  44. data/lib/ui/web/server/views/instance.erb +9 -11
  45. data/lib/ui/web/server/views/layout.erb +14 -1
  46. data/lib/ui/web/server/views/welcome.erb +7 -6
  47. data/lib/ui/web/utilities.rb +134 -0
  48. data/modules/audit/code_injection_timing.rb +6 -2
  49. data/modules/audit/code_injection_timing/payloads.txt +2 -2
  50. data/modules/audit/os_cmd_injection_timing.rb +7 -3
  51. data/modules/audit/os_cmd_injection_timing/payloads.txt +1 -1
  52. data/modules/audit/sqli_blind_rdiff.rb +18 -233
  53. data/modules/audit/sqli_blind_rdiff/payloads.txt +5 -0
  54. data/modules/audit/sqli_blind_timing.rb +9 -2
  55. data/path_extractors/anchors.rb +1 -1
  56. data/path_extractors/forms.rb +1 -1
  57. data/path_extractors/frames.rb +1 -1
  58. data/path_extractors/generic.rb +1 -1
  59. data/path_extractors/links.rb +1 -1
  60. data/path_extractors/meta_refresh.rb +1 -1
  61. data/path_extractors/scripts.rb +1 -1
  62. data/path_extractors/sitemap.rb +1 -1
  63. data/plugins/proxy/server.rb +3 -2
  64. data/plugins/waf_detector.rb +0 -3
  65. metadata +37 -34
  66. data/lib/anemone/cookie_store.rb +0 -35
  67. data/lib/anemone/core.rb +0 -371
  68. data/lib/anemone/exceptions.rb +0 -5
  69. data/lib/anemone/http.rb +0 -144
  70. data/lib/anemone/page.rb +0 -338
  71. data/lib/anemone/page_store.rb +0 -160
  72. data/lib/anemone/storage.rb +0 -34
  73. data/lib/anemone/storage/base.rb +0 -75
  74. data/lib/anemone/storage/exceptions.rb +0 -15
  75. data/lib/anemone/storage/mongodb.rb +0 -89
  76. data/lib/anemone/storage/pstore.rb +0 -50
  77. data/lib/anemone/storage/redis.rb +0 -90
  78. data/lib/anemone/storage/tokyo_cabinet.rb +0 -57
  79. data/lib/anemone/tentacle.rb +0 -40
data/lib/ui/web/server.rb CHANGED
@@ -28,31 +28,38 @@ module UI
28
28
 
29
29
  require Arachni::Options.instance.dir['lib'] + 'ui/cli/output'
30
30
  require Arachni::Options.instance.dir['lib'] + 'framework'
31
- require Arachni::Options.instance.dir['lib'] + 'rpc/xml/client/dispatcher'
32
- require Arachni::Options.instance.dir['lib'] + 'rpc/xml/client/instance'
31
+ require Arachni::Options.instance.dir['lib'] + 'ui/web/utilities'
33
32
  require Arachni::Options.instance.dir['lib'] + 'ui/web/report_manager'
34
33
  require Arachni::Options.instance.dir['lib'] + 'ui/web/dispatcher_manager'
34
+ require Arachni::Options.instance.dir['lib'] + 'ui/web/instance_manager'
35
+ require Arachni::Options.instance.dir['lib'] + 'ui/web/scheduler'
35
36
  require Arachni::Options.instance.dir['lib'] + 'ui/web/log'
36
37
  require Arachni::Options.instance.dir['lib'] + 'ui/web/output_stream'
37
38
 
39
+ require Arachni::Options.instance.dir['lib'] + 'ui/web/addon_manager'
40
+
41
+ #
38
42
  #
43
+ # Provides a web user interface for the Arachni Framework using Sinatra.
39
44
  #
40
- # Provides a web user interface for the Arachni Framework using Sinatra.<br/>
45
+ # It's basically an XMLRPC client for Dispatchers and Instances wearing a pretty frock.
41
46
  #
42
47
  # @author: Tasos "Zapotek" Laskos
43
48
  # <tasos.laskos@gmail.com>
44
49
  # <zapotek@segfault.gr>
45
- # @version: 0.1.4
50
+ # @version: 0.2
46
51
  #
47
52
  # @see Arachni::RPC::XML::Client::Instance
48
53
  # @see Arachni::RPC::XML::Client::Dispatcher
49
54
  #
50
55
  module Web
51
56
 
52
- VERSION = '0.1.4'
57
+ VERSION = '0.2'
53
58
 
54
59
  class Server < Sinatra::Base
55
60
 
61
+ include Utilities
62
+
56
63
  configure do
57
64
  use Rack::Flash
58
65
  use Rack::Session::Cookie
@@ -84,7 +91,7 @@ class Server < Sinatra::Base
84
91
  end
85
92
 
86
93
  def report_count
87
- settings.reports.all.size
94
+ reports.all.size
88
95
  end
89
96
 
90
97
  def plugin_has_required_file_option?( options )
@@ -116,14 +123,6 @@ class Server < Sinatra::Base
116
123
  cstr.chomp
117
124
  end
118
125
 
119
- def escape( str )
120
- CGI.escapeHTML( str )
121
- end
122
-
123
- def unescape( str )
124
- CGI.unescapeHTML( str )
125
- end
126
-
127
126
  def selected_tab?( tab )
128
127
  splits = env['PATH_INFO'].split( '/' )
129
128
  ( splits.empty? && tab == '/' ) || splits[1] == tab
@@ -175,15 +174,49 @@ class Server < Sinatra::Base
175
174
  #
176
175
  HELPER_OWNER = "WebUI helper"
177
176
 
177
+ enable :sessions
178
+
178
179
  set :log, Log.new( Arachni::Options.instance, settings )
179
180
  set :reports, ReportManager.new( Arachni::Options.instance, settings )
180
181
  set :dispatchers, DispatcherManager.new( Arachni::Options.instance, settings )
181
-
182
- enable :sessions
182
+ set :instances, InstanceManager.new( Arachni::Options.instance, settings )
183
+ set :scheduler, Scheduler.new( Arachni::Options.instance, settings )
184
+ set :addons, AddonManager.new( Arachni::Options.instance, settings )
183
185
 
184
186
  configure do
185
187
  # shit's on!
186
- settings.log.webui_started
188
+ log.webui_started
189
+ end
190
+
191
+ def addons
192
+ settings.addons
193
+ end
194
+
195
+ def log
196
+ settings.log
197
+ end
198
+
199
+ def reports
200
+ settings.reports
201
+ end
202
+
203
+ def dispatchers
204
+ settings.dispatchers
205
+ end
206
+
207
+ #
208
+ # Provides statistics about running jobs etc using the dispatcher
209
+ #
210
+ def dispatcher_stats
211
+ dispatchers.stats
212
+ end
213
+
214
+ def scheduler
215
+ settings.scheduler
216
+ end
217
+
218
+ def instances
219
+ settings.instances
187
220
  end
188
221
 
189
222
  def exception_jail( &block )
@@ -218,93 +251,6 @@ class Server < Sinatra::Base
218
251
  redirect '/welcome'
219
252
  end
220
253
 
221
- #
222
- # Provides an easy way to connect to an instance by port
223
- #
224
- # @param [Integer] port
225
- #
226
- def connect_to_instance( url, token = nil )
227
- prep_session
228
-
229
- url = 'https://' + url if URI( url ).scheme != 'https'
230
-
231
- @@connections ||= {}
232
-
233
- begin
234
- if @@connections[url] && @@connections[url].alive?
235
- return @@connections[url]
236
- end
237
- rescue
238
- end
239
-
240
- begin
241
-
242
- #
243
- # Sync up the session authentication tokens with the ones in the
244
- # class variables.
245
- #
246
- # This will allow users to still connect to instances even if they
247
- # shutdown the WebUI or removed their cookies.
248
- #
249
-
250
- @@tokens ||= {}
251
- session['tokens'] ||= {}
252
- @@tokens[url] = token if token
253
-
254
- session['tokens'].merge!( @@tokens )
255
- @@tokens.merge!( session['tokens'] )
256
- session['tokens'].merge!( @@tokens )
257
-
258
- return @@connections[url] =
259
- Arachni::RPC::XML::Client::Instance.new( options, url, session['tokens'][url] )
260
- rescue Exception => e
261
- raise "Instance at #{url} has shutdown."
262
- end
263
- end
264
-
265
- #
266
- # Converts a port to a URL instance.
267
- #
268
- # @param [Integer] port
269
- #
270
- def port_to_url( port, dispatcher_url, no_scheme = nil )
271
- uri = URI( dispatcher_url )
272
- uri.port = port.to_i
273
- uri = uri.to_s
274
-
275
- uri = sanitize_url( uri ) if no_scheme
276
- return uri
277
- end
278
-
279
- def dispatchers
280
- settings.dispatchers
281
- end
282
-
283
- #
284
- # Provides statistics about running jobs etc using the dispatcher
285
- #
286
- def dispatcher_stats
287
-
288
- stats = {}
289
- dispatchers.all.each {
290
- |dispatcher|
291
-
292
- begin
293
- stats[dispatcher['url']] = dispatchers.connect( dispatcher['url'] ).stats
294
- stats[dispatcher['url']]['running_jobs'].each {
295
- |job|
296
- begin
297
- job['paused'] = connect_to_instance( port_to_url( job['port'], dispatcher['url'] ) ).framework.paused?
298
- rescue
299
- end
300
- }
301
- rescue
302
- end
303
- }
304
-
305
- return stats
306
- end
307
-
308
254
  def options
309
255
  Arachni::Options.instance
310
256
  end
@@ -376,26 +322,6 @@ class Server < Sinatra::Base
376
322
  return cparams
377
323
  end
378
324
 
379
- def escape_hash( hash )
380
- hash.each_pair {
381
- |k, v|
382
- hash[k] = escape( hash[k] ) if hash[k].is_a?( String )
383
- hash[k] = escape_hash( v ) if v.is_a? Hash
384
- }
385
-
386
- return hash
387
- end
388
-
389
- def unescape_hash( hash )
390
- hash.each_pair {
391
- |k, v|
392
- hash[k] = unescape( hash[k] ) if hash[k].is_a?( String )
393
- hash[k] = unescape_hash( v ) if v.is_a? Hash
394
- }
395
-
396
- return hash
397
- end
398
-
399
325
  def prep_modules( params )
400
326
  return ['-'] if !params['modules']
401
327
  mods = params['modules'].keys
@@ -420,15 +346,18 @@ class Server < Sinatra::Base
420
346
  @@arachni ||= nil
421
347
  if !@@arachni
422
348
 
423
- d_url = dispatchers.all.first['url']
349
+ d_url = dispatchers.first_alive.url
350
+
424
351
  instance = dispatchers.connect( d_url ).dispatch( HELPER_OWNER )
425
- instance_url = port_to_url( instance['port'], d_url )
352
+ instance_url = instances.port_to_url( instance['port'], d_url )
426
353
 
427
- @@arachni = connect_to_instance( instance_url, instance['token'] )
354
+ @@arachni = instances.connect( instance_url, session, instance['token'] )
428
355
  end
429
356
 
430
357
  return @@arachni
431
- rescue
358
+ rescue Exception => e
359
+ # ap e
360
+ # ap e.backtrace
432
361
  redirect '/dispatchers/edit'
433
362
  end
434
363
  end
@@ -497,7 +426,7 @@ class Server < Sinatra::Base
497
426
  # @return [Bool] true if alive, redirect if not
498
427
  #
499
428
  def ensure_dispatcher
500
- redirect '/dispatchers/edit' if dispatchers.all.empty?
429
+ redirect '/dispatchers/edit' if !dispatchers.first_alive
501
430
  end
502
431
 
503
432
  #
@@ -508,7 +437,7 @@ class Server < Sinatra::Base
508
437
  #
509
438
  def save_shutdown_and_show( arachni )
510
439
  report = save_and_shutdown( arachni )
511
- settings.reports.get( 'html', settings.reports.all.last.id )
440
+ reports.get( 'html', reports.all.last.id )
512
441
  end
513
442
 
514
443
  #
@@ -518,7 +447,7 @@ class Server < Sinatra::Base
518
447
  #
519
448
  def save_and_shutdown( arachni )
520
449
  arachni.framework.clean_up!( true )
521
- report_path = settings.reports.save( arachni.framework.auditstore )
450
+ report_path = reports.save( arachni.framework.auditstore )
522
451
  arachni.service.shutdown!
523
452
  return report_path
524
453
  end
@@ -527,29 +456,29 @@ class Server < Sinatra::Base
527
456
  # Kills all running instances
528
457
  #
529
458
  def shutdown_all( url )
530
- settings.log.dispatcher_global_shutdown( env, url )
459
+ log.dispatcher_global_shutdown( env, url )
531
460
 
532
461
  dispatcher_stats.each_pair {
533
462
  |d_url, stats|
534
463
 
535
- next if sanitize_url( d_url.dup ) != url
464
+ next if remove_proto( d_url.dup ) != url
536
465
 
537
466
  stats['running_jobs'].each {
538
467
  |job|
539
468
 
540
- instance_url = port_to_url( job['port'], d_url )
469
+ instance_url = instances.port_to_url( job['port'], d_url )
541
470
  begin
542
- save_and_shutdown( connect_to_instance( instance_url ) )
471
+ save_and_shutdown( instances.connect( instance_url, session ) )
543
472
  rescue
544
473
  begin
545
- connect_to_instance( instance_url ).service.shutdown!
474
+ instances.connect( instance_url, session ).service.shutdown!
546
475
  rescue
547
- settings.log.instance_fucker_wont_die( env, instance_url )
476
+ log.instance_fucker_wont_die( env, instance_url )
548
477
  next
549
478
  end
550
479
  end
551
480
 
552
- settings.log.instance_shutdown( env, instance_url )
481
+ log.instance_shutdown( env, instance_url )
553
482
  }
554
483
  }
555
484
 
@@ -570,13 +499,13 @@ class Server < Sinatra::Base
570
499
  |job|
571
500
 
572
501
  begin
573
- instance_url = port_to_url( job['port'], url )
574
- arachni = connect_to_instance( instance_url )
502
+ instance_url = instances.port_to_url( job['port'], url )
503
+ arachni = instances.connect( instance_url, session )
575
504
 
576
505
  begin
577
506
  if !arachni.framework.busy? && !job['owner'] != HELPER_OWNER
578
507
  save_and_shutdown( arachni )
579
- settings.log.webui_zombie_cleanup( env, instance_url )
508
+ log.webui_zombie_cleanup( env, instance_url )
580
509
  i+=1
581
510
  end
582
511
  rescue
@@ -590,11 +519,6 @@ class Server < Sinatra::Base
590
519
  return i
591
520
  end
592
521
 
593
- def sanitize_url( url )
594
- url.gsub!( 'http://', '' )
595
- escape( url.gsub( 'https://', '' ) )
596
- end
597
-
598
522
  get "/" do
599
523
  prep_session
600
524
  ensure_welcomed
@@ -618,15 +542,13 @@ class Server < Sinatra::Base
618
542
  flash[:err] = "URL cannot be empty."
619
543
  show :dispatchers_edit
620
544
  else
621
-
622
- session[:dispatcher_url] = params['url']
623
- settings.log.dispatcher_selected( env, params['url'] )
545
+ log.dispatcher_selected( env, params['url'] )
624
546
  begin
625
- dispatcher.jobs
626
- settings.log.dispatcher_verified( env, params['url'] )
547
+ dispatchers.connect( url ).jobs
548
+ log.dispatcher_verified( env, params['url'] )
627
549
  redirect '/'
628
550
  rescue
629
- settings.log.dispatcher_error( env, params['url'] )
551
+ log.dispatcher_error( env, params['url'] )
630
552
  flash[:err] = "Couldn't find a dispatcher at \"#{escape( params['url'] )}\"."
631
553
  show :dispatchers_edit
632
554
  end
@@ -639,10 +561,9 @@ class Server < Sinatra::Base
639
561
 
640
562
  post '/dispatchers/add' do
641
563
 
642
- begin
643
- dispatchers.alive?( params[:url] )
644
- dispatchers.new( params )
645
- rescue
564
+ if dispatchers.alive?( params[:url] )
565
+ dispatchers.new( params[:url] )
566
+ else
646
567
  flash[:err] = "Couldn't find a dispatcher at \"#{escape( params['url'] )}\"."
647
568
  end
648
569
 
@@ -686,36 +607,36 @@ class Server < Sinatra::Base
686
607
  elsif !valid
687
608
  flash[:err] = "Invalid URL."
688
609
  show :home
610
+ elsif !params['dispatcher'] || params['dispatcher'].empty?
611
+ flash[:err] = "Please select a Dispatcher."
612
+ show :home
689
613
  else
690
614
 
691
- instance = dispatchers.connect( params['dispatcher'] ).dispatch( params['url'] )
692
- instance_url = port_to_url( instance['port'], params['dispatcher'] )
693
-
694
- settings.log.instance_dispatched( env, instance_url )
695
- settings.log.instance_owner_assigned( env, params['url'] )
696
-
697
- arachni = connect_to_instance( instance_url, instance['token'] )
698
-
699
- session['opts']['settings']['url'] = params['url']
615
+ session['opts']['settings']['url'] = params[:url]
700
616
 
701
617
  unescape_hash( session['opts'] )
702
-
703
618
  session['opts']['settings']['audit_links'] = true if session['opts']['settings']['audit_links']
704
619
  session['opts']['settings']['audit_forms'] = true if session['opts']['settings']['audit_forms']
705
620
  session['opts']['settings']['audit_cookies'] = true if session['opts']['settings']['audit_cookies']
706
621
  session['opts']['settings']['audit_headers'] = true if session['opts']['settings']['audit_headers']
707
622
 
708
- opts = prep_opts( session['opts']['settings'] )
709
- arachni.opts.set( opts )
710
- arachni.modules.load( session['opts']['modules'] )
711
- arachni.plugins.load( YAML::load( session['opts']['plugins'] ) )
712
- arachni.framework.run
713
-
714
- settings.log.scan_started( env, params['url'] )
715
-
623
+ opts = {}
624
+ opts['settings'] = prep_opts( session['opts']['settings'] )
625
+ opts['plugins'] = YAML::load( session['opts']['plugins'] )
626
+ opts['modules'] = session['opts']['modules']
627
+
628
+ job = Scheduler::Job.new(
629
+ :dispatcher => params[:dispatcher],
630
+ :url => params[:url],
631
+ :opts => opts.to_yaml,
632
+ :owner_addr => env['REMOTE_ADDR'],
633
+ :owner_host => env['REMOTE_HOST'],
634
+ :created_at => Time.now
635
+ )
636
+
637
+ instance_url = scheduler.run( job, env, session )
716
638
  redirect '/instance/' + instance_url.to_s.gsub( 'https://', '' )
717
639
  end
718
-
719
640
  end
720
641
 
721
642
  get "/modules" do
@@ -774,11 +695,11 @@ class Server < Sinatra::Base
774
695
 
775
696
  get "/instance/:url" do
776
697
  begin
777
- arachni = connect_to_instance( params[:url] )
698
+ arachni = instances.connect( params[:url], session )
778
699
  erb :instance, { :layout => true }, :paused => arachni.framework.paused?, :shutdown => false
779
700
  rescue Exception => e
780
701
  flash.now[:notice] = "Instance at #{params[:url]} has been shutdown."
781
- erb :instance, { :layout => true }, :shutdown => true, :stats => dispatcher_stats
702
+ erb :instance, { :layout => true }, :shutdown => true
782
703
  end
783
704
 
784
705
  end
@@ -787,17 +708,20 @@ class Server < Sinatra::Base
787
708
  content_type :json
788
709
 
789
710
  begin
790
- arachni = connect_to_instance( params[:url] )
711
+ arachni = instances.connect( params[:url], session )
791
712
  if arachni.framework.busy?
792
713
  @@output_streams ||= {}
793
714
  @@output_streams[params[:url]] ||= OutputStream.new( arachni, 38 )
794
715
  { 'data' => @@output_streams[params[:url]].data }.to_json
795
716
  else
796
- settings.log.instance_shutdown( env, params[:url] )
717
+ log.instance_shutdown( env, params[:url] )
797
718
  save_and_shutdown( arachni )
798
719
  { 'status' => 'finished', 'data' => "The server has been shut down." }.to_json
799
720
  end
800
- rescue
721
+ rescue IOError, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
722
+ Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
723
+ { 'data' => "<strong>Connection error, retrying...</strong>" }.to_json
724
+ rescue Exception => e
801
725
  { 'status' => 'finished', 'data' => "The server has been shut down." }.to_json
802
726
  end
803
727
  end
@@ -805,12 +729,15 @@ class Server < Sinatra::Base
805
729
  get "/instance/:url/output_results.json" do
806
730
  content_type :json
807
731
  begin
808
- arachni = connect_to_instance( params[:url] )
732
+ arachni = instances.connect( params[:url], session )
809
733
  if !arachni.framework.paused? && arachni.framework.busy?
810
- out = erb( :output_results, { :layout => false }, :issues => YAML.load( arachni.framework.auditstore ).issues)
734
+ out = erb( :output_results, { :layout => false }, :issues => YAML.load( arachni.framework.auditstore ).issues )
811
735
  { 'data' => out }.to_json
812
736
  end
813
- rescue
737
+ rescue IOError, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
738
+ Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
739
+ { 'data' => "<strong>Connection error, retrying...</strong>" }.to_json
740
+ rescue Exception => e
814
741
  { 'data' => "The server has been shut down." }.to_json
815
742
  end
816
743
  end
@@ -818,8 +745,8 @@ class Server < Sinatra::Base
818
745
  get "/instance/:url/stats.json" do
819
746
  content_type :json
820
747
  begin
821
- arachni = connect_to_instance( params[:url] )
822
- stats = arachni.framework.stats
748
+ arachni = instances.connect( params[:url], session )
749
+ stats = arachni.framework.stats( true )
823
750
  stats['current_page'] = escape( stats['current_page'] )
824
751
  { 'refresh' => true, 'stats' => stats }.to_json
825
752
  rescue
@@ -829,11 +756,11 @@ class Server < Sinatra::Base
829
756
 
830
757
 
831
758
  post "/*/:url/pause" do
832
- arachni = connect_to_instance( params[:url] )
759
+ arachni = instances.connect( params[:url], session )
833
760
 
834
761
  begin
835
762
  arachni.framework.pause!
836
- settings.log.instance_paused( env, params[:url] )
763
+ log.instance_paused( env, params[:url] )
837
764
 
838
765
  flash.now[:notice] = "Instance at #{params[:url]} will pause as soon as the current page is audited."
839
766
  erb params[:splat][0].to_sym, { :layout => true }, :paused => arachni.framework.paused?, :shutdown => false, :stats => dispatcher_stats
@@ -845,11 +772,11 @@ class Server < Sinatra::Base
845
772
  end
846
773
 
847
774
  post "/*/:url/resume" do
848
- arachni = connect_to_instance( params[:url] )
775
+ arachni = instances.connect( params[:url], session )
849
776
 
850
777
  begin
851
778
  arachni.framework.resume!
852
- settings.log.instance_resumed( env, params[:url] )
779
+ log.instance_resumed( env, params[:url] )
853
780
 
854
781
  flash.now[:notice] = "Instance at #{params[:url]} resumes."
855
782
  erb params[:splat][0].to_sym, { :layout => true }, :paused => arachni.framework.paused?, :shutdown => false, :stats => dispatcher_stats
@@ -860,11 +787,11 @@ class Server < Sinatra::Base
860
787
  end
861
788
 
862
789
  post "/*/:url/shutdown" do
863
- arachni = connect_to_instance( params[:url] )
790
+ arachni = instances.connect( params[:url], session )
864
791
 
865
792
  begin
866
793
  arachni.framework.busy?
867
- settings.log.instance_shutdown( env, params[:url] )
794
+ log.instance_shutdown( env, params[:url] )
868
795
 
869
796
  begin
870
797
  save_shutdown_and_show( arachni )
@@ -881,38 +808,51 @@ class Server < Sinatra::Base
881
808
  end
882
809
 
883
810
  get "/reports" do
884
- erb :reports, { :layout => true }, :reports => settings.reports.all( :order => :datestamp.desc ),
885
- :available => settings.reports.available
811
+ erb :reports, { :layout => true }, :reports => reports.all( :order => :datestamp.desc ),
812
+ :available => reports.available
886
813
  end
887
814
 
888
815
  get '/reports/formats' do
889
- erb :report_formats, { :layout => true }, :reports => settings.reports.available
816
+ erb :report_formats, { :layout => true }, :reports => reports.available
890
817
  end
891
818
 
892
819
  post '/reports/delete' do
893
- settings.reports.delete_all
894
- settings.log.reports_deleted( env )
820
+ reports.delete_all
821
+ log.reports_deleted( env )
895
822
 
896
823
  redirect '/reports'
897
824
  end
898
825
 
899
826
  post '/report/:id/delete' do
900
- settings.reports.delete( params[:id] )
901
- settings.log.report_deleted( env, params[:id] )
827
+ reports.delete( params[:id] )
828
+ log.report_deleted( env, params[:id] )
902
829
 
903
830
  redirect '/reports'
904
831
  end
905
832
 
906
833
  get '/report/:id.:type' do
907
- settings.log.report_converted( env, params[:id] + '.' + params[:type] )
834
+ log.report_converted( env, params[:id] + '.' + params[:type] )
908
835
  content_type( params[:type], :default => 'application/octet-stream' )
909
- settings.reports.get( params[:type], params[:id] )
836
+ reports.get( params[:type], params[:id] )
910
837
  end
911
838
 
912
839
  get '/log' do
913
- erb :log, { :layout => true }, :entries => settings.log.entry.all.reverse
840
+ erb :log, { :layout => true }, :entries => log.entry.all.reverse
841
+ end
842
+
843
+ get '/addons' do
844
+ erb :addons
914
845
  end
915
846
 
847
+ post '/addons' do
848
+ params['addons'] ||= {}
849
+ addon_names = params['addons'].keys
850
+
851
+ addons.enable!( addon_names )
852
+ erb :addons
853
+ end
854
+
855
+
916
856
  # override run! using this patch: https://github.com/sinatra/sinatra/pull/132
917
857
  def self.run!( options = {} )
918
858
  set options
@@ -967,7 +907,7 @@ class Server < Sinatra::Base
967
907
 
968
908
  at_exit do
969
909
 
970
- settings.log.webui_shutdown
910
+ log.webui_shutdown
971
911
 
972
912
  begin
973
913
  # shutdown our helper instance