Module: Arachni::Utilities

Overview

Includes some useful methods for the system.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.available_port_mutexObject



358
359
360
# File 'lib/arachni/utilities.rb', line 358

def self.available_port_mutex
    @available_port_mutex ||= Mutex.new
end

Instance Method Details

#available_portFixnum



343
344
345
346
347
348
349
350
351
352
353
354
355
356
# File 'lib/arachni/utilities.rb', line 343

def available_port
    available_port_mutex.synchronize do
        @used_ports ||= Set.new

        loop do
            port = self.rand_port

            if port_available?( port ) && !@used_ports.include?( port )
                @used_ports << port
                return port
            end
        end
    end
end

#bytes_to_kilobytes(bytes) ⇒ Object



415
416
417
# File 'lib/arachni/utilities.rb', line 415

def bytes_to_kilobytes( bytes )
    (bytes / 1024.0 ).round( 3 )
end

#bytes_to_megabytes(bytes) ⇒ Object



411
412
413
# File 'lib/arachni/utilities.rb', line 411

def bytes_to_megabytes( bytes )
    (bytes / 1024.0 / 1024.0).round( 3 )
end

#caller_nameString



22
23
24
# File 'lib/arachni/utilities.rb', line 22

def caller_name
    File.basename( caller_path( 3 ), '.rb' )
end

#caller_path(offset = 2) ⇒ String



28
29
30
# File 'lib/arachni/utilities.rb', line 28

def caller_path( offset = 2 )
    ::Kernel.caller[offset].split( /:(\d+):in/ ).first
end


98
99
100
# File 'lib/arachni/utilities.rb', line 98

def cookie_decode( *args )
    Cookie.decode( *args )
end


93
94
95
# File 'lib/arachni/utilities.rb', line 93

def cookie_encode( *args )
    Cookie.encode( *args )
end

#cookies_from_file(*args) ⇒ Object



88
89
90
# File 'lib/arachni/utilities.rb', line 88

def cookies_from_file( *args )
    Cookie.from_file( *args )
end

#cookies_from_parser(*args) ⇒ Object



78
79
80
# File 'lib/arachni/utilities.rb', line 78

def cookies_from_parser( *args )
    Cookie.from_parser(*args )
end

#cookies_from_response(*args) ⇒ Object



73
74
75
# File 'lib/arachni/utilities.rb', line 73

def cookies_from_response( *args )
    Cookie.from_response( *args )
end

#exception_jail(raise_exception = true, &block) ⇒ Object

Wraps the block in exception handling code and runs it.



424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
# File 'lib/arachni/utilities.rb', line 424

def exception_jail( raise_exception = true, &block )
    block.call
rescue => e
    if respond_to?( :print_error ) && respond_to?( :print_exception )
        print_exception e
        print_error
        print_error 'Parent:'
        print_error  self.class.to_s
        print_error
        print_error 'Block:'
        print_error block.to_s
        print_error
        print_error 'Caller:'
        ::Kernel.caller.each { |l| print_error l }
        print_error '-' * 80
    end

    raise e if raise_exception

    nil
end

#exclude_path?(url) ⇒ Bool

Decides whether the given url matches any framework exclusion rules.



208
209
210
# File 'lib/arachni/utilities.rb', line 208

def exclude_path?( url )
    uri_parse( url ).scope.exclude?
end

#follow_protocol?(url, reference = Options.url) ⇒ Bool

Decides whether the given url has an acceptable protocol.



250
251
252
# File 'lib/arachni/utilities.rb', line 250

def follow_protocol?( url, reference = Options.url )
    uri_parse( url ).scope.follow_protocol?( reference )
end

#form_decode(*args) ⇒ Object



53
54
55
# File 'lib/arachni/utilities.rb', line 53

def form_decode( *args )
    Form.decode( *args )
end

#form_encode(*args) ⇒ Object



48
49
50
# File 'lib/arachni/utilities.rb', line 48

def form_encode( *args )
    Form.encode( *args )
end

#forms_from_parser(*args) ⇒ Object



43
44
45
# File 'lib/arachni/utilities.rb', line 43

def forms_from_parser( *args )
    Form.from_parser(*args )
end

#forms_from_response(*args) ⇒ Object



38
39
40
# File 'lib/arachni/utilities.rb', line 38

def forms_from_response( *args )
    Form.from_response( *args )
end

#full_and_absolute_url?(url) ⇒ Boolean



162
163
164
# File 'lib/arachni/utilities.rb', line 162

