arachni 0.3 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/ACKNOWLEDGMENTS.md +1 -1
- data/CHANGELOG.md +146 -0
- data/CONTRIBUTORS.md +1 -0
- data/HACKING.md +3 -3
- data/README.md +81 -49
- data/Rakefile +11 -14
- data/bin/arachni +4 -8
- data/bin/arachni_rpc +17 -0
- data/bin/arachni_rpcd +18 -0
- data/bin/arachni_rpcd_monitor +18 -0
- data/bin/arachni_web +25 -48
- data/bin/arachni_web_autostart +3 -3
- data/conf/README.webui.yaml.txt +7 -21
- data/external/metasploit/plugins/arachni.rb +0 -7
- data/extras/modules/recon/raft_dirs.rb +108 -0
- data/extras/modules/recon/raft_dirs/raft-large-directories.txt +62290 -0
- data/extras/modules/recon/raft_files.rb +110 -0
- data/extras/modules/recon/raft_files/raft-large-files.txt +37037 -0
- data/extras/modules/recon/svn_digger_dirs.rb +108 -0
- data/extras/modules/recon/svn_digger_dirs/Licence.txt +674 -0
- data/extras/modules/recon/svn_digger_dirs/ReadMe-Arachni.txt +4 -0
- data/extras/modules/recon/svn_digger_dirs/ReadMe.txt +6 -0
- data/extras/modules/recon/svn_digger_dirs/all-dirs.txt +5960 -0
- data/extras/modules/recon/svn_digger_files.rb +114 -0
- data/extras/modules/recon/svn_digger_files/Licence.txt +674 -0
- data/extras/modules/recon/svn_digger_files/ReadMe-Arachni.txt +4 -0
- data/extras/modules/recon/svn_digger_files/ReadMe.txt +6 -0
- data/extras/modules/recon/svn_digger_files/all-extensionless.txt +25419 -0
- data/extras/modules/recon/svn_digger_files/all.txt +43135 -0
- data/lib/arachni.rb +2 -7
- data/lib/{audit_store.rb → arachni/audit_store.rb} +68 -60
- data/lib/{component_manager.rb → arachni/component_manager.rb} +8 -8
- data/lib/{component_options.rb → arachni/component_options.rb} +34 -4
- data/lib/{crypto → arachni/crypto}/rsa_aes_cbc.rb +1 -2
- data/lib/arachni/database.rb +4 -0
- data/lib/arachni/database/base.rb +125 -0
- data/lib/arachni/database/hash.rb +384 -0
- data/lib/arachni/database/queue.rb +93 -0
- data/lib/{exceptions.rb → arachni/exceptions.rb} +1 -1
- data/lib/arachni/framework.rb +899 -0
- data/lib/{http.rb → arachni/http.rb} +63 -166
- data/lib/{issue.rb → arachni/issue.rb} +46 -17
- data/lib/{mixins → arachni/mixins}/observable.rb +1 -1
- data/lib/arachni/mixins/progress_bar.rb +81 -0
- data/lib/arachni/mixins/terminal.rb +106 -0
- data/lib/{module.rb → arachni/module.rb} +0 -0
- data/lib/{module → arachni/module}/auditor.rb +250 -86
- data/lib/{module → arachni/module}/base.rb +8 -18
- data/lib/{module → arachni/module}/element_db.rb +10 -2
- data/lib/{module → arachni/module}/key_filler.rb +1 -1
- data/lib/arachni/module/manager.rb +145 -0
- data/lib/{module → arachni/module}/output.rb +6 -1
- data/lib/{module → arachni/module}/trainer.rb +48 -52
- data/lib/{module → arachni/module}/utilities.rb +66 -15
- data/lib/{nokogiri → arachni/nokogiri}/xml/node.rb +0 -0
- data/lib/arachni/options.rb +986 -0
- data/lib/{parser.rb → arachni/parser.rb} +0 -0
- data/lib/{parser → arachni/parser}/auditable.rb +111 -32
- data/lib/{parser → arachni/parser}/elements.rb +28 -20
- data/lib/{parser → arachni/parser}/page.rb +20 -3
- data/lib/{parser → arachni/parser}/parser.rb +100 -63
- data/lib/{plugin.rb → arachni/plugin.rb} +0 -0
- data/lib/{plugin → arachni/plugin}/base.rb +43 -6
- data/lib/{plugin → arachni/plugin}/manager.rb +40 -13
- data/lib/{report.rb → arachni/report.rb} +0 -0
- data/lib/{report → arachni/report}/base.rb +43 -2
- data/lib/{report → arachni/report}/manager.rb +7 -18
- data/lib/arachni/rpc/client/base.rb +42 -0
- data/lib/{rpc/xml → arachni/rpc}/client/dispatcher.rb +12 -13
- data/lib/arachni/rpc/client/instance.rb +62 -0
- data/lib/arachni/rpc/server/base.rb +51 -0
- data/lib/arachni/rpc/server/dispatcher.rb +438 -0
- data/lib/arachni/rpc/server/framework.rb +1163 -0
- data/lib/arachni/rpc/server/instance.rb +184 -0
- data/lib/{rpc/xml → arachni/rpc}/server/module/manager.rb +8 -5
- data/lib/arachni/rpc/server/node.rb +267 -0
- data/lib/{rpc/xml → arachni/rpc}/server/options.rb +6 -35
- data/lib/{rpc/xml → arachni/rpc}/server/output.rb +29 -3
- data/lib/{rpc/xml → arachni/rpc}/server/plugin/manager.rb +5 -6
- data/lib/{ruby.rb → arachni/ruby.rb} +1 -2
- data/lib/arachni/ruby/array.rb +31 -0
- data/lib/{ruby → arachni/ruby}/object.rb +1 -1
- data/lib/{ruby → arachni/ruby}/string.rb +1 -1
- data/lib/{spider.rb → arachni/spider.rb} +83 -110
- data/lib/arachni/typhoeus/hydra.rb +7 -0
- data/lib/{typhoeus → arachni/typhoeus}/request.rb +11 -9
- data/lib/{typhoeus → arachni/typhoeus}/response.rb +4 -0
- data/lib/{ui → arachni/ui}/cli/cli.rb +154 -84
- data/lib/{ui → arachni/ui}/cli/output.rb +57 -19
- data/lib/{ui/xmlrpc → arachni/ui/rpc}/dispatcher_monitor.rb +11 -10
- data/lib/{ui/xmlrpc/xmlrpc.rb → arachni/ui/rpc/rpc.rb} +102 -158
- data/lib/{ui → arachni/ui}/web/addon_manager.rb +23 -3
- data/lib/arachni/ui/web/addons/autodeploy.rb +207 -0
- data/lib/{ui → arachni/ui}/web/addons/autodeploy/lib/manager.rb +142 -35
- data/lib/arachni/ui/web/addons/autodeploy/views/index.erb +291 -0
- data/lib/{ui → arachni/ui}/web/addons/sample.rb +1 -1
- data/lib/{ui → arachni/ui}/web/addons/sample/views/index.erb +0 -0
- data/lib/{ui → arachni/ui}/web/addons/scheduler.rb +30 -22
- data/lib/{ui → arachni/ui}/web/addons/scheduler/views/index.erb +56 -22
- data/lib/{ui → arachni/ui}/web/addons/scheduler/views/options.erb +0 -0
- data/lib/arachni/ui/web/dispatcher_manager.rb +274 -0
- data/lib/arachni/ui/web/instance_manager.rb +69 -0
- data/lib/{ui → arachni/ui}/web/log.rb +1 -1
- data/lib/arachni/ui/web/output_stream.rb +54 -0
- data/lib/{ui → arachni/ui}/web/report_manager.rb +48 -54
- data/lib/{ui → arachni/ui}/web/scheduler.rb +42 -47
- data/lib/arachni/ui/web/server.rb +1197 -0
- data/lib/{ui → arachni/ui}/web/server/db/placeholder +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/banner.png +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/bodybg-small.png +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/bodybg.png +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/pbar-ani.gif +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/jquery-ui-1.8.9.custom.css +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/favicon.ico +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/footer.jpg +0 -0
- data/lib/{ui/web/server/public/icons/error.png → arachni/ui/web/server/public/icons/bad.png} +0 -0
- data/lib/arachni/ui/web/server/public/icons/error.png +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/icons/info.png +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/icons/ok.png +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/icons/status.png +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/js/jquery-1.4.4.min.js +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/js/jquery-ui-1.8.9.custom.min.js +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/js/jquery-ui-timepicker.js +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/logo.png +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/nav-left.jpg +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/nav-right.jpg +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/nav-selected-left.jpg +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/nav-selected-right.jpg +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/plugins/sample/style.css +0 -0
- data/lib/{ui/web/server/tmp → arachni/ui/web/server/public/reports}/placeholder +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/sidebar-bottom.jpg +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/sidebar-h4.jpg +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/sidebar-top.jpg +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/spider.png +0 -0
- data/lib/{ui → arachni/ui}/web/server/public/style.css +3 -2
- data/lib/arachni/ui/web/server/tmp/placeholder +0 -0
- data/lib/{ui → arachni/ui}/web/server/views/addon.erb +0 -0
- data/lib/{ui → arachni/ui}/web/server/views/addons.erb +0 -0
- data/lib/{ui → arachni/ui}/web/server/views/dispatcher_error.erb +0 -0
- data/lib/arachni/ui/web/server/views/dispatchers.erb +175 -0
- data/lib/arachni/ui/web/server/views/dispatchers_edit.erb +71 -0
- data/lib/arachni/ui/web/server/views/error.erb +22 -0
- data/lib/{ui → arachni/ui}/web/server/views/flash.erb +2 -2
- data/lib/arachni/ui/web/server/views/home.erb +60 -0
- data/lib/{ui → arachni/ui}/web/server/views/instance.erb +55 -75
- data/lib/arachni/ui/web/server/views/js/home.erb +32 -0
- data/lib/{ui → arachni/ui}/web/server/views/layout.erb +2 -2
- data/lib/{ui → arachni/ui}/web/server/views/log.erb +0 -0
- data/lib/arachni/ui/web/server/views/module.erb +30 -0
- data/lib/{ui → arachni/ui}/web/server/views/modules.erb +2 -22
- data/lib/{ui → arachni/ui}/web/server/views/options.erb +0 -0
- data/lib/{ui → arachni/ui}/web/server/views/output_results.erb +4 -4
- data/lib/{ui → arachni/ui}/web/server/views/plugins.erb +23 -12
- data/lib/{ui → arachni/ui}/web/server/views/report_formats.erb +1 -1
- data/lib/{ui → arachni/ui}/web/server/views/reports.erb +1 -1
- data/lib/{ui → arachni/ui}/web/server/views/settings.erb +59 -16
- data/lib/{ui → arachni/ui}/web/server/views/welcome.erb +3 -1
- data/lib/{ui → arachni/ui}/web/utilities.rb +8 -3
- data/lib/arachni/version.rb +16 -0
- data/modules/audit/code_injection.rb +11 -20
- data/modules/audit/code_injection_timing.rb +2 -6
- data/modules/audit/csrf.rb +8 -16
- data/modules/audit/ldapi.rb +5 -11
- data/modules/audit/os_cmd_injection.rb +5 -9
- data/modules/audit/os_cmd_injection_timing.rb +4 -8
- data/modules/audit/path_traversal.rb +7 -13
- data/modules/audit/response_splitting.rb +8 -21
- data/modules/audit/rfi.rb +6 -46
- data/modules/audit/sqli.rb +5 -11
- data/modules/audit/sqli/regexp_ids.txt +0 -6
- data/modules/audit/sqli_blind_rdiff.rb +5 -10
- data/modules/audit/sqli_blind_timing.rb +4 -9
- data/modules/audit/trainer.rb +6 -12
- data/modules/audit/unvalidated_redirect.rb +6 -17
- data/modules/audit/xpath.rb +5 -12
- data/modules/audit/xss.rb +37 -23
- data/modules/audit/xss_event.rb +5 -10
- data/modules/audit/xss_path.rb +47 -41
- data/modules/audit/xss_script_tag.rb +5 -10
- data/modules/audit/xss_tag.rb +5 -10
- data/modules/audit/xss_uri.rb +17 -89
- data/modules/recon/allowed_methods.rb +6 -15
- data/modules/recon/backdoors.rb +12 -52
- data/modules/recon/backup_files.rb +25 -88
- data/modules/recon/common_directories.rb +8 -54
- data/modules/recon/common_files.rb +7 -58
- data/modules/recon/directory_listing.rb +6 -15
- data/modules/recon/grep/captcha.rb +1 -1
- data/modules/recon/grep/credit_card.rb +62 -27
- data/modules/recon/grep/cvs_svn_users.rb +1 -1
- data/modules/recon/grep/emails.rb +1 -1
- data/modules/recon/grep/html_objects.rb +1 -1
- data/modules/recon/grep/private_ip.rb +1 -1
- data/modules/recon/grep/ssn.rb +9 -9
- data/modules/recon/htaccess_limit.rb +6 -14
- data/modules/recon/http_put.rb +7 -15
- data/modules/recon/interesting_responses.rb +7 -13
- data/modules/recon/mixed_resource.rb +100 -0
- data/modules/recon/unencrypted_password_forms.rb +8 -20
- data/modules/recon/webdav.rb +6 -16
- data/modules/recon/xst.rb +7 -13
- data/path_extractors/anchors.rb +1 -1
- data/path_extractors/forms.rb +1 -1
- data/path_extractors/frames.rb +1 -1
- data/path_extractors/generic.rb +47 -3
- data/path_extractors/links.rb +1 -1
- data/path_extractors/meta_refresh.rb +1 -1
- data/path_extractors/scripts.rb +3 -4
- data/path_extractors/sitemap.rb +1 -1
- data/plugins/autologin.rb +9 -18
- data/plugins/beep_notify.rb +51 -0
- data/plugins/cookie_collector.rb +12 -12
- data/plugins/defaults/autothrottle.rb +86 -0
- data/plugins/{content_types.rb → defaults/content_types.rb} +25 -19
- data/plugins/{healthmap.rb → defaults/healthmap.rb} +30 -18
- data/plugins/defaults/metamodules/remedies/discovery.rb +164 -0
- data/plugins/defaults/metamodules/remedies/manual_verification.rb +65 -0
- data/{metamodules/timeout_notice.rb → plugins/defaults/metamodules/remedies/timing_attacks.rb} +26 -22
- data/{metamodules → plugins/defaults/metamodules}/uniformity.rb +15 -14
- data/plugins/{profiler.rb → defaults/profiler.rb} +19 -30
- data/plugins/defaults/resolver.rb +55 -0
- data/plugins/email_notify.rb +108 -0
- data/plugins/form_dicattack.rb +8 -16
- data/plugins/http_dicattack.rb +4 -12
- data/plugins/libnotify.rb +86 -0
- data/plugins/proxy.rb +8 -17
- data/plugins/proxy/server.rb +3 -3
- data/plugins/rescan.rb +60 -0
- data/plugins/waf_detector.rb +5 -16
- data/profiles/full.afp +3 -30
- data/reports/afr.rb +2 -5
- data/reports/ap.rb +3 -1
- data/reports/html.rb +210 -68
- data/reports/html/default.erb +72 -1014
- data/reports/html/default/configuration.erb +126 -0
- data/reports/html/default/css/jquery-ui.css +570 -0
- data/reports/html/default/css/jquery.jqplot.min.css +1 -0
- data/reports/html/default/css/main.css +391 -0
- data/reports/html/default/issue.erb +189 -0
- data/reports/html/default/issues.erb +65 -0
- data/reports/html/default/js/charts.js +146 -0
- data/reports/html/default/js/helpers.js +95 -0
- data/reports/html/default/js/init.js +73 -0
- data/reports/html/default/js/lib/jqplot.barRenderer.min.js +57 -0
- data/reports/html/default/js/lib/jqplot.categoryAxisRenderer.min.js +57 -0
- data/reports/html/default/js/lib/jqplot.cursor.min.js +57 -0
- data/reports/html/default/js/lib/jqplot.pieRenderer.min.js +57 -0
- data/reports/html/default/js/lib/jqplot.pointLabels.min.js +57 -0
- data/reports/html/default/js/lib/jquery-ui.min.js +404 -0
- data/reports/html/default/js/lib/jquery.jqplot.min.js +57 -0
- data/reports/html/default/js/lib/jquery.min.js +167 -0
- data/reports/html/default/plugins.erb +22 -0
- data/reports/html/default/search.erb +8 -0
- data/reports/html/default/sitemap.erb +15 -0
- data/reports/html/default/summary.erb +68 -0
- data/reports/html/default/summary_issue.erb +19 -0
- data/reports/json.rb +51 -0
- data/reports/marshal.rb +49 -0
- data/reports/metareport.rb +4 -6
- data/reports/metareport/arachni_metareport.rb +1 -1
- data/reports/plugin_formatters/html/autologin.rb +30 -41
- data/reports/plugin_formatters/html/content_types.rb +1 -10
- data/reports/plugin_formatters/html/cookie_collector.rb +36 -44
- data/reports/plugin_formatters/html/discovery.rb +50 -0
- data/reports/plugin_formatters/html/form_dicattack.rb +24 -32
- data/reports/plugin_formatters/html/healthmap.rb +45 -54
- data/reports/plugin_formatters/html/http_dicattack.rb +24 -32
- data/reports/plugin_formatters/html/profiler.rb +17 -48
- data/reports/plugin_formatters/html/profiler/template.erb +6 -99
- data/reports/plugin_formatters/html/resolver.rb +63 -0
- data/reports/plugin_formatters/html/{metaformatters/timeout_notice.rb → timing_attacks.rb} +7 -19
- data/reports/plugin_formatters/html/{metaformatters/uniformity.rb → uniformity.rb} +5 -17
- data/reports/plugin_formatters/html/waf_detector.rb +24 -32
- data/reports/plugin_formatters/stdout/autologin.rb +30 -35
- data/reports/plugin_formatters/stdout/content_types.rb +41 -46
- data/reports/plugin_formatters/stdout/cookie_collector.rb +33 -38
- data/reports/plugin_formatters/stdout/discovery.rb +47 -0
- data/reports/plugin_formatters/stdout/form_dicattack.rb +27 -32
- data/reports/plugin_formatters/stdout/healthmap.rb +47 -51
- data/reports/plugin_formatters/stdout/http_dicattack.rb +27 -32
- data/reports/plugin_formatters/stdout/metamodules.rb +48 -55
- data/reports/plugin_formatters/stdout/profiler.rb +60 -65
- data/reports/plugin_formatters/stdout/resolver.rb +45 -0
- data/reports/plugin_formatters/stdout/{metaformatters/timeout_notice.rb → timing_attacks.rb} +6 -14
- data/reports/plugin_formatters/stdout/{metaformatters/uniformity.rb → uniformity.rb} +6 -14
- data/reports/plugin_formatters/stdout/waf_detector.rb +23 -28
- data/reports/plugin_formatters/xml/autologin.rb +36 -41
- data/reports/plugin_formatters/xml/content_types.rb +47 -52
- data/reports/plugin_formatters/xml/cookie_collector.rb +39 -44
- data/reports/plugin_formatters/xml/discovery.rb +54 -0
- data/reports/plugin_formatters/xml/form_dicattack.rb +22 -27
- data/reports/plugin_formatters/xml/healthmap.rb +53 -58
- data/reports/plugin_formatters/xml/http_dicattack.rb +22 -27
- data/reports/plugin_formatters/xml/profiler.rb +61 -77
- data/reports/plugin_formatters/xml/resolver.rb +53 -0
- data/reports/plugin_formatters/xml/{metaformatters/timeout_notice.rb → timing_attacks.rb} +3 -15
- data/reports/plugin_formatters/xml/{metaformatters/uniformity.rb → uniformity.rb} +4 -14
- data/reports/plugin_formatters/xml/waf_detector.rb +23 -28
- data/reports/stdout.rb +1 -1
- data/reports/txt.rb +2 -5
- data/reports/xml.rb +2 -5
- data/reports/xml/buffer.rb +6 -2
- data/reports/yaml.rb +49 -0
- metadata +419 -278
- data/bin/arachni_xmlrpc +0 -21
- data/bin/arachni_xmlrpcd +0 -82
- data/bin/arachni_xmlrpcd_monitor +0 -74
- data/getoptslong.rb +0 -242
- data/lib/anemone.rb +0 -2
- data/lib/framework.rb +0 -673
- data/lib/module/manager.rb +0 -111
- data/lib/options.rb +0 -547
- data/lib/rpc/xml/client/base.rb +0 -76
- data/lib/rpc/xml/client/instance.rb +0 -88
- data/lib/rpc/xml/server/base.rb +0 -112
- data/lib/rpc/xml/server/dispatcher.rb +0 -386
- data/lib/rpc/xml/server/framework.rb +0 -206
- data/lib/rpc/xml/server/instance.rb +0 -191
- data/lib/ruby/xmlrpc/server.rb +0 -27
- data/lib/ui/web/addons/autodeploy.rb +0 -172
- data/lib/ui/web/addons/autodeploy/views/index.erb +0 -124
- data/lib/ui/web/dispatcher_manager.rb +0 -165
- data/lib/ui/web/instance_manager.rb +0 -87
- data/lib/ui/web/output_stream.rb +0 -94
- data/lib/ui/web/server.rb +0 -925
- data/lib/ui/web/server/public/reports/placeholder +0 -1
- data/lib/ui/web/server/views/dispatchers.erb +0 -100
- data/lib/ui/web/server/views/dispatchers_edit.erb +0 -42
- data/lib/ui/web/server/views/error.erb +0 -1
- data/lib/ui/web/server/views/home.erb +0 -25
- data/metamodules/autothrottle.rb +0 -74
- data/plugins/metamodules.rb +0 -118
- data/profiles/comprehensive.afp +0 -74
- data/reports/plugin_formatters/html/metamodules.rb +0 -93
- data/reports/plugin_formatters/xml/metamodules.rb +0 -91
@@ -1,6 +1,6 @@
|
|
1
1
|
=begin
|
2
2
|
Arachni
|
3
|
-
Copyright (c) 2010-
|
3
|
+
Copyright (c) 2010-2012 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
4
4
|
|
5
5
|
This is free software; you can copy and distribute and modify
|
6
6
|
this program under the term of the GPL v2.0 License
|
@@ -0,0 +1,81 @@
|
|
1
|
+
=begin
|
2
|
+
Arachni
|
3
|
+
Copyright (c) 2010-2012 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
4
|
+
|
5
|
+
This is free software; you can copy and distribute and modify
|
6
|
+
this program under the term of the GPL v2.0 License
|
7
|
+
(See LICENSE file for details)
|
8
|
+
|
9
|
+
=end
|
10
|
+
|
11
|
+
module Arachni
|
12
|
+
|
13
|
+
module Mixins
|
14
|
+
|
15
|
+
#
|
16
|
+
# Progress bar and ETA methods
|
17
|
+
#
|
18
|
+
module ProgressBar
|
19
|
+
|
20
|
+
#
|
21
|
+
# Formats elapsed time to hour:min:sec
|
22
|
+
#
|
23
|
+
def format_time( t )
|
24
|
+
t = t.to_i
|
25
|
+
sec = t % 60
|
26
|
+
min = ( t / 60 ) % 60
|
27
|
+
hour = t / 3600
|
28
|
+
sprintf( "%02d:%02d:%02d", hour, min, sec )
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# Calculates ETA (Estimated Time of Arrival) based on current progress
|
33
|
+
# and the start time of the operation.
|
34
|
+
#
|
35
|
+
# @param [Float] prog current progress percentage
|
36
|
+
# @param [Time] start_time start time of the operation
|
37
|
+
#
|
38
|
+
# @return [String] ETA: hour:min:sec
|
39
|
+
#
|
40
|
+
def eta( prog, start_time )
|
41
|
+
@last_prog ||= prog
|
42
|
+
@last_eta ||= "--:--:--"
|
43
|
+
|
44
|
+
if @last_prog != prog
|
45
|
+
elapsed = Time.now - start_time
|
46
|
+
eta = elapsed * 100 / prog - elapsed
|
47
|
+
eta_str = format_time( eta )
|
48
|
+
else
|
49
|
+
eta_str = @last_eta
|
50
|
+
prog = @last_prog
|
51
|
+
end
|
52
|
+
|
53
|
+
@last_prog = prog
|
54
|
+
@last_eta = eta_str
|
55
|
+
end
|
56
|
+
|
57
|
+
#
|
58
|
+
# Returns an ASCII progress bar based on the current progress percentage
|
59
|
+
#
|
60
|
+
# @param [Float] progress progress percentage
|
61
|
+
# @param [Integer] width width of the progressbar in characters
|
62
|
+
#
|
63
|
+
# @return [String] 70% [=======> ] 100%
|
64
|
+
#
|
65
|
+
def progress_bar( progress, width = 100 )
|
66
|
+
progress = 100.0 if progress > 100
|
67
|
+
|
68
|
+
bar_prog = progress * width / 100
|
69
|
+
|
70
|
+
bar = '=' * ( bar_prog.ceil - 1 ).abs + '>'
|
71
|
+
pad = ( width - bar_prog )
|
72
|
+
bar += ' ' * pad if pad > 0
|
73
|
+
|
74
|
+
"#{progress}% [#{bar}] 100% "
|
75
|
+
end
|
76
|
+
|
77
|
+
extend self
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
=begin
|
2
|
+
Arachni
|
3
|
+
Copyright (c) 2010-2012 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
4
|
+
|
5
|
+
This is free software; you can copy and distribute and modify
|
6
|
+
this program under the term of the GPL v2.0 License
|
7
|
+
(See LICENSE file for details)
|
8
|
+
|
9
|
+
=end
|
10
|
+
|
11
|
+
module Arachni
|
12
|
+
|
13
|
+
module Mixins
|
14
|
+
|
15
|
+
|
16
|
+
#
|
17
|
+
# Terminal manipulation methods
|
18
|
+
#
|
19
|
+
#
|
20
|
+
# Driver/demo code
|
21
|
+
#
|
22
|
+
#
|
23
|
+
# require_relative 'terminal'
|
24
|
+
# require_relative 'progress_bar'
|
25
|
+
#
|
26
|
+
# include Terminal
|
27
|
+
# include ProgressBar
|
28
|
+
#
|
29
|
+
# # clear the screen
|
30
|
+
# clear_screen!
|
31
|
+
#
|
32
|
+
# start_time = Time.now
|
33
|
+
#
|
34
|
+
# MAX = 5000
|
35
|
+
# (1..MAX).each {
|
36
|
+
# |i|
|
37
|
+
#
|
38
|
+
# # move the cursor to its home, top-left of the screen.
|
39
|
+
# move_to_home!
|
40
|
+
#
|
41
|
+
# prog = i / Float( MAX ) * 100
|
42
|
+
#
|
43
|
+
# reputs "Counting to #{MAX}..."
|
44
|
+
# reputs "Progress: #{prog}%"
|
45
|
+
# reputs "Current: #{i}"
|
46
|
+
#
|
47
|
+
# reputs
|
48
|
+
# reprint eta( prog, start_time ) + " "
|
49
|
+
# reputs progress_bar( prog.ceil )
|
50
|
+
#
|
51
|
+
#
|
52
|
+
# # make sure that everything is sent out on time
|
53
|
+
# flush!
|
54
|
+
# sleep 0.003
|
55
|
+
# }
|
56
|
+
#
|
57
|
+
module Terminal
|
58
|
+
|
59
|
+
#
|
60
|
+
# Clears the line before printing using 'puts'
|
61
|
+
#
|
62
|
+
# @param [String] str string to output
|
63
|
+
#
|
64
|
+
def reputs( str = '' )
|
65
|
+
reprint str + "\n"
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
# Clears the line before printing
|
70
|
+
#
|
71
|
+
# @param [String] str string to output
|
72
|
+
#
|
73
|
+
def reprint( str = '' )
|
74
|
+
print restr( str )
|
75
|
+
end
|
76
|
+
|
77
|
+
def restr( str = '' )
|
78
|
+
"\e[0K" + str
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# Clear the bottom of the screen
|
83
|
+
#
|
84
|
+
def clear_screen!
|
85
|
+
print "\e[2J"
|
86
|
+
end
|
87
|
+
|
88
|
+
#
|
89
|
+
# Moves cursor top left to its home
|
90
|
+
#
|
91
|
+
def move_to_home!
|
92
|
+
print "\e[H"
|
93
|
+
end
|
94
|
+
|
95
|
+
#
|
96
|
+
# Flushes the STDOUT buffer
|
97
|
+
#
|
98
|
+
def flush!
|
99
|
+
$stdout.flush
|
100
|
+
end
|
101
|
+
|
102
|
+
extend self
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
File without changes
|
@@ -1,6 +1,6 @@
|
|
1
1
|
=begin
|
2
2
|
Arachni
|
3
|
-
Copyright (c) 2010-
|
3
|
+
Copyright (c) 2010-2012 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
4
4
|
|
5
5
|
This is free software; you can copy and distribute and modify
|
6
6
|
this program under the term of the GPL v2.0 License
|
@@ -25,7 +25,7 @@ module Module
|
|
25
25
|
# @author: Tasos "Zapotek" Laskos
|
26
26
|
# <tasos.laskos@gmail.com>
|
27
27
|
# <zapotek@segfault.gr>
|
28
|
-
# @version: 0.3
|
28
|
+
# @version: 0.3.1
|
29
29
|
#
|
30
30
|
module Auditor
|
31
31
|
|
@@ -33,23 +33,86 @@ module Auditor
|
|
33
33
|
# @@__timeout_audited ||= Set.new
|
34
34
|
|
35
35
|
# holds timing-attack performing Procs to be run after all
|
36
|
-
# non-
|
36
|
+
# non-timing-attack modules have finished.
|
37
37
|
@@__timeout_audit_blocks ||= Queue.new
|
38
38
|
|
39
|
+
@@__timeout_audit_operations_cnt ||= 0
|
40
|
+
|
39
41
|
# populated by timing attack phase 1 with
|
40
42
|
# candidate elements to be verified by phase 2
|
41
43
|
@@__timeout_candidates ||= Queue.new
|
42
44
|
|
43
|
-
# modules which have called the timing attack audit
|
45
|
+
# modules which have called the timing attack audit method (audit_timeout)
|
44
46
|
# we're interested in the amount, not the names, and is used to
|
45
47
|
# determine scan progress
|
46
48
|
@@__timeout_loaded_modules ||= Set.new
|
47
49
|
|
50
|
+
@@__on_timing_attacks ||= []
|
51
|
+
|
52
|
+
@@__running_timeout_attacks ||= false
|
53
|
+
|
48
54
|
# the rdiff attack performs it own redundancy checks so we need this to
|
49
55
|
# keep track audited elements
|
50
56
|
@@__rdiff_audited ||= Set.new
|
51
57
|
end
|
52
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
|
66
|
+
end
|
67
|
+
|
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
|
+
def self.timeout_audit_blocks
|
75
|
+
@@__timeout_audit_blocks
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.current_timeout_audit_operations_cnt
|
79
|
+
@@__timeout_audit_blocks.size + @@__timeout_candidates.size
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.add_timeout_audit_block( &block )
|
83
|
+
@@__timeout_audit_operations_cnt += 1
|
84
|
+
@@__timeout_audit_blocks << block
|
85
|
+
end
|
86
|
+
|
87
|
+
def Auditor.add_timeout_candidate( elem )
|
88
|
+
@@__timeout_audit_operations_cnt += 1
|
89
|
+
@@__timeout_candidates << elem
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
def self.running_timeout_attacks?
|
94
|
+
@@__running_timeout_attacks
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.on_timing_attacks( &block )
|
98
|
+
@@__on_timing_attacks << block
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.timeout_audit_operations_cnt
|
102
|
+
@@__timeout_audit_operations_cnt
|
103
|
+
end
|
104
|
+
|
105
|
+
def Auditor.call_on_timing_blocks( res, elem )
|
106
|
+
@@__on_timing_attacks.each {
|
107
|
+
|block|
|
108
|
+
block.call( res, elem )
|
109
|
+
}
|
110
|
+
end
|
111
|
+
|
112
|
+
def call_on_timing_blocks( res, elem )
|
113
|
+
Auditor.call_on_timing_blocks( res, elem )
|
114
|
+
end
|
115
|
+
|
53
116
|
#
|
54
117
|
# Holds constant bitfields that describe the preferred formatting
|
55
118
|
# of injection strings.
|
@@ -62,7 +125,7 @@ module Auditor
|
|
62
125
|
STRAIGHT = 1 << 0
|
63
126
|
|
64
127
|
#
|
65
|
-
#
|
128
|
+
# Appends the injection string to the default value of the input vector.<br/>
|
66
129
|
# (If no default value exists Arachni will choose one.)
|
67
130
|
#
|
68
131
|
APPEND = 1 << 1
|
@@ -91,6 +154,17 @@ module Auditor
|
|
91
154
|
SERVER = Issue::Element::SERVER
|
92
155
|
end
|
93
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
|
+
}
|
167
|
+
|
94
168
|
#
|
95
169
|
# Default audit options.
|
96
170
|
#
|
@@ -134,10 +208,10 @@ module Auditor
|
|
134
208
|
#
|
135
209
|
# If 'train' is set to true the HTTP response will be
|
136
210
|
# analyzed for new elements. <br/>
|
137
|
-
# Be
|
211
|
+
# Be careful when enabling it, there'll be a performance penalty.
|
138
212
|
#
|
139
213
|
# When the Auditor submits a form with original or sample values
|
140
|
-
# this option will be
|
214
|
+
# this option will be overridden to true.
|
141
215
|
#
|
142
216
|
:train => false,
|
143
217
|
|
@@ -152,6 +226,130 @@ module Auditor
|
|
152
226
|
:async => true
|
153
227
|
}
|
154
228
|
|
229
|
+
#
|
230
|
+
# ABSTRACT - OPTIONAL
|
231
|
+
#
|
232
|
+
# Prevents auditing elements that have been previously
|
233
|
+
# logged by any of the modules returned by this method.
|
234
|
+
#
|
235
|
+
# @return [Array] module names
|
236
|
+
#
|
237
|
+
def redundant
|
238
|
+
# [ 'sqli', 'sqli_blind_rdiff' ]
|
239
|
+
[]
|
240
|
+
end
|
241
|
+
|
242
|
+
#
|
243
|
+
# ABSTRACT - OPTIONAL
|
244
|
+
#
|
245
|
+
# Allows modules to ignore HPG scope restrictions
|
246
|
+
#
|
247
|
+
# This way they can audit elements that are not on the Grid sanctioned whitlist.
|
248
|
+
#
|
249
|
+
# @return [Bool]
|
250
|
+
#
|
251
|
+
def override_instance_scope?
|
252
|
+
false
|
253
|
+
end
|
254
|
+
|
255
|
+
#
|
256
|
+
# Just a delegator logs an array of issues.
|
257
|
+
#
|
258
|
+
# @param [Array<Arachni::Issue>] issues
|
259
|
+
#
|
260
|
+
# @see Arachni::Module::Manager.register_results
|
261
|
+
#
|
262
|
+
def register_results( issues )
|
263
|
+
Arachni::Module::Manager.register_results( issues )
|
264
|
+
end
|
265
|
+
|
266
|
+
#
|
267
|
+
# Logs a remote file or directory if it exists.
|
268
|
+
#
|
269
|
+
# @param [String] url
|
270
|
+
# @param [Bool] silent if false, a message will be sent to stdout
|
271
|
+
# containing the status of the operation.
|
272
|
+
# @param [Proc] &block called if the file exists, just before logging
|
273
|
+
#
|
274
|
+
# @return [Object] - nil if no URL was provided
|
275
|
+
# - false if the request couldn't be fired
|
276
|
+
# - true if everything went fine
|
277
|
+
#
|
278
|
+
# @see #remote_file_exist?
|
279
|
+
#
|
280
|
+
def log_remote_file_if_exists( url, silent = false, &block )
|
281
|
+
return nil if !url
|
282
|
+
|
283
|
+
req = @http.get( url )
|
284
|
+
return false if !req
|
285
|
+
req.on_complete {
|
286
|
+
|res|
|
287
|
+
|
288
|
+
print_status( 'Analyzing response for: ' + url ) if !silent
|
289
|
+
|
290
|
+
if remote_file_exist?( res )
|
291
|
+
block.call( res ) if block_given?
|
292
|
+
log_remote_file( res )
|
293
|
+
|
294
|
+
# if the file exists let the trainer parse it since it may
|
295
|
+
# contain brand new data to audit
|
296
|
+
@http.trainer.add_response( res )
|
297
|
+
end
|
298
|
+
}
|
299
|
+
|
300
|
+
return true
|
301
|
+
end
|
302
|
+
alias :log_remote_directory_if_exists :log_remote_file_if_exists
|
303
|
+
|
304
|
+
#
|
305
|
+
# Checks that the response points to an existing file/page and not
|
306
|
+
# an error or custom 404 response.
|
307
|
+
#
|
308
|
+
# @param [Typhoeus::Response] res
|
309
|
+
#
|
310
|
+
def remote_file_exist?( res )
|
311
|
+
res.code == 200 && !@http.custom_404?( res )
|
312
|
+
end
|
313
|
+
|
314
|
+
#
|
315
|
+
# Logs the existence of a remote file as an issue.
|
316
|
+
#
|
317
|
+
# @param [Typhoeus::Response] res
|
318
|
+
#
|
319
|
+
# @see #log_issue
|
320
|
+
#
|
321
|
+
def log_remote_file( res )
|
322
|
+
url = res.effective_url
|
323
|
+
filename = File.basename( URI( res.effective_url ).path )
|
324
|
+
|
325
|
+
log_issue(
|
326
|
+
:url => url,
|
327
|
+
:injected => filename,
|
328
|
+
:id => filename,
|
329
|
+
:elem => Issue::Element::PATH,
|
330
|
+
:response => res.body,
|
331
|
+
:headers => {
|
332
|
+
:request => res.request.headers,
|
333
|
+
:response => res.headers,
|
334
|
+
}
|
335
|
+
)
|
336
|
+
|
337
|
+
end
|
338
|
+
alias :log_remote_directory :log_remote_file
|
339
|
+
|
340
|
+
#
|
341
|
+
# Helper method for issue logging.
|
342
|
+
#
|
343
|
+
# @param [Hash] opts issue options ({Issue})
|
344
|
+
# @param [Bool] include_class_info merge opts with module.info?
|
345
|
+
#
|
346
|
+
# @see Arachni::Module::Base#register_results
|
347
|
+
#
|
348
|
+
def log_issue( opts )
|
349
|
+
# register the issue
|
350
|
+
register_results( [ Issue.new( opts.merge( self.class.info ) ) ] )
|
351
|
+
end
|
352
|
+
|
155
353
|
#
|
156
354
|
# Matches the "string" (default string is the HTML code in @page.html) to
|
157
355
|
# an array of regular expressions and logs the results.
|
@@ -231,7 +429,7 @@ module Auditor
|
|
231
429
|
request_headers = res.request.headers
|
232
430
|
response_headers = res.headers
|
233
431
|
response = res.body
|
234
|
-
url =
|
432
|
+
url = opts[:action]
|
235
433
|
method = res.request.method.to_s.upcase
|
236
434
|
end
|
237
435
|
|
@@ -251,9 +449,8 @@ module Auditor
|
|
251
449
|
print_debug( 'Request ID: ' + res.request.id.to_s ) if res
|
252
450
|
print_verbose( '---------' ) if only_positives?
|
253
451
|
|
254
|
-
# Instantiate a new
|
255
|
-
|
256
|
-
vuln = Issue.new( {
|
452
|
+
# Instantiate a new Issue class and append it to the results array
|
453
|
+
log_issue(
|
257
454
|
:var => opts[:altered],
|
258
455
|
:url => url,
|
259
456
|
:injected => opts[:injected],
|
@@ -269,8 +466,7 @@ module Auditor
|
|
269
466
|
:request => request_headers,
|
270
467
|
:response => response_headers,
|
271
468
|
}
|
272
|
-
|
273
|
-
register_results( [vuln] )
|
469
|
+
)
|
274
470
|
end
|
275
471
|
|
276
472
|
#
|
@@ -323,9 +519,9 @@ module Auditor
|
|
323
519
|
|
324
520
|
when Element::HEADER
|
325
521
|
audit_headers( injection_str, opts, &block )
|
522
|
+
when Element::BODY
|
326
523
|
else
|
327
524
|
raise( 'Unknown element to audit: ' + elem.to_s )
|
328
|
-
|
329
525
|
end
|
330
526
|
|
331
527
|
}
|
@@ -333,7 +529,7 @@ module Auditor
|
|
333
529
|
|
334
530
|
#
|
335
531
|
# This is called right before an [Arachni::Parser::Element]
|
336
|
-
# is submitted/
|
532
|
+
# is submitted/audited and is used to determine whether to skip it or not.
|
337
533
|
#
|
338
534
|
# Running modules can override this as they wish *but* at their own peril.
|
339
535
|
#
|
@@ -347,17 +543,11 @@ module Auditor
|
|
347
543
|
|
348
544
|
set_id = @framework.modules.class.issue_set_id_from_elem( mod_name, elem )
|
349
545
|
return true if @framework.modules.issue_set.include?( set_id )
|
350
|
-
}
|
351
|
-
|
352
|
-
|
353
|
-
# if !@@__timeout_audited.empty?
|
354
|
-
# return @@__timeout_audited.include?( __rdiff_audit_id( elem ) )
|
355
|
-
# end
|
546
|
+
} if @framework
|
356
547
|
|
357
548
|
return false
|
358
549
|
end
|
359
550
|
|
360
|
-
|
361
551
|
#
|
362
552
|
# Audits elements using timing attacks and automatically logs results.
|
363
553
|
#
|
@@ -365,7 +555,7 @@ module Auditor
|
|
365
555
|
# * Loop 1 -- Populates the candidate queue. We're picking the low hanging
|
366
556
|
# fruit here so we can run this in larger concurrent bursts which cause *lots* of noise.
|
367
557
|
# - Initial probing for candidates -- Any element that times out is added to a queue.
|
368
|
-
# - Stabilization -- The candidate is
|
558
|
+
# - Stabilization -- The candidate is submitted with its default values in
|
369
559
|
# order to wait until the effects of the timing attack have worn off.
|
370
560
|
# * Loop 2 -- Verifies the candidates. This is much more delicate so the
|
371
561
|
# concurrent requests are lowered to pairs.
|
@@ -387,7 +577,7 @@ module Auditor
|
|
387
577
|
#
|
388
578
|
#
|
389
579
|
# @param [Array] strings injection strings
|
390
|
-
# __TIME__ will be
|
580
|
+
# __TIME__ will be substituted with (timeout / timeout_divider)
|
391
581
|
# @param [Hash] opts options as described in {OPTIONS} with the following extra:
|
392
582
|
# * :timeout -- milliseconds to wait for the request to complete
|
393
583
|
# * :timeout_divider -- __TIME__ = timeout / timeout_divider
|
@@ -395,54 +585,31 @@ module Auditor
|
|
395
585
|
def audit_timeout( strings, opts )
|
396
586
|
@@__timeout_loaded_modules << self.class.info[:name]
|
397
587
|
|
398
|
-
|
588
|
+
Auditor.add_timeout_audit_block {
|
399
589
|
delay = opts[:timeout]
|
400
590
|
|
401
591
|
audit_timeout_debug_msg( 1, delay )
|
402
592
|
timing_attack( strings, opts ) {
|
403
|
-
|res,
|
593
|
+
|res, c_opts, elem|
|
404
594
|
|
405
|
-
|
406
|
-
# and let phase 2 clean up the mess
|
407
|
-
# if !@@__timeout_audited.include?( __rdiff_audit_id( elem ) )
|
595
|
+
elem.auditor( self )
|
408
596
|
|
409
|
-
|
410
|
-
# @@__timeout_audited << __rdiff_audit_id( elem )
|
597
|
+
print_info( "Found a candidate -- #{elem.type.capitalize} input '#{elem.altered}' at #{elem.action}" )
|
411
598
|
|
412
|
-
|
599
|
+
Arachni::Module::Auditor.audit_timeout_stabilize( elem )
|
413
600
|
|
414
|
-
|
415
|
-
|
416
|
-
@@__timeout_candidates << elem
|
417
|
-
# end
|
601
|
+
Auditor.add_timeout_candidate( elem )
|
418
602
|
}
|
419
603
|
}
|
420
604
|
end
|
421
605
|
|
422
|
-
#
|
423
|
-
# Returns the names of all loaded modules that use timing attacks.
|
424
|
-
#
|
425
|
-
# @return [Set]
|
426
|
-
#
|
427
|
-
def self.timeout_loaded_modules
|
428
|
-
@@__timeout_loaded_modules
|
429
|
-
end
|
430
|
-
|
431
|
-
#
|
432
|
-
# Holds timing-attack performing Procs to be run after all
|
433
|
-
# non-tming-attack modules have finished.
|
434
|
-
#
|
435
|
-
# @return [Queue]
|
436
|
-
#
|
437
|
-
def self.timeout_audit_blocks
|
438
|
-
@@__timeout_audit_blocks
|
439
|
-
end
|
440
|
-
|
441
606
|
#
|
442
607
|
# Runs all blocks in {timeout_audit_blocks} and verifies
|
443
608
|
# and logs the candidate elements.
|
444
609
|
#
|
445
610
|
def self.timeout_audit_run
|
611
|
+
@@__running_timeout_attacks = true
|
612
|
+
|
446
613
|
while( !@@__timeout_audit_blocks.empty? )
|
447
614
|
@@__timeout_audit_blocks.pop.call
|
448
615
|
end
|
@@ -453,7 +620,7 @@ module Auditor
|
|
453
620
|
end
|
454
621
|
|
455
622
|
#
|
456
|
-
# Runs phase 2 of the timing attack
|
623
|
+
# Runs phase 2 of the timing attack auditing an individual element
|
457
624
|
# (which passed phase 1) with a higher delay and timeout
|
458
625
|
#
|
459
626
|
def self.audit_timeout_phase_2( elem )
|
@@ -478,19 +645,21 @@ module Auditor
|
|
478
645
|
elem.get_auditor.http.get( elem.action ).on_complete {
|
479
646
|
|res|
|
480
647
|
|
648
|
+
self.call_on_timing_blocks( res, elem )
|
649
|
+
|
481
650
|
if !res.timed_out?
|
482
651
|
|
483
652
|
elem.get_auditor.print_info( 'Liveness check was successful, progressing to verification...' )
|
484
653
|
|
485
654
|
elem.audit( str, opts ) {
|
486
|
-
|
|
655
|
+
|c_res, c_opts|
|
487
656
|
|
488
|
-
if
|
657
|
+
if c_res.timed_out?
|
489
658
|
|
490
659
|
# all issues logged by timing attacks need manual verification.
|
491
660
|
# end of story.
|
492
|
-
|
493
|
-
elem.get_auditor.log(
|
661
|
+
# c_opts[:verification] = true
|
662
|
+
elem.get_auditor.log( c_opts, c_res )
|
494
663
|
|
495
664
|
self.audit_timeout_stabilize( elem )
|
496
665
|
|
@@ -554,7 +723,7 @@ module Auditor
|
|
554
723
|
# Optionally, you can add a :timeout_divider.
|
555
724
|
#
|
556
725
|
# @param [Array] strings injection strings
|
557
|
-
# '__TIME__' will be
|
726
|
+
# '__TIME__' will be substituted with (timeout / timeout_divider)
|
558
727
|
# @param [Hash] opts options as described in {OPTIONS}
|
559
728
|
# @param [Block] &block block to call if a timeout occurs,
|
560
729
|
# it will be passed the response and opts
|
@@ -562,7 +731,6 @@ module Auditor
|
|
562
731
|
def timing_attack( strings, opts, &block )
|
563
732
|
|
564
733
|
opts[:timeout_divider] ||= 1
|
565
|
-
# opts[:async] = false
|
566
734
|
|
567
735
|
[strings].flatten.each {
|
568
736
|
|str|
|
@@ -572,8 +740,10 @@ module Auditor
|
|
572
740
|
opts[:skip_orig] = true
|
573
741
|
|
574
742
|
audit( str, opts ) {
|
575
|
-
|res,
|
576
|
-
|
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?
|
577
747
|
}
|
578
748
|
}
|
579
749
|
|
@@ -627,15 +797,6 @@ module Auditor
|
|
627
797
|
opts[:elements] = OPTIONS[:elements]
|
628
798
|
end
|
629
799
|
|
630
|
-
opts = {
|
631
|
-
# append our seeds to the default values
|
632
|
-
:format => [ Format::APPEND ],
|
633
|
-
# allow duplicate requests
|
634
|
-
:redundant => true,
|
635
|
-
# amound of rdiff iterations
|
636
|
-
:precision => 2
|
637
|
-
}.merge( opts )
|
638
|
-
|
639
800
|
opts[:elements].each {
|
640
801
|
|elem|
|
641
802
|
|
@@ -644,30 +805,31 @@ module Auditor
|
|
644
805
|
when Element::LINK
|
645
806
|
next if !Options.instance.audit_links
|
646
807
|
@page.links.each {
|
647
|
-
|
|
648
|
-
audit_rdiff_elem(
|
808
|
+
|c_elem|
|
809
|
+
audit_rdiff_elem( c_elem, opts, &block )
|
649
810
|
}
|
650
811
|
|
651
812
|
when Element::FORM
|
652
813
|
next if !Options.instance.audit_forms
|
653
814
|
@page.forms.each {
|
654
|
-
|
|
655
|
-
audit_rdiff_elem(
|
815
|
+
|c_elem|
|
816
|
+
audit_rdiff_elem( c_elem, opts, &block )
|
656
817
|
}
|
657
818
|
|
658
819
|
when Element::COOKIE
|
659
820
|
next if !Options.instance.audit_cookies
|
660
821
|
@page.cookies.each {
|
661
|
-
|
|
662
|
-
audit_rdiff_elem(
|
822
|
+
|c_elem|
|
823
|
+
audit_rdiff_elem( c_elem, opts, &block )
|
663
824
|
}
|
664
825
|
|
665
826
|
when Element::HEADER
|
666
827
|
next if !Options.instance.audit_headers
|
667
828
|
@page.headers.each {
|
668
|
-
|
|
669
|
-
audit_rdiff_elem(
|
829
|
+
|c_elem|
|
830
|
+
audit_rdiff_elem( c_elem, opts, &block )
|
670
831
|
}
|
832
|
+
when Element::BODY
|
671
833
|
else
|
672
834
|
raise( 'Unknown element to audit: ' + elem.to_s )
|
673
835
|
|
@@ -685,6 +847,8 @@ module Auditor
|
|
685
847
|
#
|
686
848
|
def audit_rdiff_elem( elem, opts = {}, &block )
|
687
849
|
|
850
|
+
opts = RDIFF_OPTIONS.merge( opts )
|
851
|
+
|
688
852
|
# don't continue if there's a missing value
|
689
853
|
elem.auditable.values.each {
|
690
854
|
|val|
|
@@ -814,7 +978,7 @@ module Auditor
|
|
814
978
|
:regexp_match => 'n/a',
|
815
979
|
:elem => res['elem'].type,
|
816
980
|
:response => res['res'].body,
|
817
|
-
:verification => true,
|
981
|
+
# :verification => true,
|
818
982
|
:headers => {
|
819
983
|
:request => res['res'].request.headers,
|
820
984
|
:response => res['res'].headers,
|
@@ -874,7 +1038,7 @@ module Auditor
|
|
874
1038
|
end
|
875
1039
|
|
876
1040
|
#
|
877
|
-
# Audits
|
1041
|
+
# Audits Auditable HTML/HTTP elements
|
878
1042
|
#
|
879
1043
|
# @param [Array<Arachni::Element::Auditable>] elements elements to audit
|
880
1044
|
# @param [String] injection_str same as for {#audit}
|
@@ -885,12 +1049,12 @@ module Auditor
|
|
885
1049
|
#
|
886
1050
|
def audit_elems( elements, injection_str, opts = { }, &block )
|
887
1051
|
|
888
|
-
opts
|
889
|
-
url
|
1052
|
+
opts = OPTIONS.merge( opts )
|
1053
|
+
url = @page.url
|
890
1054
|
|
891
1055
|
opts[:injected_orig] = injection_str
|
892
1056
|
|
893
|
-
elements.each{
|
1057
|
+
elements.deep_clone.each {
|
894
1058
|
|elem|
|
895
1059
|
elem.auditor( self )
|
896
1060
|
elem.audit( injection_str, opts, &block )
|