Class: Arachni::Module::Manager

Inherits:
Component::Manager show all
Extended by:
Utilities
Includes:
Utilities
Defined in:
lib/arachni/module/manager.rb

Overview

Holds and manages the modules and their results.

Author:

Direct Known Subclasses

RPC::Server::Module::Manager

Constant Summary collapse

NAMESPACE =

Namespace under which all modules reside.

::Arachni::Modules

Constants inherited from Component::Manager

Component::Manager::EXCLUDE, Component::Manager::WILDCARD

Instance Attribute Summary

Attributes inherited from Component::Manager

#lib, #namespace

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Utilities

available_port, cookie_encode, cookies_from_document, cookies_from_file, cookies_from_response, exception_jail, exclude_path?, extract_domain, follow_protocol?, form_decode, form_encode, form_parse_request_body, forms_from_document, forms_from_response, generate_token, get_path, html_decode, html_encode, include_path?, links_from_document, links_from_response, normalize_url, page_from_response, page_from_url, parse_query, parse_set_cookie, parse_url_vars, path_in_domain?, path_too_deep?, port_available?, rand_port, redundant_path?, remove_constants, seed, skip_page?, skip_path?, skip_resource?, to_absolute, uri_decode, uri_encode, uri_parse, uri_parser, url_sanitize

Methods included from Utilities

#read_file

Methods inherited from Component::Manager

#[], #available, #clear, #delete, #include?, #load, #load_all, #load_by_tags, #loaded, #name_to_path, #parse, #path_to_name, #paths, #prep_opts

Methods included from UI::Output

#debug?, #debug_off, #debug_on, #disable_only_positives, #error_logfile, #flush_buffer, #log_error, #mute, #muted?, old_reset_output_options, #only_positives, #only_positives?, #print_bad, #print_debug, #print_debug_backtrace, #print_debug_pp, #print_error, #print_error_backtrace, #print_info, #print_line, #print_ok, #print_status, #print_verbose, #reroute_to_file, #reroute_to_file?, reset_output_options, #set_buffer_cap, #set_error_logfile, #uncap_buffer, #unmute, #verbose, #verbose?

Methods inherited from Hash

#downcase, #find_symbol_keys_recursively, #recode, #stringify_keys, #symbolize_keys

Constructor Details

#initialize(framework) ⇒ Manager

Returns a new instance of Manager.

Parameters:



40
41
42
43
44
45
46
# File 'lib/arachni/module/manager.rb', line 40

def initialize( framework )
    self.class.reset

    @framework = framework
    @opts = @framework.opts
    super( @opts.dir['modules'], NAMESPACE )
end

Class Method Details

.do_not_storeObject



151
152
153
# File 'lib/arachni/module/manager.rb', line 151

def self.do_not_store
    @do_not_store = true
end

.issue_setObject



204
205
206
# File 'lib/arachni/module/manager.rb', line 204

def self.issue_set
    @issue_set
end

.issuesObject



200
201
202
# File 'lib/arachni/module/manager.rb', line 200

def self.issues
    results
end

.on_register_results(&block) ⇒ Object



130
131
132
# File 'lib/arachni/module/manager.rb', line 130

def self.on_register_results( &block )
    on_register_results_blocks << block
end

.on_register_results_raw(&block) ⇒ Object



137
138
139
# File 'lib/arachni/module/manager.rb', line 137

def self.on_register_results_raw( &block )
    on_register_results_blocks_raw << block
end

.register_results(results) ⇒ Integer

De-duplicates and registers module results (issues).

Parameters:

Returns:

  • (Integer)

    amount of (unique) issues registered



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/arachni/module/manager.rb', line 172

def self.register_results( results )
    on_register_results_blocks_raw.each { |block| block.call( results ) }

    unique = dedup( results )
    return results if unique.empty?

    # Don't allow multiple variations of the same audit-type issue,
    # only allow variations for recon modules.
    unique.each { |issue| issue_set << issue.unique_id if issue.audit? }

    on_register_results_blocks.each { |block| block.call( unique ) }
    return results if !store?

    unique.each { |issue| self.results << issue }
    results
end

.resetObject



211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/arachni/module/manager.rb', line 211

