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
data/bin/arachni_xmlrpc
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
=begin
|
3
|
-
Arachni
|
4
|
-
Copyright (c) 2010-2011 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
5
|
-
|
6
|
-
This is free software; you can copy and distribute and modify
|
7
|
-
this program under the term of the GPL v2.0 License
|
8
|
-
(See LICENSE file for details)
|
9
|
-
|
10
|
-
=end
|
11
|
-
|
12
|
-
require 'pp'
|
13
|
-
require 'ap'
|
14
|
-
|
15
|
-
cwd = File.expand_path( File.dirname( __FILE__ ) )
|
16
|
-
$:.unshift( cwd )
|
17
|
-
require cwd + '/../getoptslong.rb'
|
18
|
-
require Arachni::Options.instance.dir['lib'] + 'ui/xmlrpc/xmlrpc'
|
19
|
-
|
20
|
-
client = Arachni::UI::XMLRPC.new( Arachni::Options.instance )
|
21
|
-
client.run
|
data/bin/arachni_xmlrpcd
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
=begin
|
3
|
-
Arachni
|
4
|
-
Copyright (c) 2010-2011 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
5
|
-
|
6
|
-
This is free software; you can copy and distribute and modify
|
7
|
-
this program under the term of the GPL v2.0 License
|
8
|
-
(See LICENSE file for details)
|
9
|
-
|
10
|
-
=end
|
11
|
-
|
12
|
-
require 'getoptlong'
|
13
|
-
require 'pp'
|
14
|
-
require 'ap'
|
15
|
-
|
16
|
-
cwd = File.expand_path( File.dirname( __FILE__ ) )
|
17
|
-
$:.unshift( cwd )
|
18
|
-
|
19
|
-
require cwd + '/../lib/options'
|
20
|
-
options = Arachni::Options.instance
|
21
|
-
|
22
|
-
options.dir = Hash.new
|
23
|
-
options.dir['root'] = File.expand_path( cwd + '/../' ) + '/'
|
24
|
-
options.dir['modules'] = options.dir['root'] + 'modules/'
|
25
|
-
options.dir['reports'] = options.dir['root'] + 'reports/'
|
26
|
-
options.dir['plugins'] = options.dir['root'] + 'plugins/'
|
27
|
-
options.dir['lib'] = options.dir['root'] + 'lib/'
|
28
|
-
|
29
|
-
# Construct getops struct
|
30
|
-
opts = GetoptLong.new(
|
31
|
-
[ '--help', '-h', GetoptLong::NO_ARGUMENT ],
|
32
|
-
[ '--port', GetoptLong::OPTIONAL_ARGUMENT ],
|
33
|
-
[ '--debug', GetoptLong::NO_ARGUMENT ],
|
34
|
-
[ '--reroute-to-logfile', GetoptLong::NO_ARGUMENT ],
|
35
|
-
[ '--pool-size', GetoptLong::REQUIRED_ARGUMENT ],
|
36
|
-
[ '--ssl', GetoptLong::NO_ARGUMENT ],
|
37
|
-
[ '--ssl-pkey', GetoptLong::REQUIRED_ARGUMENT ],
|
38
|
-
[ '--ssl-cert', GetoptLong::REQUIRED_ARGUMENT ],
|
39
|
-
[ '--ssl-ca', GetoptLong::REQUIRED_ARGUMENT ],
|
40
|
-
)
|
41
|
-
|
42
|
-
begin
|
43
|
-
opts.each {
|
44
|
-
|opt, arg|
|
45
|
-
|
46
|
-
case opt
|
47
|
-
|
48
|
-
when '--help'
|
49
|
-
options.help = true
|
50
|
-
|
51
|
-
when '--debug'
|
52
|
-
options.debug = true
|
53
|
-
|
54
|
-
when '--reroute-to-logfile'
|
55
|
-
options.reroute_to_logfile = true
|
56
|
-
|
57
|
-
when '--port'
|
58
|
-
options.rpc_port = arg.to_i
|
59
|
-
|
60
|
-
when '--pool-size'
|
61
|
-
options.pool_size = arg.to_i
|
62
|
-
|
63
|
-
when '--ssl'
|
64
|
-
options.ssl = true
|
65
|
-
|
66
|
-
when '--ssl-pkey'
|
67
|
-
options.ssl_pkey = arg.to_s
|
68
|
-
|
69
|
-
when '--ssl-cert'
|
70
|
-
options.ssl_cert = arg.to_s
|
71
|
-
|
72
|
-
when '--ssl-ca'
|
73
|
-
options.ssl_ca = arg.to_s
|
74
|
-
|
75
|
-
end
|
76
|
-
}
|
77
|
-
end
|
78
|
-
|
79
|
-
require options.dir['lib'] + 'rpc/xml/server/dispatcher'
|
80
|
-
|
81
|
-
dispatcher = Arachni::RPC::XML::Server::Dispatcher.new( Arachni::Options.instance )
|
82
|
-
dispatcher.run
|
data/bin/arachni_xmlrpcd_monitor
DELETED
@@ -1,74 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
=begin
|
3
|
-
Arachni
|
4
|
-
Copyright (c) 2010-2011 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
5
|
-
|
6
|
-
This is free software; you can copy and distribute and modify
|
7
|
-
this program under the term of the GPL v2.0 License
|
8
|
-
(See LICENSE file for details)
|
9
|
-
|
10
|
-
=end
|
11
|
-
|
12
|
-
require 'getoptlong'
|
13
|
-
require 'pp'
|
14
|
-
require 'ap'
|
15
|
-
|
16
|
-
cwd = File.expand_path( File.dirname( __FILE__ ) )
|
17
|
-
$:.unshift( cwd )
|
18
|
-
|
19
|
-
require cwd + '/../lib/options'
|
20
|
-
options = Arachni::Options.instance
|
21
|
-
|
22
|
-
options.dir = Hash.new
|
23
|
-
options.dir['root'] = File.expand_path( cwd + '/../' ) + '/'
|
24
|
-
options.dir['modules'] = options.dir['root'] + 'modules/'
|
25
|
-
options.dir['reports'] = options.dir['root'] + 'reports/'
|
26
|
-
options.dir['plugins'] = options.dir['root'] + 'plugins/'
|
27
|
-
options.dir['lib'] = options.dir['root'] + 'lib/'
|
28
|
-
|
29
|
-
# Construct getops struct
|
30
|
-
opts = GetoptLong.new(
|
31
|
-
[ '--help', '-h', GetoptLong::NO_ARGUMENT ],
|
32
|
-
[ '--port', GetoptLong::OPTIONAL_ARGUMENT ],
|
33
|
-
[ '--debug', GetoptLong::NO_ARGUMENT ],
|
34
|
-
[ '--reroute-to-logfile', GetoptLong::NO_ARGUMENT ],
|
35
|
-
[ '--ssl', GetoptLong::NO_ARGUMENT ],
|
36
|
-
[ '--ssl-pkey', GetoptLong::REQUIRED_ARGUMENT ],
|
37
|
-
[ '--ssl-cert', GetoptLong::REQUIRED_ARGUMENT ],
|
38
|
-
[ '--ssl-ca', GetoptLong::REQUIRED_ARGUMENT ],
|
39
|
-
)
|
40
|
-
|
41
|
-
begin
|
42
|
-
opts.each {
|
43
|
-
|opt, arg|
|
44
|
-
|
45
|
-
case opt
|
46
|
-
|
47
|
-
when '--help'
|
48
|
-
options.help = true
|
49
|
-
|
50
|
-
when '--debug'
|
51
|
-
options.debug = true
|
52
|
-
|
53
|
-
when '--ssl'
|
54
|
-
options.ssl = true
|
55
|
-
|
56
|
-
when '--ssl-pkey'
|
57
|
-
options.ssl_pkey = arg.to_s
|
58
|
-
|
59
|
-
when '--ssl-cert'
|
60
|
-
options.ssl_cert = arg.to_s
|
61
|
-
|
62
|
-
when '--ssl-ca'
|
63
|
-
options.ssl_ca = arg.to_s
|
64
|
-
|
65
|
-
end
|
66
|
-
}
|
67
|
-
end
|
68
|
-
|
69
|
-
options.url = ARGV.shift
|
70
|
-
|
71
|
-
require options.dir['lib'] + 'ui/xmlrpc/dispatcher_monitor'
|
72
|
-
|
73
|
-
dispatcher = Arachni::UI::DispatcherMonitor.new( Arachni::Options.instance )
|
74
|
-
dispatcher.run
|
data/getoptslong.rb
DELETED
@@ -1,242 +0,0 @@
|
|
1
|
-
=begin
|
2
|
-
Arachni
|
3
|
-
Copyright (c) 2010-2011 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
|
-
require 'getoptlong'
|
12
|
-
|
13
|
-
# Construct getops struct
|
14
|
-
opts = GetoptLong.new(
|
15
|
-
[ '--help', '-h', GetoptLong::NO_ARGUMENT ],
|
16
|
-
[ '--verbosity', '-v', GetoptLong::NO_ARGUMENT ],
|
17
|
-
[ '--only-positives', '-k', GetoptLong::NO_ARGUMENT ],
|
18
|
-
[ '--lsmod', GetoptLong::OPTIONAL_ARGUMENT ],
|
19
|
-
[ '--lsrep', GetoptLong::OPTIONAL_ARGUMENT ],
|
20
|
-
[ '--audit-links', '-g', GetoptLong::NO_ARGUMENT ],
|
21
|
-
[ '--audit-forms', '-p', GetoptLong::NO_ARGUMENT ],
|
22
|
-
[ '--audit-cookies', '-c', GetoptLong::NO_ARGUMENT ],
|
23
|
-
[ '--audit-cookie-jar', GetoptLong::NO_ARGUMENT ],
|
24
|
-
[ '--audit-headers', GetoptLong::NO_ARGUMENT ],
|
25
|
-
[ '--spider-first', GetoptLong::NO_ARGUMENT ],
|
26
|
-
[ '--obey-robots-txt', '-o', GetoptLong::NO_ARGUMENT ],
|
27
|
-
[ '--redundant', GetoptLong::REQUIRED_ARGUMENT ],
|
28
|
-
[ '--depth', '-d', GetoptLong::REQUIRED_ARGUMENT ],
|
29
|
-
[ '--redirect-limit', '-q', GetoptLong::REQUIRED_ARGUMENT ],
|
30
|
-
[ '--link-count', '-u', GetoptLong::REQUIRED_ARGUMENT ],
|
31
|
-
[ '--mods', '-m', GetoptLong::REQUIRED_ARGUMENT ],
|
32
|
-
[ '--report', GetoptLong::REQUIRED_ARGUMENT ],
|
33
|
-
[ '--repload', GetoptLong::REQUIRED_ARGUMENT ],
|
34
|
-
[ '--authed-by', GetoptLong::REQUIRED_ARGUMENT ],
|
35
|
-
[ '--load-profile', GetoptLong::REQUIRED_ARGUMENT ],
|
36
|
-
[ '--save-profile', GetoptLong::REQUIRED_ARGUMENT ],
|
37
|
-
[ '--show-profile', GetoptLong::NO_ARGUMENT ],
|
38
|
-
[ '--proxy', '-z', GetoptLong::REQUIRED_ARGUMENT ],
|
39
|
-
[ '--proxy-auth', '-x', GetoptLong::REQUIRED_ARGUMENT ],
|
40
|
-
[ '--proxy-type', '-y', GetoptLong::REQUIRED_ARGUMENT ],
|
41
|
-
[ '--cookie-jar', '-j', GetoptLong::REQUIRED_ARGUMENT ],
|
42
|
-
[ '--user-agent', '-b', GetoptLong::REQUIRED_ARGUMENT ],
|
43
|
-
[ '--exclude', '-e', GetoptLong::REQUIRED_ARGUMENT ],
|
44
|
-
[ '--include', '-i', GetoptLong::REQUIRED_ARGUMENT ],
|
45
|
-
[ '--exclude-cookie', GetoptLong::REQUIRED_ARGUMENT ],
|
46
|
-
[ '--http-req-limit', GetoptLong::REQUIRED_ARGUMENT ],
|
47
|
-
[ '--follow-subdomains', '-f', GetoptLong::NO_ARGUMENT ],
|
48
|
-
[ '--http-harvest-last', '-s', GetoptLong::NO_ARGUMENT ],
|
49
|
-
[ '--debug', '-w', GetoptLong::NO_ARGUMENT ],
|
50
|
-
[ '--server', GetoptLong::REQUIRED_ARGUMENT ],
|
51
|
-
[ '--plugin', GetoptLong::OPTIONAL_ARGUMENT ],
|
52
|
-
[ '--lsplug', GetoptLong::OPTIONAL_ARGUMENT ],
|
53
|
-
[ '--ssl', GetoptLong::NO_ARGUMENT ],
|
54
|
-
[ '--ssl-pkey', GetoptLong::REQUIRED_ARGUMENT ],
|
55
|
-
[ '--ssl-cert', GetoptLong::REQUIRED_ARGUMENT ],
|
56
|
-
[ '--ssl-ca', GetoptLong::REQUIRED_ARGUMENT ],
|
57
|
-
)
|
58
|
-
|
59
|
-
$:.unshift( File.expand_path( File.dirname( __FILE__ ) ) )
|
60
|
-
|
61
|
-
require 'lib/options'
|
62
|
-
options = Arachni::Options.instance
|
63
|
-
|
64
|
-
options.dir = Hash.new
|
65
|
-
options.dir['root'] = File.dirname( File.expand_path(__FILE__) ) + '/'
|
66
|
-
options.dir['data'] = options.dir['root'] + 'data/'
|
67
|
-
options.dir['modules'] = options.dir['root'] + 'modules/'
|
68
|
-
options.dir['reports'] = options.dir['root'] + 'reports/'
|
69
|
-
options.dir['plugins'] = options.dir['root'] + 'plugins/'
|
70
|
-
options.dir['lib'] = options.dir['root'] + 'lib/'
|
71
|
-
|
72
|
-
opts.quiet = true
|
73
|
-
|
74
|
-
begin
|
75
|
-
opts.each {
|
76
|
-
|opt, arg|
|
77
|
-
|
78
|
-
case opt
|
79
|
-
|
80
|
-
when '--help'
|
81
|
-
options.help = true
|
82
|
-
|
83
|
-
when '--only-positives'
|
84
|
-
options.only_positives = true
|
85
|
-
|
86
|
-
when '--verbosity'
|
87
|
-
options.arachni_verbose = true
|
88
|
-
|
89
|
-
when '--debug'
|
90
|
-
options.debug = true
|
91
|
-
|
92
|
-
when '--spider-first'
|
93
|
-
options.spider_first = true
|
94
|
-
|
95
|
-
when '--plugin'
|
96
|
-
plugin, opt_str = arg.split( ':', 2 )
|
97
|
-
|
98
|
-
opts = {}
|
99
|
-
if( opt_str )
|
100
|
-
opt_arr = opt_str.split( ',' )
|
101
|
-
opt_arr.each {
|
102
|
-
|opt|
|
103
|
-
name, val = opt.split( '=', 2 )
|
104
|
-
opts[name] = val
|
105
|
-
}
|
106
|
-
end
|
107
|
-
|
108
|
-
options.plugins[plugin] = opts
|
109
|
-
|
110
|
-
when '--redundant'
|
111
|
-
options.redundant << {
|
112
|
-
'regexp' => Regexp.new( arg.to_s.split( /:/ )[0] ),
|
113
|
-
'count' => Integer( arg.to_s.split( /:/ )[1] ),
|
114
|
-
}
|
115
|
-
|
116
|
-
when '--obey_robots_txt'
|
117
|
-
options.obey_robots_txt = true
|
118
|
-
|
119
|
-
when '--depth'
|
120
|
-
options.depth_limit = arg.to_i
|
121
|
-
|
122
|
-
when '--link-count'
|
123
|
-
options.link_count_limit = arg.to_i
|
124
|
-
|
125
|
-
when '--redirect-limit'
|
126
|
-
options.redirect_limit = arg.to_i
|
127
|
-
|
128
|
-
when '--lsmod'
|
129
|
-
options.lsmod << Regexp.new( arg.to_s )
|
130
|
-
|
131
|
-
when '--lsplug'
|
132
|
-
options.lsplug << Regexp.new( arg.to_s )
|
133
|
-
|
134
|
-
when '--lsrep'
|
135
|
-
options.lsrep << Regexp.new( arg.to_s )
|
136
|
-
|
137
|
-
when '--http-req-limit'
|
138
|
-
options.http_req_limit = arg.to_i
|
139
|
-
|
140
|
-
when '--audit-links'
|
141
|
-
options.audit_links = true
|
142
|
-
|
143
|
-
when '--audit-forms'
|
144
|
-
options.audit_forms = true
|
145
|
-
|
146
|
-
when '--audit-cookies'
|
147
|
-
options.audit_cookies = true
|
148
|
-
|
149
|
-
when '--audit-cookie-jar'
|
150
|
-
options.audit_cookie_jar = true
|
151
|
-
|
152
|
-
when '--audit-headers'
|
153
|
-
options.audit_headers = true
|
154
|
-
|
155
|
-
when '--mods'
|
156
|
-
options.mods = arg.to_s.split( /,/ )
|
157
|
-
|
158
|
-
when '--report'
|
159
|
-
report, opt_str = arg.split( ':' )
|
160
|
-
|
161
|
-
opts = {}
|
162
|
-
if( opt_str )
|
163
|
-
opt_arr = opt_str.split( ',' )
|
164
|
-
opt_arr.each {
|
165
|
-
|opt|
|
166
|
-
name, val = opt.split( '=' )
|
167
|
-
opts[name] = val
|
168
|
-
}
|
169
|
-
end
|
170
|
-
|
171
|
-
options.reports[report] = opts
|
172
|
-
|
173
|
-
when '--repload'
|
174
|
-
options.repload = arg
|
175
|
-
|
176
|
-
when '--save-profile'
|
177
|
-
options.save_profile = arg
|
178
|
-
|
179
|
-
when '--load-profile'
|
180
|
-
options.load_profile << arg
|
181
|
-
|
182
|
-
when '--show-profile'
|
183
|
-
options.show_profile = true
|
184
|
-
|
185
|
-
when '--authed-by'
|
186
|
-
options.authed_by = arg
|
187
|
-
|
188
|
-
when '--proxy'
|
189
|
-
options.proxy_addr, options.proxy_port =
|
190
|
-
arg.to_s.split( /:/ )
|
191
|
-
|
192
|
-
when '--proxy-auth'
|
193
|
-
options.proxy_user, options.proxy_pass =
|
194
|
-
arg.to_s.split( /:/ )
|
195
|
-
|
196
|
-
when '--proxy-type'
|
197
|
-
options.proxy_type = arg.to_s
|
198
|
-
|
199
|
-
when '--cookie-jar'
|
200
|
-
options.cookie_jar = arg.to_s
|
201
|
-
|
202
|
-
when '--user-agent'
|
203
|
-
options.user_agent = arg.to_s
|
204
|
-
|
205
|
-
when '--exclude'
|
206
|
-
options.exclude << Regexp.new( arg )
|
207
|
-
|
208
|
-
when '--include'
|
209
|
-
options.include << Regexp.new( arg )
|
210
|
-
|
211
|
-
when '--exclude-cookie'
|
212
|
-
options.exclude_cookies << arg
|
213
|
-
|
214
|
-
when '--follow-subdomains'
|
215
|
-
options.follow_subdomains = true
|
216
|
-
|
217
|
-
when '--http-harvest-last'
|
218
|
-
options.http_harvest_last = true
|
219
|
-
|
220
|
-
when '--ssl'
|
221
|
-
options.ssl = true
|
222
|
-
|
223
|
-
when '--ssl-pkey'
|
224
|
-
options.ssl_pkey = arg.to_s
|
225
|
-
|
226
|
-
when '--ssl-cert'
|
227
|
-
options.ssl_cert = arg.to_s
|
228
|
-
|
229
|
-
when '--ssl-ca'
|
230
|
-
options.ssl_ca = arg.to_s
|
231
|
-
|
232
|
-
when '--server'
|
233
|
-
options.server = arg.to_s
|
234
|
-
|
235
|
-
end
|
236
|
-
}
|
237
|
-
rescue Exception => e
|
238
|
-
puts e.inspect
|
239
|
-
exit
|
240
|
-
end
|
241
|
-
|
242
|
-
options.url = ARGV.shift
|
data/lib/anemone.rb
DELETED
data/lib/framework.rb
DELETED
@@ -1,673 +0,0 @@
|
|
1
|
-
=begin
|
2
|
-
Arachni
|
3
|
-
Copyright (c) 2010-2011 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
|
-
|
12
|
-
require 'rubygems'
|
13
|
-
|
14
|
-
require File.expand_path( File.dirname( __FILE__ ) ) + '/options'
|
15
|
-
opts = Arachni::Options.instance
|
16
|
-
|
17
|
-
require opts.dir['lib'] + 'arachni'
|
18
|
-
require opts.dir['lib'] + 'ruby'
|
19
|
-
require opts.dir['lib'] + 'exceptions'
|
20
|
-
require opts.dir['lib'] + 'spider'
|
21
|
-
require opts.dir['lib'] + 'parser'
|
22
|
-
require opts.dir['lib'] + 'audit_store'
|
23
|
-
require opts.dir['lib'] + 'module'
|
24
|
-
require opts.dir['lib'] + 'plugin'
|
25
|
-
require opts.dir['lib'] + 'http'
|
26
|
-
require opts.dir['lib'] + 'report'
|
27
|
-
require opts.dir['lib'] + 'component_manager'
|
28
|
-
require 'yaml'
|
29
|
-
require 'ap'
|
30
|
-
require 'pp'
|
31
|
-
|
32
|
-
|
33
|
-
module Arachni
|
34
|
-
|
35
|
-
#
|
36
|
-
# Resets the Framework providing a clean slate.
|
37
|
-
#
|
38
|
-
# This is useful to user interfaces that require the framework to be reused.
|
39
|
-
#
|
40
|
-
def self.reset
|
41
|
-
Element::Auditable.reset
|
42
|
-
Module::Manager.reset
|
43
|
-
Report::Manager.reset
|
44
|
-
Arachni::HTTP.instance.reset
|
45
|
-
end
|
46
|
-
|
47
|
-
#
|
48
|
-
# Arachni::Framework class
|
49
|
-
#
|
50
|
-
# The Framework class ties together all the components.<br/>
|
51
|
-
# It should be wrapped by a UI class.
|
52
|
-
#
|
53
|
-
# It's the brains of the operation, it bosses the rest of the classes around.<br/>
|
54
|
-
# It runs the audit, loads modules and reports and runs them according to
|
55
|
-
# user options.
|
56
|
-
#
|
57
|
-
# @author: Tasos "Zapotek" Laskos
|
58
|
-
# <tasos.laskos@gmail.com>
|
59
|
-
# <zapotek@segfault.gr>
|
60
|
-
# @version: 0.2.3
|
61
|
-
#
|
62
|
-
class Framework
|
63
|
-
|
64
|
-
#
|
65
|
-
# include the output interface but try to use it as little as possible
|
66
|
-
#
|
67
|
-
# the UI classes should take care of communicating with the user
|
68
|
-
#
|
69
|
-
include Arachni::UI::Output
|
70
|
-
include Arachni::Module::Utilities
|
71
|
-
include Arachni::Mixins::Observable
|
72
|
-
|
73
|
-
# the version of *this* class
|
74
|
-
REVISION = '0.2.3'
|
75
|
-
|
76
|
-
#
|
77
|
-
# Instance options
|
78
|
-
#
|
79
|
-
# @return [Options]
|
80
|
-
#
|
81
|
-
attr_reader :opts
|
82
|
-
|
83
|
-
#
|
84
|
-
# @return [Arachni::Report::Manager] report manager
|
85
|
-
#
|
86
|
-
attr_reader :reports
|
87
|
-
|
88
|
-
#
|
89
|
-
# @return [Arachni::Module::Manager] module manager
|
90
|
-
#
|
91
|
-
attr_reader :modules
|
92
|
-
|
93
|
-
#
|
94
|
-
# @return [Arachni::Plugin::Manager] plugin manager
|
95
|
-
#
|
96
|
-
attr_reader :plugins
|
97
|
-
|
98
|
-
#
|
99
|
-
# @return [Arachni::Spider] spider
|
100
|
-
#
|
101
|
-
attr_reader :spider
|
102
|
-
|
103
|
-
#
|
104
|
-
# @return [Arachni::HTTP]
|
105
|
-
#
|
106
|
-
attr_reader :http
|
107
|
-
|
108
|
-
attr_reader :sitemap
|
109
|
-
attr_reader :auditmap
|
110
|
-
|
111
|
-
#
|
112
|
-
# Holds candidate pages to be audited.
|
113
|
-
#
|
114
|
-
# Pages in the queue are pushed in by the trainer, the queue doesn't hold
|
115
|
-
# pages returned by the spider.
|
116
|
-
#
|
117
|
-
# Plug-ins can push their own pages to be audited if they wish to...
|
118
|
-
#
|
119
|
-
# @return [Queue<Arachni::Parser::Page>] page queue
|
120
|
-
#
|
121
|
-
attr_reader :page_queue
|
122
|
-
|
123
|
-
|
124
|
-
#
|
125
|
-
# Initializes system components.
|
126
|
-
#
|
127
|
-
# @param [Options] opts
|
128
|
-
#
|
129
|
-
def initialize( opts )
|
130
|
-
|
131
|
-
Encoding.default_external = "BINARY"
|
132
|
-
Encoding.default_internal = "BINARY"
|
133
|
-
|
134
|
-
@opts = opts
|
135
|
-
|
136
|
-
@modules = Arachni::Module::Manager.new( @opts )
|
137
|
-
@reports = Arachni::Report::Manager.new( @opts )
|
138
|
-
@plugins = Arachni::Plugin::Manager.new( self )
|
139
|
-
|
140
|
-
@page_queue = Queue.new
|
141
|
-
|
142
|
-
prepare_cookie_jar( )
|
143
|
-
prepare_user_agent( )
|
144
|
-
|
145
|
-
# deep clone the redundancy rules to preserve their counter
|
146
|
-
# for the reports
|
147
|
-
@orig_redundant = @opts.redundant.deep_clone
|
148
|
-
|
149
|
-
@running = false
|
150
|
-
@paused = []
|
151
|
-
|
152
|
-
@plugin_store = {}
|
153
|
-
|
154
|
-
@current_url = ''
|
155
|
-
end
|
156
|
-
|
157
|
-
def http
|
158
|
-
Arachni::HTTP.instance
|
159
|
-
end
|
160
|
-
|
161
|
-
#
|
162
|
-
# Runs the system
|
163
|
-
#
|
164
|
-
# It parses the instanse options and runs the audit
|
165
|
-
#
|
166
|
-
# @param [Block] &block a block to call after the audit has finished
|
167
|
-
# but before running the reports
|
168
|
-
#
|
169
|
-
def run( &block )
|
170
|
-
@running = true
|
171
|
-
|
172
|
-
@opts.start_datetime = Time.now
|
173
|
-
|
174
|
-
# run all plugins
|
175
|
-
@plugins.run
|
176
|
-
|
177
|
-
# catch exceptions so that if something breaks down or the user opted to
|
178
|
-
# exit the reports will still run with whatever results
|
179
|
-
# Arachni managed to gather
|
180
|
-
begin
|
181
|
-
# start the audit
|
182
|
-
audit( )
|
183
|
-
rescue Exception
|
184
|
-
end
|
185
|
-
|
186
|
-
clean_up!
|
187
|
-
begin
|
188
|
-
block.call if block
|
189
|
-
rescue Exception
|
190
|
-
end
|
191
|
-
|
192
|
-
# run reports
|
193
|
-
if( @opts.reports && !@opts.reports.empty? )
|
194
|
-
exception_jail{ @reports.run( audit_store( ) ) }
|
195
|
-
end
|
196
|
-
|
197
|
-
return true
|
198
|
-
end
|
199
|
-
|
200
|
-
def stats( refresh_time = false )
|
201
|
-
req_cnt = http.request_count
|
202
|
-
res_cnt = http.response_count
|
203
|
-
|
204
|
-
@auditmap ||= []
|
205
|
-
@sitemap ||= []
|
206
|
-
if !refresh_time || @auditmap.size == @sitemap.size
|
207
|
-
@opts.delta_time ||= Time.now - @opts.start_datetime
|
208
|
-
else
|
209
|
-
@opts.delta_time = Time.now - @opts.start_datetime
|
210
|
-
end
|
211
|
-
|
212
|
-
curr_avg = 0
|
213
|
-
if http.curr_res_cnt > 0 && http.curr_res_time > 0
|
214
|
-
curr_avg = (http.curr_res_cnt / http.curr_res_time).to_i.to_s
|
215
|
-
end
|
216
|
-
|
217
|
-
avg = 0
|
218
|
-
if res_cnt > 0
|
219
|
-
avg = ( res_cnt / @opts.delta_time ).to_i.to_s
|
220
|
-
end
|
221
|
-
|
222
|
-
progress = (Float( @auditmap.size ) / @sitemap.size) * 100
|
223
|
-
|
224
|
-
if Arachni::Module::Auditor.timeout_loaded_modules.size > 0 &&
|
225
|
-
Arachni::Module::Auditor.timeout_audit_blocks.size > 0
|
226
|
-
|
227
|
-
progress /= 2
|
228
|
-
progress += ( Float( Arachni::Module::Auditor.timeout_loaded_modules.size ) /
|
229
|
-
Arachni::Module::Auditor.timeout_audit_blocks.size ) * 50
|
230
|
-
end
|
231
|
-
|
232
|
-
return {
|
233
|
-
:requests => req_cnt,
|
234
|
-
:responses => res_cnt,
|
235
|
-
:time_out_count => http.time_out_count,
|
236
|
-
:time => audit_store.delta_time,
|
237
|
-
:avg => avg,
|
238
|
-
:sitemap_size => @sitemap.size,
|
239
|
-
:auditmap_size => @auditmap.size,
|
240
|
-
:progress => progress.to_s[0...5],
|
241
|
-
:curr_res_time => http.curr_res_time,
|
242
|
-
:curr_res_cnt => http.curr_res_cnt,
|
243
|
-
:curr_avg => curr_avg,
|
244
|
-
:average_res_time => http.average_res_time,
|
245
|
-
:max_concurrency => http.max_concurrency,
|
246
|
-
:current_page => @current_url
|
247
|
-
}
|
248
|
-
end
|
249
|
-
|
250
|
-
#
|
251
|
-
# Audits the site.
|
252
|
-
#
|
253
|
-
# Runs the spider, analyzes each page as it appears and passes it
|
254
|
-
# to (#run_mods} to be audited.
|
255
|
-
#
|
256
|
-
def audit
|
257
|
-
|
258
|
-
wait_if_paused
|
259
|
-
|
260
|
-
@spider = Arachni::Spider.new( @opts )
|
261
|
-
|
262
|
-
@sitemap ||= []
|
263
|
-
@auditmap ||= []
|
264
|
-
|
265
|
-
# initiates the crawl
|
266
|
-
@spider.run {
|
267
|
-
|page|
|
268
|
-
|
269
|
-
@sitemap |= @spider.sitemap
|
270
|
-
|
271
|
-
@page_queue << page
|
272
|
-
audit_queue if !@opts.spider_first
|
273
|
-
}
|
274
|
-
|
275
|
-
exception_jail {
|
276
|
-
if !Arachni::Module::Auditor.timeout_audit_blocks.empty?
|
277
|
-
print_line
|
278
|
-
print_status( 'Running timing attacks.' )
|
279
|
-
print_info( '---------------------------------------' )
|
280
|
-
Arachni::Module::Auditor.timeout_audit_run
|
281
|
-
end
|
282
|
-
}
|
283
|
-
|
284
|
-
audit_queue
|
285
|
-
|
286
|
-
if( @opts.http_harvest_last )
|
287
|
-
harvest_http_responses( )
|
288
|
-
end
|
289
|
-
|
290
|
-
end
|
291
|
-
|
292
|
-
def audit_queue
|
293
|
-
|
294
|
-
# this will run until no new elements appear for the given page
|
295
|
-
while( !@page_queue.empty? && page = @page_queue.pop )
|
296
|
-
|
297
|
-
# audit the page
|
298
|
-
exception_jail{ run_mods( page ) }
|
299
|
-
|
300
|
-
# run all the queued HTTP requests and harvest the responses
|
301
|
-
http.run
|
302
|
-
|
303
|
-
# check to see if the page was updated
|
304
|
-
page = http.trainer.page
|
305
|
-
# and push it in the queue to be audited as well
|
306
|
-
@page_queue << page if page
|
307
|
-
|
308
|
-
end
|
309
|
-
end
|
310
|
-
|
311
|
-
|
312
|
-
#
|
313
|
-
# Returns the results of the audit as an {AuditStore} instance
|
314
|
-
#
|
315
|
-
# @see AuditStore
|
316
|
-
#
|
317
|
-
# @return [AuditStore]
|
318
|
-
#
|
319
|
-
def audit_store( fresh = false )
|
320
|
-
|
321
|
-
# restore the original redundacy rules and their counters
|
322
|
-
@opts.redundant = @orig_redundant
|
323
|
-
opts = @opts.to_h
|
324
|
-
opts['mods'] = @modules.keys
|
325
|
-
|
326
|
-
if( !fresh && @store )
|
327
|
-
return @store
|
328
|
-
else
|
329
|
-
return @store = AuditStore.new( {
|
330
|
-
:version => version( ),
|
331
|
-
:revision => REVISION,
|
332
|
-
:options => opts,
|
333
|
-
:sitemap => @sitemap ? @sitemap.sort : ['N/A'],
|
334
|
-
:issues => @modules.results( ).deep_clone,
|
335
|
-
:plugins => @plugin_store
|
336
|
-
}, self )
|
337
|
-
end
|
338
|
-
end
|
339
|
-
|
340
|
-
def plugin_store( plugin, obj )
|
341
|
-
name = ''
|
342
|
-
@plugins.each_pair {
|
343
|
-
|k, v|
|
344
|
-
|
345
|
-
if plugin.class.name == v.name
|
346
|
-
name = k
|
347
|
-
break
|
348
|
-
end
|
349
|
-
}
|
350
|
-
|
351
|
-
return if @plugin_store[name]
|
352
|
-
|
353
|
-
@plugin_store[name] = {
|
354
|
-
:results => obj
|
355
|
-
}.merge( plugin.class.info )
|
356
|
-
end
|
357
|
-
|
358
|
-
#
|
359
|
-
# Returns an array of hashes with information
|
360
|
-
# about all available modules
|
361
|
-
#
|
362
|
-
# @return [Array<Hash>]
|
363
|
-
#
|
364
|
-
def lsmod
|
365
|
-
|
366
|
-
mod_info = []
|
367
|
-
@modules.available( ).each {
|
368
|
-
|name|
|
369
|
-
|
370
|
-
path = @modules.name_to_path( name )
|
371
|
-
next if !lsmod_match?( path )
|
372
|
-
|
373
|
-
info = @modules[name].info( )
|
374
|
-
|
375
|
-
info[:mod_name] = name
|
376
|
-
info[:name] = info[:name].strip
|
377
|
-
info[:description] = info[:description].strip
|
378
|
-
|
379
|
-
if( !info[:dependencies] )
|
380
|
-
info[:dependencies] = []
|
381
|
-
end
|
382
|
-
|
383
|
-
info[:author] = info[:author].strip
|
384
|
-
info[:version] = info[:version].strip
|
385
|
-
info[:path] = path.strip
|
386
|
-
|
387
|
-
mod_info << info
|
388
|
-
}
|
389
|
-
|
390
|
-
# unload all modules
|
391
|
-
@modules.clear( )
|
392
|
-
|
393
|
-
return mod_info
|
394
|
-
|
395
|
-
end
|
396
|
-
|
397
|
-
#
|
398
|
-
# Returns an array of hashes with information
|
399
|
-
# about all available reports
|
400
|
-
#
|
401
|
-
# @return [Array<Hash>]
|
402
|
-
#
|
403
|
-
def lsrep
|
404
|
-
|
405
|
-
rep_info = []
|
406
|
-
@reports.available( ).each {
|
407
|
-
|report|
|
408
|
-
|
409
|
-
info = @reports[report].info
|
410
|
-
|
411
|
-
info[:rep_name] = report
|
412
|
-
info[:path] = @reports.name_to_path( report )
|
413
|
-
|
414
|
-
rep_info << info
|
415
|
-
}
|
416
|
-
@reports.clear( )
|
417
|
-
|
418
|
-
return rep_info
|
419
|
-
end
|
420
|
-
|
421
|
-
#
|
422
|
-
# Returns an array of hashes with information
|
423
|
-
# about all available reports
|
424
|
-
#
|
425
|
-
# @return [Array<Hash>]
|
426
|
-
#
|
427
|
-
def lsplug
|
428
|
-
|
429
|
-
plug_info = []
|
430
|
-
|
431
|
-
@plugins.available( ).each {
|
432
|
-
|plugin|
|
433
|
-
|
434
|
-
info = @plugins[plugin].info
|
435
|
-
|
436
|
-
info[:plug_name] = plugin
|
437
|
-
info[:path] = @plugins.name_to_path( plugin )
|
438
|
-
|
439
|
-
plug_info << info
|
440
|
-
}
|
441
|
-
|
442
|
-
@plugins.clear( )
|
443
|
-
|
444
|
-
return plug_info
|
445
|
-
end
|
446
|
-
|
447
|
-
def running?
|
448
|
-
@running
|
449
|
-
end
|
450
|
-
|
451
|
-
def paused?
|
452
|
-
!@paused.empty?
|
453
|
-
end
|
454
|
-
|
455
|
-
def pause!
|
456
|
-
@spider.pause! if @spider
|
457
|
-
@paused << caller
|
458
|
-
return true
|
459
|
-
end
|
460
|
-
|
461
|
-
def resume!
|
462
|
-
@paused.delete( caller )
|
463
|
-
@spider.resume! if @spider
|
464
|
-
return true
|
465
|
-
end
|
466
|
-
|
467
|
-
#
|
468
|
-
# Returns the version of the framework
|
469
|
-
#
|
470
|
-
# @return [String]
|
471
|
-
#
|
472
|
-
def version
|
473
|
-
Arachni::VERSION
|
474
|
-
end
|
475
|
-
|
476
|
-
#
|
477
|
-
# Returns the revision of the {Framework} (this) class
|
478
|
-
#
|
479
|
-
# @return [String]
|
480
|
-
#
|
481
|
-
def revision
|
482
|
-
REVISION
|
483
|
-
end
|
484
|
-
|
485
|
-
private
|
486
|
-
|
487
|
-
def clean_up!( skip_audit_queue = false )
|
488
|
-
@opts.finish_datetime = Time.now
|
489
|
-
@opts.delta_time = @opts.finish_datetime - @opts.start_datetime
|
490
|
-
|
491
|
-
# make sure this is disabled or it'll break report output
|
492
|
-
@@only_positives = false
|
493
|
-
|
494
|
-
@running = false
|
495
|
-
|
496
|
-
# wait for the plugins to finish
|
497
|
-
@plugins.block!
|
498
|
-
|
499
|
-
# a plug-in may have updated the page queue, rock it!
|
500
|
-
audit_queue if !skip_audit_queue
|
501
|
-
|
502
|
-
# refresh the audit store
|
503
|
-
audit_store( true )
|
504
|
-
|
505
|
-
return true
|
506
|
-
end
|
507
|
-
|
508
|
-
def caller
|
509
|
-
if /^(.+?):(\d+)(?::in `(.*)')?/ =~ ::Kernel.caller[1]
|
510
|
-
return Regexp.last_match[1]
|
511
|
-
end
|
512
|
-
end
|
513
|
-
|
514
|
-
def wait_if_paused
|
515
|
-
while( paused? )
|
516
|
-
::IO::select( nil, nil, nil, 1 )
|
517
|
-
end
|
518
|
-
end
|
519
|
-
|
520
|
-
|
521
|
-
#
|
522
|
-
# Prepares the user agent to be used throughout the system.
|
523
|
-
#
|
524
|
-
def prepare_user_agent
|
525
|
-
if( !@opts.user_agent )
|
526
|
-
@opts.user_agent = 'Arachni/' + version( )
|
527
|
-
end
|
528
|
-
|
529
|
-
if( @opts.authed_by )
|
530
|
-
authed_by = " (Scan authorized by: #{@opts.authed_by})"
|
531
|
-
@opts.user_agent += authed_by
|
532
|
-
end
|
533
|
-
|
534
|
-
end
|
535
|
-
|
536
|
-
def prepare_cookie_jar( )
|
537
|
-
return if !@opts.cookie_jar || !@opts.cookie_jar.is_a?( String )
|
538
|
-
|
539
|
-
# make sure that the provided cookie-jar file exists
|
540
|
-
if !File.exist?( @opts.cookie_jar )
|
541
|
-
raise( Arachni::Exceptions::NoCookieJar,
|
542
|
-
'Cookie-jar \'' + @opts.cookie_jar + '\' doesn\'t exist.' )
|
543
|
-
end
|
544
|
-
|
545
|
-
end
|
546
|
-
|
547
|
-
|
548
|
-
#
|
549
|
-
# Takes care of page audit and module execution
|
550
|
-
#
|
551
|
-
# It will audit one page at a time as discovered by the spider <br/>
|
552
|
-
# and recursively check for new elements that may have <br/>
|
553
|
-
# appeared during the audit.
|
554
|
-
#
|
555
|
-
# When no new elements appear the recursion will stop and a new page<br/>
|
556
|
-
# will be accepted.
|
557
|
-
#
|
558
|
-
# @see Page
|
559
|
-
#
|
560
|
-
# @param [Page] page
|
561
|
-
#
|
562
|
-
def run_mods( page )
|
563
|
-
return if !page
|
564
|
-
|
565
|
-
call_on_run_mods( page.deep_clone )
|
566
|
-
|
567
|
-
@current_url = page.url.to_s
|
568
|
-
|
569
|
-
@modules.each_pair {
|
570
|
-
|name, mod|
|
571
|
-
|
572
|
-
wait_if_paused
|
573
|
-
run_mod( mod, page.deep_clone )
|
574
|
-
}
|
575
|
-
|
576
|
-
@auditmap << page.url
|
577
|
-
@auditmap.uniq!
|
578
|
-
@sitemap |= @auditmap
|
579
|
-
@sitemap.uniq!
|
580
|
-
|
581
|
-
|
582
|
-
if( !@opts.http_harvest_last )
|
583
|
-
harvest_http_responses( )
|
584
|
-
end
|
585
|
-
|
586
|
-
end
|
587
|
-
|
588
|
-
def harvest_http_responses
|
589
|
-
|
590
|
-
print_status( 'Harvesting HTTP responses...' )
|
591
|
-
print_info( 'Depending on server responsiveness and network' +
|
592
|
-
' conditions this may take a while.' )
|
593
|
-
|
594
|
-
# run all the queued HTTP requests and harvest the responses
|
595
|
-
http.run
|
596
|
-
|
597
|
-
# try to get an updated page from the Trainer
|
598
|
-
page = http.trainer.page
|
599
|
-
|
600
|
-
# if there was an updated page push it in the queue
|
601
|
-
@page_queue << page if page
|
602
|
-
audit_queue
|
603
|
-
end
|
604
|
-
|
605
|
-
#
|
606
|
-
# Passes a page to the module and runs it.<br/>
|
607
|
-
# It also handles any exceptions thrown by the module at runtime.
|
608
|
-
#
|
609
|
-
# @see Page
|
610
|
-
#
|
611
|
-
# @param [Class] mod the module to run
|
612
|
-
# @param [Page] page
|
613
|
-
#
|
614
|
-
def run_mod( mod, page )
|
615
|
-
return if !run_mod?( mod, page )
|
616
|
-
|
617
|
-
begin
|
618
|
-
|
619
|
-
# instantiate the module
|
620
|
-
mod_new = mod.new( page )
|
621
|
-
mod_new.set_framework( self )
|
622
|
-
|
623
|
-
mod_new.prepare
|
624
|
-
mod_new.run
|
625
|
-
mod_new.clean_up
|
626
|
-
rescue SystemExit
|
627
|
-
raise
|
628
|
-
rescue Exception => e
|
629
|
-
print_error( 'Error in ' + mod.to_s + ': ' + e.to_s )
|
630
|
-
print_debug_backtrace( e )
|
631
|
-
end
|
632
|
-
end
|
633
|
-
|
634
|
-
#
|
635
|
-
# Determines whether or not to run the module against the given page
|
636
|
-
# depending on which elements exist in the page, which elements the module
|
637
|
-
# is configured to audit and user options.
|
638
|
-
#
|
639
|
-
# @param [Class] mod the module to run
|
640
|
-
# @param [Page] page
|
641
|
-
#
|
642
|
-
# @return [Bool]
|
643
|
-
#
|
644
|
-
def run_mod?( mod, page )
|
645
|
-
return true if( !mod.info[:elements] || mod.info[:elements].empty? )
|
646
|
-
|
647
|
-
elems = {
|
648
|
-
Issue::Element::LINK => page.links && page.links.size > 0 && @opts.audit_links,
|
649
|
-
Issue::Element::FORM => page.forms && page.forms.size > 0 && @opts.audit_forms,
|
650
|
-
Issue::Element::COOKIE => page.cookies && page.cookies.size > 0 && @opts.audit_cookies,
|
651
|
-
Issue::Element::HEADER => page.headers && page.headers.size > 0 && @opts.audit_headers,
|
652
|
-
}
|
653
|
-
|
654
|
-
elems.each_pair {
|
655
|
-
|elem, expr|
|
656
|
-
return true if mod.info[:elements].include?( elem ) && expr
|
657
|
-
}
|
658
|
-
|
659
|
-
return false
|
660
|
-
end
|
661
|
-
|
662
|
-
def lsmod_match?( path )
|
663
|
-
cnt = 0
|
664
|
-
@opts.lsmod.each {
|
665
|
-
|filter|
|
666
|
-
cnt += 1 if path =~ filter
|
667
|
-
}
|
668
|
-
return true if cnt == @opts.lsmod.size
|
669
|
-
end
|
670
|
-
|
671
|
-
end
|
672
|
-
|
673
|
-
end
|