arachni 0.4.0.4 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/ACKNOWLEDGMENTS.md +2 -2
- data/AUTHORS.md +1 -4
- data/CHANGELOG.md +102 -3
- data/CONTRIBUTORS.md +4 -1
- data/EXPLOITATION.md +6 -6
- data/Gemfile +3 -0
- data/HACKING.md +29 -10
- data/LICENSE.md +176 -339
- data/NOTICE +12 -0
- data/README.md +160 -119
- data/Rakefile +83 -45
- data/arachni.gemspec +124 -0
- data/bin/arachni +14 -8
- data/bin/arachni_console +52 -0
- data/bin/arachni_rpc +14 -8
- data/bin/arachni_rpcd +15 -9
- data/bin/arachni_rpcd_monitor +14 -8
- data/bin/arachni_script +41 -0
- data/bin/arachni_web +18 -19
- data/bin/arachni_web_autostart +17 -18
- data/external/metasploit/plugins/arachni.rb +7 -9
- data/external/metasploit/{LICENSE → plugins/arachni/LICENSE} +0 -0
- data/external/metasploit/{modules → plugins/arachni/modules}/exploits/unix/webapp/arachni_exec.rb +1 -1
- data/external/metasploit/{modules → plugins/arachni/modules}/exploits/unix/webapp/arachni_path_traversal.rb +2 -2
- data/external/metasploit/{modules → plugins/arachni/modules}/exploits/unix/webapp/arachni_php_eval.rb +1 -1
- data/external/metasploit/{modules → plugins/arachni/modules}/exploits/unix/webapp/arachni_php_include.rb +1 -1
- data/external/metasploit/{modules → plugins/arachni/modules}/exploits/unix/webapp/arachni_sqlmap.rb +2 -2
- data/external/scripts/LICENSE.tpl +174 -0
- data/external/scripts/README.md +95 -0
- data/external/scripts/README.tpl +30 -0
- data/external/scripts/build.sh +631 -0
- data/external/scripts/build_all.sh +29 -0
- data/external/scripts/build_and_package.sh +100 -0
- data/external/scripts/cross_build_and_package.sh +20 -0
- data/external/scripts/installer.sh.tpl +166 -0
- data/external/scripts/lib/readlink_f.sh +40 -0
- data/external/scripts/package.sh +134 -0
- data/external/scripts/push_nightlies.sh +125 -0
- data/extras/placeholder +0 -0
- data/gfx/README.md +18 -0
- data/gfx/compiled/banner.png +0 -0
- data/gfx/compiled/favicon.ico +0 -0
- data/gfx/compiled/icon.png +0 -0
- data/gfx/compiled/logo.png +0 -0
- data/gfx/compiled/spider.png +0 -0
- data/gfx/font/Beneath_the_Surface.ttf +0 -0
- data/gfx/font/bts_readme.txt +14 -0
- data/gfx/source/banner.svg +999 -0
- data/gfx/source/icon.svg +627 -0
- data/gfx/source/logo.svg +672 -0
- data/gfx/source/spider.png +0 -0
- data/gfx/source/spider.svg +277 -0
- data/lib/arachni.rb +30 -5
- data/lib/arachni/audit_store.rb +111 -143
- data/lib/arachni/banner.rb +37 -0
- data/lib/arachni/bloom_filter.rb +74 -0
- data/lib/arachni/cache.rb +21 -0
- data/lib/arachni/cache/base.rb +170 -0
- data/lib/arachni/cache/least_cost_replacement.rb +89 -0
- data/lib/arachni/cache/least_recently_used.rb +73 -0
- data/lib/arachni/cache/random_replacement.rb +52 -0
- data/lib/arachni/component/manager.rb +391 -0
- data/lib/arachni/component/options.rb +38 -0
- data/lib/arachni/component/options/address.rb +41 -0
- data/lib/arachni/component/options/base.rb +126 -0
- data/lib/arachni/component/options/bool.rb +55 -0
- data/lib/arachni/component/options/enum.rb +51 -0
- data/lib/arachni/component/options/float.rb +45 -0
- data/lib/arachni/component/options/int.rb +44 -0
- data/lib/arachni/component/options/path.rb +36 -0
- data/lib/arachni/component/options/port.rb +37 -0
- data/lib/arachni/component/options/string.rb +44 -0
- data/lib/arachni/component/options/url.rb +42 -0
- data/lib/arachni/crypto/rsa_aes_cbc.rb +14 -8
- data/lib/arachni/database.rb +4 -4
- data/lib/arachni/database/base.rb +14 -8
- data/lib/arachni/database/hash.rb +21 -12
- data/lib/arachni/database/queue.rb +15 -9
- data/lib/arachni/element/base.rb +147 -0
- data/lib/arachni/element/capabilities/auditable.rb +623 -0
- data/lib/arachni/element/capabilities/auditable/rdiff.rb +243 -0
- data/lib/arachni/element/capabilities/auditable/taint.rb +141 -0
- data/lib/arachni/element/capabilities/auditable/timeout.rb +330 -0
- data/lib/arachni/element/capabilities/body.rb +19 -0
- data/lib/arachni/element/capabilities/mutable.rb +286 -0
- data/lib/arachni/element/capabilities/path.rb +19 -0
- data/lib/arachni/element/capabilities/refreshable.rb +48 -0
- data/lib/arachni/element/capabilities/server.rb +19 -0
- data/lib/arachni/element/cookie.rb +1043 -0
- data/lib/arachni/element/form.rb +1364 -0
- data/lib/arachni/element/header.rb +87 -0
- data/lib/arachni/element/link.rb +227 -0
- data/lib/arachni/exceptions.rb +12 -34
- data/lib/arachni/framework.rb +345 -436
- data/lib/arachni/http.rb +445 -409
- data/lib/arachni/http/cookie_jar.rb +163 -0
- data/lib/arachni/issue.rb +102 -65
- data/lib/arachni/mixins/observable.rb +25 -28
- data/lib/arachni/mixins/progress_bar.rb +11 -5
- data/lib/arachni/mixins/terminal.rb +17 -11
- data/lib/arachni/module.rb +4 -4
- data/lib/arachni/module/auditor.rb +270 -793
- data/lib/arachni/module/base.rb +107 -101
- data/lib/arachni/module/element_db.rb +54 -59
- data/lib/arachni/module/key_filler.rb +35 -35
- data/lib/arachni/module/manager.rb +178 -68
- data/lib/arachni/module/output.rb +25 -30
- data/lib/arachni/module/trainer.rb +85 -156
- data/lib/arachni/module/utilities.rb +29 -138
- data/lib/arachni/options.rb +496 -162
- data/lib/arachni/page.rb +186 -0
- data/lib/arachni/parser.rb +392 -2
- data/lib/arachni/plugin.rb +4 -4
- data/lib/arachni/plugin/base.rb +113 -44
- data/lib/arachni/plugin/manager.rb +120 -54
- data/lib/arachni/report.rb +4 -4
- data/lib/arachni/report/base.rb +59 -44
- data/lib/arachni/report/manager.rb +33 -32
- data/lib/arachni/rpc/client.rb +2 -0
- data/lib/arachni/rpc/client/base.rb +31 -18
- data/lib/arachni/rpc/client/dispatcher.rb +24 -11
- data/lib/arachni/rpc/client/instance.rb +24 -11
- data/lib/arachni/rpc/server/base.rb +12 -9
- data/lib/arachni/rpc/server/dispatcher.rb +161 -164
- data/lib/arachni/rpc/server/dispatcher/handler.rb +164 -0
- data/lib/arachni/rpc/server/{node.rb → dispatcher/node.rb} +86 -104
- data/lib/arachni/rpc/server/distributor.rb +432 -0
- data/lib/arachni/rpc/server/framework.rb +266 -758
- data/lib/arachni/rpc/server/instance.rb +38 -53
- data/lib/arachni/rpc/server/module/manager.rb +17 -20
- data/lib/arachni/rpc/server/output.rb +73 -179
- data/lib/arachni/rpc/server/plugin/manager.rb +58 -24
- data/lib/arachni/ruby.rb +6 -4
- data/lib/arachni/ruby/array.rb +30 -9
- data/lib/arachni/ruby/enumerable.rb +29 -0
- data/lib/arachni/ruby/object.rb +47 -12
- data/lib/arachni/ruby/string.rb +69 -24
- data/lib/arachni/ruby/webrick.rb +31 -0
- data/lib/arachni/session.rb +279 -0
- data/lib/arachni/spider.rb +295 -149
- data/lib/arachni/typhoeus/hydra.rb +18 -4
- data/lib/arachni/typhoeus/request.rb +52 -65
- data/lib/arachni/typhoeus/response.rb +62 -22
- data/lib/arachni/typhoeus/utils.rb +25 -0
- data/lib/arachni/ui/cli/cli.rb +331 -298
- data/lib/arachni/ui/cli/output.rb +105 -77
- data/lib/arachni/ui/foo/output.rb +116 -0
- data/lib/arachni/ui/rpc/dispatcher_monitor.rb +5 -12
- data/lib/arachni/ui/rpc/rpc.rb +43 -48
- data/lib/arachni/ui/web/addon_manager.rb +18 -13
- data/lib/arachni/ui/web/addons/sample.rb +14 -8
- data/lib/arachni/ui/web/addons/scheduler.rb +14 -8
- data/lib/arachni/ui/web/addons/scheduler/views/index.erb +1 -1
- data/lib/arachni/ui/web/addons/scheduler/views/options.erb +0 -3
- data/lib/arachni/ui/web/dispatcher_manager.rb +14 -9
- data/lib/arachni/ui/web/instance_manager.rb +14 -8
- data/lib/arachni/ui/web/log.rb +14 -10
- data/lib/arachni/ui/web/output_stream.rb +11 -5
- data/lib/arachni/ui/web/report_manager.rb +14 -10
- data/lib/arachni/ui/web/scheduler.rb +16 -11
- data/lib/arachni/ui/web/server.rb +62 -56
- data/lib/arachni/ui/web/server/public/style.css +1 -1
- data/lib/arachni/ui/web/server/views/addon.erb +1 -1
- data/lib/arachni/ui/web/server/views/dispatchers.erb +3 -3
- data/lib/arachni/ui/web/server/views/dispatchers_edit.erb +2 -2
- data/lib/arachni/ui/web/server/views/error.erb +1 -1
- data/lib/arachni/ui/web/server/views/home.erb +2 -2
- data/lib/arachni/ui/web/server/views/instance.erb +6 -6
- data/lib/arachni/ui/web/server/views/layout.erb +4 -4
- data/lib/arachni/ui/web/server/views/settings.erb +13 -8
- data/lib/arachni/ui/web/server/views/welcome.erb +1 -1
- data/lib/arachni/ui/web/utilities.rb +24 -35
- data/lib/arachni/uri.rb +619 -0
- data/lib/arachni/utilities.rb +316 -0
- data/lib/arachni/version.rb +12 -6
- data/lib/version +1 -0
- data/modules/audit/code_injection.rb +64 -81
- data/modules/audit/code_injection_timing.rb +57 -75
- data/modules/audit/csrf.rb +87 -185
- data/modules/audit/ldapi.rb +42 -67
- data/modules/audit/os_cmd_injection.rb +53 -71
- data/modules/audit/os_cmd_injection/payloads.txt +1 -1
- data/modules/audit/os_cmd_injection_timing.rb +54 -75
- data/modules/audit/os_cmd_injection_timing/payloads.txt +1 -3
- data/modules/audit/path_traversal.rb +84 -110
- data/modules/audit/response_splitting.rb +41 -53
- data/modules/audit/rfi.rb +68 -76
- data/modules/audit/session_fixation.rb +86 -0
- data/modules/audit/sqli.rb +51 -77
- data/modules/audit/sqli/regexp_ids.txt +5 -19
- data/modules/audit/sqli/regexp_ignore.txt +2 -0
- data/modules/audit/sqli_blind_rdiff.rb +51 -62
- data/modules/audit/sqli_blind_timing.rb +53 -73
- data/modules/audit/trainer.rb +21 -58
- data/modules/audit/unvalidated_redirect.rb +41 -51
- data/modules/audit/xpath.rb +38 -69
- data/modules/audit/xpath/errors.txt +2 -3
- data/modules/audit/xss.rb +65 -69
- data/modules/audit/xss_event.rb +50 -69
- data/modules/audit/xss_path.rb +63 -89
- data/modules/audit/xss_script_tag.rb +53 -66
- data/modules/audit/xss_tag.rb +46 -65
- data/modules/audit/xss_uri.rb +22 -24
- data/modules/recon/allowed_methods.rb +46 -62
- data/modules/recon/backdoors.rb +39 -66
- data/modules/recon/backup_files.rb +49 -79
- data/modules/recon/common_directories.rb +39 -63
- data/modules/recon/common_directories/directories.txt +0 -5
- data/modules/recon/common_files.rb +34 -63
- data/modules/recon/directory_listing.rb +66 -116
- data/modules/recon/grep/captcha.rb +34 -41
- data/modules/recon/grep/credit_card.rb +57 -68
- data/modules/recon/grep/cvs_svn_users.rb +40 -50
- data/modules/recon/grep/emails.rb +34 -41
- data/modules/recon/grep/html_objects.rb +30 -33
- data/modules/recon/grep/http_only_cookies.rb +57 -0
- data/modules/recon/grep/insecure_cookies.rb +55 -0
- data/modules/recon/grep/mixed_resource.rb +93 -0
- data/modules/recon/grep/private_ip.rb +34 -32
- data/modules/recon/grep/ssn.rb +33 -31
- data/modules/recon/grep/unencrypted_password_forms.rb +84 -0
- data/modules/recon/htaccess_limit.rb +38 -54
- data/modules/recon/http_put.rb +48 -62
- data/modules/recon/interesting_responses.rb +77 -79
- data/modules/recon/webdav.rb +53 -79
- data/modules/recon/xst.rb +44 -63
- data/modules/test2.rb +46 -0
- data/path_extractors/anchors.rb +17 -15
- data/path_extractors/forms.rb +17 -15
- data/path_extractors/frames.rb +17 -18
- data/path_extractors/generic.rb +52 -55
- data/path_extractors/links.rb +16 -14
- data/path_extractors/meta_refresh.rb +33 -18
- data/path_extractors/scripts.rb +17 -15
- data/plugins/autologin.rb +60 -85
- data/plugins/beep_notify.rb +25 -27
- data/plugins/cookie_collector.rb +28 -45
- data/plugins/defaults/autothrottle.rb +43 -51
- data/plugins/defaults/content_types.rb +63 -52
- data/plugins/defaults/healthmap.rb +45 -62
- data/plugins/defaults/{metamodules → meta}/remedies/discovery.rb +34 -69
- data/plugins/defaults/meta/remedies/manual_verification.rb +61 -0
- data/plugins/defaults/meta/remedies/timing_attacks.rb +108 -0
- data/plugins/defaults/meta/uniformity.rb +81 -0
- data/plugins/defaults/profiler.rb +68 -115
- data/plugins/defaults/resolver.rb +33 -28
- data/plugins/email_notify.rb +60 -62
- data/plugins/form_dicattack.rb +67 -121
- data/plugins/http_dicattack.rb +51 -65
- data/plugins/libnotify.rb +37 -41
- data/plugins/proxy.rb +407 -152
- data/plugins/proxy/panel/403_forbidden.html.erb +11 -0
- data/plugins/proxy/panel/404_not_found.html.erb +6 -0
- data/plugins/proxy/panel/css/bootstrap.min.css +9 -0
- data/plugins/proxy/panel/css/panel.css +30 -0
- data/plugins/proxy/panel/help.html.erb +66 -0
- data/plugins/proxy/panel/img/glyphicons-halflings-white.png +0 -0
- data/plugins/proxy/panel/img/glyphicons-halflings.png +0 -0
- data/plugins/proxy/panel/img/record.png +0 -0
- data/plugins/proxy/panel/inspect.html.erb +7 -0
- data/plugins/proxy/panel/js/bootstrap.min.js +6 -0
- data/plugins/proxy/panel/js/jquery.min.js +2 -0
- data/plugins/proxy/panel/js/panel.js +39 -0
- data/plugins/proxy/panel/layout.html.erb +25 -0
- data/plugins/proxy/panel/page_accordion.html.erb +67 -0
- data/plugins/proxy/panel/page_twin_accordion.html.erb +18 -0
- data/plugins/proxy/panel/panel.html.erb +63 -0
- data/plugins/proxy/panel/shutdown_message.html.erb +7 -0
- data/plugins/proxy/panel/verify_login_check.html.erb +31 -0
- data/plugins/proxy/panel/verify_login_final.html.erb +26 -0
- data/plugins/proxy/panel/verify_login_sequence.html.erb +45 -0
- data/plugins/proxy/server.rb +175 -47
- data/plugins/proxy/ssl-interceptor-cert.pem +34 -0
- data/plugins/proxy/ssl-interceptor-pkey.pem +51 -0
- data/plugins/rescan.rb +27 -28
- data/plugins/script.rb +53 -0
- data/plugins/vector_feed.rb +226 -0
- data/plugins/waf_detector.rb +70 -73
- data/reports/afr.rb +23 -24
- data/reports/ap.rb +25 -36
- data/reports/html.rb +109 -163
- data/reports/html/default.erb +13 -12
- data/reports/html/default/configuration.erb +21 -21
- data/reports/html/default/css/main.css +350 -350
- data/reports/html/default/issues.erb +1 -1
- data/reports/html/default/js/charts.js +2 -2
- data/reports/html/default/js/helpers.js +0 -42
- data/reports/html/default/js/init.js +0 -1
- data/reports/html/default/sitemap.erb +2 -2
- data/reports/html/default/summary.erb +4 -4
- data/reports/html/default/summary_issue.erb +1 -1
- data/reports/json.rb +26 -28
- data/reports/marshal.rb +23 -25
- data/reports/metareport.rb +65 -98
- data/reports/plugin_formatters/html/autologin.rb +34 -41
- data/reports/plugin_formatters/html/content_types.rb +46 -52
- data/reports/plugin_formatters/html/cookie_collector.rb +41 -47
- data/reports/plugin_formatters/html/discovery.rb +36 -41
- data/reports/plugin_formatters/html/form_dicattack.rb +28 -34
- data/reports/plugin_formatters/html/healthmap.rb +48 -55
- data/reports/plugin_formatters/html/http_dicattack.rb +28 -34
- data/reports/plugin_formatters/html/profiler.rb +26 -30
- data/reports/plugin_formatters/html/profiler/template.erb +7 -7
- data/reports/plugin_formatters/html/resolver.rb +44 -52
- data/reports/plugin_formatters/html/timing_attacks.rb +42 -44
- data/reports/plugin_formatters/html/uniformity.rb +37 -42
- data/reports/plugin_formatters/html/waf_detector.rb +26 -34
- data/reports/plugin_formatters/stdout/autologin.rb +28 -40
- data/reports/plugin_formatters/stdout/content_types.rb +36 -53
- data/reports/plugin_formatters/stdout/cookie_collector.rb +28 -41
- data/reports/plugin_formatters/stdout/discovery.rb +27 -37
- data/reports/plugin_formatters/stdout/form_dicattack.rb +22 -35
- data/reports/plugin_formatters/stdout/healthmap.rb +40 -57
- data/reports/plugin_formatters/stdout/http_dicattack.rb +22 -36
- data/reports/plugin_formatters/stdout/profiler.rb +55 -74
- data/reports/plugin_formatters/stdout/resolver.rb +18 -34
- data/reports/plugin_formatters/stdout/timing_attacks.rb +27 -39
- data/reports/plugin_formatters/stdout/uniformity.rb +32 -44
- data/reports/plugin_formatters/stdout/waf_detector.rb +20 -32
- data/reports/plugin_formatters/xml/autologin.rb +27 -49
- data/reports/plugin_formatters/xml/content_types.rb +41 -66
- data/reports/plugin_formatters/xml/cookie_collector.rb +29 -49
- data/reports/plugin_formatters/xml/discovery.rb +23 -41
- data/reports/plugin_formatters/xml/form_dicattack.rb +22 -40
- data/reports/plugin_formatters/xml/healthmap.rb +44 -63
- data/reports/plugin_formatters/xml/http_dicattack.rb +22 -41
- data/reports/plugin_formatters/xml/profiler.rb +65 -89
- data/reports/plugin_formatters/xml/resolver.rb +21 -41
- data/reports/plugin_formatters/xml/timing_attacks.rb +27 -45
- data/reports/plugin_formatters/xml/uniformity.rb +36 -55
- data/reports/plugin_formatters/xml/waf_detector.rb +23 -42
- data/reports/stdout.rb +120 -121
- data/reports/txt.rb +29 -45
- data/reports/xml.rb +109 -148
- data/reports/xml/buffer.rb +66 -79
- data/reports/yaml.rb +26 -28
- data/rpcd_handlers/placeholder +0 -0
- data/spec/arachni/audit_store_spec.rb +223 -0
- data/spec/arachni/bloom_filter_spec.rb +76 -0
- data/spec/arachni/cache/base_spec.rb +275 -0
- data/spec/arachni/cache/least_cost_replacement_spec.rb +58 -0
- data/spec/arachni/cache/least_recently_used_spec.rb +91 -0
- data/spec/arachni/cache/random_replacement_spec.rb +43 -0
- data/spec/arachni/component/manager_spec.rb +448 -0
- data/spec/arachni/component/options/address_spec.rb +32 -0
- data/spec/arachni/component/options/base_spec.rb +105 -0
- data/spec/arachni/component/options/bool_spec.rb +67 -0
- data/spec/arachni/component/options/enum_spec.rb +51 -0
- data/spec/arachni/component/options/float_spec.rb +42 -0
- data/spec/arachni/component/options/int_spec.rb +46 -0
- data/spec/arachni/component/options/path_spec.rb +32 -0
- data/spec/arachni/component/options/port_spec.rb +38 -0
- data/spec/arachni/component/options/string_spec.rb +38 -0
- data/spec/arachni/component/options/url_spec.rb +36 -0
- data/spec/arachni/crypto/rsa_aes_cbc_spec.rb +31 -0
- data/spec/arachni/database/hash_spec.rb +217 -0
- data/spec/arachni/database/queue_spec.rb +52 -0
- data/spec/arachni/element/base_spec.rb +127 -0
- data/spec/arachni/element/body_spec.rb +9 -0
- data/spec/arachni/element/capabilities/auditable/rdiff_spec.rb +47 -0
- data/spec/arachni/element/capabilities/auditable/taint_spec.rb +110 -0
- data/spec/arachni/element/capabilities/auditable/timeout_spec.rb +107 -0
- data/spec/arachni/element/capabilities/mutable_spec.rb +261 -0
- data/spec/arachni/element/cookie_spec.rb +362 -0
- data/spec/arachni/element/form_spec.rb +668 -0
- data/spec/arachni/element/header_spec.rb +49 -0
- data/spec/arachni/element/link_spec.rb +220 -0
- data/spec/arachni/element/path_spec.rb +9 -0
- data/spec/arachni/element/server_spec.rb +9 -0
- data/spec/arachni/framework_spec.rb +860 -0
- data/spec/arachni/http/cookie_jar_spec.rb +267 -0
- data/spec/arachni/http_spec.rb +991 -0
- data/spec/arachni/issue_spec.rb +307 -0
- data/spec/arachni/mixins/observable_spec.rb +59 -0
- data/spec/arachni/mixins/progress_bar_spec.rb +41 -0
- data/spec/arachni/module/auditor_spec.rb +506 -0
- data/spec/arachni/module/element_db_spec.rb +131 -0
- data/spec/arachni/module/key_filler.rb +15 -0
- data/spec/arachni/module/manager_spec.rb +154 -0
- data/spec/arachni/module/trainer_spec.rb +102 -0
- data/spec/arachni/module/utilities_spec.rb +30 -0
- data/spec/arachni/module/utilities_spec/read_file.txt +3 -0
- data/spec/arachni/options_spec.rb +555 -0
- data/spec/arachni/page_spec.rb +290 -0
- data/spec/arachni/parser_spec.rb +508 -0
- data/spec/arachni/plugin/manager_spec.rb +174 -0
- data/spec/arachni/report/base_spec.rb +53 -0
- data/spec/arachni/report/manager_spec.rb +82 -0
- data/spec/arachni/rpc/client/base_spec.rb +157 -0
- data/spec/arachni/rpc/client/dispatcher_spec.rb +40 -0
- data/spec/arachni/rpc/client/instance_spec.rb +92 -0
- data/spec/arachni/rpc/server/base_spec.rb +40 -0
- data/spec/arachni/rpc/server/dispatcher/handler.rb +120 -0
- data/spec/arachni/rpc/server/dispatcher/node_spec.rb +220 -0
- data/spec/arachni/rpc/server/dispatcher_spec.rb +136 -0
- data/spec/arachni/rpc/server/distributor_spec.rb +628 -0
- data/spec/arachni/rpc/server/framework_hpg_spec.rb +321 -0
- data/spec/arachni/rpc/server/framework_simple_spec.rb +453 -0
- data/spec/arachni/rpc/server/instance_spec.rb +81 -0
- data/spec/arachni/rpc/server/modules/manager_spec.rb +79 -0
- data/spec/arachni/rpc/server/options_spec.rb +124 -0
- data/spec/arachni/rpc/server/output_spec.rb +238 -0
- data/spec/arachni/rpc/server/plugin/manager_spec.rb +86 -0
- data/spec/arachni/ruby/array_spec.rb +103 -0
- data/spec/arachni/ruby/enumerable_spec.rb +37 -0
- data/spec/arachni/ruby/object_spec.rb +38 -0
- data/spec/arachni/ruby/string_spec.rb +77 -0
- data/spec/arachni/ruby/webrick_spec.rb +15 -0
- data/spec/arachni/session_spec.rb +308 -0
- data/spec/arachni/spider_spec.rb +383 -0
- data/spec/arachni/typhoeus/hydra_spec.rb +14 -0
- data/spec/arachni/typhoeus/requrest_spec.rb +58 -0
- data/spec/arachni/typhoeus/response_spec.rb +78 -0
- data/spec/arachni/uri_spec.rb +462 -0
- data/spec/arachni/utilities_spec.rb +297 -0
- data/spec/fixtures/auditstore.afr +2959 -0
- data/spec/fixtures/cookies.txt +9 -0
- data/spec/fixtures/modules/test.rb +58 -0
- data/spec/fixtures/modules/test2.rb +46 -0
- data/spec/fixtures/modules/test3.rb +46 -0
- data/spec/fixtures/passwords.txt +17 -0
- data/spec/fixtures/plugins/bad.rb +46 -0
- data/spec/fixtures/plugins/defaults/default.rb +45 -0
- data/spec/fixtures/plugins/distributable.rb +42 -0
- data/spec/fixtures/plugins/loop.rb +32 -0
- data/spec/fixtures/plugins/wait.rb +34 -0
- data/spec/fixtures/plugins/with_options.rb +31 -0
- data/spec/fixtures/reports/base_spec/plugin_formatters/with_formatters/foobar.rb +21 -0
- data/spec/fixtures/reports/base_spec/with_formatters.rb +23 -0
- data/spec/fixtures/reports/base_spec/with_outfile.rb +24 -0
- data/spec/fixtures/reports/base_spec/without_outfile.rb +20 -0
- data/spec/fixtures/reports/manager_spec/afr.rb +21 -0
- data/spec/fixtures/reports/manager_spec/foo.rb +26 -0
- data/spec/fixtures/rescan.afr.tpl +145 -0
- data/spec/fixtures/rpcd_handlers/echo.rb +68 -0
- data/spec/fixtures/run_mod/body.rb +58 -0
- data/spec/fixtures/run_mod/cookies.rb +58 -0
- data/spec/fixtures/run_mod/empty.rb +58 -0
- data/spec/fixtures/run_mod/flch.rb +63 -0
- data/spec/fixtures/run_mod/forms.rb +58 -0
- data/spec/fixtures/run_mod/headers.rb +58 -0
- data/spec/fixtures/run_mod/links.rb +58 -0
- data/spec/fixtures/run_mod/nil.rb +57 -0
- data/spec/fixtures/run_mod/path.rb +58 -0
- data/spec/fixtures/run_mod/server.rb +58 -0
- data/spec/fixtures/script_plugin.rb +1 -0
- data/spec/fixtures/taint_module/taint.rb +48 -0
- data/spec/fixtures/usernames.txt +13 -0
- data/spec/fixtures/wait_module/wait.rb +48 -0
- data/spec/helpers/auditor.rb +9 -0
- data/spec/helpers/misc.rb +41 -0
- data/spec/helpers/processes.rb +112 -0
- data/spec/helpers/requires.rb +8 -0
- data/spec/helpers/server.rb +54 -0
- data/spec/logs/Dispatcher - 2752-13830.log +49 -0
- data/spec/logs/Dispatcher - 2766-8238.log +35 -0
- data/spec/logs/Dispatcher - 2808-9029.log +31 -0
- data/spec/logs/Dispatcher - 2854-8571.log +26 -0
- data/spec/logs/Dispatcher - 2888-10411.log +20 -0
- data/spec/logs/Dispatcher - 2922-14464.log +13 -0
- data/spec/logs/Dispatcher - 2957-15255.log +19 -0
- data/spec/logs/Dispatcher - 3216-14203.log +35 -0
- data/spec/logs/Dispatcher - 3305-8622.log +43 -0
- data/spec/logs/Dispatcher - 3340-15426.log +35 -0
- data/spec/logs/Dispatcher - 3399-12586.log +40 -0
- data/spec/logs/Dispatcher - 3433-14149.log +26 -0
- data/spec/logs/Dispatcher - 3582-6198.log +27 -0
- data/spec/logs/Dispatcher - 3616-11169.log +13 -0
- data/spec/logs/Dispatcher - 3849-9016.log +7 -0
- data/spec/logs/output_spec.log +4 -0
- data/spec/logs/placeholder +0 -0
- data/spec/modules/audit/code_injection_spec.rb +25 -0
- data/spec/modules/audit/code_injection_timing_spec.rb +24 -0
- data/spec/modules/audit/csrf_spec.rb +38 -0
- data/spec/modules/audit/ldapi_spec.rb +19 -0
- data/spec/modules/audit/os_cmd_injection_spec.rb +24 -0
- data/spec/modules/audit/os_cmd_injection_timing_spec.rb +24 -0
- data/spec/modules/audit/path_traversal_spec.rb +23 -0
- data/spec/modules/audit/response_splitting_spec.rb +19 -0
- data/spec/modules/audit/rfi_spec.rb +19 -0
- data/spec/modules/audit/session_fixation_spec.rb +23 -0
- data/spec/modules/audit/sqli_blind_rdiff_spec.rb +19 -0
- data/spec/modules/audit/sqli_blind_timing_spec.rb +23 -0
- data/spec/modules/audit/sqli_spec.rb +24 -0
- data/spec/modules/audit/trainer_spec.rb +25 -0
- data/spec/modules/audit/unvalidated_redirect_spec.rb +24 -0
- data/spec/modules/audit/xpath_spec.rb +25 -0
- data/spec/modules/audit/xss_event_spec.rb +19 -0
- data/spec/modules/audit/xss_path_spec.rb +19 -0
- data/spec/modules/audit/xss_script_tag_spec.rb +19 -0
- data/spec/modules/audit/xss_spec.rb +24 -0
- data/spec/modules/audit/xss_tag_spec.rb +19 -0
- data/spec/modules/recon/allowed_methods_spec.rb +19 -0
- data/spec/modules/recon/backdoors_spec.rb +19 -0
- data/spec/modules/recon/backup_files_spec.rb +19 -0
- data/spec/modules/recon/common_directories_spec.rb +19 -0
- data/spec/modules/recon/common_files_spec.rb +19 -0
- data/spec/modules/recon/directory_listing_spec.rb +19 -0
- data/spec/modules/recon/grep/captcha_spec.rb +19 -0
- data/spec/modules/recon/grep/credit_card_spec.rb +19 -0
- data/spec/modules/recon/grep/cvs_svn_users_spec.rb +19 -0
- data/spec/modules/recon/grep/emails_spec.rb +19 -0
- data/spec/modules/recon/grep/html_objects_spec.rb +19 -0
- data/spec/modules/recon/grep/http_only_cookies_spec.rb +19 -0
- data/spec/modules/recon/grep/insecure_cookies_spec.rb +19 -0
- data/spec/modules/recon/grep/mixed_resource_spec.rb +20 -0
- data/spec/modules/recon/grep/private_ip_spec.rb +26 -0
- data/spec/modules/recon/grep/ssn_spec.rb +19 -0
- data/spec/modules/recon/grep/unencrypted_password_forms_spec.rb +19 -0
- data/spec/modules/recon/htaccess_limit_spec.rb +19 -0
- data/spec/modules/recon/http_put_spec.rb +19 -0
- data/spec/modules/recon/interesting_responses_spec.rb +27 -0
- data/spec/modules/recon/webdav_spec.rb +19 -0
- data/spec/modules/recon/xst_spec.rb +19 -0
- data/spec/path_extractors/anchors_spec.rb +19 -0
- data/spec/path_extractors/forms_spec.rb +19 -0
- data/spec/path_extractors/frames_spec.rb +20 -0
- data/spec/path_extractors/generic_spec.rb +28 -0
- data/spec/path_extractors/links_spec.rb +19 -0
- data/spec/path_extractors/meta_refresh_spec.rb +24 -0
- data/spec/path_extractors/scripts_spec.rb +19 -0
- data/spec/pems/cacert.pem +39 -0
- data/spec/pems/client/cert.pem +39 -0
- data/spec/pems/client/foo-cert.pem +39 -0
- data/spec/pems/client/foo-key.pem +51 -0
- data/spec/pems/client/key.pem +51 -0
- data/spec/pems/server/cert.pem +39 -0
- data/spec/pems/server/key.pem +51 -0
- data/spec/plugins/autologin_spec.rb +76 -0
- data/spec/plugins/autothrottle_spec.rb +45 -0
- data/spec/plugins/content_types_spec.rb +93 -0
- data/spec/plugins/cookie_collector_spec.rb +32 -0
- data/spec/plugins/form_dicattack_spec.rb +60 -0
- data/spec/plugins/healthmap_spec.rb +40 -0
- data/spec/plugins/http_dicattack_spec.rb +40 -0
- data/spec/plugins/meta/remedies/discovery_spec.rb +15 -0
- data/spec/plugins/meta/remedies/manual_verification_spec.rb +28 -0
- data/spec/plugins/meta/remedies/timing_attacks_spec.rb +30 -0
- data/spec/plugins/meta/uniformity_spec.rb +83 -0
- data/spec/plugins/profiler_spec.rb +82 -0
- data/spec/plugins/rescan_spec.rb +26 -0
- data/spec/plugins/resolver_spec.rb +16 -0
- data/spec/plugins/script_spec.rb +12 -0
- data/spec/plugins/vector_feed_spec.rb +155 -0
- data/spec/plugins/waf_detector_spec.rb +41 -0
- data/spec/reports/afr_spec.rb +13 -0
- data/spec/reports/ap_spec.rb +9 -0
- data/spec/reports/html_spec.rb +13 -0
- data/spec/reports/json_spec.rb +17 -0
- data/spec/reports/marshal_spec.rb +13 -0
- data/spec/reports/stdout_spec.rb +9 -0
- data/spec/reports/txt_spec.rb +8 -0
- data/spec/reports/xml_spec.rb +13 -0
- data/spec/reports/yaml_spec.rb +13 -0
- data/spec/servers/arachni/element/capabilities/auditable/rdiff.rb +36 -0
- data/spec/servers/arachni/element/capabilities/auditable/taint.rb +10 -0
- data/spec/servers/arachni/element/capabilities/auditable/timeout.rb +30 -0
- data/spec/servers/arachni/element/cookie.rb +37 -0
- data/spec/servers/arachni/element/form.rb +93 -0
- data/spec/servers/arachni/element/header.rb +22 -0
- data/spec/servers/arachni/element/link.rb +26 -0
- data/spec/servers/arachni/framework.rb +54 -0
- data/spec/servers/arachni/http.rb +140 -0
- data/spec/servers/arachni/http_auth.rb +9 -0
- data/spec/servers/arachni/module/auditor.rb +135 -0
- data/spec/servers/arachni/module/trainer.rb +40 -0
- data/spec/servers/arachni/parser.rb +70 -0
- data/spec/servers/arachni/rpc/server/framework_hpg.rb +21 -0
- data/spec/servers/arachni/rpc/server/framework_simple.rb +30 -0
- data/spec/servers/arachni/session.rb +110 -0
- data/spec/servers/arachni/spider.rb +148 -0
- data/spec/servers/modules/audit/code_injection.rb +140 -0
- data/spec/servers/modules/audit/code_injection_timing.rb +110 -0
- data/spec/servers/modules/audit/csrf.rb +80 -0
- data/spec/servers/modules/audit/ldapi.rb +73 -0
- data/spec/servers/modules/audit/os_cmd_injection.rb +140 -0
- data/spec/servers/modules/audit/os_cmd_injection_timing.rb +111 -0
- data/spec/servers/modules/audit/path_traversal.rb +176 -0
- data/spec/servers/modules/audit/response_splitting.rb +114 -0
- data/spec/servers/modules/audit/rfi.rb +113 -0
- data/spec/servers/modules/audit/session_fixation.rb +87 -0
- data/spec/servers/modules/audit/sqli.rb +118 -0
- data/spec/servers/modules/audit/sqli/coldfusion +1 -0
- data/spec/servers/modules/audit/sqli/db2 +4 -0
- data/spec/servers/modules/audit/sqli/emc +2 -0
- data/spec/servers/modules/audit/sqli/informix +3 -0
- data/spec/servers/modules/audit/sqli/interbase +2 -0
- data/spec/servers/modules/audit/sqli/jdbc +0 -0
- data/spec/servers/modules/audit/sqli/mssql +26 -0
- data/spec/servers/modules/audit/sqli/mysql +13 -0
- data/spec/servers/modules/audit/sqli/oracle +6 -0
- data/spec/servers/modules/audit/sqli/postgresql +7 -0
- data/spec/servers/modules/audit/sqli/sqlite +4 -0
- data/spec/servers/modules/audit/sqli/sybase +0 -0
- data/spec/servers/modules/audit/sqli_blind_rdiff.rb +74 -0
- data/spec/servers/modules/audit/sqli_blind_timing.rb +121 -0
- data/spec/servers/modules/audit/trainer_module.rb +160 -0
- data/spec/servers/modules/audit/unvalidated_redirect.rb +115 -0
- data/spec/servers/modules/audit/xpath.rb +111 -0
- data/spec/servers/modules/audit/xpath/dotnet +5 -0
- data/spec/servers/modules/audit/xpath/general +13 -0
- data/spec/servers/modules/audit/xpath/java +3 -0
- data/spec/servers/modules/audit/xpath/libxml2 +2 -0
- data/spec/servers/modules/audit/xpath/php +2 -0
- data/spec/servers/modules/audit/xss.rb +152 -0
- data/spec/servers/modules/audit/xss_event.rb +80 -0
- data/spec/servers/modules/audit/xss_path.rb +44 -0
- data/spec/servers/modules/audit/xss_script_tag.rb +73 -0
- data/spec/servers/modules/audit/xss_tag.rb +139 -0
- data/spec/servers/modules/module_server.rb +14 -0
- data/spec/servers/modules/recon/allowed_methods.rb +5 -0
- data/spec/servers/modules/recon/backdoors.rb +4 -0
- data/spec/servers/modules/recon/backup_files.rb +28 -0
- data/spec/servers/modules/recon/common_directories.rb +6 -0
- data/spec/servers/modules/recon/common_files.rb +6 -0
- data/spec/servers/modules/recon/directory_listing.rb +30 -0
- data/spec/servers/modules/recon/grep/captcha.rb +27 -0
- data/spec/servers/modules/recon/grep/credit_card.rb +28 -0
- data/spec/servers/modules/recon/grep/cvs_svn_users.rb +23 -0
- data/spec/servers/modules/recon/grep/emails.rb +21 -0
- data/spec/servers/modules/recon/grep/html_objects.rb +7 -0
- data/spec/servers/modules/recon/grep/http_only_cookies.rb +21 -0
- data/spec/servers/modules/recon/grep/insecure_cookies.rb +21 -0
- data/spec/servers/modules/recon/grep/mixed_resource.rb +83 -0
- data/spec/servers/modules/recon/grep/private_ip.rb +18 -0
- data/spec/servers/modules/recon/grep/ssn.rb +5 -0
- data/spec/servers/modules/recon/grep/unencrypted_password_forms.rb +33 -0
- data/spec/servers/modules/recon/htaccess_limit.rb +8 -0
- data/spec/servers/modules/recon/http_put.rb +7 -0
- data/spec/servers/modules/recon/interesting_responses.rb +5 -0
- data/spec/servers/modules/recon/webdav.rb +25 -0
- data/spec/servers/modules/recon/xst.rb +6 -0
- data/spec/servers/plugins/autologin.rb +38 -0
- data/spec/servers/plugins/autothrottle.rb +8 -0
- data/spec/servers/plugins/content_types.rb +17 -0
- data/spec/servers/plugins/cookie_collector.rb +20 -0
- data/spec/servers/plugins/form_dicattack.rb +28 -0
- data/spec/servers/plugins/healthmap.rb +16 -0
- data/spec/servers/plugins/http_dicattack.rb +9 -0
- data/spec/servers/plugins/http_dicattack_secure.rb +9 -0
- data/spec/servers/plugins/http_dicattack_unprotected.rb +5 -0
- data/spec/servers/plugins/meta/remedies/discovery.rb +7 -0
- data/spec/servers/plugins/meta/remedies/timing_attacks.rb +29 -0
- data/spec/servers/plugins/profiler.rb +82 -0
- data/spec/servers/plugins/rescan.rb +31 -0
- data/spec/servers/plugins/waf_detector.rb +33 -0
- data/spec/shared/component.rb +43 -0
- data/spec/shared/element/capabilities/auditable.rb +729 -0
- data/spec/shared/element/capabilities/refreshable.rb +56 -0
- data/spec/shared/module.rb +162 -0
- data/spec/shared/path_extractor.rb +47 -0
- data/spec/shared/plugin.rb +50 -0
- data/spec/shared/reports.rb +47 -0
- data/spec/spec_helper.rb +53 -0
- metadata +870 -323
- data/extras/modules/recon/raft_dirs.rb +0 -108
- data/extras/modules/recon/raft_dirs/raft-large-directories.txt +0 -62290
- data/extras/modules/recon/raft_files.rb +0 -110
- data/extras/modules/recon/raft_files/raft-large-files.txt +0 -37037
- data/extras/modules/recon/svn_digger_dirs.rb +0 -108
- data/extras/modules/recon/svn_digger_dirs/Licence.txt +0 -674
- data/extras/modules/recon/svn_digger_dirs/ReadMe-Arachni.txt +0 -4
- data/extras/modules/recon/svn_digger_dirs/ReadMe.txt +0 -6
- data/extras/modules/recon/svn_digger_dirs/all-dirs.txt +0 -5960
- data/extras/modules/recon/svn_digger_files.rb +0 -114
- data/extras/modules/recon/svn_digger_files/Licence.txt +0 -674
- data/extras/modules/recon/svn_digger_files/ReadMe-Arachni.txt +0 -4
- data/extras/modules/recon/svn_digger_files/ReadMe.txt +0 -6
- data/extras/modules/recon/svn_digger_files/all-extensionless.txt +0 -25419
- data/extras/modules/recon/svn_digger_files/all.txt +0 -43135
- data/lib/arachni/component_manager.rb +0 -293
- data/lib/arachni/component_options.rb +0 -425
- data/lib/arachni/parser/auditable.rb +0 -606
- data/lib/arachni/parser/elements.rb +0 -315
- data/lib/arachni/parser/page.rb +0 -168
- data/lib/arachni/parser/parser.rb +0 -866
- data/lib/arachni/rpc/server/options.rb +0 -95
- data/lib/arachni/ui/web/addons/autodeploy.rb +0 -207
- data/lib/arachni/ui/web/addons/autodeploy/lib/manager.rb +0 -398
- data/lib/arachni/ui/web/addons/autodeploy/views/index.erb +0 -291
- data/modules/recon/mixed_resource.rb +0 -100
- data/modules/recon/unencrypted_password_forms.rb +0 -107
- data/path_extractors/sitemap.rb +0 -31
- data/plugins/defaults/metamodules/remedies/manual_verification.rb +0 -65
- data/plugins/defaults/metamodules/remedies/timing_attacks.rb +0 -134
- data/plugins/defaults/metamodules/uniformity.rb +0 -99
- data/reports/metareport/arachni_metareport.rb +0 -174
- data/reports/plugin_formatters/stdout/metamodules.rb +0 -82
@@ -1,11 +1,17 @@
|
|
1
1
|
=begin
|
2
|
-
|
3
|
-
Copyright (c) 2010-2012 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
2
|
+
Copyright 2010-2012 Tasos Laskos <tasos.laskos@gmail.com>
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
8
7
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
9
15
|
=end
|
10
16
|
|
11
17
|
module Arachni
|
@@ -1,11 +1,17 @@
|
|
1
1
|
=begin
|
2
|
-
|
3
|
-
Copyright (c) 2010-2012 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
2
|
+
Copyright 2010-2012 Tasos Laskos <tasos.laskos@gmail.com>
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
8
7
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
9
15
|
=end
|
10
16
|
|
11
17
|
module Arachni
|
@@ -27,7 +33,7 @@ module Mixins
|
|
27
33
|
# include ProgressBar
|
28
34
|
#
|
29
35
|
# # clear the screen
|
30
|
-
# clear_screen
|
36
|
+
# clear_screen
|
31
37
|
#
|
32
38
|
# start_time = Time.now
|
33
39
|
#
|
@@ -36,7 +42,7 @@ module Mixins
|
|
36
42
|
# |i|
|
37
43
|
#
|
38
44
|
# # move the cursor to its home, top-left of the screen.
|
39
|
-
# move_to_home
|
45
|
+
# move_to_home
|
40
46
|
#
|
41
47
|
# prog = i / Float( MAX ) * 100
|
42
48
|
#
|
@@ -50,7 +56,7 @@ module Mixins
|
|
50
56
|
#
|
51
57
|
#
|
52
58
|
# # make sure that everything is sent out on time
|
53
|
-
# flush
|
59
|
+
# flush
|
54
60
|
# sleep 0.003
|
55
61
|
# }
|
56
62
|
#
|
@@ -81,21 +87,21 @@ module Terminal
|
|
81
87
|
#
|
82
88
|
# Clear the bottom of the screen
|
83
89
|
#
|
84
|
-
def clear_screen
|
90
|
+
def clear_screen
|
85
91
|
print "\e[2J"
|
86
92
|
end
|
87
93
|
|
88
94
|
#
|
89
95
|
# Moves cursor top left to its home
|
90
96
|
#
|
91
|
-
def move_to_home
|
97
|
+
def move_to_home
|
92
98
|
print "\e[H"
|
93
99
|
end
|
94
100
|
|
95
101
|
#
|
96
102
|
# Flushes the STDOUT buffer
|
97
103
|
#
|
98
|
-
def flush
|
104
|
+
def flush
|
99
105
|
$stdout.flush
|
100
106
|
end
|
101
107
|
|
data/lib/arachni/module.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
lib = Arachni::Options.dir['lib']
|
2
|
+
require lib + 'component/manager'
|
3
|
+
require lib + 'module/base'
|
4
|
+
require lib + 'module/manager'
|
@@ -1,11 +1,17 @@
|
|
1
1
|
=begin
|
2
|
-
|
3
|
-
Copyright (c) 2010-2012 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
2
|
+
Copyright 2010-2012 Tasos Laskos <tasos.laskos@gmail.com>
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
8
7
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
9
15
|
=end
|
10
16
|
|
11
17
|
module Arachni
|
@@ -14,244 +20,156 @@ module Module
|
|
14
20
|
#
|
15
21
|
# Auditor module
|
16
22
|
#
|
17
|
-
# Included by {Module::Base} and provides
|
23
|
+
# Included by {Module::Base} and provides helper audit methods to all modules.
|
24
|
+
#
|
25
|
+
# There are 3 main types of audit and analysis techniques available:
|
26
|
+
# * Taint analysis -- {#audit}
|
27
|
+
# * Timeout analysis -- {#audit_timeout}
|
28
|
+
# * Differential analysis -- {#audit_rdiff}
|
18
29
|
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
# * Timing attacks -- {#audit_timeout}
|
22
|
-
# * Differential analysis attacks -- {#audit_rdiff}
|
30
|
+
# It should be noted that actual analysis takes place at the element level,
|
31
|
+
# and to be more specific, the {Arachni::Element::Capabilities::Auditable} element level.
|
23
32
|
#
|
33
|
+
# The module also provides:
|
34
|
+
# * discovery helpers for checking and logging the existence of remote files
|
35
|
+
# * pattern matching helpers for checking and logging the existence of strings
|
36
|
+
# in responses or in the body of the page that's being audited
|
37
|
+
# * general {Arachni::Issue} logging helpers
|
24
38
|
#
|
25
|
-
# @author
|
26
|
-
# <tasos.laskos@gmail.com>
|
27
|
-
# <zapotek@segfault.gr>
|
28
|
-
# @version: 0.3.1
|
39
|
+
# @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
29
40
|
#
|
30
41
|
module Auditor
|
42
|
+
include Output
|
31
43
|
|
32
|
-
def self.
|
33
|
-
|
34
|
-
|
35
|
-
# holds timing-attack performing Procs to be run after all
|
36
|
-
# non-timing-attack modules have finished.
|
37
|
-
@@__timeout_audit_blocks ||= Queue.new
|
38
|
-
|
39
|
-
@@__timeout_audit_operations_cnt ||= 0
|
40
|
-
|
41
|
-
# populated by timing attack phase 1 with
|
42
|
-
# candidate elements to be verified by phase 2
|
43
|
-
@@__timeout_candidates ||= Queue.new
|
44
|
-
|
45
|
-
# modules which have called the timing attack audit method (audit_timeout)
|
46
|
-
# we're interested in the amount, not the names, and is used to
|
47
|
-
# determine scan progress
|
48
|
-
@@__timeout_loaded_modules ||= Set.new
|
49
|
-
|
50
|
-
@@__on_timing_attacks ||= []
|
51
|
-
|
52
|
-
@@__running_timeout_attacks ||= false
|
53
|
-
|
54
|
-
# the rdiff attack performs it own redundancy checks so we need this to
|
55
|
-
# keep track audited elements
|
56
|
-
@@__rdiff_audited ||= Set.new
|
57
|
-
end
|
58
|
-
|
59
|
-
#
|
60
|
-
# Returns the names of all loaded modules that use timing attacks.
|
61
|
-
#
|
62
|
-
# @return [Set]
|
63
|
-
#
|
64
|
-
def self.timeout_loaded_modules
|
65
|
-
@@__timeout_loaded_modules
|
44
|
+
def self.reset
|
45
|
+
audited.clear
|
66
46
|
end
|
67
47
|
|
68
|
-
#
|
69
|
-
# Holds timing-attack performing Procs to be run after all
|
70
|
-
# non-timing-attack modules have finished.
|
71
|
-
#
|
72
|
-
# @return [Queue]
|
73
|
-
#
|
74
48
|
def self.timeout_audit_blocks
|
75
|
-
|
76
|
-
end
|
77
|
-
|
78
|
-
def self.current_timeout_audit_operations_cnt
|
79
|
-
@@__timeout_audit_blocks.size + @@__timeout_candidates.size
|
49
|
+
Element::Capabilities::Auditable.timeout_audit_blocks
|
80
50
|
end
|
81
|
-
|
82
|
-
|
83
|
-
@@__timeout_audit_operations_cnt += 1
|
84
|
-
@@__timeout_audit_blocks << block
|
51
|
+
def self.timeout_loaded_modules
|
52
|
+
Element::Capabilities::Auditable.timeout_loaded_modules
|
85
53
|
end
|
86
|
-
|
87
|
-
|
88
|
-
@@__timeout_audit_operations_cnt += 1
|
89
|
-
@@__timeout_candidates << elem
|
54
|
+
def self.on_timing_attacks( &block )
|
55
|
+
Element::Capabilities::Auditable.on_timing_attacks( &block )
|
90
56
|
end
|
91
|
-
|
92
|
-
|
93
57
|
def self.running_timeout_attacks?
|
94
|
-
|
58
|
+
Element::Capabilities::Auditable.running_timeout_attacks?
|
95
59
|
end
|
96
|
-
|
97
|
-
|
98
|
-
@@__on_timing_attacks << block
|
60
|
+
def self.timeout_audit_run
|
61
|
+
Element::Capabilities::Auditable.timeout_audit_run
|
99
62
|
end
|
100
|
-
|
101
63
|
def self.timeout_audit_operations_cnt
|
102
|
-
|
64
|
+
Element::Capabilities::Auditable.timeout_audit_operations_cnt
|
65
|
+
end
|
66
|
+
def self.current_timeout_audit_operations_cnt
|
67
|
+
Element::Capabilities::Auditable.current_timeout_audit_operations_cnt
|
103
68
|
end
|
104
69
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
70
|
+
#
|
71
|
+
# @param [#to_s] id identifier of the object to be marked as audited
|
72
|
+
#
|
73
|
+
# @see #audited?
|
74
|
+
#
|
75
|
+
def audited( id )
|
76
|
+
Auditor.audited << "#{self.class}-#{id}"
|
110
77
|
end
|
111
78
|
|
112
|
-
|
113
|
-
|
79
|
+
#
|
80
|
+
# @param [#to_s] id identifier of the object to be checked
|
81
|
+
#
|
82
|
+
# @return [Bool] +true+ if audited, +false+ otherwise
|
83
|
+
#
|
84
|
+
# @see #audited
|
85
|
+
#
|
86
|
+
def audited?( id )
|
87
|
+
Auditor.audited.include?( "#{self.class}-#{id}" )
|
114
88
|
end
|
115
89
|
|
116
90
|
#
|
117
91
|
# Holds constant bitfields that describe the preferred formatting
|
118
92
|
# of injection strings.
|
119
93
|
#
|
120
|
-
|
121
|
-
|
122
|
-
#
|
123
|
-
# Leaves the injection string as is.
|
124
|
-
#
|
125
|
-
STRAIGHT = 1 << 0
|
126
|
-
|
127
|
-
#
|
128
|
-
# Appends the injection string to the default value of the input vector.<br/>
|
129
|
-
# (If no default value exists Arachni will choose one.)
|
130
|
-
#
|
131
|
-
APPEND = 1 << 1
|
132
|
-
|
133
|
-
#
|
134
|
-
# Terminates the injection string with a null character.
|
135
|
-
#
|
136
|
-
NULL = 1 << 2
|
137
|
-
|
138
|
-
#
|
139
|
-
# Prefix the string with a ';', useful for command injection modules
|
140
|
-
#
|
141
|
-
SEMICOLON = 1 << 3
|
142
|
-
end
|
94
|
+
Format = Element::Capabilities::Mutable::Format
|
143
95
|
|
144
96
|
#
|
145
97
|
# Holds constants that describe the HTML elements to be audited.
|
146
98
|
#
|
147
|
-
module Element
|
148
|
-
|
149
|
-
|
150
|
-
COOKIE = Issue::Element::COOKIE
|
151
|
-
HEADER = Issue::Element::HEADER
|
152
|
-
BODY = Issue::Element::BODY
|
153
|
-
PATH = Issue::Element::PATH
|
154
|
-
SERVER = Issue::Element::SERVER
|
155
|
-
end
|
156
|
-
|
157
|
-
RDIFF_OPTIONS = {
|
158
|
-
# append our seeds to the default values
|
159
|
-
:format => [ Format::APPEND ],
|
160
|
-
|
161
|
-
# allow duplicate requests
|
162
|
-
:redundant => true,
|
163
|
-
|
164
|
-
# amount of rdiff iterations
|
165
|
-
:precision => 2
|
166
|
-
}
|
99
|
+
#module Element
|
100
|
+
# include Issue::Element
|
101
|
+
#end
|
167
102
|
|
168
103
|
#
|
169
|
-
#
|
104
|
+
# Holds constants that describe Issue severities.
|
170
105
|
#
|
171
|
-
|
106
|
+
#Severity = Issue::Severity
|
172
107
|
|
108
|
+
OPTIONS = {
|
173
109
|
#
|
174
110
|
# Elements to audit.
|
175
111
|
#
|
176
|
-
#
|
177
|
-
#
|
178
|
-
# use the elements in {#self.info}.
|
112
|
+
# If no elements have been passed to audit candidates will be
|
113
|
+
# determined by {#candidate_elements}.
|
179
114
|
#
|
180
|
-
:
|
181
|
-
|
182
|
-
|
115
|
+
elements: [Element::LINK, Element::FORM,
|
116
|
+
Element::COOKIE, Element::HEADER,
|
117
|
+
Element::BODY],
|
183
118
|
|
184
119
|
#
|
185
|
-
#
|
186
|
-
#
|
187
|
-
:regexp => nil,
|
188
|
-
|
189
|
-
#
|
190
|
-
# Verify the matched string with this value.
|
191
|
-
#
|
192
|
-
:match => nil,
|
193
|
-
|
194
|
-
#
|
195
|
-
# Formatting of the injection strings.
|
196
|
-
#
|
197
|
-
# A new set of audit inputs will be generated
|
198
|
-
# for each value in the array.
|
199
|
-
#
|
200
|
-
# Values can be OR'ed bitfields of all available constants
|
201
|
-
# of {Auditor::Format}.
|
202
|
-
#
|
203
|
-
# @see Auditor::Format
|
204
|
-
#
|
205
|
-
:format => [ Format::STRAIGHT, Format::APPEND,
|
206
|
-
Format::NULL, Format::APPEND | Format::NULL ],
|
207
|
-
|
208
|
-
#
|
209
|
-
# If 'train' is set to true the HTTP response will be
|
210
|
-
# analyzed for new elements. <br/>
|
120
|
+
# If set to +true+ the HTTP response will be
|
121
|
+
# analyzed for new elements.
|
211
122
|
# Be careful when enabling it, there'll be a performance penalty.
|
212
123
|
#
|
213
|
-
#
|
214
|
-
# this option will be overridden to true.
|
215
|
-
#
|
216
|
-
:train => false,
|
217
|
-
|
218
|
-
#
|
219
|
-
# Enable skipping of already audited inputs
|
220
|
-
#
|
221
|
-
:redundant => false,
|
222
|
-
|
124
|
+
# If set to +false+, no training is going to occur.
|
223
125
|
#
|
224
|
-
#
|
126
|
+
# If set to +nil+, when the Auditor submits a form with original or sample values
|
127
|
+
# this option will be overridden to +true+.
|
225
128
|
#
|
226
|
-
:
|
129
|
+
train: nil
|
227
130
|
}
|
228
131
|
|
229
132
|
#
|
230
|
-
#
|
133
|
+
# REQUIRED
|
231
134
|
#
|
232
|
-
#
|
233
|
-
# logged by any of the modules returned by this method.
|
135
|
+
# Must return the Page object you wish to be audited.
|
234
136
|
#
|
235
|
-
# @return [
|
137
|
+
# @return [Arachni::Page]
|
138
|
+
# @abstract
|
236
139
|
#
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
140
|
+
attr_reader :page
|
141
|
+
|
142
|
+
#
|
143
|
+
# REQUIRED
|
144
|
+
#
|
145
|
+
# Must return the Framework
|
146
|
+
#
|
147
|
+
# @return [Arachni::Framework]
|
148
|
+
#
|
149
|
+
# @abstract
|
150
|
+
#
|
151
|
+
attr_reader :framework
|
241
152
|
|
242
153
|
#
|
243
|
-
#
|
154
|
+
# OPTIONAL
|
244
155
|
#
|
245
156
|
# Allows modules to ignore HPG scope restrictions
|
246
157
|
#
|
247
|
-
# This way they can audit elements that are not on the Grid sanctioned
|
158
|
+
# This way they can audit elements that are not on the Grid sanctioned whitelist.
|
248
159
|
#
|
249
160
|
# @return [Bool]
|
250
161
|
#
|
162
|
+
# @abstract
|
163
|
+
#
|
251
164
|
def override_instance_scope?
|
252
165
|
false
|
253
166
|
end
|
254
167
|
|
168
|
+
# @return [Arachni::HTTP]
|
169
|
+
def http
|
170
|
+
HTTP
|
171
|
+
end
|
172
|
+
|
255
173
|
#
|
256
174
|
# Just a delegator logs an array of issues.
|
257
175
|
#
|
@@ -260,7 +178,7 @@ module Auditor
|
|
260
178
|
# @see Arachni::Module::Manager.register_results
|
261
179
|
#
|
262
180
|
def register_results( issues )
|
263
|
-
|
181
|
+
Module::Manager.register_results( issues )
|
264
182
|
end
|
265
183
|
|
266
184
|
#
|
@@ -269,7 +187,7 @@ module Auditor
|
|
269
187
|
# @param [String] url
|
270
188
|
# @param [Bool] silent if false, a message will be sent to stdout
|
271
189
|
# containing the status of the operation.
|
272
|
-
# @param [Proc]
|
190
|
+
# @param [Proc] block called if the file exists, just before logging
|
273
191
|
#
|
274
192
|
# @return [Object] - nil if no URL was provided
|
275
193
|
# - false if the request couldn't be fired
|
@@ -280,24 +198,20 @@ module Auditor
|
|
280
198
|
def log_remote_file_if_exists( url, silent = false, &block )
|
281
199
|
return nil if !url
|
282
200
|
|
283
|
-
|
284
|
-
|
285
|
-
req.on_complete {
|
286
|
-
|res|
|
287
|
-
|
201
|
+
print_status( "Checking for #{url}" ) if !silent
|
202
|
+
remote_file_exist?( url ) do |bool, res|
|
288
203
|
print_status( 'Analyzing response for: ' + url ) if !silent
|
289
204
|
|
290
|
-
if
|
205
|
+
if bool
|
291
206
|
block.call( res ) if block_given?
|
292
207
|
log_remote_file( res )
|
293
208
|
|
294
209
|
# if the file exists let the trainer parse it since it may
|
295
210
|
# contain brand new data to audit
|
296
|
-
|
211
|
+
http.trainer.push( res )
|
297
212
|
end
|
298
|
-
|
299
|
-
|
300
|
-
return true
|
213
|
+
end
|
214
|
+
true
|
301
215
|
end
|
302
216
|
alias :log_remote_directory_if_exists :log_remote_file_if_exists
|
303
217
|
|
@@ -305,10 +219,20 @@ module Auditor
|
|
305
219
|
# Checks that the response points to an existing file/page and not
|
306
220
|
# an error or custom 404 response.
|
307
221
|
#
|
308
|
-
# @param [
|
222
|
+
# @param [String] url
|
309
223
|
#
|
310
|
-
def remote_file_exist?(
|
311
|
-
|
224
|
+
def remote_file_exist?( url, &block )
|
225
|
+
req = http.get( url )
|
226
|
+
return false if !req
|
227
|
+
|
228
|
+
req.on_complete do |res|
|
229
|
+
if res.code != 200
|
230
|
+
block.call( false, res )
|
231
|
+
else
|
232
|
+
http.custom_404?( res ) { |bool| block.call( !bool, res ) }
|
233
|
+
end
|
234
|
+
end
|
235
|
+
true
|
312
236
|
end
|
313
237
|
|
314
238
|
#
|
@@ -318,22 +242,23 @@ module Auditor
|
|
318
242
|
#
|
319
243
|
# @see #log_issue
|
320
244
|
#
|
321
|
-
def log_remote_file( res )
|
245
|
+
def log_remote_file( res, silent = false )
|
322
246
|
url = res.effective_url
|
323
247
|
filename = File.basename( URI( res.effective_url ).path )
|
324
248
|
|
325
249
|
log_issue(
|
326
|
-
:url
|
327
|
-
:
|
328
|
-
:
|
329
|
-
:
|
330
|
-
:
|
331
|
-
:
|
332
|
-
:
|
333
|
-
:
|
250
|
+
url: url,
|
251
|
+
injected: filename,
|
252
|
+
id: filename,
|
253
|
+
elem: Element::PATH,
|
254
|
+
response: res.body,
|
255
|
+
headers: {
|
256
|
+
request: res.request.headers,
|
257
|
+
response: res.headers,
|
334
258
|
}
|
335
259
|
)
|
336
260
|
|
261
|
+
print_ok( "Found #{filename} at #{url}" ) if !silent
|
337
262
|
end
|
338
263
|
alias :log_remote_directory :log_remote_file
|
339
264
|
|
@@ -341,7 +266,6 @@ module Auditor
|
|
341
266
|
# Helper method for issue logging.
|
342
267
|
#
|
343
268
|
# @param [Hash] opts issue options ({Issue})
|
344
|
-
# @param [Bool] include_class_info merge opts with module.info?
|
345
269
|
#
|
346
270
|
# @see Arachni::Module::Base#register_results
|
347
271
|
#
|
@@ -351,714 +275,267 @@ module Auditor
|
|
351
275
|
end
|
352
276
|
|
353
277
|
#
|
354
|
-
# Matches the "string" (default string is the HTML code in
|
278
|
+
# Matches the "string" (default string is the HTML code in page.body) to
|
355
279
|
# an array of regular expressions and logs the results.
|
356
280
|
#
|
357
|
-
# For good measure, regexps will also be run against the page headers (
|
281
|
+
# For good measure, regexps will also be run against the page headers (page.response_headers).
|
358
282
|
#
|
359
283
|
# @param [Array<Regexp>] regexps array of regular expressions to be tested
|
360
284
|
# @param [String] string string to
|
361
285
|
# @param [Block] block block to verify matches before logging,
|
362
286
|
# must return true/false
|
363
287
|
#
|
364
|
-
def match_and_log( regexps, string =
|
365
|
-
|
288
|
+
def match_and_log( regexps, string = page.body, &block )
|
366
289
|
# make sure that we're working with an array
|
367
290
|
regexps = [regexps].flatten
|
368
291
|
|
369
292
|
elems = self.class.info[:elements]
|
370
293
|
elems = OPTIONS[:elements] if !elems || elems.empty?
|
371
294
|
|
372
|
-
regexps.each
|
373
|
-
|
374
|
-
|
375
|
-
string.scan( regexp ).flatten.uniq.each {
|
376
|
-
|match|
|
295
|
+
regexps.each do |regexp|
|
296
|
+
string.scan( regexp ).flatten.uniq.each do |match|
|
377
297
|
|
378
298
|
next if !match
|
379
299
|
next if block && !block.call( match )
|
380
300
|
|
381
301
|
log(
|
382
|
-
:
|
383
|
-
:
|
384
|
-
:
|
302
|
+
regexp: regexp,
|
303
|
+
match: match,
|
304
|
+
element: Element::BODY
|
385
305
|
)
|
386
|
-
|
306
|
+
end if elems.include? Element::BODY
|
387
307
|
|
388
|
-
next if string
|
308
|
+
next if string != page.body
|
389
309
|
|
390
|
-
|
391
|
-
|k,v|
|
310
|
+
page.response_headers.each do |k,v|
|
392
311
|
next if !v
|
393
312
|
|
394
|
-
v.to_s.scan( regexp ).flatten.uniq.each
|
395
|
-
|match|
|
396
|
-
|
313
|
+
v.to_s.scan( regexp ).flatten.uniq.each do |match|
|
397
314
|
next if !match
|
398
315
|
next if block && !block.call( match )
|
399
316
|
|
400
317
|
log(
|
401
|
-
:
|
402
|
-
:
|
403
|
-
:
|
404
|
-
:
|
318
|
+
var: k,
|
319
|
+
regexp: regexp,
|
320
|
+
match: match,
|
321
|
+
element: Element::HEADER
|
405
322
|
)
|
406
|
-
|
407
|
-
|
323
|
+
end
|
324
|
+
end if elems.include? Element::HEADER
|
408
325
|
|
409
|
-
|
326
|
+
end
|
410
327
|
end
|
411
328
|
|
412
329
|
#
|
413
330
|
# Populates and logs an {Arachni::Issue} based on data from "opts" and "res".
|
414
331
|
#
|
415
332
|
# @param [Hash] opts as passed to blocks by audit methods
|
416
|
-
# @param [Typhoeus::Response] res defaults to
|
333
|
+
# @param [Typhoeus::Response] res defaults to page data
|
417
334
|
#
|
418
335
|
def log( opts, res = nil )
|
336
|
+
response_headers = {}
|
337
|
+
request_headers = {}
|
338
|
+
response = nil
|
339
|
+
method = nil
|
340
|
+
|
341
|
+
if page
|
342
|
+
request_headers = nil
|
343
|
+
response_headers = page.response_headers
|
344
|
+
response = page.body
|
345
|
+
url = page.url
|
346
|
+
method = page.method.to_s.upcase if page.method
|
347
|
+
end
|
419
348
|
|
420
|
-
|
421
|
-
|
422
|
-
request_headers = nil
|
423
|
-
response_headers = @page.response_headers
|
424
|
-
response = @page.html
|
425
|
-
url = @page.url
|
426
|
-
method = @page.method.to_s.upcase if @page.method
|
427
|
-
|
428
|
-
if( res )
|
349
|
+
if res
|
429
350
|
request_headers = res.request.headers
|
430
351
|
response_headers = res.headers
|
431
352
|
response = res.body
|
432
|
-
url = opts[:action]
|
353
|
+
url = opts[:action] || res.effective_url
|
433
354
|
method = res.request.method.to_s.upcase
|
434
355
|
end
|
435
356
|
|
436
|
-
if response_headers['content-type']
|
437
|
-
!response_headers['content-type'].substring?( 'text' )
|
357
|
+
if !response_headers['content-type'].to_s.include?( 'text' )
|
438
358
|
response = nil
|
439
359
|
end
|
440
360
|
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
361
|
+
var = opts[:altered] || opts[:var]
|
362
|
+
|
363
|
+
msg = "In #{opts[:element]}"
|
364
|
+
msg << " var '#{var}'" if var
|
365
|
+
print_ok "#{msg} ( #{url} )"
|
445
366
|
|
446
367
|
print_verbose( "Injected string:\t" + opts[:injected] ) if opts[:injected]
|
447
368
|
print_verbose( "Verified string:\t" + opts[:match].to_s ) if opts[:match]
|
448
|
-
print_verbose( "Matched regular expression: " + opts[:regexp].to_s )
|
369
|
+
print_verbose( "Matched regular expression: " + opts[:regexp].to_s ) if opts[:regexp]
|
449
370
|
print_debug( 'Request ID: ' + res.request.id.to_s ) if res
|
450
371
|
print_verbose( '---------' ) if only_positives?
|
451
372
|
|
452
|
-
# Instantiate a new Issue class and append it to the results array
|
453
373
|
log_issue(
|
454
|
-
:var
|
455
|
-
:
|
456
|
-
:
|
457
|
-
:
|
458
|
-
:
|
459
|
-
:
|
460
|
-
:
|
461
|
-
:
|
462
|
-
:
|
463
|
-
:
|
464
|
-
:
|
465
|
-
:
|
466
|
-
:
|
467
|
-
:
|
374
|
+
var: var,
|
375
|
+
url: url,
|
376
|
+
injected: opts[:injected],
|
377
|
+
id: opts[:id],
|
378
|
+
regexp: opts[:regexp],
|
379
|
+
regexp_match: opts[:match],
|
380
|
+
elem: opts[:element],
|
381
|
+
verification: !!opts[:verification],
|
382
|
+
method: method,
|
383
|
+
response: response,
|
384
|
+
opts: opts,
|
385
|
+
headers: {
|
386
|
+
request: request_headers,
|
387
|
+
response: response_headers,
|
468
388
|
}
|
469
389
|
)
|
470
390
|
end
|
471
391
|
|
472
|
-
#
|
473
|
-
|
474
|
-
|
475
|
-
#
|
476
|
-
# If a block has been provided analysis and logging will be delegated to it,
|
477
|
-
# otherwise, if a match is found it will be automatically logged.
|
478
|
-
#
|
479
|
-
# If no elements have been specified in 'opts' it will
|
480
|
-
# use the elements from the module's "self.info()" hash. <br/>
|
481
|
-
# If no elements have been specified in 'opts' or "self.info()" it will
|
482
|
-
# use the elements in {OPTIONS}. <br/>
|
483
|
-
#
|
484
|
-
#
|
485
|
-
# @param [String] injection_str the string to be injected
|
486
|
-
# @param [Hash] opts options as described in {OPTIONS}
|
487
|
-
# @param [Block] &block block to be used for custom analysis of responses; will be passed the following:
|
488
|
-
# * HTTP response
|
489
|
-
# * options
|
490
|
-
# * element
|
491
|
-
# The block will be called as soon as the
|
492
|
-
# HTTP response is received.
|
493
|
-
#
|
494
|
-
def audit( injection_str, opts = { }, &block )
|
495
|
-
|
496
|
-
if( !opts.include?( :elements) || !opts[:elements] || opts[:elements].empty? )
|
497
|
-
opts[:elements] = self.class.info[:elements]
|
498
|
-
end
|
499
|
-
|
500
|
-
if( !opts.include?( :elements) || !opts[:elements] || opts[:elements].empty? )
|
501
|
-
opts[:elements] = OPTIONS[:elements]
|
502
|
-
end
|
503
|
-
|
504
|
-
opts = OPTIONS.merge( opts )
|
505
|
-
|
506
|
-
opts[:elements].each {
|
507
|
-
|elem|
|
508
|
-
|
509
|
-
case elem
|
510
|
-
|
511
|
-
when Element::LINK
|
512
|
-
audit_links( injection_str, opts, &block )
|
513
|
-
|
514
|
-
when Element::FORM
|
515
|
-
audit_forms( injection_str, opts, &block )
|
516
|
-
|
517
|
-
when Element::COOKIE
|
518
|
-
audit_cookies( injection_str, opts, &block )
|
519
|
-
|
520
|
-
when Element::HEADER
|
521
|
-
audit_headers( injection_str, opts, &block )
|
522
|
-
when Element::BODY
|
523
|
-
else
|
524
|
-
raise( 'Unknown element to audit: ' + elem.to_s )
|
525
|
-
end
|
526
|
-
|
527
|
-
}
|
392
|
+
# @see Arachni::Module::Base.preferred
|
393
|
+
def preferred
|
394
|
+
[]
|
528
395
|
end
|
529
396
|
|
530
397
|
#
|
531
|
-
# This is called right before an [Arachni::
|
532
|
-
# is
|
398
|
+
# This is called right before an [Arachni::Element]
|
399
|
+
# is audited and is used to determine whether to skip it or not.
|
533
400
|
#
|
534
401
|
# Running modules can override this as they wish *but* at their own peril.
|
535
402
|
#
|
536
|
-
# @param [Arachni::
|
403
|
+
# @param [Arachni::Element] elem
|
537
404
|
#
|
538
405
|
def skip?( elem )
|
539
|
-
|
540
|
-
|
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
406
|
+
if framework
|
407
|
+
@modname ||= framework.modules.map { |k, v| k if v == self.class }.compact.first
|
408
|
+
(preferred | [@modname]).each do |mod|
|
409
|
+
next if !framework.modules.include?( mod )
|
410
|
+
issue_id = elem.provisioned_issue_id( framework.modules[mod].info[:name] )
|
411
|
+
return true if framework.modules.issue_set.include?( issue_id )
|
412
|
+
end
|
413
|
+
end
|
547
414
|
|
548
|
-
|
415
|
+
false
|
549
416
|
end
|
550
417
|
|
551
418
|
#
|
552
|
-
#
|
553
|
-
#
|
554
|
-
# Here's how it works:
|
555
|
-
# * Loop 1 -- Populates the candidate queue. We're picking the low hanging
|
556
|
-
# fruit here so we can run this in larger concurrent bursts which cause *lots* of noise.
|
557
|
-
# - Initial probing for candidates -- Any element that times out is added to a queue.
|
558
|
-
# - Stabilization -- The candidate is submitted with its default values in
|
559
|
-
# order to wait until the effects of the timing attack have worn off.
|
560
|
-
# * Loop 2 -- Verifies the candidates. This is much more delicate so the
|
561
|
-
# concurrent requests are lowered to pairs.
|
562
|
-
# - Liveness test -- Ensures that stabilization was successful before moving on.
|
563
|
-
# - Verification using an increased timeout -- Any elements that time out again are logged.
|
564
|
-
# - Stabilization
|
565
|
-
#
|
566
|
-
# Ideally, all requests involved with timing attacks would be run in sync mode
|
567
|
-
# but the performance penalties are too high, thus we compromise and make the best of it
|
568
|
-
# by running as little an amount of concurrent requests as possible for any given phase.
|
419
|
+
# Returns a list of prepared elements to be audited.
|
569
420
|
#
|
570
|
-
#
|
571
|
-
#
|
572
|
-
# :timeout => 4000,
|
573
|
-
# :timeout_divider => 1000
|
574
|
-
# }
|
421
|
+
# If no element types have been specified in 'opts' it will
|
422
|
+
# use the elements from the module's "self.info()" hash.
|
575
423
|
#
|
576
|
-
#
|
424
|
+
# If no elements have been specified in 'opts' or "self.info()" it will
|
425
|
+
# use the elements in {OPTIONS}.
|
577
426
|
#
|
427
|
+
# @param [Hash] opts options as described in {OPTIONS} -- only interested in opts[:elements]
|
578
428
|
#
|
579
|
-
# @
|
580
|
-
# __TIME__ will be substituted with (timeout / timeout_divider)
|
581
|
-
# @param [Hash] opts options as described in {OPTIONS} with the following extra:
|
582
|
-
# * :timeout -- milliseconds to wait for the request to complete
|
583
|
-
# * :timeout_divider -- __TIME__ = timeout / timeout_divider
|
429
|
+
# @return [Array<Arachni::Element::Capabilities::Auditable] array of auditable elements
|
584
430
|
#
|
585
|
-
def
|
586
|
-
|
587
|
-
|
588
|
-
Auditor.add_timeout_audit_block {
|
589
|
-
delay = opts[:timeout]
|
590
|
-
|
591
|
-
audit_timeout_debug_msg( 1, delay )
|
592
|
-
timing_attack( strings, opts ) {
|
593
|
-
|res, c_opts, elem|
|
594
|
-
|
595
|
-
elem.auditor( self )
|
596
|
-
|
597
|
-
print_info( "Found a candidate -- #{elem.type.capitalize} input '#{elem.altered}' at #{elem.action}" )
|
598
|
-
|
599
|
-
Arachni::Module::Auditor.audit_timeout_stabilize( elem )
|
600
|
-
|
601
|
-
Auditor.add_timeout_candidate( elem )
|
602
|
-
}
|
603
|
-
}
|
604
|
-
end
|
605
|
-
|
606
|
-
#
|
607
|
-
# Runs all blocks in {timeout_audit_blocks} and verifies
|
608
|
-
# and logs the candidate elements.
|
609
|
-
#
|
610
|
-
def self.timeout_audit_run
|
611
|
-
@@__running_timeout_attacks = true
|
612
|
-
|
613
|
-
while( !@@__timeout_audit_blocks.empty? )
|
614
|
-
@@__timeout_audit_blocks.pop.call
|
431
|
+
def candidate_elements( opts = {} )
|
432
|
+
if !opts.include?( :elements) || !opts[:elements] || opts[:elements].empty?
|
433
|
+
opts[:elements] = self.class.info[:elements]
|
615
434
|
end
|
616
435
|
|
617
|
-
|
618
|
-
|
436
|
+
if !opts.include?( :elements) || !opts[:elements] || opts[:elements].empty?
|
437
|
+
opts[:elements] = OPTIONS[:elements]
|
619
438
|
end
|
620
|
-
end
|
621
|
-
|
622
|
-
#
|
623
|
-
# Runs phase 2 of the timing attack auditing an individual element
|
624
|
-
# (which passed phase 1) with a higher delay and timeout
|
625
|
-
#
|
626
|
-
def self.audit_timeout_phase_2( elem )
|
627
|
-
|
628
|
-
# reset the audited list since we're going to re-audit the elements
|
629
|
-
# @@__timeout_audited = Set.new
|
630
439
|
|
631
|
-
|
632
|
-
opts[:
|
633
|
-
|
634
|
-
# self.audit_timeout_debug_msg( 2, opts[:timeout] )
|
440
|
+
elements = []
|
441
|
+
opts[:elements].each do |elem|
|
442
|
+
next if !Options.audit?( elem )
|
635
443
|
|
636
|
-
|
637
|
-
|
444
|
+
elements |= case elem
|
445
|
+
when Element::LINK
|
446
|
+
page.links
|
638
447
|
|
639
|
-
|
448
|
+
when Element::FORM
|
449
|
+
page.forms
|
640
450
|
|
641
|
-
|
451
|
+
when Element::COOKIE
|
452
|
+
page.cookies
|
642
453
|
|
643
|
-
|
644
|
-
|
645
|
-
elem.get_auditor.http.get( elem.action ).on_complete {
|
646
|
-
|res|
|
454
|
+
when Element::HEADER
|
455
|
+
page.headers
|
647
456
|
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
elem.get_auditor.print_info( 'Liveness check was successful, progressing to verification...' )
|
653
|
-
|
654
|
-
elem.audit( str, opts ) {
|
655
|
-
|c_res, c_opts|
|
656
|
-
|
657
|
-
if c_res.timed_out?
|
658
|
-
|
659
|
-
# all issues logged by timing attacks need manual verification.
|
660
|
-
# end of story.
|
661
|
-
# c_opts[:verification] = true
|
662
|
-
elem.get_auditor.log( c_opts, c_res )
|
663
|
-
|
664
|
-
self.audit_timeout_stabilize( elem )
|
665
|
-
|
666
|
-
else
|
667
|
-
elem.get_auditor.print_info( 'Verification failed.' )
|
668
|
-
end
|
669
|
-
}
|
670
|
-
else
|
671
|
-
elem.get_auditor.print_info( 'Liveness check failed, bailing out...' )
|
457
|
+
when Element::BODY
|
458
|
+
else
|
459
|
+
failt "Unknown element to audit: #{elem}"
|
672
460
|
end
|
673
|
-
|
461
|
+
end
|
674
462
|
|
675
|
-
|
463
|
+
elements.map { |e| d = e.dup; d.auditor = self; d }
|
676
464
|
end
|
677
465
|
|
678
466
|
#
|
679
|
-
#
|
680
|
-
#
|
681
|
-
# attack has worn off in order to safely continue the audit.
|
467
|
+
# If a block has been provided it calls {Arachni::Element::Capabilities::Auditable#audit}
|
468
|
+
# for every element, otherwise, it defaults to {#audit_taint}.
|
682
469
|
#
|
683
|
-
#
|
470
|
+
# Uses {#candidate_elements} to decide which elements to audit.
|
684
471
|
#
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
}
|
694
|
-
|
695
|
-
orig_opts = elem.opts
|
696
|
-
|
697
|
-
elem.get_auditor.print_info( 'Waiting for the effects of the timing attack to wear off.' )
|
698
|
-
elem.get_auditor.print_info( 'Max waiting time: ' + ( d_opts[:timeout] /1000 ).to_s + ' seconds.' )
|
699
|
-
|
700
|
-
elem.auditable = elem.orig
|
701
|
-
res = elem.submit( d_opts ).response
|
702
|
-
|
703
|
-
if !res.timed_out?
|
704
|
-
elem.get_auditor.print_info( 'Server seems responsive again.' )
|
472
|
+
# @see OPTIONS
|
473
|
+
# @see Arachni::Element::Capabilities::Auditable#audit
|
474
|
+
# @see #audit_taint
|
475
|
+
#
|
476
|
+
def audit( injection_str, opts = {}, &block )
|
477
|
+
opts = OPTIONS.merge( opts )
|
478
|
+
if !block_given?
|
479
|
+
audit_taint( injection_str, opts )
|
705
480
|
else
|
706
|
-
|
481
|
+
candidate_elements( opts ).each { |e| e.audit( injection_str, opts, &block ) }
|
707
482
|
end
|
708
|
-
|
709
|
-
elem.opts.merge!( orig_opts )
|
710
|
-
end
|
711
|
-
|
712
|
-
def audit_timeout_debug_msg( phase, delay )
|
713
|
-
print_debug( '---------------------------------------------' )
|
714
|
-
print_debug( "Running phase #{phase.to_s} of timing attack." )
|
715
|
-
print_debug( "Delay set to: #{delay.to_s} milliseconds" )
|
716
|
-
print_debug( '---------------------------------------------' )
|
717
483
|
end
|
718
484
|
|
719
485
|
#
|
720
|
-
#
|
486
|
+
# Provides easy access to element auditing using simple taint analysis.
|
721
487
|
#
|
722
|
-
#
|
723
|
-
# Optionally, you can add a :timeout_divider.
|
488
|
+
# Uses {#candidate_elements} to decide which elements to audit.
|
724
489
|
#
|
725
|
-
# @
|
726
|
-
#
|
727
|
-
# @param [Hash] opts options as described in {OPTIONS}
|
728
|
-
# @param [Block] &block block to call if a timeout occurs,
|
729
|
-
# it will be passed the response and opts
|
490
|
+
# @see OPTIONS
|
491
|
+
# @see Arachni::Element::Analysis::Taint
|
730
492
|
#
|
731
|
-
def
|
732
|
-
|
733
|
-
opts
|
734
|
-
|
735
|
-
[strings].flatten.each {
|
736
|
-
|str|
|
737
|
-
|
738
|
-
opts[:timing_string] = str
|
739
|
-
str = str.gsub( '__TIME__', ( (opts[:timeout] + 3 * opts[:timeout_divider]) / opts[:timeout_divider] ).to_s )
|
740
|
-
opts[:skip_orig] = true
|
741
|
-
|
742
|
-
audit( str, opts ) {
|
743
|
-
|res, c_opts, elem|
|
744
|
-
|
745
|
-
call_on_timing_blocks( res, elem )
|
746
|
-
block.call( res, c_opts, elem ) if block && res.timed_out?
|
747
|
-
}
|
748
|
-
}
|
749
|
-
|
750
|
-
@http.run
|
493
|
+
def audit_taint( taint, opts = {} )
|
494
|
+
opts = OPTIONS.merge( opts )
|
495
|
+
candidate_elements( opts ).each { |e| e.taint_analysis( taint, opts ) }
|
751
496
|
end
|
752
497
|
|
753
498
|
#
|
754
|
-
# Audits
|
755
|
-
# if there are none in opts) using differential analysis attacks.
|
756
|
-
#
|
757
|
-
# opts = {
|
758
|
-
# :precision => 3,
|
759
|
-
# :faults => [ 'fault injections' ],
|
760
|
-
# :bools => [ 'boolean injections' ]
|
761
|
-
# }
|
762
|
-
#
|
763
|
-
# audit_rdiff( opts )
|
764
|
-
#
|
765
|
-
# Here's how it goes:
|
766
|
-
# let default be the default/original response
|
767
|
-
# let fault be the response of the fault injection
|
768
|
-
# let bool be the response of the boolean injection
|
499
|
+
# Audits elements using differential analysis attacks.
|
769
500
|
#
|
770
|
-
#
|
501
|
+
# Uses {#candidate_elements} to decide which elements to audit.
|
771
502
|
#
|
772
|
-
#
|
773
|
-
#
|
774
|
-
# If a block has been provided analysis and logging will be delegated to it.
|
775
|
-
#
|
776
|
-
# @param [Hash] opts available options:
|
777
|
-
# * :format -- as seen in {OPTIONS}
|
778
|
-
# * :elements -- as seen in {OPTIONS}
|
779
|
-
# * :train -- as seen in {OPTIONS}
|
780
|
-
# * :precision -- amount of rdiff iterations
|
781
|
-
# * :faults -- array of fault injection strings (these are supposed to force erroneous conditions when interpreted)
|
782
|
-
# * :bools -- array of boolean injection strings (these are supposed to not alter the webapp behavior when interpreted)
|
783
|
-
# @param [Block] &block block to be used for custom analysis of responses; will be passed the following:
|
784
|
-
# * injected string
|
785
|
-
# * audited element
|
786
|
-
# * default response body
|
787
|
-
# * boolean response
|
788
|
-
# * fault injection response body
|
503
|
+
# @see OPTIONS
|
504
|
+
# @see Arachni::Element::Analysis::RDiff
|
789
505
|
#
|
790
506
|
def audit_rdiff( opts = {}, &block )
|
791
|
-
|
792
|
-
|
793
|
-
opts[:elements] = self.class.info[:elements]
|
794
|
-
end
|
795
|
-
|
796
|
-
if( !opts.include?( :elements) || !opts[:elements] || opts[:elements].empty? )
|
797
|
-
opts[:elements] = OPTIONS[:elements]
|
798
|
-
end
|
799
|
-
|
800
|
-
opts[:elements].each {
|
801
|
-
|elem|
|
802
|
-
|
803
|
-
case elem
|
804
|
-
|
805
|
-
when Element::LINK
|
806
|
-
next if !Options.instance.audit_links
|
807
|
-
@page.links.each {
|
808
|
-
|c_elem|
|
809
|
-
audit_rdiff_elem( c_elem, opts, &block )
|
810
|
-
}
|
811
|
-
|
812
|
-
when Element::FORM
|
813
|
-
next if !Options.instance.audit_forms
|
814
|
-
@page.forms.each {
|
815
|
-
|c_elem|
|
816
|
-
audit_rdiff_elem( c_elem, opts, &block )
|
817
|
-
}
|
818
|
-
|
819
|
-
when Element::COOKIE
|
820
|
-
next if !Options.instance.audit_cookies
|
821
|
-
@page.cookies.each {
|
822
|
-
|c_elem|
|
823
|
-
audit_rdiff_elem( c_elem, opts, &block )
|
824
|
-
}
|
825
|
-
|
826
|
-
when Element::HEADER
|
827
|
-
next if !Options.instance.audit_headers
|
828
|
-
@page.headers.each {
|
829
|
-
|c_elem|
|
830
|
-
audit_rdiff_elem( c_elem, opts, &block )
|
831
|
-
}
|
832
|
-
when Element::BODY
|
833
|
-
else
|
834
|
-
raise( 'Unknown element to audit: ' + elem.to_s )
|
835
|
-
|
836
|
-
end
|
837
|
-
|
838
|
-
}
|
507
|
+
opts = OPTIONS.merge( opts )
|
508
|
+
candidate_elements( opts ).each { |e| e.rdiff_analysis( opts, &block ) }
|
839
509
|
end
|
840
510
|
|
841
511
|
#
|
842
|
-
# Audits
|
512
|
+
# Audits elements using timing attacks and automatically logs results.
|
843
513
|
#
|
844
|
-
#
|
845
|
-
# @param [Hash] opts same as for {#audit_rdiff}
|
846
|
-
# @param [Block] &block same as for {#audit_rdiff}
|
514
|
+
# Uses {#candidate_elements} to decide which elements to audit.
|
847
515
|
#
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|val|
|
855
|
-
return if !val || val.empty?
|
856
|
-
}
|
857
|
-
|
858
|
-
return if __rdiff_audited?( elem )
|
859
|
-
__rdiff_audited!( elem )
|
860
|
-
|
861
|
-
responses = {
|
862
|
-
:orig => nil,
|
863
|
-
:good => {},
|
864
|
-
:bad => {},
|
865
|
-
:bad_total => 0,
|
866
|
-
:good_total => 0
|
867
|
-
}
|
868
|
-
|
869
|
-
elem.auditor( self )
|
870
|
-
opts[:precision].times {
|
871
|
-
# get the default responses
|
872
|
-
elem.audit( '', opts ) {
|
873
|
-
|res|
|
874
|
-
responses[:orig] ||= res.body
|
875
|
-
# remove context-irrelevant dynamic content like banners and such
|
876
|
-
# from the error page
|
877
|
-
responses[:orig] = responses[:orig].rdiff( res.body )
|
878
|
-
}
|
879
|
-
}
|
880
|
-
|
881
|
-
opts[:precision].times {
|
882
|
-
opts[:faults].each {
|
883
|
-
|str|
|
884
|
-
|
885
|
-
# get injection variations that will hopefully cause an internal/silent
|
886
|
-
# SQL error
|
887
|
-
variations = elem.injection_sets( str, opts )
|
888
|
-
|
889
|
-
responses[:bad_total] = variations.size
|
890
|
-
|
891
|
-
variations.each {
|
892
|
-
|c_elem|
|
893
|
-
|
894
|
-
print_status( c_elem.get_status_str( c_elem.altered ) )
|
895
|
-
|
896
|
-
# register us as the auditor
|
897
|
-
c_elem.auditor( self )
|
898
|
-
# submit the link and get the response
|
899
|
-
c_elem.submit( opts ).on_complete {
|
900
|
-
|res|
|
901
|
-
|
902
|
-
responses[:bad][c_elem.altered] ||= res.body.clone
|
903
|
-
|
904
|
-
# remove context-irrelevant dynamic content like banners and such
|
905
|
-
# from the error page
|
906
|
-
responses[:bad][c_elem.altered] =
|
907
|
-
responses[:bad][c_elem.altered].rdiff( res.body.clone )
|
908
|
-
}
|
909
|
-
}
|
910
|
-
}
|
911
|
-
}
|
912
|
-
|
913
|
-
opts[:bools].each {
|
914
|
-
|str|
|
915
|
-
|
916
|
-
# get injection variations that will not affect the outcome of the query
|
917
|
-
variations = elem.injection_sets( str, opts )
|
918
|
-
|
919
|
-
responses[:good_total] = variations.size
|
920
|
-
|
921
|
-
variations.each {
|
922
|
-
|c_elem|
|
923
|
-
|
924
|
-
print_status( c_elem.get_status_str( c_elem.altered ) )
|
925
|
-
|
926
|
-
# register us as the auditor
|
927
|
-
c_elem.auditor( self )
|
928
|
-
# submit the link and get the response
|
929
|
-
c_elem.submit( opts ).on_complete {
|
930
|
-
|res|
|
931
|
-
|
932
|
-
responses[:good][c_elem.altered] ||= []
|
933
|
-
|
934
|
-
# save the response for later analysis
|
935
|
-
responses[:good][c_elem.altered] << {
|
936
|
-
'str' => str,
|
937
|
-
'res' => res,
|
938
|
-
'elem' => c_elem
|
939
|
-
}
|
940
|
-
}
|
941
|
-
}
|
942
|
-
}
|
943
|
-
|
944
|
-
# when this runs the 'responses' hash will have been populated
|
945
|
-
@http.after_run {
|
946
|
-
|
947
|
-
responses[:good].keys.each {
|
948
|
-
|key|
|
949
|
-
|
950
|
-
responses[:good][key].each {
|
951
|
-
|res|
|
952
|
-
|
953
|
-
if block
|
954
|
-
block.call( res['str'], res['elem'], responses[:orig], res['res'], responses[:bad][key] )
|
955
|
-
elsif( responses[:orig] == res['res'].body &&
|
956
|
-
responses[:bad][key] != res['res'].body &&
|
957
|
-
!@http.custom_404?( res['res'] ) && res['res'].code == 200 )
|
958
|
-
|
959
|
-
url = res['res'].effective_url
|
960
|
-
|
961
|
-
# since we bypassed the auditor completely we need to create
|
962
|
-
# our own opts hash and pass it to the Vulnerability class.
|
963
|
-
#
|
964
|
-
# this is only required for Metasploitable vulnerabilities
|
965
|
-
opts = {
|
966
|
-
:injected_orig => res['str'],
|
967
|
-
:combo => res['elem'].auditable
|
968
|
-
}
|
969
|
-
|
970
|
-
issue = Issue.new( {
|
971
|
-
:var => key,
|
972
|
-
:url => url,
|
973
|
-
:method => res['res'].request.method.to_s,
|
974
|
-
:opts => opts,
|
975
|
-
:injected => res['str'],
|
976
|
-
:id => res['str'],
|
977
|
-
:regexp => 'n/a',
|
978
|
-
:regexp_match => 'n/a',
|
979
|
-
:elem => res['elem'].type,
|
980
|
-
:response => res['res'].body,
|
981
|
-
# :verification => true,
|
982
|
-
:headers => {
|
983
|
-
:request => res['res'].request.headers,
|
984
|
-
:response => res['res'].headers,
|
985
|
-
}
|
986
|
-
}.merge( self.class.info )
|
987
|
-
)
|
988
|
-
|
989
|
-
print_ok( "In #{res['elem'].type} var '#{key}' ( #{url} )" )
|
990
|
-
|
991
|
-
# register our results with the system
|
992
|
-
register_results( [ issue ] )
|
993
|
-
end
|
994
|
-
|
995
|
-
}
|
996
|
-
}
|
997
|
-
}
|
998
|
-
end
|
999
|
-
|
1000
|
-
def __rdiff_audited!( elem )
|
1001
|
-
@@__rdiff_audited << __rdiff_audit_id( elem )
|
516
|
+
# @see OPTIONS
|
517
|
+
# @see Arachni::Element::Analysis::Timeout
|
518
|
+
#
|
519
|
+
def audit_timeout( strings, opts = {} )
|
520
|
+
opts = OPTIONS.merge( opts )
|
521
|
+
candidate_elements( opts ).each { |e| e.timeout_analysis( strings, opts ) }
|
1002
522
|
end
|
1003
523
|
|
1004
|
-
def __rdiff_audited?( elem )
|
1005
|
-
@@__rdiff_audited.include?( __rdiff_audit_id( elem ) )
|
1006
|
-
end
|
1007
524
|
|
1008
|
-
|
1009
|
-
elem.action + elem.auditable.keys.to_s
|
1010
|
-
end
|
525
|
+
private
|
1011
526
|
|
1012
527
|
#
|
1013
|
-
#
|
1014
|
-
#
|
1015
|
-
# * audit_forms()
|
1016
|
-
# * audit_cookies()
|
1017
|
-
# * audit_headers()
|
528
|
+
# Helper +Set+ for modules which want to keep track of what they've audited
|
529
|
+
# by themselves.
|
1018
530
|
#
|
1019
|
-
#
|
1020
|
-
# and method shortcuts.
|
1021
|
-
#
|
1022
|
-
# @see #audit_elems
|
1023
|
-
#
|
1024
|
-
def method_missing( sym, *args, &block )
|
1025
|
-
|
1026
|
-
elem = sym.to_s.gsub!( 'audit_', '@' )
|
1027
|
-
raise NoMethodError.new( "Undefined method '#{sym.to_s}'.", sym, args ) if !elem
|
1028
|
-
|
1029
|
-
elems = @page.instance_variable_get( elem )
|
1030
|
-
|
1031
|
-
if( elems && elem )
|
1032
|
-
raise ArgumentError.new( "Missing required argument 'injection_str'" +
|
1033
|
-
" for audit_#{elem.gsub( '@', '' )}()." ) if( !args[0] )
|
1034
|
-
audit_elems( elems, args[0], args[1] ? args[1]: {}, &block )
|
1035
|
-
else
|
1036
|
-
raise NoMethodError.new( "Undefined method '#{sym.to_s}'.", sym, args )
|
1037
|
-
end
|
1038
|
-
end
|
1039
|
-
|
1040
|
-
#
|
1041
|
-
# Audits Auditable HTML/HTTP elements
|
531
|
+
# @return [Set]
|
1042
532
|
#
|
1043
|
-
# @
|
1044
|
-
# @
|
1045
|
-
# @param [Hash] opts same as for {#audit}
|
1046
|
-
# @param [Block] &block same as for {#audit}
|
533
|
+
# @see #audited?
|
534
|
+
# @see #audited
|
1047
535
|
#
|
1048
|
-
# @see #method_missing
|
1049
536
|
#
|
1050
|
-
def
|
1051
|
-
|
1052
|
-
opts = OPTIONS.merge( opts )
|
1053
|
-
url = @page.url
|
1054
|
-
|
1055
|
-
opts[:injected_orig] = injection_str
|
1056
|
-
|
1057
|
-
elements.deep_clone.each {
|
1058
|
-
|elem|
|
1059
|
-
elem.auditor( self )
|
1060
|
-
elem.audit( injection_str, opts, &block )
|
1061
|
-
}
|
537
|
+
def self.audited
|
538
|
+
@audited ||= BloomFilter.new
|
1062
539
|
end
|
1063
540
|
|
1064
541
|
end
|