def self.reset
    # Holds issues.
    @results                        = []
    # Used to deduplicate issues.
    @issue_set                      = Support::LookUp::HashSet.new
    # Determines whether or not to store the pushed issues.
    @do_not_store                   = false
    # Blocks to call for logged issues after deduplication takes place.
    @on_register_results_blocks     = []
    # Blocks to call for logged issues without deduplication taking place.
    @on_register_results_blocks_raw = []

    remove_constants( NAMESPACE )
end

.resultsObject



192
193
194
# File 'lib/arachni/module/manager.rb', line 192

def self.results
    @results
end

.storeObject



158
159
160
# File 'lib/arachni/module/manager.rb', line 158

def self.store
    @do_not_store = false
end

.store?Boolean

Returns:

  • (Boolean)


144
145
146
# File 'lib/arachni/module/manager.rb', line 144

def self.store?
    !@do_not_store
end

Instance Method Details

#do_not_storeObject



154
155
156
# File 'lib/arachni/module/manager.rb', line 154

def do_not_store
    self.class.do_not_store
end

#issue_setObject



207
208
209
# File 'lib/arachni/module/manager.rb', line 207

def issue_set
    self.class.issue_set
end

#on_register_results(&block) ⇒ Object



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

def on_register_results( &block )
    self.class.on_register_results( &block )
end

#on_register_results_raw(&block) ⇒ Object



140
141
142
# File 'lib/arachni/module/manager.rb', line 140

def on_register_results_raw( &block )
    self.class.on_register_results_raw( &block )
end

#register_results(results) ⇒ Object



188
189
190
# File 'lib/arachni/module/manager.rb', line 188

def register_results( results )
    self.class.register_results( results )
end

#resetObject



225
226
227
# File 'lib/arachni/module/manager.rb', line 225

def reset
    self.class.reset
end

#resultsObject Also known as: issues



195
196
197
# File 'lib/arachni/module/manager.rb', line 195

def results
    self.class.results
end

#run(page) ⇒ Object

Runs all modules against ‘page’.

Parameters:



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

def run( page )
    schedule.each { |mod| exception_jail( false ){ run_one( mod, page ) } }
end

#run_module?(mod, page) ⇒ Bool

Determines whether or not to run the module against the given page depending on which elements exist in the page, which elements the module is configured to audit and user options.

Parameters:

  • mod (Class)

    the module to run

  • page (Page)

Returns:

  • (Bool)


110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/arachni/module/manager.rb', line 110

def run_module?( mod, page )
    return false if mod.issue_limit_reached?

    elements = mod.info[:elements]
    return true if !elements || elements.empty?

    elems = {
        Element::LINK   => page.links.any?   && @opts.audit_links,
        Element::FORM   => page.forms.any?   && @opts.audit_forms,
        Element::COOKIE => page.cookies.any? && @opts.audit_cookies,
        Element::HEADER => page.headers.any? && @opts.audit_headers,
        Element::BODY   => !page.body.empty?,
        Element::PATH   => true,
        Element::SERVER => true
    }

    elems.each_pair { |elem, expr| return true if elements.include?( elem ) && expr }
    false
end

#run_one(mod, page) ⇒ Object

Runs a single module against ‘page’.

Parameters:



91
92
93
94
95
96
97
98
# File 'lib/arachni/module/manager.rb', line 91

def run_one( mod, page )
    return false if !run_module?( mod, page )

    mod_new = mod.new( page, @framework )
    mod_new.prepare
    mod_new.run
    mod_new.clean_up
end

#scheduleArray

Returns Modules in proper running order.

Returns:

  • (Array)

    Modules in proper running order.



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/arachni/module/manager.rb', line 58

def schedule
    schedule       = Set.new
    preferred_over = Hash.new([])

    preferred = self.reject do |name, klass|
        preferred_over[name] = klass.preferred if klass.preferred.any?
    end

    return self.values if preferred_over.empty? || preferred.empty?

    preferred_over.size.times do
        update = {}
        preferred.each do |name, klass|
            schedule << klass
            preferred_over.select { |_, v| v.include?( name ) }.each do |k, v|
                schedule << (update[k] = self[k])
            end
        end

        preferred.merge!( update )
    end

    schedule |= preferred_over.keys.map { |n| self[n] }

    schedule.to_a
end

#storeObject



161
162
163
# File 'lib/arachni/module/manager.rb', line 161

def store
    self.class.store
end

#store?Boolean

Returns:

  • (Boolean)


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

def store?
    self.class.store
end