arachni 0.2.2.2 → 0.2.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.
data/lib/ui/web/server.rb CHANGED
@@ -31,6 +31,7 @@ require Arachni::Options.instance.dir['lib'] + 'framework'
31
31
  require Arachni::Options.instance.dir['lib'] + 'rpc/xml/client/dispatcher'
32
32
  require Arachni::Options.instance.dir['lib'] + 'rpc/xml/client/instance'
33
33
  require Arachni::Options.instance.dir['lib'] + 'ui/web/report_manager'
34
+ require Arachni::Options.instance.dir['lib'] + 'ui/web/dispatcher_manager'
34
35
  require Arachni::Options.instance.dir['lib'] + 'ui/web/log'
35
36
  require Arachni::Options.instance.dir['lib'] + 'ui/web/output_stream'
36
37
 
@@ -41,14 +42,14 @@ require Arachni::Options.instance.dir['lib'] + 'ui/web/output_stream'
41
42
  # @author: Tasos "Zapotek" Laskos
42
43
  # <tasos.laskos@gmail.com>
43
44
  # <zapotek@segfault.gr>
44
- # @version: 0.1.1-pre
45
+ # @version: 0.1.3
45
46
  #
46
47
  # @see Arachni::RPC::XML::Client::Instance
47
48
  # @see Arachni::RPC::XML::Client::Dispatcher
48
49
  #
49
50
  module Web
50
51
 
51
- VERSION = '0.1.1-pre'
52
+ VERSION = '0.1.3'
52
53
 
53
54
  class Server < Sinatra::Base
54
55
 
@@ -67,6 +68,21 @@ class Server < Sinatra::Base
67
68
 
68
69
  helpers do
69
70
 
71
+ def title
72
+ main = 'Arachni - Web Application Security Scanner Framework'
73
+
74
+ sub = env['PATH_INFO'].split( '/' ).map {
75
+ |part|
76
+ normalize_section_name( part )
77
+ }.reject { |part| part.empty? }.join( ' &rarr; ' )
78
+
79
+ return sub.empty? ? main : sub + ' :: ' + main
80
+ end
81
+
82
+ def normalize_section_name( name )
83
+ name.gsub( '_', ' ' ).capitalize
84
+ end
85
+
70
86
  def report_count
71
87
  settings.reports.all.size
72
88
  end
@@ -131,7 +147,7 @@ class Server < Sinatra::Base
131
147
 
132
148
  def proc_mem( rss )
133
149
  # we assume a page size of 4096
134
- (rss.to_i * 4096 / 1024 / 1024).to_s + 'MB'
150
+ rss.to_i * 4096 / 1024 / 1024
135
151
  end
136
152
 
137
153
  def secs_to_hms( secs )
@@ -161,6 +177,7 @@ class Server < Sinatra::Base
161
177
 
162
178
  set :log, Log.new( Arachni::Options.instance, settings )
163
179
  set :reports, ReportManager.new( Arachni::Options.instance, settings )
180
+ set :dispatchers, DispatcherManager.new( Arachni::Options.instance, settings )
164
181
 
165
182
  enable :sessions
166
183
 
@@ -178,9 +195,9 @@ class Server < Sinatra::Base
178
195
  end
179
196
 
180
197
  def show( page, layout = true )
181
- if page == :dispatcher
198
+ if page == :dispatchers
182
199
  ensure_dispatcher
183
- erb :dispatcher, { :layout => true }, :stats => dispatcher_stats
200
+ erb :dispatchers, { :layout => true }, :stats => dispatcher_stats
184
201
  else
185
202
  erb page.to_sym, { :layout => layout }
186
203
  end
@@ -206,13 +223,42 @@ class Server < Sinatra::Base
206
223
  #
207
224
  # @param [Integer] port
208
225
  #
209
- def connect_to_instance( port )
226
+ def connect_to_instance( url, token = nil )
210
227
  prep_session
211
228
 
229
+ url = 'https://' + url if URI( url ).scheme != 'https'
230
+
231
+ @@connections ||= {}
232
+
212
233
  begin
213
- return Arachni::RPC::XML::Client::Instance.new( options, port_to_url( port ) )
214
- rescue Exception
215
- raise "Instance on port #{port} has shutdown."
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."
216
262
  end
