Module: Arachni::Framework::Parts::Audit

Includes:
Support::Mixins::Observable
Included in:
Arachni::Framework
Defined in:
lib/arachni/framework/parts/audit.rb

Overview

Provides Page audit functionality and everything related to it, like handling the Session and Trainer.

Author:

  • Tasos “Zapotek” Laskos <tasos.laskos@arachni-scanner.com>

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Support::Mixins::Observable

included

Methods included from Utilities

#available_port, available_port_mutex, #bytes_to_kilobytes, #bytes_to_megabytes, #caller_name, #caller_path, #cookie_decode, #cookie_encode, #cookies_from_file, #cookies_from_parser, #cookies_from_response, #exception_jail, #exclude_path?, #follow_protocol?, #form_decode, #form_encode, #forms_from_parser, #forms_from_response, #full_and_absolute_url?, #generate_token, #get_path, #hms_to_seconds, #html_decode, #html_encode, #include_path?, #links_from_parser, #links_from_response, #normalize_url, #page_from_response, #page_from_url, #parse_set_cookie, #path_in_domain?, #path_too_deep?, #port_available?, #rand_port, #random_seed, #redundant_path?, #regexp_array_match, #remove_constants, #request_parse_body, #seconds_to_hms, #skip_page?, #skip_path?, #skip_resource?, #skip_response?, #to_absolute, #uri_decode, #uri_encode, #uri_parse, #uri_parse_query, #uri_parser, #uri_rewrite

Methods included from UI::Output

#debug?, #debug_level_1?, #debug_level_2?, #debug_level_3?, #debug_level_4?, #debug_off, #debug_on, #disable_only_positives, #included, #mute, #muted?, #only_positives, #only_positives?, #print_bad, #print_debug, #print_debug_backtrace, #print_debug_level_1, #print_debug_level_2, #print_debug_level_3, #print_debug_level_4, #print_error, #print_error_backtrace, #print_exception, #print_info, #print_line, #print_ok, #print_status, #print_verbose, #reroute_to_file, #reroute_to_file?, reset_output_options, #unmute, #verbose?, #verbose_on

Instance Attribute Details

#failuresArray<String> (readonly)

Returns Page URLs which elicited no response from the server and were not audited. Not determined by HTTP status codes, we're talking network failures here.

Returns:

  • (Array<String>)

    Page URLs which elicited no response from the server and were not audited. Not determined by HTTP status codes, we're talking network failures here.



42
43
44
# File 'lib/arachni/framework/parts/audit.rb', line 42

def failures
  @failures
end

#httpArachni::HTTP (readonly)

Returns:



37
38
39
# File 'lib/arachni/framework/parts/audit.rb', line 37

def http
  @http
end

#sessionSession (readonly)

Returns Web application session manager.

Returns:

  • (Session)

    Web application session manager.



34
35
36
# File 'lib/arachni/framework/parts/audit.rb', line 34

def session
  @session
end

#trainerTrainer (readonly)

Returns:



30
31
32
# File 'lib/arachni/framework/parts/audit.rb', line 30

def trainer
  @trainer
end

Instance Method Details

#after_page_audit(&block) ⇒ Object



27
# File 'lib/arachni/framework/parts/audit.rb', line 27

advertise :after_page_audit

#audit_page(page) ⇒ Object

Note:
Note:

It will audit just the given `page` and not any subsequent pages discovered by the Trainer – i.e. ignore any new elements that might appear as a result.

Note:

It will pass the `page` to the BrowserCluster for analysis if the DOM depth limit has not been reached and push resulting pages to #push_to_page_queue but will not audit those pages either.

Parameters:

  • page (Page)

    Runs loaded checks against `page`



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/arachni/framework/parts/audit.rb', line 70

def audit_page( page )
    return if !page

    if page.scope.out?
        print_info "Ignoring page due to exclusion criteria: #{page.dom.url}"
        return false
    end

    # Initialize the BrowserCluster.
    browser_cluster

    state.audited_page_count += 1
    add_to_sitemap( page )

    print_line

    if page.response.ok?
        print_status "[HTTP: #{page.code}] #{page.dom.url}"
    else
        print_error "[HTTP: #{page.code}] #{page.dom.url}"
        print_error "[#{page.response.return_code}] #{page.response.return_message}"
    end

    if page.platforms.any?
        print_info "Identified as: #{page.platforms.to_a.join( ', ' )}"
    end

    if crawl?
        pushed = push_paths_from_page( page )
        print_info "Analysis resulted in #{pushed.size} usable paths."
    end

    if host_has_browser?
        print_info "DOM depth: #{page.dom.depth} (Limit: " <<
                       "#{options.scope.dom_depth_limit})"

        if page.dom.transitions.any?
            print_info '  Transitions:'
            page.dom.print_transitions( method(:print_info), '    ' )
        end
    end

    # Aside from plugins and whatnot, the Trainer hooks here to update the
    # ElementFilter so that it'll know if new elements appear during the
    # audit, so it's a big deal.
    notify_on_page_audit( page )

    @current_url = page.dom.url.to_s

    http.update_cookies( page.cookie_jar )

    # Pass the page to the BrowserCluster to explore its DOM and feed
    # resulting pages back to the framework.
    perform_browser_analysis( page )

    run_http = false

    if checks.any?
        # Remove elements which have already passed through here.
        pre_audit_element_filter( page )

        notify_on_effective_page_audit( page )

        # Run checks which **don't** benefit from fingerprinting first, so
        # that we can use the responses of their HTTP requests to fingerprint
        # the webapp platforms, so that the checks which **do** benefit from
        # knowing the remote platforms can run more efficiently.
        run_http = run_checks( @checks.without_platforms, page )
        run_http = true if run_checks( @checks.with_platforms, page )
    end

    notify_after_page_audit( page )

    # Makes it easier on the GC but it is important that it be called
    # **after** all the callbacks have been executed because they may need
    # access to the cached data and there's no sense in re-parsing.
    page.clear_cache

    if Arachni::Check::Auditor.has_timeout_candidates?
        print_line
        print_status "Processing timeout-analysis candidates for: #{page.dom.url}"
        print_info   '-------------------------------------------'
        Arachni::Check::Auditor.timeout_audit_run
        run_http = true
    end

    run_http
end

#initializeObject



44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/arachni/framework/parts/audit.rb', line 44

def initialize
    super

    @http = HTTP::Client.instance

    # Holds page URLs which returned no response.
    @failures = []
    @retries  = {}

    @current_url = ''

    reset_session
    reset_trainer
end

#on_effective_page_audit(&block) ⇒ Object



24
# File 'lib/arachni/framework/parts/audit.rb', line 24

advertise :on_effective_page_audit

#on_page_audit(&block) ⇒ Object



21
# File 'lib/arachni/framework/parts/audit.rb', line 21

advertise :on_page_audit