def full_and_absolute_url?( url )
    Arachni::URI.full_and_absolute?( url.to_s )
end

#generate_tokenObject



374
375
376
# File 'lib/arachni/utilities.rb', line 374

def generate_token
    SecureRandom.hex
end

#get_path(url) ⇒ String

Returns path Full URL up to the path component (no resource, query etc.).



172
173
174
# File 'lib/arachni/utilities.rb', line 172

def get_path( url )
    uri_parse( url ).up_to_path
end

#hms_to_seconds(time) ⇒ Object



404
405
406
407
408
409
# File 'lib/arachni/utilities.rb', line 404

def hms_to_seconds( time )
    a = [1, 60, 3600] * 2
    time.split( /[:\.]/ ).map { |t| t.to_i * a.pop }.inject(&:+)
rescue
    0
end

#html_decode(str) ⇒ Object Also known as: html_unescape



112
113
114
# File 'lib/arachni/utilities.rb', line 112

def html_decode( str )
    ::CGI.unescapeHTML( str.to_s )
end

#html_encode(str) ⇒ Object Also known as: html_escape



117
118
119
# File 'lib/arachni/utilities.rb', line 117

def html_encode( str )
    ::CGI.escapeHTML( str.to_s )
end

#include_path?(url) ⇒ Bool

Decides whether the given url matches any framework inclusion rules.

See Also:

  • URI.include?
  • Options#include


220
221
222
# File 'lib/arachni/utilities.rb', line 220

def include_path?( url )
    uri_parse( url ).scope.include?
end


68
69
70
# File 'lib/arachni/utilities.rb', line 68

def links_from_parser( *args )
    Link.from_parser(*args )
end


63
64
65
# File 'lib/arachni/utilities.rb', line 63

def links_from_response( *args )
    Link.from_response( *args )
end

#normalize_url(url) ⇒ Object



157
158
159
# File 'lib/arachni/utilities.rb', line 157

def normalize_url( url )
    URI.normalize( url )
end

#page_from_response(*args) ⇒ Object

See Also:



103
104
105
# File 'lib/arachni/utilities.rb', line 103

def page_from_response( *args )
    Page.from_response( *args )
end

#page_from_url(*args, &block) ⇒ Object

See Also:



108
109
110
# File 'lib/arachni/utilities.rb', line 108

def page_from_url( *args, &block )
    Page.from_url( *args, &block )
end


83
84
85
# File 'lib/arachni/utilities.rb', line 83

def parse_set_cookie( *args )
    Cookie.parse_set_cookie( *args )
end

#path_in_domain?(url, reference = Options.url) ⇒ Bool

Compares 2 urls in order to decide whether or not they belong to the same domain.

See Also:



196
197
198
# File 'lib/arachni/utilities.rb', line 196

def path_in_domain?( url, reference = Options.url )
    uri_parse( url ).scope.in_domain?( reference )
end

#path_too_deep?(url) ⇒ Bool

Returns true is the path exceeds the framework limit, false otherwise.



182
183
184
# File 'lib/arachni/utilities.rb', line 182

def path_too_deep?( url )
    uri_parse( url ).scope.too_deep?
end

#port_available?(port) ⇒ Bool

Checks whether the port number is available.



383
384
385
386
387
388
389
390
391
392
# File 'lib/arachni/utilities.rb', line 383

def port_available?( port )
    begin
        socket = ::Socket.new( :INET, :STREAM, 0 )
        socket.bind( ::Socket.sockaddr_in( port, '127.0.0.1' ) )
        socket.close
        true
    rescue Errno::EADDRINUSE, Errno::EACCES
        false
    end
end

#rand_portInteger

Returns Random port within the user specified range.



367
368
369
370
371
372
# File 'lib/arachni/utilities.rb', line 367

def rand_port
    first, last = Options.dispatcher.instance_port_range
    range = (first..last).to_a

    range[ rand( range.last - range.first ) ]
end

#random_seedString



33
34
35
# File 'lib/arachni/utilities.rb', line 33

def random_seed
    @@random_seed ||= generate_token
end

#redundant_path?(url, update_counters = false) ⇒ Bool

Checks if the provided URL matches a redundant filter and decreases its counter if so.

If a filter's counter has reached 0 the method returns true.

See Also:

  • OptionGroups::Scope#redundant_path_patterns?


235
236
237
# File 'lib/arachni/utilities.rb', line 235