217
263
  end
218
264
 
@@ -221,35 +267,41 @@ class Server < Sinatra::Base
221
267
  #
222
268
  # @param [Integer] port
223
269
  #
224
- def port_to_url( port )
225
- uri = URI( session[:dispatcher_url] )
270
+ def port_to_url( port, dispatcher_url, no_scheme = nil )
271
+ uri = URI( dispatcher_url )
226
272
  uri.port = port.to_i
227
- uri.to_s
273
+ uri = uri.to_s
274
+
275
+ uri = sanitize_url( uri ) if no_scheme
276
+ return uri
228
277
  end
229
278
 
230
- #
231
- # Provides easy access to the dispatcher and handles failure
232
- #
233
- def dispatcher
234
- begin
235
- @dispatcher ||= Arachni::RPC::XML::Client::Dispatcher.new( options, session[:dispatcher_url] )
236
- rescue Exception => e
237
- redirect '/dispatcher_error'
238
- end
279
+ def dispatchers
280
+ settings.dispatchers
239
281
  end
240
282
 
241
283
  #
242
284
  # Provides statistics about running jobs etc using the dispatcher
243
285
  #
244
286
  def dispatcher_stats
245
- stats = dispatcher.stats
246
- stats['running_jobs'].each {
247
- |job|
287
+
288
+ stats = {}
289
+ dispatchers.all.each {
290
+ |dispatcher|
291
+
248
292
  begin
249
- job['paused'] = connect_to_instance( job['port'] ).framework.paused?
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
+ }
250
301
  rescue
251
302
  end
252
303
  }
304
+
253
305
  return stats
254
306
  end
255
307
 
@@ -367,12 +419,17 @@ class Server < Sinatra::Base
367
419
  begin
368
420
  @@arachni ||= nil
369
421
  if !@@arachni
370
- instance = dispatcher.dispatch( HELPER_OWNER )
371
- @@arachni = connect_to_instance( instance['port'] )
422
+
423
+ d_url = dispatchers.all.first['url']
424
+ instance = dispatchers.connect( d_url ).dispatch( HELPER_OWNER )
425
+ instance_url = port_to_url( instance['port'], d_url )
426
+
427
+ @@arachni = connect_to_instance( instance_url, instance['token'] )
372
428
  end
429
+
373
430
  return @@arachni
374
431
  rescue
375
- redirect '/dispatcher/error'
432
+ redirect '/dispatchers/edit'
376
433
  end
377
434
  end
378
435
 
@@ -403,8 +460,6 @@ class Server < Sinatra::Base
403
460
  # Makes sure that all systems are go and populates the session with default values
404
461
  #
405
462
  def prep_session
406
- session[:dispatcher_url] ||= 'http://localhost:7331'
407
-
408
463
  ensure_dispatcher
409
464
 
410
465
  session['opts'] ||= {}
@@ -442,11 +497,7 @@ class Server < Sinatra::Base
442
497
  # @return [Bool] true if alive, redirect if not
443
498
  #
444
499
  def ensure_dispatcher
445
- begin
446
- dispatcher.alive?
447
- rescue Exception => e
448
- redirect '/dispatcher/error'
449
- end
500
+ redirect '/dispatchers/edit' if dispatchers.all.empty?
450
501
  end
451
502
 
452
503
  #
@@ -475,23 +526,33 @@ class Server < Sinatra::Base
475
526
  #
476
527
  # Kills all running instances
477
528
  #
