arachni 0.2.4 → 0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +33 -0
- data/README.md +2 -4
- data/Rakefile +15 -4
- data/bin/arachni +0 -0
- data/bin/arachni_web +0 -0
- data/bin/arachni_web_autostart +0 -0
- data/bin/arachni_xmlrpc +0 -0
- data/bin/arachni_xmlrpcd +0 -0
- data/bin/arachni_xmlrpcd_monitor +0 -0
- data/lib/arachni.rb +1 -1
- data/lib/framework.rb +36 -6
- data/lib/http.rb +12 -5
- data/lib/module/auditor.rb +482 -59
- data/lib/module/base.rb +17 -0
- data/lib/module/manager.rb +26 -2
- data/lib/module/trainer.rb +1 -12
- data/lib/module/utilities.rb +12 -0
- data/lib/parser/auditable.rb +8 -3
- data/lib/parser/elements.rb +11 -0
- data/lib/parser/page.rb +3 -1
- data/lib/parser/parser.rb +130 -18
- data/lib/rpc/xml/server/dispatcher.rb +21 -0
- data/lib/spider.rb +141 -82
- data/lib/ui/cli/cli.rb +2 -3
- data/lib/ui/web/addon_manager.rb +273 -0
- data/lib/ui/web/addons/autodeploy.rb +172 -0
- data/lib/ui/web/addons/autodeploy/lib/manager.rb +291 -0
- data/lib/ui/web/addons/autodeploy/views/index.erb +124 -0
- data/lib/ui/web/addons/sample.rb +78 -0
- data/lib/ui/web/addons/sample/views/index.erb +4 -0
- data/lib/ui/web/addons/scheduler.rb +139 -0
- data/lib/ui/web/addons/scheduler/views/index.erb +131 -0
- data/lib/ui/web/addons/scheduler/views/options.erb +93 -0
- data/lib/ui/web/dispatcher_manager.rb +80 -13
- data/lib/ui/web/instance_manager.rb +87 -0
- data/lib/ui/web/scheduler.rb +166 -0
- data/lib/ui/web/server.rb +142 -202
- data/lib/ui/web/server/public/js/jquery-ui-timepicker.js +985 -0
- data/lib/ui/web/server/public/plugins/sample/style.css +0 -0
- data/lib/ui/web/server/public/style.css +42 -0
- data/lib/ui/web/server/views/addon.erb +15 -0
- data/lib/ui/web/server/views/addons.erb +46 -0
- data/lib/ui/web/server/views/dispatchers.erb +1 -1
- data/lib/ui/web/server/views/instance.erb +9 -11
- data/lib/ui/web/server/views/layout.erb +14 -1
- data/lib/ui/web/server/views/welcome.erb +7 -6
- data/lib/ui/web/utilities.rb +134 -0
- data/modules/audit/code_injection_timing.rb +6 -2
- data/modules/audit/code_injection_timing/payloads.txt +2 -2
- data/modules/audit/os_cmd_injection_timing.rb +7 -3
- data/modules/audit/os_cmd_injection_timing/payloads.txt +1 -1
- data/modules/audit/sqli_blind_rdiff.rb +18 -233
- data/modules/audit/sqli_blind_rdiff/payloads.txt +5 -0
- data/modules/audit/sqli_blind_timing.rb +9 -2
- data/path_extractors/anchors.rb +1 -1
- data/path_extractors/forms.rb +1 -1
- data/path_extractors/frames.rb +1 -1
- data/path_extractors/generic.rb +1 -1
- data/path_extractors/links.rb +1 -1
- data/path_extractors/meta_refresh.rb +1 -1
- data/path_extractors/scripts.rb +1 -1
- data/path_extractors/sitemap.rb +1 -1
- data/plugins/proxy/server.rb +3 -2
- data/plugins/waf_detector.rb +0 -3
- metadata +37 -34
- data/lib/anemone/cookie_store.rb +0 -35
- data/lib/anemone/core.rb +0 -371
- data/lib/anemone/exceptions.rb +0 -5
- data/lib/anemone/http.rb +0 -144
- data/lib/anemone/page.rb +0 -338
- data/lib/anemone/page_store.rb +0 -160
- data/lib/anemone/storage.rb +0 -34
- data/lib/anemone/storage/base.rb +0 -75
- data/lib/anemone/storage/exceptions.rb +0 -15
- data/lib/anemone/storage/mongodb.rb +0 -89
- data/lib/anemone/storage/pstore.rb +0 -50
- data/lib/anemone/storage/redis.rb +0 -90
- data/lib/anemone/storage/tokyo_cabinet.rb +0 -57
- 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'] + '
|
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
|
-
#
|
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.
|
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.
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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 =
|
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.
|
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
|
-
|
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 =
|
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
|
-
|
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
|
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(
|
471
|
+
save_and_shutdown( instances.connect( instance_url, session ) )
|
543
472
|
rescue
|
544
473
|
begin
|
545
|
-
|
474
|
+
instances.connect( instance_url, session ).service.shutdown!
|
546
475
|
rescue
|
547
|
-
|
476
|
+
log.instance_fucker_wont_die( env, instance_url )
|
548
477
|
next
|
549
478
|
end
|
550
479
|
end
|
551
480
|
|
552
|
-
|
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 =
|
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
|
-
|
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
|
-
|
626
|
-
|
547
|
+
dispatchers.connect( url ).jobs
|
548
|
+
log.dispatcher_verified( env, params['url'] )
|
627
549
|
redirect '/'
|
628
550
|
rescue
|
629
|
-
|
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
|
-
|
643
|
-
dispatchers.
|
644
|
-
|
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
|
-
|
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 =
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
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 =
|
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
|
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 =
|
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
|
-
|
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 =
|
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 =
|
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 =
|
759
|
+
arachni = instances.connect( params[:url], session )
|
833
760
|
|
834
761
|
begin
|
835
762
|
arachni.framework.pause!
|
836
|
-
|
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 =
|
775
|
+
arachni = instances.connect( params[:url], session )
|
849
776
|
|
850
777
|
begin
|
851
778
|
arachni.framework.resume!
|
852
|
-
|
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 =
|
790
|
+
arachni = instances.connect( params[:url], session )
|
864
791
|
|
865
792
|
begin
|
866
793
|
arachni.framework.busy?
|
867
|
-
|
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 =>
|
885
|
-
: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 =>
|
816
|
+
erb :report_formats, { :layout => true }, :reports => reports.available
|
890
817
|
end
|
891
818
|
|
892
819
|
post '/reports/delete' do
|
893
|
-
|
894
|
-
|
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
|
-
|
901
|
-
|
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
|
-
|
834
|
+
log.report_converted( env, params[:id] + '.' + params[:type] )
|
908
835
|
content_type( params[:type], :default => 'application/octet-stream' )
|
909
|
-
|
836
|
+
reports.get( params[:type], params[:id] )
|
910
837
|
end
|
911
838
|
|
912
839
|
get '/log' do
|
913
|
-
erb :log, { :layout => true }, :entries =>
|
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
|
-
|
910
|
+
log.webui_shutdown
|
971
911
|
|
972
912
|
begin
|
973
913
|
# shutdown our helper instance
|