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
File without changes
|
@@ -53,6 +53,13 @@ class Auditable
|
|
53
53
|
@auditor
|
54
54
|
end
|
55
55
|
|
56
|
+
def override_instance_scope!
|
57
|
+
@override_instance_scope = true
|
58
|
+
end
|
59
|
+
|
60
|
+
def override_instance_scope?
|
61
|
+
@override_instance_scope ||= false
|
62
|
+
end
|
56
63
|
|
57
64
|
#
|
58
65
|
# Delegate output related methods to the auditor
|
@@ -142,6 +149,7 @@ class Auditable
|
|
142
149
|
injection_sets( injection_str, opts ).each {
|
143
150
|
|elem|
|
144
151
|
|
152
|
+
elem.auditor( get_auditor )
|
145
153
|
opts[:altered] = elem.altered.dup
|
146
154
|
|
147
155
|
return if skip?( elem )
|
@@ -168,11 +176,14 @@ class Auditable
|
|
168
176
|
end
|
169
177
|
|
170
178
|
#
|
171
|
-
#
|
172
|
-
# and returns an array of
|
173
|
-
# <altered_variable> => <new element>
|
179
|
+
# Injects the injecton_str in self's values according to formatting options
|
180
|
+
# and returns an array of Element permutations.
|
174
181
|
#
|
175
182
|
# @param [String] injection_str the string to inject
|
183
|
+
# @param [Hash] opts formatting and permutation options
|
184
|
+
# * :skip_orig => skip submission with default/original values (for {Arachni::Parser::Element::Form} elements)
|
185
|
+
# * :format => {Format}
|
186
|
+
# * :param_flip => flip injection value and input name
|
176
187
|
#
|
177
188
|
# @return [Array]
|
178
189
|
#
|
@@ -224,13 +235,51 @@ class Auditable
|
|
224
235
|
|
225
236
|
}
|
226
237
|
|
227
|
-
if opts[:param_flip]
|
238
|
+
if opts[:param_flip] #&& !self.is_a?( Arachni::Parser::Element::Cookie )
|
228
239
|
elem = self.dup
|
240
|
+
|
241
|
+
# when under HPG mode element auditing is strictly regulated
|
242
|
+
# and when we flip params we essentially create a new element
|
243
|
+
# which won't be on the whitelist
|
244
|
+
elem.override_instance_scope!
|
245
|
+
|
229
246
|
elem.altered = 'Parameter flip'
|
230
247
|
elem.auditable[injection_str] = seed
|
231
248
|
var_combo << elem
|
232
249
|
end
|
233
250
|
|
251
|
+
# if there are two password type fields in the form there's a good
|
252
|
+
# chance that it's a 'please retype your password' thing so make sure
|
253
|
+
# that we have a variation which has identical password values
|
254
|
+
if self.is_a?( Arachni::Parser::Element::Form )
|
255
|
+
chash = hash.dup
|
256
|
+
chash = Arachni::Module::KeyFiller.fill( chash )
|
257
|
+
delem = self.dup
|
258
|
+
|
259
|
+
add = false
|
260
|
+
@raw['auditable'].each {
|
261
|
+
|input|
|
262
|
+
|
263
|
+
if input['type'] == 'password'
|
264
|
+
delem.altered = input['name']
|
265
|
+
|
266
|
+
opts[:format].each {
|
267
|
+
|format|
|
268
|
+
chash[input['name']] =
|
269
|
+
format_str( injection_str, chash[input['name']], format )
|
270
|
+
}
|
271
|
+
|
272
|
+
add = true
|
273
|
+
end
|
274
|
+
} if @raw['auditable']
|
275
|
+
|
276
|
+
if add
|
277
|
+
delem.auditable = chash
|
278
|
+
var_combo << delem
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
|
234
283
|
print_debug_injection_set( var_combo, opts )
|
235
284
|
|
236
285
|
return var_combo
|
@@ -258,6 +307,34 @@ class Auditable
|
|
258
307
|
return "Auditing #{self.type} variable '" + altered + "' of " + @action
|
259
308
|
end
|
260
309
|
|
310
|
+
#
|
311
|
+
# Returns am audit identifier string to be registered using {#audited}.
|
312
|
+
#
|
313
|
+
# @param [Hash] input
|
314
|
+
# @param [Hash] opts
|
315
|
+
#
|
316
|
+
# @return [String]
|
317
|
+
#
|
318
|
+
def audit_id( injection_str = '', opts = {} )
|
319
|
+
vars = auditable.keys.sort.to_s
|
320
|
+
|
321
|
+
str = ''
|
322
|
+
str += !opts[:no_auditor] ? "#{@auditor.class.info[:name]}:" : ''
|
323
|
+
|
324
|
+
str += "#{@action}:" + "#{self.type}:#{vars}"
|
325
|
+
str += "=#{injection_str.to_s}" if !opts[:no_injection_str]
|
326
|
+
str += ":timeout=#{opts[:timeout]}" if !opts[:no_timeout]
|
327
|
+
|
328
|
+
return str
|
329
|
+
end
|
330
|
+
|
331
|
+
def self.restrict_to_elements!( elements )
|
332
|
+
@@restrict_to_elements = Set.new
|
333
|
+
elements.each {
|
334
|
+
|elem|
|
335
|
+
@@restrict_to_elements << elem
|
336
|
+
}
|
337
|
+
end
|
261
338
|
|
262
339
|
private
|
263
340
|
|
@@ -297,7 +374,7 @@ class Auditable
|
|
297
374
|
|
298
375
|
# make sure that we have a response before continuing
|
299
376
|
if !res
|
300
|
-
print_error( 'Failed to get
|
377
|
+
print_error( 'Failed to get response, backing out...' )
|
301
378
|
next
|
302
379
|
else
|
303
380
|
print_status( 'Analyzing response #' + res.request.id.to_s + '...' ) if elem.opts && !elem.opts[:silent]
|
@@ -353,6 +430,8 @@ class Auditable
|
|
353
430
|
end
|
354
431
|
|
355
432
|
def match_regexp_and_log( regexp, res, opts )
|
433
|
+
regexp = regexp.is_a?( Regexp ) ? regexp :
|
434
|
+
Regexp.new( regexp.to_s, Regexp::IGNORECASE )
|
356
435
|
|
357
436
|
match_data = res.body.scan( regexp )[0]
|
358
437
|
match_data = match_data.to_s
|
@@ -380,35 +459,36 @@ class Auditable
|
|
380
459
|
end
|
381
460
|
|
382
461
|
#
|
383
|
-
#
|
384
|
-
#
|
385
|
-
# @param [Hash] input
|
386
|
-
# @param [Hash] opts
|
462
|
+
# Checks whether or not an audit has been already performed.
|
387
463
|
#
|
388
|
-
# @
|
464
|
+
# @param [String] elem_audit_id a string returned by {#audit_id}
|
389
465
|
#
|
390
|
-
def
|
391
|
-
vars = auditable.keys.sort.to_s
|
466
|
+
def audited?( elem_audit_id )
|
392
467
|
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
468
|
+
opts = {
|
469
|
+
:no_auditor => true,
|
470
|
+
:no_timeout => true,
|
471
|
+
:no_injection_str => true
|
472
|
+
}
|
398
473
|
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
474
|
+
@@restrict_to_elements ||= Set.new
|
475
|
+
|
476
|
+
if @@audited.include?( elem_audit_id )
|
477
|
+
msg = 'Skipping, already audited: ' + elem_audit_id
|
478
|
+
ret = true
|
479
|
+
elsif !get_auditor.override_instance_scope? && !override_instance_scope? &&
|
480
|
+
!@@restrict_to_elements.empty? &&
|
481
|
+
!@@restrict_to_elements.include?( audit_id( nil, opts ) )
|
482
|
+
msg = 'Skipping, out of instance scope.'
|
483
|
+
ret = true
|
484
|
+
else
|
485
|
+
msg = 'Current audit ID: ' + elem_audit_id
|
486
|
+
ret = false
|
487
|
+
end
|
406
488
|
|
407
|
-
|
408
|
-
msg = 'Skipping, already audited: ' if ret
|
409
|
-
print_debug( msg + audit_id )
|
489
|
+
print_debug( msg )
|
410
490
|
|
411
|
-
|
491
|
+
return ret
|
412
492
|
end
|
413
493
|
|
414
494
|
#
|
@@ -441,8 +521,7 @@ class Auditable
|
|
441
521
|
append = default_str if ( format & Format::APPEND ) != 0
|
442
522
|
semicolon = append = null = '' if ( format & Format::STRAIGHT ) != 0
|
443
523
|
|
444
|
-
|
445
|
-
return semicolon + append + injection_str + null
|
524
|
+
return semicolon + append + injection_str.to_s + null
|
446
525
|
end
|
447
526
|
|
448
527
|
def print_debug_injection_set( var_combo, opts )
|
@@ -504,8 +583,8 @@ class Auditable
|
|
504
583
|
print_debug( "|--> Combo: " )
|
505
584
|
|
506
585
|
combo.each {
|
507
|
-
|
|
508
|
-
print_debug( "|------> " +
|
586
|
+
|c_combo|
|
587
|
+
print_debug( "|------> " + c_combo.to_s )
|
509
588
|
}
|
510
589
|
|
511
590
|
}
|
@@ -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
|
@@ -78,7 +78,7 @@ class Base < Arachni::Element::Auditable
|
|
78
78
|
#
|
79
79
|
def initialize( url, raw = {} )
|
80
80
|
@raw = raw.dup
|
81
|
-
@url = url.
|
81
|
+
@url = url.to_s
|
82
82
|
end
|
83
83
|
|
84
84
|
#
|
@@ -104,6 +104,10 @@ class Base < Arachni::Element::Auditable
|
|
104
104
|
|
105
105
|
end
|
106
106
|
|
107
|
+
def dup
|
108
|
+
self.class.new( @url.dup, @raw.dup )
|
109
|
+
end
|
110
|
+
|
107
111
|
end
|
108
112
|
|
109
113
|
class Link < Base
|
@@ -111,10 +115,10 @@ class Link < Base
|
|
111
115
|
def initialize( url, raw = {} )
|
112
116
|
super( url, raw )
|
113
117
|
|
114
|
-
@action = @raw['href']
|
118
|
+
@action = @raw['href'] || @raw[:href] || @raw['action'] || @raw[:action]
|
115
119
|
@method = 'get'
|
116
120
|
|
117
|
-
@auditable = @raw['vars']
|
121
|
+
@auditable = @raw['vars'] || @raw[:vars] || @raw['inputs'] || @raw[:inputs]
|
118
122
|
@orig = @auditable.deep_clone
|
119
123
|
@orig.freeze
|
120
124
|
end
|
@@ -131,14 +135,18 @@ class Link < Base
|
|
131
135
|
Arachni::Module::Auditor::Element::LINK
|
132
136
|
end
|
133
137
|
|
134
|
-
def audit_id( injection_str, opts = {} )
|
138
|
+
def audit_id( injection_str = '', opts = {} )
|
135
139
|
vars = auditable.keys.sort.to_s
|
136
|
-
url =
|
140
|
+
url = @action.gsub( /\?.*/, '' )
|
141
|
+
|
142
|
+
str = ''
|
143
|
+
str += !opts[:no_auditor] ? "#{@auditor.class.info[:name]}:" : ''
|
137
144
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
145
|
+
str += "#{url}:" + "#{self.type}:#{vars}"
|
146
|
+
str += "=#{injection_str.to_s}" if !opts[:no_injection_str]
|
147
|
+
str += ":timeout=#{opts[:timeout]}" if !opts[:no_timeout]
|
148
|
+
|
149
|
+
return str
|
142
150
|
end
|
143
151
|
|
144
152
|
|
@@ -155,17 +163,15 @@ class Form < Base
|
|
155
163
|
def initialize( url, raw = {} )
|
156
164
|
super( url, raw )
|
157
165
|
|
158
|
-
@action = @raw['attrs']['action']
|
159
|
-
@method = @raw['attrs']['method']
|
166
|
+
@action = @raw['action'] || @raw[:action] || @raw['attrs']['action']
|
167
|
+
@method = @raw['method'] || @raw[:method] || @raw['attrs']['method']
|
160
168
|
|
161
|
-
@auditable = simple['auditable'] || {}
|
169
|
+
@auditable = @raw[:inputs] || @raw['inputs'] || simple['auditable'] || {}
|
162
170
|
@orig = @auditable.deep_clone
|
163
171
|
@orig.freeze
|
164
172
|
end
|
165
173
|
|
166
174
|
def http_request( url, opts )
|
167
|
-
|
168
|
-
|
169
175
|
params = opts[:params]
|
170
176
|
altered = opts[:altered]
|
171
177
|
|
@@ -203,7 +209,6 @@ class Form < Base
|
|
203
209
|
end
|
204
210
|
|
205
211
|
def id
|
206
|
-
|
207
212
|
id = simple['attrs'].to_s
|
208
213
|
|
209
214
|
auditable.map {
|
@@ -213,12 +218,10 @@ class Form < Base
|
|
213
218
|
}
|
214
219
|
|
215
220
|
return id
|
216
|
-
|
217
221
|
end
|
218
222
|
|
219
223
|
def simple
|
220
|
-
|
221
|
-
form = Hash.new
|
224
|
+
form = {}
|
222
225
|
|
223
226
|
return form if !@raw || !@raw['auditable'] || @raw['auditable'].empty?
|
224
227
|
|
@@ -248,7 +251,12 @@ class Cookie < Base
|
|
248
251
|
@action = @url
|
249
252
|
@method = 'cookie'
|
250
253
|
|
251
|
-
|
254
|
+
if @raw['name']
|
255
|
+
@auditable = { @raw['name'] => @raw['value'] }
|
256
|
+
else
|
257
|
+
@auditable = @raw
|
258
|
+
end
|
259
|
+
|
252
260
|
@simple = @auditable.dup
|
253
261
|
@auditable.reject! {
|
254
262
|
|cookie|
|
@@ -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
|
@@ -19,7 +19,7 @@ class Parser
|
|
19
19
|
# @author: Tasos "Zapotek" Laskos
|
20
20
|
# <tasos.laskos@gmail.com>
|
21
21
|
# <zapotek@segfault.gr>
|
22
|
-
# @version: 0.2.
|
22
|
+
# @version: 0.2.2
|
23
23
|
#
|
24
24
|
class Page
|
25
25
|
|
@@ -90,12 +90,29 @@ class Page
|
|
90
90
|
#
|
91
91
|
attr_accessor :cookiejar
|
92
92
|
|
93
|
+
def self.from_http_response( res, opts )
|
94
|
+
page = Arachni::Parser.new( opts, res ).run
|
95
|
+
page.url = Arachni::Module::Utilities.url_sanitize( res.effective_url )
|
96
|
+
return page
|
97
|
+
end
|
98
|
+
|
93
99
|
def initialize( opts = {} )
|
100
|
+
|
101
|
+
@forms = []
|
102
|
+
@links = []
|
103
|
+
@cookies = []
|
104
|
+
@headers = []
|
105
|
+
|
106
|
+
@cookiejar = {}
|
107
|
+
@paths = []
|
108
|
+
|
109
|
+
@response_headers = {}
|
110
|
+
@query_vars = {}
|
111
|
+
|
94
112
|
opts.each {
|
95
113
|
|k, v|
|
96
114
|
send( "#{k}=", v )
|
97
115
|
}
|
98
|
-
|
99
116
|
end
|
100
117
|
|
101
118
|
def body
|
@@ -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
|
@@ -50,33 +50,33 @@ class Parser
|
|
50
50
|
include Arachni::Module::Utilities
|
51
51
|
|
52
52
|
module Extractors
|
53
|
-
#
|
54
|
-
# Base Spider parser class for modules.
|
55
|
-
#
|
56
|
-
# The aim of such modules is to extract paths from a webpage for the Spider to follow.
|
57
|
-
#
|
58
|
-
#
|
59
|
-
# @author: Tasos "Zapotek" Laskos
|
60
|
-
# <tasos.laskos@gmail.com>
|
61
|
-
# <zapotek@segfault.gr>
|
62
|
-
# @version: 0.1
|
63
|
-
# @abstract
|
64
|
-
#
|
65
|
-
class Paths
|
66
|
-
|
67
53
|
#
|
68
|
-
#
|
69
|
-
# of paths as plain strings
|
54
|
+
# Base Spider parser class for modules.
|
70
55
|
#
|
71
|
-
#
|
56
|
+
# The aim of such modules is to extract paths from a webpage for the Spider to follow.
|
72
57
|
#
|
73
|
-
# @return [Array<String>] paths
|
74
58
|
#
|
75
|
-
|
59
|
+
# @author: Tasos "Zapotek" Laskos
|
60
|
+
# <tasos.laskos@gmail.com>
|
61
|
+
# <zapotek@segfault.gr>
|
62
|
+
# @version: 0.1
|
63
|
+
# @abstract
|
64
|
+
#
|
65
|
+
class Paths
|
66
|
+
|
67
|
+
#
|
68
|
+
# This method must be implemented by all modules and must return an array
|
69
|
+
# of paths as plain strings
|
70
|
+
#
|
71
|
+
# @param [Nokogiri] Nokogiri document
|
72
|
+
#
|
73
|
+
# @return [Array<String>] paths
|
74
|
+
#
|
75
|
+
def run( doc )
|
76
|
+
end
|
76
77
|
|
77
78
|
end
|
78
79
|
end
|
79
|
-
end
|
80
80
|
|
81
81
|
#
|
82
82
|
# @return [String] the url of the page
|
@@ -99,9 +99,13 @@ class Parser
|
|
99
99
|
def initialize( opts, res )
|
100
100
|
@opts = opts
|
101
101
|
|
102
|
+
@code = res.code
|
102
103
|
@url = url_sanitize( res.effective_url )
|
103
104
|
@html = res.body
|
104
105
|
@response_headers = res.headers_hash
|
106
|
+
|
107
|
+
@doc = nil
|
108
|
+
@paths = nil
|
105
109
|
end
|
106
110
|
|
107
111
|
#
|
@@ -112,9 +116,9 @@ class Parser
|
|
112
116
|
def run
|
113
117
|
|
114
118
|
# non text files won't contain any auditable elements
|
115
|
-
|
116
|
-
if type.is_a?( String) && !type.substring?( 'text' )
|
119
|
+
if !text?
|
117
120
|
return Page.new( {
|
121
|
+
:code => @code,
|
118
122
|
:url => @url,
|
119
123
|
:query_vars => link_vars( @url ),
|
120
124
|
:html => @html,
|
@@ -151,6 +155,7 @@ class Parser
|
|
151
155
|
end
|
152
156
|
|
153
157
|
return Page.new( {
|
158
|
+
:code => @code,
|
154
159
|
:url => @url,
|
155
160
|
:query_vars => link_vars( @url ),
|
156
161
|
:html => @html,
|
@@ -165,6 +170,12 @@ class Parser
|
|
165
170
|
|
166
171
|
end
|
167
172
|
|
173
|
+
def text?
|
174
|
+
type = Arachni::HTTP.content_type( @response_headers )
|
175
|
+
return false if !type
|
176
|
+
return type.to_s.substring?( 'text' )
|
177
|
+
end
|
178
|
+
|
168
179
|
def doc
|
169
180
|
return @doc if @doc
|
170
181
|
@doc = Nokogiri::HTML( @html ) if @html rescue nil
|
@@ -303,7 +314,7 @@ class Parser
|
|
303
314
|
else
|
304
315
|
action = url_sanitize( elements[i]['attrs']['action'] )
|
305
316
|
end
|
306
|
-
action =
|
317
|
+
action = uri_encode( action ).to_s
|
307
318
|
|
308
319
|
elements[i]['attrs']['action'] = to_absolute( action.clone ).to_s
|
309
320
|
|
@@ -314,10 +325,7 @@ class Parser
|
|
314
325
|
elements[i]['attrs']['method'].downcase
|
315
326
|
end
|
316
327
|
|
317
|
-
|
318
|
-
if !in_domain?( url )
|
319
|
-
next
|
320
|
-
end
|
328
|
+
next if skip?( elements[i]['attrs']['action'] )
|
321
329
|
|
322
330
|
elements[i]['textarea'] = form_textareas( form )
|
323
331
|
elements[i]['select'] = form_selects( form )
|
@@ -361,9 +369,7 @@ class Parser
|
|
361
369
|
link['href'] = to_absolute( link['href'] )
|
362
370
|
|
363
371
|
if !link['href'] then next end
|
364
|
-
if
|
365
|
-
if( !include?( link['href'] ) ) then next end
|
366
|
-
if !in_domain?( URI.parse( link['href'] ) ) then next end
|
372
|
+
next if skip?( link['href'] )
|
367
373
|
|
368
374
|
link['vars'] = {}
|
369
375
|
link_vars( link['href'] ).each_pair {
|
@@ -405,16 +411,20 @@ class Parser
|
|
405
411
|
k, v = elem['content'].split( ';' )[0].split( '=', 2 )
|
406
412
|
cookies_arr << Element::Cookie.new( @url, { 'name' => k, 'value' => v } )
|
407
413
|
}
|
408
|
-
rescue
|
414
|
+
rescue Exception => e
|
415
|
+
# ap e
|
416
|
+
# ap e.backtrace
|
409
417
|
end
|
410
418
|
|
411
419
|
|
412
420
|
# don't ask me why....
|
413
|
-
if @response_headers.to_s.substring?( 'set-cookie' )
|
421
|
+
if @response_headers.to_s.downcase.substring?( 'set-cookie' )
|
414
422
|
begin
|
415
423
|
cookies << ::WEBrick::Cookie.parse_set_cookies( @response_headers['Set-Cookie'].to_s )
|
416
424
|
cookies << ::WEBrick::Cookie.parse_set_cookies( @response_headers['set-cookie'].to_s )
|
417
|
-
rescue
|
425
|
+
rescue Exception => e
|
426
|
+
# ap e
|
427
|
+
# ap e.backtrace
|
418
428
|
return cookies_arr
|
419
429
|
end
|
420
430
|
end
|
@@ -457,15 +467,7 @@ class Parser
|
|
457
467
|
@paths = []
|
458
468
|
return @paths if !doc
|
459
469
|
|
460
|
-
|
461
|
-
|path|
|
462
|
-
next if path.nil? or path.empty?
|
463
|
-
abs = to_absolute( path ) rescue next
|
464
|
-
|
465
|
-
@paths << abs if in_domain?( abs )
|
466
|
-
}
|
467
|
-
|
468
|
-
@paths.uniq!
|
470
|
+
@paths = run_extractors
|
469
471
|
return @paths
|
470
472
|
end
|
471
473
|
|
@@ -508,28 +510,37 @@ class Parser
|
|
508
510
|
def to_absolute( link )
|
509
511
|
|
510
512
|
begin
|
511
|
-
|
513
|
+
link = normalize_url( link )
|
514
|
+
if uri_parser.parse( link ).host
|
512
515
|
return link
|
513
516
|
end
|
514
517
|
rescue Exception => e
|
515
|
-
|
518
|
+
# ap e
|
519
|
+
# ap e.backtrace
|
520
|
+
return nil
|
516
521
|
end
|
517
522
|
|
518
|
-
|
519
|
-
|
523
|
+
begin
|
524
|
+
# remove anchor
|
525
|
+
link = uri_encode( link.to_s.gsub( /#[a-zA-Z0-9_-]*$/,'' ) )
|
520
526
|
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
527
|
+
if url = base
|
528
|
+
base_url = uri_parser.parse( url )
|
529
|
+
else
|
530
|
+
base_url = uri_parser.parse( @url )
|
531
|
+
end
|
526
532
|
|
527
|
-
|
528
|
-
|
533
|
+
relative = uri_parser.parse( link )
|
534
|
+
absolute = base_url.merge( relative )
|
529
535
|
|
530
|
-
|
536
|
+
absolute.path = '/' if absolute.path && absolute.path.empty?
|
531
537
|
|
532
|
-
|
538
|
+
return absolute.to_s
|
539
|
+
rescue Exception => e
|
540
|
+
# ap e
|
541
|
+
# ap e.backtrace
|
542
|
+
return nil
|
543
|
+
end
|
533
544
|
end
|
534
545
|
|
535
546
|
|
@@ -543,11 +554,20 @@ class Parser
|
|
543
554
|
end
|
544
555
|
|
545
556
|
|
557
|
+
def too_deep?( url )
|
558
|
+
if @opts.depth_limit > 0 && (@opts.depth_limit + 1) <= URI(url.to_s).path.count( '/' )
|
559
|
+
return true
|
560
|
+
else
|
561
|
+
return false
|
562
|
+
end
|
563
|
+
end
|
564
|
+
|
546
565
|
#
|
547
566
|
# Returns +true+ if *uri* is in the same domain as the page, returns
|
548
567
|
# +false+ otherwise
|
549
568
|
#
|
550
569
|
def in_domain?( uri )
|
570
|
+
|
551
571
|
curi = URI.parse( normalize_url( uri.to_s ) )
|
552
572
|
|
553
573
|
if( @opts.follow_subdomains )
|
@@ -589,11 +609,24 @@ class Parser
|
|
589
609
|
|
590
610
|
@opts.include.each {
|
591
611
|
|pattern|
|
612
|
+
pattern = Regexp.new( pattern ) if pattern.is_a?( String )
|
592
613
|
return true if url.to_s =~ pattern
|
593
614
|
}
|
594
615
|
return false
|
595
616
|
end
|
596
617
|
|
618
|
+
def skip?( path )
|
619
|
+
return true if !path
|
620
|
+
|
621
|
+
begin
|
622
|
+
return true if !include?( path )
|
623
|
+
return true if exclude?( path )
|
624
|
+
return true if too_deep?( path )
|
625
|
+
return true if !in_domain?( path )
|
626
|
+
rescue
|
627
|
+
true
|
628
|
+
end
|
629
|
+
end
|
597
630
|
|
598
631
|
private
|
599
632
|
|
@@ -603,20 +636,20 @@ class Parser
|
|
603
636
|
# @return [Array] paths
|
604
637
|
#
|
605
638
|
def run_extractors
|
606
|
-
lib = @opts.dir['root'] + 'path_extractors/'
|
607
|
-
|
608
|
-
|
609
639
|
begin
|
610
|
-
@@manager ||=
|
640
|
+
@@manager ||=
|
641
|
+
::Arachni::ComponentManager.new( @opts.dir['path_extractors'], Extractors )
|
611
642
|
|
612
643
|
return @@manager.available.map {
|
613
644
|
|name|
|
614
645
|
@@manager[name].new.run( doc )
|
615
|
-
}.flatten.uniq
|
646
|
+
}.flatten.uniq.compact.
|
647
|
+
map { |path| to_absolute( url_sanitize( path ) ) }.
|
648
|
+
reject { |path| skip?( path ) }
|
616
649
|
|
617
650
|
rescue ::Exception => e
|
618
651
|
print_error( e.to_s )
|
619
|
-
|
652
|
+
print_error_backtrace( e )
|
620
653
|
end
|
621
654
|
end
|
622
655
|
|
@@ -641,7 +674,11 @@ class Parser
|
|
641
674
|
i = new_arr.size
|
642
675
|
selects.each {
|
643
676
|
|select|
|
644
|
-
|
677
|
+
|
678
|
+
begin
|
679
|
+
select['attrs']['value'] = select['options'][0]['value']
|
680
|
+
rescue
|
681
|
+
end
|
645
682
|
new_arr << select['attrs']
|
646
683
|
}
|
647
684
|
|