478
- def shutdown_all
479
- settings.log.dispatcher_global_shutdown( env )
480
- dispatcher.stats['running_jobs'].each {
481
- |job|
482
- begin
483
- save_and_shutdown( connect_to_instance( job['port'] ) )
484
- rescue
529
+ def shutdown_all( url )
530
+ settings.log.dispatcher_global_shutdown( env, url )
531
+
532
+ dispatcher_stats.each_pair {
533
+ |d_url, stats|
534
+
535
+ next if sanitize_url( d_url.dup ) != url
536
+
537
+ stats['running_jobs'].each {
538
+ |job|
539
+
540
+ instance_url = port_to_url( job['port'], d_url )
485
541
  begin
486
- connect_to_instance( job['port'] ).service.shutdown!
542
+ save_and_shutdown( connect_to_instance( instance_url ) )
487
543
  rescue
488
- settings.log.instance_fucker_wont_die( env, port_to_url( job['port'] ) )
489
- next
544
+ begin
545
+ connect_to_instance( instance_url ).service.shutdown!
546
+ rescue
547
+ settings.log.instance_fucker_wont_die( env, instance_url )
548
+ next
549
+ end
490
550
  end
491
- end
492
551
 
493
- settings.log.instance_shutdown( env, port_to_url( job['port'] ) )
552
+ settings.log.instance_shutdown( env, instance_url )
553
+ }
494
554
  }
555
+
495
556
  end
496
557
 
497
558
  #
@@ -501,29 +562,39 @@ class Server < Sinatra::Base
501
562
  #
502
563
  def shutdown_zombies
503
564
  i = 0
504
- dispatcher.stats['running_jobs'].each {
505
- |job|
506
565
 
507
- begin
508
- arachni = connect_to_instance( job['port'] )
566
+ dispatcher_stats.each_pair {
567
+ |url, stats|
568
+
569
+ stats['running_jobs'].each {
570
+ |job|
509
571
 
510
572
  begin
511
- if !arachni.framework.busy? && !job['owner'] != HELPER_OWNER
512
- save_and_shutdown( arachni )
513
- settings.log.webui_zombie_cleanup( env, port_to_url( job['port'] ) )
514
- i+=1
573
+ instance_url = port_to_url( job['port'], url )
574
+ arachni = connect_to_instance( instance_url )
575
+
576
+ begin
577
+ if !arachni.framework.busy? && !job['owner'] != HELPER_OWNER
578
+ save_and_shutdown( arachni )
579
+ settings.log.webui_zombie_cleanup( env, instance_url )
580
+ i+=1
581
+ end
582
+ rescue
515
583
  end
516
- rescue
517
584
 
585
+ rescue
518
586
  end
519
-
520
- rescue
521
- end
587
+ }
522
588
  }
523
589
 
524
590
  return i
525
591
  end
526
592
 
593
+ def sanitize_url( url )
594
+ url.gsub!( 'http://', '' )
595
+ escape( url.gsub( 'https://', '' ) )
596
+ end
597
+
527
598
  get "/" do
528
599
  prep_session
529
600
  ensure_welcomed
@@ -534,18 +605,18 @@ class Server < Sinatra::Base
534
605
  erb :welcome, { :layout => true }
535
606
  end
536
607
 
537
- get "/dispatcher" do
538
- show :dispatcher
608
+ get "/dispatchers" do
609
+ show :dispatchers
539
610
  end
540
611
 
541
612
  #
542
613
  # sets the dispatcher URL
543
614
  #
544
- post "/dispatcher" do
615
+ post "/dispatchers" do
545
616
 
546
617
  if !params['url'] || params['url'].empty?
547
618
  flash[:err] = "URL cannot be empty."
548
- show :dispatcher_error
619
+ show :dispatchers_edit
549
620
  else
550
621
 
551
622
  session[:dispatcher_url] = params['url']
@@ -557,22 +628,44 @@ class Server < Sinatra::Base
557
628
  rescue
558
629
  settings.log.dispatcher_error( env, params['url'] )
559
630
  flash[:err] = "Couldn't find a dispatcher at \"#{escape( params['url'] )}\"."
560
- show :dispatcher_error
631
+ show :dispatchers_edit
561
632
  end
562
633
  end
563
634
  end
564
635
 
636
+ get '/dispatchers/edit' do
637
+ show :dispatchers_edit
638
+ end
639
+
640
+ post '/dispatchers/add' do
641
+
642
+ begin
643
+ dispatchers.alive?( params[:url] )
644
+ dispatchers.new( params )
645
+ rescue
646
+ flash[:err] = "Couldn't find a dispatcher at \"#{escape( params['url'] )}\"."
647
+ end
648
+
649
+ show :dispatchers_edit
650
+ end
651
+
652
+ post '/dispatchers/:url/delete' do
653
+ dispatchers.delete( params[:url] )
654
+ show :dispatchers_edit
655
+ end
656
+
657
+
565
658
  #
566
659
  # shuts down all instances
567
660
  #
568
- post "/dispatcher/shutdown" do
569
- shutdown_all
570
- redirect '/dispatcher'
661
+ post "/dispatchers/:url/shutdown" do
662
+ shutdown_all( params[:url] )
663
+ redirect '/dispatchers'
571
664
  end
572
665
 
573
666
 
574
- get '/dispatcher/error' do
575
- show :dispatcher_error
667
+ get '/dispatchers/error' do
668
+ show :dispatchers_edit
576
669
  end
577
670
 
578
671
  #
@@ -595,11 +688,13 @@ class Server < Sinatra::Base
595
688
  show :home
596
689
  else
597
690
 
598
- instance = dispatcher.dispatch( params['url'] )
599
- settings.log.instance_dispatched( env, port_to_url( instance['port'] ) )
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 )
600
695
  settings.log.instance_owner_assigned( env, params['url'] )
601
696
 
602
- arachni = connect_to_instance( instance['port'] )
697
+ arachni = connect_to_instance( instance_url, instance['token'] )
603
698
 
604
699
  session['opts']['settings']['url'] = params['url']
605
700
 
@@ -618,7 +713,7 @@ class Server < Sinatra::Base
618
713
 
619
714
  settings.log.scan_started( env, params['url'] )
620
715
 
621
- redirect '/instance/' + instance['port'].to_s
716
+ redirect '/instance/' + instance_url.to_s.gsub( 'https://', '' )
622
717
  end
623
718
 
624
719
  end
@@ -677,33 +772,27 @@ class Server < Sinatra::Base
677
772
  show :settings, true
678
773
  end
679
774
 
680
- get "/instance/:port" do
775
+ get "/instance/:url" do
681
776
  begin
682
- arachni = connect_to_instance( params[:port] )
777
+ arachni = connect_to_instance( params[:url] )
683
778
  erb :instance, { :layout => true }, :paused => arachni.framework.paused?, :shutdown => false
684
- rescue
685
- flash.now[:notice] = "Instance on port #{params[:port]} has been shutdown."
779
+ rescue Exception => e
780
+ flash.now[:notice] = "Instance at #{params[:url]} has been shutdown."
686
781
  erb :instance, { :layout => true }, :shutdown => true, :stats => dispatcher_stats
687
782
  end
688
783
 
689
784
  end
690
785
 
691
- get "/instance/:port/output.json" do
786
+ get "/instance/:url/output.json" do
692
787
  content_type :json
693
788
 
694
789
  begin
695
- arachni = connect_to_instance( params[:port] )
790
+ arachni = connect_to_instance( params[:url] )
696
791
  if arachni.framework.busy?
697
792
  { 'data' => OutputStream.new( arachni, 38 ).data }.to_json
698
793
  else
699
- settings.log.instance_shutdown( env, port_to_url( params[:port] ) )
794
+ settings.log.instance_shutdown( env, params[:url] )
700
795
  save_and_shutdown( arachni )
701
-
702
- # {
703
- # 'report' => '"data:text/html;base64, ' +
704
- # Base64.encode64( save_shutdown_and_show( arachni ) ) + '"'
705
- # }.to_json
706
-
707
796
  { 'status' => 'finished', 'data' => "The server has been shut down." }.to_json
708
797
  end
709
798
  rescue
@@ -711,10 +800,10 @@ class Server < Sinatra::Base
711
800
  end
712
801
  end
713
802
 
714
- get "/instance/:port/output_results.json" do
803
+ get "/instance/:url/output_results.json" do
715
804
  content_type :json
716
805
  begin
717
- arachni = connect_to_instance( params[:port] )
806
+ arachni = connect_to_instance( params[:url] )
718
807
  if !arachni.framework.paused? && arachni.framework.busy?
719
808
  out = erb( :output_results, { :layout => false }, :issues => YAML.load( arachni.framework.auditstore ).issues)
720
809
  { 'data' => out }.to_json
@@ -724,10 +813,10 @@ class Server < Sinatra::Base
724
813
  end
725
814
  end
726
815
 
727
- get "/instance/:port/stats.json" do
816
+ get "/instance/:url/stats.json" do
728
817
  content_type :json
729
818
  begin
730
- arachni = connect_to_instance( params[:port] )
819
+ arachni = connect_to_instance( params[:url] )
731
820
  stats = arachni.framework.stats
732
821
  stats['current_page'] = escape( stats['current_page'] )
733
822
  { 'refresh' => true, 'stats' => stats }.to_json
@@ -737,54 +826,54 @@ class Server < Sinatra::Base
737
826
  end
738
827
 
739
828
 
740
- post "/*/:port/pause" do
741
- arachni = connect_to_instance( params[:port] )
829
+ post "/*/:url/pause" do
830
+ arachni = connect_to_instance( params[:url] )
742
831
 
743
832
  begin
744
833
  arachni.framework.pause!
745
- settings.log.instance_paused( env, port_to_url( params[:port] ) )
834
+ settings.log.instance_paused( env, params[:url] )
746
835
 
747
- flash.now[:notice] = "Instance on port #{params[:port]} will pause as soon as the current page is audited."
836
+ flash.now[:notice] = "Instance at #{params[:url]} will pause as soon as the current page is audited."
748
837
  erb params[:splat][0].to_sym, { :layout => true }, :paused => arachni.framework.paused?, :shutdown => false, :stats => dispatcher_stats
749
838
  rescue
750
- flash.now[:notice] = "Instance on port #{params[:port]} has been shutdown."
839
+ flash.now[:notice] = "Instance at #{params[:url]} has been shutdown."
751
840
  erb params[:splat][0].to_sym, { :layout => true }, :shutdown => true, :stats => dispatcher_stats
752
841
  end
753
842
 
754
843
  end
755
844
 
756
- post "/*/:port/resume" do
757
- arachni = connect_to_instance( params[:port] )
845
+ post "/*/:url/resume" do
846
+ arachni = connect_to_instance( params[:url] )
758
847
 
759
848
  begin
760
849
  arachni.framework.resume!
761
- settings.log.instance_resumed( env, port_to_url( params[:port] ) )
850
+ settings.log.instance_resumed( env, params[:url] )
762
851
 
763
- flash.now[:notice] = "Instance on port #{params[:port]} resumes."
852
+ flash.now[:notice] = "Instance at #{params[:url]} resumes."
764
853
  erb params[:splat][0].to_sym, { :layout => true }, :paused => arachni.framework.paused?, :shutdown => false, :stats => dispatcher_stats
765
854
  rescue
766
- flash.now[:notice] = "Instance on port #{params[:port]} has been shutdown."
855
+ flash.now[:notice] = "Instance at #{params[:url]} has been shutdown."
767
856
  erb params[:splat][0].to_sym, { :layout => true }, :shutdown => true, :stats => dispatcher_stats
768
857
  end
769
858
  end
770
859
 
771
- post "/*/:port/shutdown" do
772
- arachni = connect_to_instance( params[:port] )
860
+ post "/*/:url/shutdown" do
861
+ arachni = connect_to_instance( params[:url] )
773
862
 
774
863
  begin
775
864
  arachni.framework.busy?
776
- settings.log.instance_shutdown( env, port_to_url( params[:port] ) )
865
+ settings.log.instance_shutdown( env, params[:url] )
777
866
 
778
867
  begin
779
868
  save_shutdown_and_show( arachni )
780
869
  rescue
781
- flash.now[:notice] = "Instance on port #{params[:port]} has been shutdown."
870
+ flash.now[:notice] = "Instance at #{params[:url]} has been shutdown."
782
871
  show params[:splat][0].to_sym
783
872
  ensure
784
873
  arachni.service.shutdown!
785
874
  end
786
875
  rescue
787
- flash.now[:notice] = "Instance on port #{params[:port]} has already been shutdown."
876
+ flash.now[:notice] = "Instance at #{params[:url]} has already been shutdown."
788
877
  erb params[:splat][0].to_sym, { :layout => true }, :shutdown => true, :stats => dispatcher_stats
789
878
  end
790
879
  end
@@ -176,17 +176,13 @@ class DispatcherMonitor
176
176
  #
177
177
  def usage
178
178
  print_line <<USAGE
179
- Usage: arachni_xmlrpcd_monitor [server address]
179
+ Usage: arachni_xmlrpcd_monitor https://host:port
180
180
 
181
181
  Supported options:
182
182
 
183
183
 
184
184
  SSL --------------------------
185
185
 
186
- --ssl use SSL?
187
- (If you want encryption without authentication
188
- you can skip rest of the SSL options.)
189
-
190
186
  --ssl-pkey <file> location of the SSL private key (.pem)
191
187
  (Used to verify the the client to the servers.)
192
188
 
@@ -95,7 +95,7 @@ class XMLRPC
95
95
  instance_url.port = @instance['port']
96
96
 
97
97
  # start the XMLRPC client
98
- @server = Arachni::RPC::XML::Client::Instance.new( @opts, instance_url.to_s )
98
+ @server = Arachni::RPC::XML::Client::Instance.new( @opts, instance_url.to_s, @instance['token'] )
99
99
  rescue Exception => e
100
100
  print_error( "Could not connect to server." )
101
101
  print_error( "Error: #{e.to_s}." )
@@ -662,7 +662,7 @@ class XMLRPC
662
662
  #
663
663
  def usage
664
664
  print_line <<USAGE
665
- Usage: arachni_xmlrpc --server http[s]://host:port/ \[options\] url
665
+ Usage: arachni_xmlrpc --server https://host:port \[options\] url
666
666
 
667
667
  Supported options:
668
668
 
@@ -670,10 +670,6 @@ class XMLRPC
670
670
  SSL --------------------------
671
671
  (Do *not* use encrypted keys!)
672
672
 
673
- --ssl use SSL?
674
- (If you want encryption without authentication
675
- you can skip rest of the SSL options.)
676
-
677
673
  --ssl-pkey <file> location of the SSL private key (.pem)
678
674
  (Used to verify the the client to the servers.)
679
675
 
@@ -18,7 +18,7 @@ module Modules
18
18
  # @author: Tasos "Zapotek" Laskos
19
19
  # <tasos.laskos@gmail.com>
20
20
  # <zapotek@segfault.gr>
21
- # @version: 0.2.1
21
+ # @version: 0.2.2
22
22
  #
23
23
  # @see http://cwe.mitre.org/data/definitions/22.html
24
24
  # @see http://www.owasp.org/index.php/Path_Traversal
@@ -48,7 +48,12 @@ class PathTraversal < Arachni::Module::Base
48
48
  #
49
49
 
50
50
 
51
- @__trv = '../../../../../../../../../../../../../../../../'
51
+ @__trv = [
52
+ '../../../../../../../../../../../../../../../../',
53
+ '//%252e%252e/%252e%252e/%252e%252e/%252e%252e/%252e%252e/%252e%252e/' +
54
+ '%252e%252e/%252e%252e/%252e%252e/%252e%252e/%252e%252e/%252e%252e/' +
55
+ '%252e%252e/%252e%252e/%252e%252e/%252e%252e/%252e%252e/%252e%252e/'
56
+ ]
52
57
  @__ext = [
53
58
  "",
54
59
  "\0.htm",
@@ -91,9 +96,11 @@ class PathTraversal < Arachni::Module::Base
91
96
  @__opts[:regexp] = param['regexp']
92
97
  @__ext.each {
93
98
  |ext|
94
-
95
- injection_str = @__trv + param['value'] + ext
96
- audit( injection_str, @__opts )
99
+ @__trv.each {
100
+ |trv|
101
+ injection_str = trv + param['value'] + ext
102
+ audit( injection_str, @__opts )
103
+ }
97
104
  }
98
105
  }
99
106
  end
@@ -112,7 +119,7 @@ class PathTraversal < Arachni::Module::Base
112
119
  Issue::Element::HEADER
113
120
  ],
114
121
  :author => 'Tasos "Zapotek" Laskos <tasos.laskos@gmail.com> ',
115
- :version => '0.2.1',
122
+ :version => '0.2.2',
116
123
  :references => {
117
124
  'OWASP' => 'http://www.owasp.org/index.php/Path_Traversal',
118
125
  'WASC' => 'http://projects.webappsec.org/Path-Traversal'