arachni 0.2.4 → 0.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 (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