arachni 1.1 → 1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +159 -0
- data/LICENSE.md +126 -196
- data/README.md +32 -24
- data/arachni.gemspec +7 -7
- data/components/checks/active/code_injection_timing.rb +3 -3
- data/components/checks/active/csrf.rb +2 -2
- data/components/checks/active/file_inclusion.rb +6 -7
- data/components/checks/active/os_cmd_injection.rb +3 -3
- data/components/checks/active/path_traversal.rb +7 -7
- data/components/checks/active/response_splitting.rb +9 -4
- data/components/checks/active/session_fixation.rb +7 -3
- data/components/checks/active/source_code_disclosure.rb +5 -5
- data/components/checks/active/unvalidated_redirect.rb +12 -3
- data/components/checks/active/unvalidated_redirect_dom.rb +3 -3
- data/components/checks/active/xss.rb +23 -10
- data/components/checks/active/xss_dom_inputs.rb +113 -11
- data/components/checks/active/xxe.rb +3 -3
- data/components/checks/passive/backdoors.rb +6 -5
- data/components/checks/passive/backup_directories.rb +6 -6
- data/components/checks/passive/backup_files.rb +6 -6
- data/components/checks/passive/common_admin_interfaces.rb +58 -0
- data/components/checks/passive/common_admin_interfaces/admin-panels.txt +49 -0
- data/components/checks/passive/common_directories/directories.txt +0 -16
- data/components/checks/passive/common_files.rb +6 -5
- data/components/checks/passive/common_files/filenames.txt +0 -2
- data/components/checks/passive/directory_listing.rb +6 -6
- data/components/checks/passive/grep/cookie_set_for_parent_domain.rb +3 -3
- data/components/checks/passive/grep/hsts.rb +6 -3
- data/components/checks/passive/grep/http_only_cookies.rb +3 -3
- data/components/checks/passive/grep/insecure_cookies.rb +2 -2
- data/components/checks/passive/grep/insecure_cors_policy.rb +6 -4
- data/components/checks/passive/grep/x_frame_options.rb +6 -4
- data/components/checks/passive/htaccess_limit.rb +6 -2
- data/components/checks/passive/http_put.rb +8 -4
- data/components/checks/passive/interesting_responses.rb +3 -2
- data/components/checks/passive/localstart_asp.rb +6 -2
- data/components/checks/passive/origin_spoof_access_restriction_bypass.rb +5 -1
- data/components/checks/passive/xst.rb +6 -2
- data/components/fingerprinters/frameworks/aspx_mvc.rb +43 -0
- data/components/fingerprinters/frameworks/cakephp.rb +28 -0
- data/components/fingerprinters/frameworks/cherrypy.rb +31 -0
- data/components/fingerprinters/frameworks/django.rb +33 -0
- data/components/fingerprinters/frameworks/jsf.rb +30 -0
- data/components/fingerprinters/frameworks/rack.rb +5 -7
- data/components/fingerprinters/frameworks/rails.rb +43 -0
- data/components/fingerprinters/languages/aspx.rb +11 -11
- data/components/fingerprinters/languages/{jsp.rb → java.rb} +11 -7
- data/components/fingerprinters/languages/php.rb +6 -6
- data/components/fingerprinters/languages/python.rb +14 -6
- data/components/fingerprinters/languages/ruby.rb +3 -5
- data/components/fingerprinters/servers/apache.rb +5 -4
- data/components/fingerprinters/servers/gunicorn.rb +33 -0
- data/components/fingerprinters/servers/jetty.rb +1 -1
- data/components/fingerprinters/servers/tomcat.rb +11 -4
- data/components/path_extractors/anchors.rb +5 -12
- data/components/path_extractors/areas.rb +5 -13
- data/components/path_extractors/comments.rb +5 -3
- data/components/path_extractors/data_url.rb +21 -0
- data/components/path_extractors/forms.rb +5 -13
- data/components/path_extractors/frames.rb +6 -13
- data/components/path_extractors/generic.rb +3 -12
- data/components/path_extractors/links.rb +5 -13
- data/components/path_extractors/meta_refresh.rb +5 -13
- data/components/path_extractors/scripts.rb +8 -14
- data/components/plugins/autologin.rb +17 -5
- data/components/plugins/defaults/meta/remedies/discovery.rb +11 -29
- data/components/plugins/login_script.rb +40 -10
- data/components/plugins/metrics.rb +235 -0
- data/components/plugins/proxy.rb +21 -4
- data/components/plugins/proxy/panel/page_accordion.html.erb +34 -2
- data/components/plugins/restrict_to_dom_state.rb +70 -0
- data/components/plugins/vector_feed.rb +38 -9
- data/components/reporters/plugin_formatters/html/metrics.rb +290 -0
- data/components/reporters/plugin_formatters/stdout/metrics.rb +80 -0
- data/components/reporters/plugin_formatters/xml/metrics.rb +29 -0
- data/components/reporters/stdout.rb +4 -2
- data/components/reporters/xml.rb +4 -4
- data/components/reporters/xml/schema.xsd +95 -0
- data/lib/arachni.rb +2 -0
- data/lib/arachni/browser.rb +132 -77
- data/lib/arachni/browser/javascript.rb +173 -45
- data/lib/arachni/browser/javascript/scripts/dom_monitor.js +81 -6
- data/lib/arachni/browser/javascript/scripts/taint_tracer.js +31 -3
- data/lib/arachni/browser_cluster.rb +41 -15
- data/lib/arachni/browser_cluster/job.rb +4 -0
- data/lib/arachni/browser_cluster/jobs/resource_exploration.rb +0 -9
- data/lib/arachni/browser_cluster/worker.rb +8 -5
- data/lib/arachni/check/auditor.rb +20 -8
- data/lib/arachni/check/base.rb +38 -6
- data/lib/arachni/element/base.rb +18 -1
- data/lib/arachni/element/capabilities/analyzable/differential.rb +0 -1
- data/lib/arachni/element/capabilities/analyzable/taint.rb +40 -10
- data/lib/arachni/element/capabilities/analyzable/timeout.rb +27 -23
- data/lib/arachni/element/capabilities/auditable/dom.rb +22 -0
- data/lib/arachni/element/capabilities/inputtable.rb +6 -2
- data/lib/arachni/element/capabilities/submittable.rb +1 -1
- data/lib/arachni/element/cookie.rb +37 -23
- data/lib/arachni/element/cookie/capabilities/mutable.rb +6 -6
- data/lib/arachni/element/cookie/dom.rb +0 -8
- data/lib/arachni/element/form.rb +28 -14
- data/lib/arachni/element/form/capabilities/auditable.rb +2 -2
- data/lib/arachni/element/form/capabilities/mutable.rb +5 -5
- data/lib/arachni/element/form/dom.rb +0 -8
- data/lib/arachni/element/generic_dom.rb +1 -1
- data/lib/arachni/element/json.rb +2 -1
- data/lib/arachni/element/json/capabilities/inputtable.rb +6 -6
- data/lib/arachni/element/json/capabilities/mutable.rb +1 -1
- data/lib/arachni/element/link.rb +13 -16
- data/lib/arachni/element/link/dom.rb +1 -14
- data/lib/arachni/element/link_template.rb +3 -2
- data/lib/arachni/element/link_template/dom.rb +0 -16
- data/lib/arachni/element/server.rb +51 -9
- data/lib/arachni/element/xml.rb +1 -0
- data/lib/arachni/ethon/easy.rb +4 -1
- data/lib/arachni/framework/parts/audit.rb +26 -77
- data/lib/arachni/framework/parts/browser.rb +50 -55
- data/lib/arachni/framework/parts/check.rb +4 -3
- data/lib/arachni/framework/parts/data.rb +41 -6
- data/lib/arachni/framework/parts/state.rb +16 -7
- data/lib/arachni/http/client.rb +66 -38
- data/lib/arachni/http/client/dynamic_404_handler.rb +46 -14
- data/lib/arachni/http/headers.rb +22 -10
- data/lib/arachni/http/proxy_server.rb +67 -22
- data/lib/arachni/http/proxy_server/ssl-interceptor-cacert.pem +34 -0
- data/lib/arachni/http/proxy_server/ssl-interceptor-cakey.pem +51 -0
- data/lib/arachni/http/request.rb +71 -18
- data/lib/arachni/issue.rb +17 -3
- data/lib/arachni/option_groups/browser_cluster.rb +34 -1
- data/lib/arachni/option_groups/http.rb +1 -1
- data/lib/arachni/page.rb +26 -13
- data/lib/arachni/page/dom/transition.rb +2 -2
- data/lib/arachni/parser.rb +28 -11
- data/lib/arachni/platform/fingerprinter.rb +5 -0
- data/lib/arachni/platform/manager.rb +65 -32
- data/lib/arachni/plugin/base.rb +8 -0
- data/lib/arachni/processes/instances.rb +25 -11
- data/lib/arachni/reporter/manager.rb +2 -2
- data/lib/arachni/rpc/client/instance.rb +4 -0
- data/lib/arachni/rpc/server/framework/master.rb +3 -3
- data/lib/arachni/rpc/server/framework/multi_instance.rb +0 -8
- data/lib/arachni/rpc/server/instance.rb +2 -1
- data/lib/arachni/ruby/array.rb +5 -0
- data/lib/arachni/ruby/hash.rb +5 -0
- data/lib/arachni/ruby/string.rb +2 -3
- data/lib/arachni/session.rb +32 -6
- data/lib/arachni/state/framework.rb +6 -2
- data/lib/arachni/support/cache.rb +1 -0
- data/lib/arachni/support/cache/base.rb +12 -8
- data/lib/arachni/support/cache/least_recently_pushed.rb +29 -0
- data/lib/arachni/support/cache/least_recently_used.rb +5 -8
- data/lib/arachni/support/cache/preference.rb +1 -1
- data/lib/arachni/support/cache/random_replacement.rb +1 -25
- data/lib/arachni/support/database/queue.rb +21 -8
- data/lib/arachni/support/lookup/base.rb +7 -1
- data/lib/arachni/support/mixins/observable.rb +3 -1
- data/lib/arachni/support/profiler.rb +51 -10
- data/lib/arachni/support/signature.rb +11 -2
- data/lib/arachni/trainer.rb +8 -2
- data/lib/arachni/uri.rb +28 -25
- data/lib/arachni/uri/scope.rb +1 -1
- data/lib/arachni/utilities.rb +8 -0
- data/lib/arachni/watir/element.rb +1 -1
- data/lib/version +1 -1
- data/spec/arachni/browser/javascript/dom_monitor_spec.rb +388 -53
- data/spec/arachni/browser/javascript/taint_tracer_spec.rb +41 -0
- data/spec/arachni/browser/javascript_spec.rb +235 -61
- data/spec/arachni/browser_cluster/jobs/resource_exploration_spec.rb +0 -9
- data/spec/arachni/browser_cluster_spec.rb +58 -10
- data/spec/arachni/browser_spec.rb +170 -26
- data/spec/arachni/check/auditor_spec.rb +22 -3
- data/spec/arachni/check/base_spec.rb +84 -0
- data/spec/arachni/element/body_spec.rb +1 -1
- data/spec/arachni/element/capabilities/analyzable/taint_spec.rb +3 -3
- data/spec/arachni/element/capabilities/analyzable/timeout_spec.rb +1 -1
- data/spec/arachni/element/cookie/dom_spec.rb +0 -9
- data/spec/arachni/element/cookie_spec.rb +85 -0
- data/spec/arachni/element/form/dom_spec.rb +0 -9
- data/spec/arachni/element/form_spec.rb +46 -3
- data/spec/arachni/element/json_spec.rb +20 -0
- data/spec/arachni/element/link/dom_spec.rb +0 -9
- data/spec/arachni/element/link_spec.rb +40 -15
- data/spec/arachni/element/link_template/dom_spec.rb +0 -8
- data/spec/arachni/element/link_template_spec.rb +2 -6
- data/spec/arachni/element/server_spec.rb +94 -8
- data/spec/arachni/element/xml_spec.rb +20 -0
- data/spec/arachni/framework/parts/audit_spec.rb +12 -14
- data/spec/arachni/framework/parts/browser_spec.rb +0 -171
- data/spec/arachni/framework/parts/platform_spec.rb +14 -8
- data/spec/arachni/framework/parts/report_spec.rb +1 -1
- data/spec/arachni/framework/parts/state_spec.rb +0 -9
- data/spec/arachni/http/client/dynamic_404_handlers_spec.rb +19 -0
- data/spec/arachni/http/client_spec.rb +169 -42
- data/spec/arachni/http/headers_spec.rb +18 -0
- data/spec/arachni/http/request_spec.rb +23 -0
- data/spec/arachni/issue_spec.rb +17 -6
- data/spec/arachni/page_spec.rb +22 -2
- data/spec/arachni/parser_spec.rb +5 -0
- data/spec/arachni/platform/manager_spec.rb +57 -25
- data/spec/arachni/reporter/manager_spec.rb +26 -0
- data/spec/arachni/rpc/server/active_options_spec.rb +9 -4
- data/spec/arachni/state/framework_spec.rb +2 -8
- data/spec/arachni/support/cache/least_recently_pushed_spec.rb +90 -0
- data/spec/arachni/support/cache/least_recently_used_spec.rb +5 -13
- data/spec/arachni/support/database/queue_spec.rb +7 -0
- data/spec/arachni/support/mixins/observable_spec.rb +15 -1
- data/spec/arachni/trainer_spec.rb +2 -2
- data/spec/components/checks/active/code_injection_timing_spec.rb +1 -1
- data/spec/components/checks/active/file_inclusion_spec.rb +6 -6
- data/spec/components/checks/active/path_traversal_spec.rb +2 -2
- data/spec/components/checks/active/source_code_disclosure_spec.rb +2 -2
- data/spec/components/checks/active/unvalidated_redirect_spec.rb +6 -6
- data/spec/components/checks/active/xss_dom_inputs_spec.rb +3 -5
- data/spec/components/checks/active/xss_dom_script_context_spec.rb +1 -1
- data/spec/components/checks/active/xss_spec.rb +5 -5
- data/spec/components/checks/passive/common_admin_interfaces_spec.rb +15 -0
- data/spec/components/checks/passive/interesting_responses_spec.rb +14 -1
- data/spec/components/fingerprinters/frameworks/aspx_mvc_spec.rb +31 -0
- data/spec/components/fingerprinters/frameworks/cakephp_spec.rb +22 -0
- data/spec/components/fingerprinters/frameworks/cherrypy_spec.rb +28 -0
- data/spec/components/fingerprinters/frameworks/django_spec.rb +37 -0
- data/spec/components/fingerprinters/frameworks/jsf_spec.rb +27 -0
- data/spec/components/fingerprinters/frameworks/rack_spec.rb +11 -14
- data/spec/components/fingerprinters/frameworks/rails_spec.rb +53 -0
- data/spec/components/fingerprinters/languages/asp_spec.rb +7 -9
- data/spec/components/fingerprinters/languages/aspx_spec.rb +10 -24
- data/spec/components/fingerprinters/languages/java_spec.rb +88 -0
- data/spec/components/fingerprinters/languages/php_spec.rb +19 -12
- data/spec/components/fingerprinters/languages/python_spec.rb +22 -9
- data/spec/components/fingerprinters/languages/ruby.rb +6 -4
- data/spec/components/fingerprinters/os/bsd_spec.rb +6 -4
- data/spec/components/fingerprinters/os/linux_spec.rb +6 -4
- data/spec/components/fingerprinters/os/solaris_spec.rb +6 -4
- data/spec/components/fingerprinters/os/unix_spec.rb +6 -4
- data/spec/components/fingerprinters/os/windows_spec.rb +6 -4
- data/spec/components/fingerprinters/servers/apache_spec.rb +15 -4
- data/spec/components/fingerprinters/servers/gunicorn_spec.rb +28 -0
- data/spec/components/fingerprinters/servers/iis_spec.rb +6 -6
- data/spec/components/fingerprinters/servers/jetty_spec.rb +6 -6
- data/spec/components/fingerprinters/servers/nginx_spec.rb +6 -4
- data/spec/components/fingerprinters/servers/tomcat_spec.rb +15 -6
- data/spec/components/path_extractors/data_url_spec.rb +19 -0
- data/spec/components/plugins/autologin_spec.rb +23 -0
- data/spec/components/plugins/login_script_spec.rb +112 -24
- data/spec/components/plugins/restrict_to_dom_state_spec.rb +16 -0
- data/spec/components/plugins/vector_feed_spec.rb +39 -1
- data/spec/support/factories/page/dom.rb +9 -4
- data/spec/support/factories/page/dom/transition.rb +31 -9
- data/spec/support/factories/scan_report.rb +8 -6
- data/spec/support/fixtures/empty/placeholder +0 -0
- data/spec/support/fixtures/report.afr +0 -0
- data/spec/support/fixtures/reporters/manager_spec/error.rb +18 -0
- data/spec/support/servers/arachni/browser.rb +117 -11
- data/spec/support/servers/arachni/browser/javascript/dom_monitor.rb +148 -4
- data/spec/support/servers/arachni/check/auditor.rb +4 -0
- data/spec/support/servers/arachni/element/cookie/cookie_dom.rb +1 -1
- data/spec/support/servers/arachni/http/client.rb +5 -0
- data/spec/support/servers/arachni/http/client/dynamic_404_handler.rb +13 -0
- data/spec/support/servers/checks/active/code_injection_timing.rb +1 -1
- data/spec/support/servers/checks/active/file_inclusion.rb +2 -2
- data/spec/support/servers/checks/active/path_traversal.rb +2 -2
- data/spec/support/servers/checks/active/source_code_disclosure.rb +40 -33
- data/spec/support/servers/checks/active/trainer_check.rb +9 -10
- data/spec/support/servers/checks/active/unvalidated_redirect_dom.rb +7 -4
- data/spec/support/servers/checks/active/xss.rb +35 -0
- data/spec/support/servers/checks/active/xss_dom.rb +1 -1
- data/spec/support/servers/checks/active/xss_dom_inputs.rb +24 -0
- data/spec/support/servers/checks/active/xss_dom_script_context.rb +1 -1
- data/spec/support/servers/checks/passive/common_admin_interfaces.rb +6 -0
- data/spec/support/servers/plugins/autologin.rb +9 -0
- data/spec/support/servers/plugins/restrict_to_dom_state.rb +4 -0
- data/spec/support/shared/element/base.rb +42 -0
- data/spec/support/shared/element/capabilities/auditable.rb +4 -4
- data/spec/support/shared/element/capabilities/auditable/dom.rb +26 -0
- data/spec/support/shared/element/capabilities/inputtable.rb +16 -11
- data/spec/support/shared/element/capabilities/submitable.rb +7 -2
- data/spec/support/shared/fingerprinter.rb +8 -0
- data/spec/support/shared/path_extractor.rb +1 -1
- data/ui/cli/framework.rb +3 -3
- data/ui/cli/framework/option_parser.rb +9 -0
- data/ui/cli/output.rb +9 -0
- data/ui/cli/reporter.rb +5 -2
- data/ui/cli/utilities.rb +4 -2
- metadata +76 -17
- data/lib/arachni/http/proxy_server/ssl-interceptor-cert.pem +0 -34
- data/lib/arachni/http/proxy_server/ssl-interceptor-pkey.pem +0 -51
- data/spec/components/fingerprinters/languages/jsp_spec.rb +0 -56
@@ -12,18 +12,31 @@
|
|
12
12
|
class Arachni::Plugins::LoginScript < Arachni::Plugin::Base
|
13
13
|
|
14
14
|
STATUSES = {
|
15
|
-
success:
|
16
|
-
failure:
|
17
|
-
error:
|
18
|
-
|
15
|
+
success: 'Login was successful.',
|
16
|
+
failure: 'The script was executed successfully, but the login check failed.',
|
17
|
+
error: 'A runtime error was encountered while executing the login script.',
|
18
|
+
missing_browser: 'A browser is required for this operation but is not available.',
|
19
|
+
missing_check: 'No session check was provided, either via interface options or the script.'
|
19
20
|
}
|
20
21
|
|
21
22
|
def prepare
|
22
|
-
script
|
23
|
-
@script
|
23
|
+
script = IO.read( @options[:script] )
|
24
|
+
@script = proc do |browser|
|
25
|
+
if javascript?
|
26
|
+
browser.goto @framework.options.url
|
27
|
+
browser.execute_script script
|
28
|
+
else
|
29
|
+
eval script
|
30
|
+
end
|
31
|
+
end
|
24
32
|
end
|
25
33
|
|
26
34
|
def run
|
35
|
+
if javascript? && !session.has_browser?
|
36
|
+
set_status :missing_browser, :error
|
37
|
+
return
|
38
|
+
end
|
39
|
+
|
27
40
|
framework_pause
|
28
41
|
print_info 'System paused.'
|
29
42
|
|
@@ -71,6 +84,10 @@ class Arachni::Plugins::LoginScript < Arachni::Plugin::Base
|
|
71
84
|
framework_resume
|
72
85
|
end
|
73
86
|
|
87
|
+
def javascript?
|
88
|
+
@options[:script].split( '.' ).last == 'js'
|
89
|
+
end
|
90
|
+
|
74
91
|
def set_status( status, type = nil, extra = {} )
|
75
92
|
type ||= status
|
76
93
|
|
@@ -96,7 +113,9 @@ The script needn't necessarily perform an actual login operation. If another
|
|
96
113
|
process is used to manage sessions, the script can be used to communicate with
|
97
114
|
that process and, for example, load and set cookies from a shared cookie-jar.
|
98
115
|
|
99
|
-
|
116
|
+
# Ruby
|
117
|
+
|
118
|
+
## With browser (slow)
|
100
119
|
|
101
120
|
If a [browser](http://watirwebdriver.com/) is available, it will be exposed to
|
102
121
|
the script via the `browser` variable. Otherwise, that variable will have a
|
@@ -115,7 +134,7 @@ value of `nil`.
|
|
115
134
|
framework.options.session.check_url = browser.url
|
116
135
|
framework.options.session.check_pattern = /Sign Off|MY ACCOUNT/
|
117
136
|
|
118
|
-
|
137
|
+
## Without browser (fast)
|
119
138
|
|
120
139
|
If a real browser environment is not required for the login operation, then
|
121
140
|
using the system-wide HTTP interface is preferable, as it will be much faster
|
@@ -133,15 +152,26 @@ and consume much less resources.
|
|
133
152
|
framework.options.session.check_url = to_absolute( response.headers.location, response.url )
|
134
153
|
framework.options.session.check_pattern = /Sign Off|MY ACCOUNT/
|
135
154
|
|
136
|
-
|
155
|
+
## From cookie-jar
|
137
156
|
|
138
157
|
If an external process is used to manage sessions, you can keep Arachni in sync
|
139
158
|
by loading cookies from a shared Netscape-style cookie-jar file.
|
140
159
|
|
141
160
|
http.cookie_jar.load 'cookies.txt'
|
161
|
+
|
162
|
+
# Javascript
|
163
|
+
|
164
|
+
When the given script has a `.js` file extension, it will be loaded and executed
|
165
|
+
in the browser, within the page of the target URL.
|
166
|
+
|
167
|
+
document.getElementById( 'uid' ).value = 'jsmith';
|
168
|
+
document.getElementById( 'passw' ).value = 'Demo1234';
|
169
|
+
|
170
|
+
document.getElementById( 'login' ).submit();
|
171
|
+
|
142
172
|
},
|
143
173
|
author: 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>',
|
144
|
-
version: '0.
|
174
|
+
version: '0.2',
|
145
175
|
options: [
|
146
176
|
Options::Path.new( :script,
|
147
177
|
required: true,
|
@@ -0,0 +1,235 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2010-2015 Tasos Laskos <tasos.laskos@arachni-scanner.com>
|
3
|
+
|
4
|
+
This file is part of the Arachni Framework project and is subject to
|
5
|
+
redistribution and commercial restrictions. Please see the Arachni Framework
|
6
|
+
web site for more information on licensing and terms of use.
|
7
|
+
=end
|
8
|
+
|
9
|
+
# @author Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>
|
10
|
+
# @version 0.1
|
11
|
+
class Arachni::Plugins::Metrics < Arachni::Plugin::Base
|
12
|
+
|
13
|
+
def prepare
|
14
|
+
@metrics = {
|
15
|
+
'general' => {
|
16
|
+
'egress_traffic' => 0,
|
17
|
+
# Approximation, may differ from the real value depending on
|
18
|
+
# compression and other factors.
|
19
|
+
'ingress_traffic' => 0,
|
20
|
+
'uses_http' => false,
|
21
|
+
'uses_https' => false
|
22
|
+
},
|
23
|
+
'scan' => {
|
24
|
+
'duration' => 0,
|
25
|
+
'authenticated' => false
|
26
|
+
},
|
27
|
+
'http' => {
|
28
|
+
'requests' => 0,
|
29
|
+
'response_time_min' => 0,
|
30
|
+
'response_time_max' => 0,
|
31
|
+
'response_time_average' => 0,
|
32
|
+
'request_size_min' => 0,
|
33
|
+
'request_size_max' => 0,
|
34
|
+
'request_size_average' => 0,
|
35
|
+
'response_size_min' => 0,
|
36
|
+
'response_size_max' => 0,
|
37
|
+
'response_size_average' => 0
|
38
|
+
},
|
39
|
+
'resource' => {
|
40
|
+
'binary' => Arachni::Support::LookUp::HashSet.new,
|
41
|
+
'without_parameters' => Arachni::Support::LookUp::HashSet.new,
|
42
|
+
'with_parameters' => Arachni::Support::LookUp::HashSet.new
|
43
|
+
},
|
44
|
+
'element' => {
|
45
|
+
'links' => 0,
|
46
|
+
'forms' => 0,
|
47
|
+
'cookies' => 0,
|
48
|
+
'jsons' => 0,
|
49
|
+
'xmls' => 0,
|
50
|
+
'headers' => 0,
|
51
|
+
'has_forms_with_nonces' => false,
|
52
|
+
'has_forms_with_passwords' => false,
|
53
|
+
'input_names_total' => 0,
|
54
|
+
'input_names_unique' => Arachni::Support::LookUp::HashSet.new
|
55
|
+
},
|
56
|
+
'dom' => {
|
57
|
+
'event_listeners' => Arachni::Support::LookUp::HashSet.new,
|
58
|
+
'swf_objects' => Arachni::Support::LookUp::HashSet.new
|
59
|
+
},
|
60
|
+
'platforms' => Arachni::Platform::Manager::TYPES.keys.
|
61
|
+
inject({}) { |h, t| h[t.to_s] = Set.new; h }
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
def run
|
66
|
+
http_response_time_total = 0
|
67
|
+
|
68
|
+
http.on_complete do |response|
|
69
|
+
response.platforms.to_a.each do |platform|
|
70
|
+
@metrics['platforms'][Arachni::Platform::Manager.find_type( platform ).to_s] << platform.to_s
|
71
|
+
end
|
72
|
+
|
73
|
+
@metrics['general']['egress_traffic'] += response.request.to_s.size
|
74
|
+
@metrics['general']['ingress_traffic'] += response.to_s.size
|
75
|
+
|
76
|
+
if @metrics['http']['response_time_min'].is_a?( Integer ) ||
|
77
|
+
response.time < @metrics['http']['response_time_min']
|
78
|
+
|
79
|
+
@metrics['http']['response_time_min'] = response.time
|
80
|
+
end
|
81
|
+
if response.time > @metrics['http']['response_time_max']
|
82
|
+
@metrics['http']['response_time_max'] = response.time
|
83
|
+
end
|
84
|
+
|
85
|
+
response_size = response.to_s.size
|
86
|
+
if @metrics['http']['response_size_min'].is_a?( Integer ) ||
|
87
|
+
response_size < @metrics['http']['response_size_min']
|
88
|
+
|
89
|
+
@metrics['http']['response_size_min'] = response_size
|
90
|
+
end
|
91
|
+
if response_size > @metrics['http']['response_size_max']
|
92
|
+
@metrics['http']['response_size_max'] = response_size
|
93
|
+
end
|
94
|
+
|
95
|
+
request_size = response.request.to_s.size
|
96
|
+
if @metrics['http']['request_size_min'].is_a?( Integer ) ||
|
97
|
+
request_size < @metrics['http']['request_size_min']
|
98
|
+
|
99
|
+
@metrics['http']['request_size_min'] = request_size
|
100
|
+
end
|
101
|
+
if request_size > @metrics['http']['request_size_max']
|
102
|
+
@metrics['http']['request_size_max'] = request_size
|
103
|
+
end
|
104
|
+
|
105
|
+
# Only track OK codes, otherwise discovery checks will muck with the
|
106
|
+
# data.
|
107
|
+
if response.code == 200
|
108
|
+
if response.request.body.is_a?( Hash ) ||
|
109
|
+
response.request.parameters.any? ||
|
110
|
+
response.request.url.include?( '?' )
|
111
|
+
|
112
|
+
if response.request.body.is_a? Hash
|
113
|
+
body = response.request.body.keys.sort
|
114
|
+
else
|
115
|
+
body = nil
|
116
|
+
end
|
117
|
+
|
118
|
+
@metrics['resource']['with_parameters'] <<
|
119
|
+
"#{response.parsed_url.up_to_path}#{response.request.parameters.keys.sort}:#{body}"
|
120
|
+
else
|
121
|
+
@metrics['resource']['without_parameters'] << response.url
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
@metrics['general']['uses_http'] ||=
|
126
|
+
(response.parsed_url.scheme == 'http')
|
127
|
+
@metrics['general']['uses_https'] ||=
|
128
|
+
(response.parsed_url.scheme == 'https')
|
129
|
+
|
130
|
+
if !response.text?
|
131
|
+
@metrics['resource']['binary'] << response.url
|
132
|
+
end
|
133
|
+
|
134
|
+
http_response_time_total += response.time
|
135
|
+
end
|
136
|
+
|
137
|
+
framework.on_page_audit do |page|
|
138
|
+
%w(links forms cookies headers jsons xmls).each do |type|
|
139
|
+
page.send( type ).each do |e|
|
140
|
+
next if e.inputs.empty?
|
141
|
+
|
142
|
+
@metrics['element'][type] += 1
|
143
|
+
@metrics['element']['input_names_total'] += e.inputs.size
|
144
|
+
|
145
|
+
e.inputs.keys.each do |name|
|
146
|
+
@metrics['element']['input_names_unique'] << name
|
147
|
+
end
|
148
|
+
|
149
|
+
if e.is_a? Arachni::Element::Form
|
150
|
+
# Probably not a real form, just a request with inputs
|
151
|
+
# captured by the browsers and fed back to the system.
|
152
|
+
if !e.source
|
153
|
+
@metrics['element'][type] -= 1
|
154
|
+
end
|
155
|
+
|
156
|
+
@metrics['element']['has_forms_with_nonces'] ||= !!e.has_nonce?
|
157
|
+
@metrics['element']['has_forms_with_passwords'] ||= !!e.requires_password?
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
if (swf = find_swf( page ))
|
163
|
+
@metrics['dom']['swf_objects'] << swf
|
164
|
+
end
|
165
|
+
|
166
|
+
if Arachni::Options.scope.dom_depth_limit.to_i < page.dom.depth + 1 &&
|
167
|
+
browser_cluster && page.has_script?
|
168
|
+
|
169
|
+
with_browser do |browser|
|
170
|
+
browser.load( page ).each_element_with_events do |locator, event_data|
|
171
|
+
event_data.each do |data|
|
172
|
+
@metrics['dom']['event_listeners'] << "#{locator}:#{data}"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
wait_while_framework_running
|
180
|
+
|
181
|
+
@metrics = process( @metrics )
|
182
|
+
|
183
|
+
@metrics['http']['requests'] = framework.statistics[:http][:response_count]
|
184
|
+
|
185
|
+
@metrics['http']['response_time_average'] =
|
186
|
+
http_response_time_total / @metrics['http']['requests']
|
187
|
+
|
188
|
+
@metrics['http']['response_size_average'] =
|
189
|
+
@metrics['general']['ingress_traffic'] / @metrics['http']['requests']
|
190
|
+
|
191
|
+
@metrics['http']['request_size_average'] =
|
192
|
+
@metrics['general']['egress_traffic'] / @metrics['http']['requests']
|
193
|
+
|
194
|
+
@metrics['scan']['duration'] = framework.statistics[:runtime]
|
195
|
+
@metrics['scan']['authenticated'] = !!Arachni::Options.session.check_url
|
196
|
+
|
197
|
+
register_results @metrics
|
198
|
+
end
|
199
|
+
|
200
|
+
def find_swf( page )
|
201
|
+
page.body.scan( /(?:data|src)=['"]?(.*)\.swf['"]?>/ )[0]
|
202
|
+
end
|
203
|
+
|
204
|
+
def process( hash )
|
205
|
+
h = {}
|
206
|
+
hash.each do |k, v|
|
207
|
+
case v
|
208
|
+
when Hash
|
209
|
+
v = process( v )
|
210
|
+
|
211
|
+
when Set
|
212
|
+
v = v.to_a
|
213
|
+
|
214
|
+
when Arachni::Support::LookUp::HashSet
|
215
|
+
v = v.size
|
216
|
+
|
217
|
+
end
|
218
|
+
|
219
|
+
h[k] = v
|
220
|
+
end
|
221
|
+
h
|
222
|
+
end
|
223
|
+
|
224
|
+
def self.info
|
225
|
+
{
|
226
|
+
name: 'Metrics',
|
227
|
+
description: %q{
|
228
|
+
Captures metrics about multiple aspects of the scan and the web application.
|
229
|
+
},
|
230
|
+
author: 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>',
|
231
|
+
version: '0.1'
|
232
|
+
}
|
233
|
+
end
|
234
|
+
|
235
|
+
end
|
data/components/plugins/proxy.rb
CHANGED
@@ -60,7 +60,13 @@ class Arachni::Plugins::Proxy < Arachni::Plugin::Base
|
|
60
60
|
print_info "Control panel URL: #{url_for( :panel )}"
|
61
61
|
print_info "Shutdown URL: #{url_for( :shutdown )}"
|
62
62
|
print_info 'The scan will resume once you visit the shutdown URL.'
|
63
|
-
|
63
|
+
print_info
|
64
|
+
print_info 'When browsing HTTPS sites, please accept the Arachni SSL certificate' +
|
65
|
+
' or install the CA certificate manually from:'
|
66
|
+
print_info " #{Arachni::HTTP::ProxyServer::INTERCEPTOR_CA_CERTIFICATE}"
|
67
|
+
print_info
|
68
|
+
print_bad '**DO NOT** forget to revoke it after using the proxy, as it' +
|
69
|
+
' can be used by anyone to impersonate 3rd party servers.'
|
64
70
|
print_info
|
65
71
|
print_info '*' * 82
|
66
72
|
print_info '* You need to clear your browser\'s cookies for this site before using the proxy! *'
|
@@ -77,7 +83,12 @@ class Arachni::Plugins::Proxy < Arachni::Plugin::Base
|
|
77
83
|
end
|
78
84
|
|
79
85
|
def prepare_pages_for_inspection
|
80
|
-
@pages.select
|
86
|
+
(@pages.select do |p|
|
87
|
+
next if !p.text?
|
88
|
+
|
89
|
+
p.forms.any? || p.links.any? || p.cookies.any? || p.jsons.any? ||
|
90
|
+
p.xmls.any?
|
91
|
+
end).to_a
|
81
92
|
end
|
82
93
|
|
83
94
|
def vectors_yaml
|
@@ -86,12 +97,18 @@ class Arachni::Plugins::Proxy < Arachni::Plugin::Base
|
|
86
97
|
page.elements.each do |element|
|
87
98
|
next if element.inputs.empty?
|
88
99
|
|
89
|
-
|
100
|
+
data = {
|
90
101
|
type: element.type,
|
91
102
|
method: element.method,
|
92
103
|
action: element.action,
|
93
104
|
inputs: element.inputs
|
94
105
|
}
|
106
|
+
|
107
|
+
if element.respond_to? :source
|
108
|
+
data[:source] = element.source
|
109
|
+
end
|
110
|
+
|
111
|
+
vectors << data
|
95
112
|
end
|
96
113
|
end
|
97
114
|
vectors.to_yaml
|
@@ -476,7 +493,7 @@ a way to restrict usage enough to avoid users unwittingly interfering with each
|
|
476
493
|
others' sessions.
|
477
494
|
},
|
478
495
|
author: 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>',
|
479
|
-
version: '0.3.
|
496
|
+
version: '0.3.3',
|
480
497
|
options: [
|
481
498
|
Options::Port.new( :port,
|
482
499
|
description: 'Port to bind to.',
|
@@ -7,9 +7,13 @@
|
|
7
7
|
<%= html_encode page.title %>
|
8
8
|
-
|
9
9
|
<%= page.forms.size %> forms,
|
10
|
-
<%= page.links.size %> links
|
11
|
-
<%= page.cookies.size %> cookies
|
10
|
+
<%= page.links.size %> links,
|
11
|
+
<%= page.cookies.size %> cookies,
|
12
|
+
<%= page.jsons.size %> JSONs and
|
13
|
+
<%= page.xmls.size %> XMLs.
|
14
|
+
|
12
15
|
<br/>
|
16
|
+
|
13
17
|
(<%= page.url %>)
|
14
18
|
</p>
|
15
19
|
</div>
|
@@ -60,6 +64,34 @@
|
|
60
64
|
<hr />
|
61
65
|
<% end %>
|
62
66
|
</div>
|
67
|
+
<div class="well links">
|
68
|
+
<h2>JSONs</h2>
|
69
|
+
<% page.jsons.each do |json| %>
|
70
|
+
<p>
|
71
|
+
<b>Action: <%= html_encode json.action %></b>
|
72
|
+
<ul>
|
73
|
+
<% json.inputs.each do |k, v| %>
|
74
|
+
<li><%= k.inspect %> = <%= v.inspect %></li>
|
75
|
+
<% end %>
|
76
|
+
</ul>
|
77
|
+
</p>
|
78
|
+
<hr />
|
79
|
+
<% end %>
|
80
|
+
</div>
|
81
|
+
<div class="well links">
|
82
|
+
<h2>XMLs</h2>
|
83
|
+
<% page.xmls.each do |xml| %>
|
84
|
+
<p>
|
85
|
+
<b>Action: <%= html_encode xml.action %></b>
|
86
|
+
<ul>
|
87
|
+
<% xml.inputs.each do |k, v| %>
|
88
|
+
<li><%= k.inspect %> = <%= v.inspect %></li>
|
89
|
+
<% end %>
|
90
|
+
</ul>
|
91
|
+
</p>
|
92
|
+
<hr />
|
93
|
+
<% end %>
|
94
|
+
</div>
|
63
95
|
</div>
|
64
96
|
</div>
|
65
97
|
</div>
|
@@ -0,0 +1,70 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2010-2015 Tasos Laskos <tasos.laskos@arachni-scanner.com>
|
3
|
+
|
4
|
+
This file is part of the Arachni Framework project and is subject to
|
5
|
+
redistribution and commercial restrictions. Please see the Arachni Framework
|
6
|
+
web site for more information on licensing and terms of use.
|
7
|
+
=end
|
8
|
+
|
9
|
+
# @author Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>
|
10
|
+
# @version 0.1
|
11
|
+
class Arachni::Plugins::RestrictToDOMState < Arachni::Plugin::Base
|
12
|
+
|
13
|
+
def prepare
|
14
|
+
print_status 'Sending pause signal...'
|
15
|
+
@pause_id = framework.pause( false )
|
16
|
+
print_status '...done.'
|
17
|
+
|
18
|
+
# Disable any operations that can lead to a crawl, we only want the
|
19
|
+
# system to audit the page snapshot we give it.
|
20
|
+
framework.options.scope.do_not_crawl
|
21
|
+
|
22
|
+
@fragment = options[:fragment]
|
23
|
+
@url = "#{framework.options.url}##{@fragment}"
|
24
|
+
|
25
|
+
print_info "Full URL set to: #{@url}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def run
|
29
|
+
print_status 'Initialising browser...'
|
30
|
+
browser = Arachni::Browser.new( store_pages: false )
|
31
|
+
print_status '...done.'
|
32
|
+
|
33
|
+
print_status 'Loading page...'
|
34
|
+
page = browser.load( @url ).to_page
|
35
|
+
print_info ' Transitions:'
|
36
|
+
page.dom.print_transitions( method(:print_info), ' ' )
|
37
|
+
|
38
|
+
framework.push_to_page_queue page, true
|
39
|
+
print_status 'Pushed to page queue.'
|
40
|
+
ensure
|
41
|
+
return if !browser
|
42
|
+
|
43
|
+
print_status 'Shutting down browser...'
|
44
|
+
browser.shutdown
|
45
|
+
print_status '...done.'
|
46
|
+
end
|
47
|
+
|
48
|
+
def clean_up
|
49
|
+
print_status 'Resuming scan...'
|
50
|
+
framework.resume @pause_id
|
51
|
+
print_status '...done.'
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.info
|
55
|
+
{
|
56
|
+
name: 'Restrict to DOM state',
|
57
|
+
description: %q{Restricts the scan to a single page's DOM state.},
|
58
|
+
author: 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>',
|
59
|
+
version: '0.1',
|
60
|
+
options: [
|
61
|
+
Options::String.new( :fragment,
|
62
|
+
required: true,
|
63
|
+
description: 'URL fragment for the desired state.'
|
64
|
+
)
|
65
|
+
],
|
66
|
+
priority: 0 # run before any other plugin
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|