def redundant_path?( url, update_counters = false )
    uri_parse( url ).scope.redundant?( update_counters )
end

#regexp_array_match(regexps, str) ⇒ Object



446
447
448
449
450
451
452
453
454
# File 'lib/arachni/utilities.rb', line 446

def regexp_array_match( regexps, str )
    regexps = [regexps].flatten.compact.
        map { |s| s.is_a?( Regexp ) ? s : Regexp.new( s.to_s ) }
    return true if regexps.empty?

    cnt = 0
    regexps.each { |filter| cnt += 1 if str =~ filter }
    cnt == regexps.size
end

#remove_constants(mod, skip = []) ⇒ Object



456
457
458
459
460
461
462
463
464
465
466
467
468
# File 'lib/arachni/utilities.rb', line 456

def remove_constants( mod, skip = [] )
    return if skip.include?( mod )
    return if !(mod.is_a?( Class ) || mod.is_a?( Module )) ||
        !mod.to_s.start_with?( 'Arachni' )

    parent = Object
    mod.to_s.split( '::' )[0..-2].each do |ancestor|
        parent = parent.const_get( ancestor.to_sym )
    end

    mod.constants.each { |m| mod.send( :remove_const, m ) }
    nil
end

#request_parse_body(*args) ⇒ Object



58
59
60
# File 'lib/arachni/utilities.rb', line 58

def request_parse_body( *args )
    HTTP::Request.parse_body( *args )
end

#seconds_to_hms(seconds) ⇒ String



398
399
400
401
402
# File 'lib/arachni/utilities.rb', line 398

def seconds_to_hms( seconds )
    seconds = seconds.to_i
    [seconds / 3600, seconds / 60 % 60, seconds % 60].
        map { |t| t.to_s.rjust( 2, '0' ) }.join( ':' )
end

#skip_page?(page) ⇒ Bool

Determines whether or not the given Page.

See Also:



304
305
306
# File 'lib/arachni/utilities.rb', line 304

def skip_page?( page )
    page.scope.out?
end

#skip_path?(path) ⇒ Bool

Note:

Does not call #redundant_path?.

Decides whether or not the provided path should be skipped based on:



266
267
268
269
270
271
272
273
# File 'lib/arachni/utilities.rb', line 266

def skip_path?( path )
    return true if !path

    parsed = uri_parse( path.to_s )
    return true if !parsed

    parsed.scope.out?
end

#skip_resource?(resource) ⇒ Bool

Determines whether or not the given resource should be ignored depending on its type and content.

See Also:

  • #skip_path?
  • ignore_page?
  • ignore_response?
  • Options#ignore?


328
329
330
331
332
333
334
335
336
337
338
339
# File 'lib/arachni/utilities.rb', line 328

def skip_resource?( resource )
    case resource
        when Page
            skip_page?( resource )

        when Arachni::HTTP::Response
            skip_response?( resource )

        else
            skip_path? resource.to_s
    end
end

#skip_response?(response) ⇒ Bool

Determines whether or not the given HTTP::Response should be ignored.

See Also:



287
288
289
# File 'lib/arachni/utilities.rb', line 287

def skip_response?( response )
    response.scope.out?
end

#to_absolute(relative_url, reference_url = Options.instance.url.to_s) ⇒ Object



152
153
154
# File 'lib/arachni/utilities.rb', line 152

def to_absolute( relative_url, reference_url = Options.instance.url.to_s )
    URI.to_absolute( relative_url, reference_url )
end

#uri_decode(url) ⇒ Object



138
139
140
# File 'lib/arachni/utilities.rb', line 138

def uri_decode( url )
    URI.decode( url )
end

#uri_encode(*args) ⇒ Object



133
134
135
# File 'lib/arachni/utilities.rb', line 133

def uri_encode( *args )
    URI.encode( *args )
end

#uri_parse(url) ⇒ Object

See Also:



128
129
130
# File 'lib/arachni/utilities.rb', line 128

def uri_parse( url )
    URI.parse( url )
end

#uri_parse_query(url) ⇒ Object



147
148
149
# File 'lib/arachni/utilities.rb', line 147

def uri_parse_query( url )
    URI.parse_query( url )
end

#uri_parserURI::Parser



123
124
125
# File 'lib/arachni/utilities.rb', line 123

def uri_parser
    URI.parser
end

#uri_rewrite(*args) ⇒ Object



142
143
144
# File 'lib/arachni/utilities.rb', line 142

def uri_rewrite( *args )
    URI.rewrite( *args )
end