arachni 0.2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ACKNOWLEDGMENTS.md +14 -0
- data/AUTHORS.md +6 -0
- data/CHANGELOG.md +162 -0
- data/CONTRIBUTORS.md +10 -0
- data/EXPLOITATION.md +429 -0
- data/HACKING.md +101 -0
- data/LICENSE.md +341 -0
- data/README.md +350 -0
- data/Rakefile +86 -0
- data/bin/arachni +22 -0
- data/bin/arachni_web +77 -0
- data/bin/arachni_xmlrpc +21 -0
- data/bin/arachni_xmlrpcd +82 -0
- data/bin/arachni_xmlrpcd_monitor +74 -0
- data/conf/README.webui.yaml.txt +44 -0
- data/conf/webui.yaml +11 -0
- data/external/metasploit/LICENSE +24 -0
- data/external/metasploit/modules/exploits/unix/webapp/arachni_exec.rb +142 -0
- data/external/metasploit/modules/exploits/unix/webapp/arachni_path_traversal.rb +113 -0
- data/external/metasploit/modules/exploits/unix/webapp/arachni_php_eval.rb +150 -0
- data/external/metasploit/modules/exploits/unix/webapp/arachni_php_include.rb +141 -0
- data/external/metasploit/modules/exploits/unix/webapp/arachni_sqlmap.rb +92 -0
- data/external/metasploit/plugins/arachni.rb +536 -0
- data/getoptslong.rb +241 -0
- data/lib/anemone.rb +2 -0
- data/lib/anemone/cookie_store.rb +35 -0
- data/lib/anemone/core.rb +371 -0
- data/lib/anemone/exceptions.rb +5 -0
- data/lib/anemone/http.rb +144 -0
- data/lib/anemone/page.rb +337 -0
- data/lib/anemone/page_store.rb +160 -0
- data/lib/anemone/storage.rb +34 -0
- data/lib/anemone/storage/base.rb +75 -0
- data/lib/anemone/storage/exceptions.rb +15 -0
- data/lib/anemone/storage/mongodb.rb +89 -0
- data/lib/anemone/storage/pstore.rb +50 -0
- data/lib/anemone/storage/redis.rb +90 -0
- data/lib/anemone/storage/tokyo_cabinet.rb +57 -0
- data/lib/anemone/tentacle.rb +40 -0
- data/lib/arachni.rb +16 -0
- data/lib/audit_store.rb +346 -0
- data/lib/component_manager.rb +293 -0
- data/lib/component_options.rb +395 -0
- data/lib/exceptions.rb +76 -0
- data/lib/framework.rb +637 -0
- data/lib/http.rb +809 -0
- data/lib/issue.rb +302 -0
- data/lib/module.rb +4 -0
- data/lib/module/auditor.rb +455 -0
- data/lib/module/base.rb +188 -0
- data/lib/module/element_db.rb +158 -0
- data/lib/module/key_filler.rb +87 -0
- data/lib/module/manager.rb +87 -0
- data/lib/module/output.rb +68 -0
- data/lib/module/trainer.rb +240 -0
- data/lib/module/utilities.rb +110 -0
- data/lib/options.rb +547 -0
- data/lib/parser.rb +2 -0
- data/lib/parser/auditable.rb +522 -0
- data/lib/parser/elements.rb +296 -0
- data/lib/parser/page.rb +149 -0
- data/lib/parser/parser.rb +717 -0
- data/lib/plugin.rb +4 -0
- data/lib/plugin/base.rb +110 -0
- data/lib/plugin/manager.rb +162 -0
- data/lib/report.rb +4 -0
- data/lib/report/base.rb +119 -0
- data/lib/report/manager.rb +92 -0
- data/lib/rpc/xml/client/base.rb +71 -0
- data/lib/rpc/xml/client/dispatcher.rb +49 -0
- data/lib/rpc/xml/client/instance.rb +88 -0
- data/lib/rpc/xml/server/base.rb +90 -0
- data/lib/rpc/xml/server/dispatcher.rb +357 -0
- data/lib/rpc/xml/server/framework.rb +206 -0
- data/lib/rpc/xml/server/instance.rb +191 -0
- data/lib/rpc/xml/server/module/manager.rb +46 -0
- data/lib/rpc/xml/server/options.rb +124 -0
- data/lib/rpc/xml/server/output.rb +299 -0
- data/lib/rpc/xml/server/plugin/manager.rb +58 -0
- data/lib/ruby.rb +5 -0
- data/lib/ruby/object.rb +32 -0
- data/lib/ruby/string.rb +74 -0
- data/lib/ruby/xmlrpc/server.rb +27 -0
- data/lib/spider.rb +200 -0
- data/lib/typhoeus/request.rb +91 -0
- data/lib/typhoeus/response.rb +34 -0
- data/lib/ui/cli/cli.rb +744 -0
- data/lib/ui/cli/output.rb +279 -0
- data/lib/ui/web/log.rb +82 -0
- data/lib/ui/web/output_stream.rb +94 -0
- data/lib/ui/web/report_manager.rb +222 -0
- data/lib/ui/web/server.rb +903 -0
- data/lib/ui/web/server/db/placeholder +0 -0
- data/lib/ui/web/server/public/banner.png +0 -0
- data/lib/ui/web/server/public/bodybg-small.png +0 -0
- data/lib/ui/web/server/public/bodybg.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/pbar-ani.gif +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/jquery-ui-1.8.9.custom.css +573 -0
- data/lib/ui/web/server/public/favicon.ico +0 -0
- data/lib/ui/web/server/public/footer.jpg +0 -0
- data/lib/ui/web/server/public/icons/error.png +0 -0
- data/lib/ui/web/server/public/icons/info.png +0 -0
- data/lib/ui/web/server/public/icons/ok.png +0 -0
- data/lib/ui/web/server/public/icons/status.png +0 -0
- data/lib/ui/web/server/public/js/jquery-1.4.4.min.js +167 -0
- data/lib/ui/web/server/public/js/jquery-ui-1.8.9.custom.min.js +781 -0
- data/lib/ui/web/server/public/logo.png +0 -0
- data/lib/ui/web/server/public/nav-left.jpg +0 -0
- data/lib/ui/web/server/public/nav-right.jpg +0 -0
- data/lib/ui/web/server/public/nav-selected-left.jpg +0 -0
- data/lib/ui/web/server/public/nav-selected-right.jpg +0 -0
- data/lib/ui/web/server/public/reports/placeholder +1 -0
- data/lib/ui/web/server/public/sidebar-bottom.jpg +0 -0
- data/lib/ui/web/server/public/sidebar-h4.jpg +0 -0
- data/lib/ui/web/server/public/sidebar-top.jpg +0 -0
- data/lib/ui/web/server/public/spider.png +0 -0
- data/lib/ui/web/server/public/style.css +604 -0
- data/lib/ui/web/server/tmp/placeholder +0 -0
- data/lib/ui/web/server/views/dispatcher.erb +85 -0
- data/lib/ui/web/server/views/dispatcher_error.erb +14 -0
- data/lib/ui/web/server/views/error.erb +1 -0
- data/lib/ui/web/server/views/flash.erb +18 -0
- data/lib/ui/web/server/views/home.erb +14 -0
- data/lib/ui/web/server/views/instance.erb +213 -0
- data/lib/ui/web/server/views/layout.erb +95 -0
- data/lib/ui/web/server/views/log.erb +40 -0
- data/lib/ui/web/server/views/modules.erb +71 -0
- data/lib/ui/web/server/views/options.erb +23 -0
- data/lib/ui/web/server/views/output_results.erb +51 -0
- data/lib/ui/web/server/views/plugins.erb +42 -0
- data/lib/ui/web/server/views/report_formats.erb +30 -0
- data/lib/ui/web/server/views/reports.erb +55 -0
- data/lib/ui/web/server/views/settings.erb +120 -0
- data/lib/ui/web/server/views/welcome.erb +38 -0
- data/lib/ui/xmlrpc/dispatcher_monitor.rb +204 -0
- data/lib/ui/xmlrpc/xmlrpc.rb +843 -0
- data/logs/placeholder +0 -0
- data/metamodules/autothrottle.rb +74 -0
- data/metamodules/timeout_notice.rb +118 -0
- data/metamodules/uniformity.rb +98 -0
- data/modules/audit/code_injection.rb +136 -0
- data/modules/audit/code_injection_timing.rb +115 -0
- data/modules/audit/code_injection_timing/payloads.txt +4 -0
- data/modules/audit/csrf.rb +301 -0
- data/modules/audit/ldapi.rb +103 -0
- data/modules/audit/ldapi/errors.txt +26 -0
- data/modules/audit/os_cmd_injection.rb +103 -0
- data/modules/audit/os_cmd_injection/payloads.txt +2 -0
- data/modules/audit/os_cmd_injection_timing.rb +104 -0
- data/modules/audit/os_cmd_injection_timing/payloads.txt +3 -0
- data/modules/audit/path_traversal.rb +141 -0
- data/modules/audit/response_splitting.rb +105 -0
- data/modules/audit/rfi.rb +193 -0
- data/modules/audit/sqli.rb +120 -0
- data/modules/audit/sqli/regexp_ids.txt +90 -0
- data/modules/audit/sqli_blind_rdiff.rb +321 -0
- data/modules/audit/sqli_blind_timing.rb +103 -0
- data/modules/audit/sqli_blind_timing/payloads.txt +51 -0
- data/modules/audit/trainer.rb +89 -0
- data/modules/audit/unvalidated_redirect.rb +90 -0
- data/modules/audit/xpath.rb +104 -0
- data/modules/audit/xpath/errors.txt +26 -0
- data/modules/audit/xss.rb +99 -0
- data/modules/audit/xss_event.rb +134 -0
- data/modules/audit/xss_path.rb +125 -0
- data/modules/audit/xss_script_tag.rb +112 -0
- data/modules/audit/xss_tag.rb +112 -0
- data/modules/audit/xss_uri.rb +125 -0
- data/modules/recon/allowed_methods.rb +104 -0
- data/modules/recon/backdoors.rb +131 -0
- data/modules/recon/backdoors/filenames.txt +16 -0
- data/modules/recon/backup_files.rb +177 -0
- data/modules/recon/backup_files/extensions.txt +28 -0
- data/modules/recon/common_directories.rb +138 -0
- data/modules/recon/common_directories/directories.txt +265 -0
- data/modules/recon/common_files.rb +138 -0
- data/modules/recon/common_files/filenames.txt +17 -0
- data/modules/recon/directory_listing.rb +171 -0
- data/modules/recon/grep/captcha.rb +62 -0
- data/modules/recon/grep/credit_card.rb +85 -0
- data/modules/recon/grep/cvs_svn_users.rb +73 -0
- data/modules/recon/grep/emails.rb +59 -0
- data/modules/recon/grep/html_objects.rb +53 -0
- data/modules/recon/grep/private_ip.rb +54 -0
- data/modules/recon/grep/ssn.rb +53 -0
- data/modules/recon/htaccess_limit.rb +82 -0
- data/modules/recon/http_put.rb +95 -0
- data/modules/recon/interesting_responses.rb +118 -0
- data/modules/recon/unencrypted_password_forms.rb +119 -0
- data/modules/recon/webdav.rb +126 -0
- data/modules/recon/xst.rb +107 -0
- data/path_extractors/anchors.rb +35 -0
- data/path_extractors/forms.rb +35 -0
- data/path_extractors/frames.rb +38 -0
- data/path_extractors/generic.rb +39 -0
- data/path_extractors/links.rb +35 -0
- data/path_extractors/meta_refresh.rb +39 -0
- data/path_extractors/scripts.rb +37 -0
- data/path_extractors/sitemap.rb +31 -0
- data/plugins/autologin.rb +137 -0
- data/plugins/content_types.rb +90 -0
- data/plugins/cookie_collector.rb +99 -0
- data/plugins/form_dicattack.rb +185 -0
- data/plugins/healthmap.rb +94 -0
- data/plugins/http_dicattack.rb +133 -0
- data/plugins/metamodules.rb +118 -0
- data/plugins/proxy.rb +248 -0
- data/plugins/proxy/server.rb +66 -0
- data/plugins/waf_detector.rb +184 -0
- data/profiles/comprehensive.afp +74 -0
- data/profiles/full.afp +75 -0
- data/reports/afr.rb +59 -0
- data/reports/ap.rb +55 -0
- data/reports/html.rb +179 -0
- data/reports/html/default.erb +967 -0
- data/reports/metareport.rb +139 -0
- data/reports/metareport/arachni_metareport.rb +174 -0
- data/reports/plugin_formatters/html/content_types.rb +82 -0
- data/reports/plugin_formatters/html/cookie_collector.rb +66 -0
- data/reports/plugin_formatters/html/form_dicattack.rb +54 -0
- data/reports/plugin_formatters/html/healthmap.rb +76 -0
- data/reports/plugin_formatters/html/http_dicattack.rb +54 -0
- data/reports/plugin_formatters/html/metaformatters/timeout_notice.rb +65 -0
- data/reports/plugin_formatters/html/metaformatters/uniformity.rb +71 -0
- data/reports/plugin_formatters/html/metamodules.rb +93 -0
- data/reports/plugin_formatters/html/waf_detector.rb +54 -0
- data/reports/plugin_formatters/stdout/content_types.rb +73 -0
- data/reports/plugin_formatters/stdout/cookie_collector.rb +61 -0
- data/reports/plugin_formatters/stdout/form_dicattack.rb +52 -0
- data/reports/plugin_formatters/stdout/healthmap.rb +72 -0
- data/reports/plugin_formatters/stdout/http_dicattack.rb +53 -0
- data/reports/plugin_formatters/stdout/metaformatters/timeout_notice.rb +55 -0
- data/reports/plugin_formatters/stdout/metaformatters/uniformity.rb +68 -0
- data/reports/plugin_formatters/stdout/metamodules.rb +89 -0
- data/reports/plugin_formatters/stdout/waf_detector.rb +48 -0
- data/reports/plugin_formatters/xml/content_types.rb +91 -0
- data/reports/plugin_formatters/xml/cookie_collector.rb +70 -0
- data/reports/plugin_formatters/xml/form_dicattack.rb +57 -0
- data/reports/plugin_formatters/xml/healthmap.rb +82 -0
- data/reports/plugin_formatters/xml/http_dicattack.rb +57 -0
- data/reports/plugin_formatters/xml/metaformatters/timeout_notice.rb +67 -0
- data/reports/plugin_formatters/xml/metaformatters/uniformity.rb +82 -0
- data/reports/plugin_formatters/xml/metamodules.rb +91 -0
- data/reports/plugin_formatters/xml/waf_detector.rb +58 -0
- data/reports/stdout.rb +182 -0
- data/reports/txt.rb +77 -0
- data/reports/xml.rb +231 -0
- data/reports/xml/buffer.rb +98 -0
- metadata +516 -0
|
@@ -0,0 +1,118 @@
|
|
|
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 'digest/md5'
|
|
12
|
+
|
|
13
|
+
module Arachni
|
|
14
|
+
|
|
15
|
+
module Modules
|
|
16
|
+
|
|
17
|
+
#
|
|
18
|
+
# Logs all non 200 (OK) and non 404 server responses.
|
|
19
|
+
#
|
|
20
|
+
# @author: Tasos "Zapotek" Laskos
|
|
21
|
+
# <tasos.laskos@gmail.com>
|
|
22
|
+
# <zapotek@segfault.gr>
|
|
23
|
+
# @version: 0.1
|
|
24
|
+
#
|
|
25
|
+
#
|
|
26
|
+
class InterestingResponses < Arachni::Module::Base
|
|
27
|
+
|
|
28
|
+
include Arachni::Module::Utilities
|
|
29
|
+
|
|
30
|
+
IGNORE_CODES = [
|
|
31
|
+
200,
|
|
32
|
+
404
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
def initialize( page )
|
|
36
|
+
super( page )
|
|
37
|
+
|
|
38
|
+
# we need to run only once
|
|
39
|
+
@@__ran ||= false
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def run( )
|
|
43
|
+
return if @@__ran
|
|
44
|
+
|
|
45
|
+
print_status( "Listening..." )
|
|
46
|
+
|
|
47
|
+
# tell the HTTP interface to cal this block every-time a request completes
|
|
48
|
+
@http.on_complete {
|
|
49
|
+
|res|
|
|
50
|
+
__log_results( res ) if !IGNORE_CODES.include?( res.code ) && !res.body.empty?
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def clean_up
|
|
56
|
+
@@__ran = true
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def self.info
|
|
60
|
+
{
|
|
61
|
+
:name => 'Interesting responses',
|
|
62
|
+
:description => %q{Logs all non 200 (OK) server responses.},
|
|
63
|
+
:elements => [ ],
|
|
64
|
+
:author => 'Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>',
|
|
65
|
+
:version => '0.1',
|
|
66
|
+
:targets => { 'Generic' => 'all' },
|
|
67
|
+
:issue => {
|
|
68
|
+
:name => %q{Interesting server response.},
|
|
69
|
+
:description => %q{The server responded with a non 200 (OK) code. },
|
|
70
|
+
:tags => [ 'interesting', 'response', 'server' ],
|
|
71
|
+
:cwe => '',
|
|
72
|
+
:severity => Issue::Severity::INFORMATIONAL,
|
|
73
|
+
:cvssv2 => '',
|
|
74
|
+
:remedy_guidance => '',
|
|
75
|
+
:remedy_code => '',
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
}
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def __log_results( res )
|
|
82
|
+
|
|
83
|
+
@@_loged ||= {
|
|
84
|
+
:paths => Set.new,
|
|
85
|
+
:digests => Set.new
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
digest = Digest::MD5.hexdigest( res.body )
|
|
89
|
+
path = URI( res.effective_url ).path
|
|
90
|
+
|
|
91
|
+
return if @@_loged[:paths].include?( path ) ||
|
|
92
|
+
@@_loged[:digests].include?( digest )
|
|
93
|
+
|
|
94
|
+
@@_loged[:paths] << path
|
|
95
|
+
@@_loged[:digests] << digest
|
|
96
|
+
|
|
97
|
+
issue = Issue.new( {
|
|
98
|
+
:url => res.effective_url,
|
|
99
|
+
:method => res.request.method.to_s.upcase,
|
|
100
|
+
:id => "Code: #{res.code.to_s}",
|
|
101
|
+
:elem => Issue::Element::SERVER,
|
|
102
|
+
:response => res.body,
|
|
103
|
+
:headers => {
|
|
104
|
+
:request => res.request.headers,
|
|
105
|
+
:response => res.headers,
|
|
106
|
+
}
|
|
107
|
+
}.merge( self.class.info ) )
|
|
108
|
+
|
|
109
|
+
# register our results with the system
|
|
110
|
+
register_results( [issue] )
|
|
111
|
+
|
|
112
|
+
# inform the user that we have a match
|
|
113
|
+
print_ok( "Found an interesting response (Code: #{res.code.to_s})." )
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
$Id$
|
|
3
|
+
|
|
4
|
+
Arachni
|
|
5
|
+
Copyright (c) 2010-2011 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
|
|
6
|
+
|
|
7
|
+
This is free software; you can copy and distribute and modify
|
|
8
|
+
this program under the term of the GPL v2.0 License
|
|
9
|
+
(See LICENSE file for details)
|
|
10
|
+
|
|
11
|
+
=end
|
|
12
|
+
|
|
13
|
+
module Arachni
|
|
14
|
+
|
|
15
|
+
module Modules
|
|
16
|
+
|
|
17
|
+
#
|
|
18
|
+
# Unencrypted password form
|
|
19
|
+
#
|
|
20
|
+
# Looks for password inputs that don't submit data over an encrypted channel (HTTPS).
|
|
21
|
+
#
|
|
22
|
+
# @author: Tasos "Zapotek" Laskos
|
|
23
|
+
# <tasos.laskos@gmail.com>
|
|
24
|
+
# <zapotek@segfault.gr>
|
|
25
|
+
# @version: 0.1.1
|
|
26
|
+
#
|
|
27
|
+
# @see http://www.owasp.org/index.php/Top_10_2010-A9-Insufficient_Transport_Layer_Protection
|
|
28
|
+
#
|
|
29
|
+
class UnencryptedPasswordForms < Arachni::Module::Base
|
|
30
|
+
|
|
31
|
+
def initialize( page )
|
|
32
|
+
# in this case we don't need to call the parent
|
|
33
|
+
@page = page
|
|
34
|
+
|
|
35
|
+
@results = []
|
|
36
|
+
@@__audited ||= Set.new
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def run( )
|
|
40
|
+
|
|
41
|
+
@page.forms.each {
|
|
42
|
+
|form|
|
|
43
|
+
__check( form )
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
# register our results with the system
|
|
47
|
+
register_results( @results )
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def __check( form )
|
|
51
|
+
|
|
52
|
+
scheme = URI( form.action ).scheme
|
|
53
|
+
return if( scheme.downcase == 'https' )
|
|
54
|
+
|
|
55
|
+
form.raw['auditable'].each {
|
|
56
|
+
|input|
|
|
57
|
+
|
|
58
|
+
next if !input['type']
|
|
59
|
+
|
|
60
|
+
if( input['type'].downcase == 'password' )
|
|
61
|
+
__log( form.url, input )
|
|
62
|
+
end
|
|
63
|
+
}
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def __log( url, input )
|
|
67
|
+
|
|
68
|
+
if @@__audited.include?( input['name'] )
|
|
69
|
+
print_info( 'Skipping already audited field \'' +
|
|
70
|
+
input['name'] + '\' of url: ' + url )
|
|
71
|
+
return
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
name = input['name'] || input['id'] || 'n/a'
|
|
75
|
+
@@__audited << name
|
|
76
|
+
|
|
77
|
+
# append the result to the results array
|
|
78
|
+
@results << Issue.new( {
|
|
79
|
+
:var => name,
|
|
80
|
+
:url => url,
|
|
81
|
+
:elem => Issue::Element::FORM,
|
|
82
|
+
:response => @page.html,
|
|
83
|
+
}.merge( self.class.info ) )
|
|
84
|
+
|
|
85
|
+
print_ok( "Found unprotected password field '#{input['name']}' at #{url}" )
|
|
86
|
+
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def self.info
|
|
90
|
+
{
|
|
91
|
+
:name => 'UnencryptedPasswordForms',
|
|
92
|
+
:description => %q{Looks for password inputs that don't submit data
|
|
93
|
+
over an encrypted channel (HTTPS).},
|
|
94
|
+
:elements => [
|
|
95
|
+
Issue::Element::FORM
|
|
96
|
+
],
|
|
97
|
+
:author => 'Tasos "Zapotek" Laskos <tasos.laskos@gmail.com> ',
|
|
98
|
+
:version => '0.1',
|
|
99
|
+
:references => {
|
|
100
|
+
'OWASP Top 10 2010' => 'http://www.owasp.org/index.php/Top_10_2010-A9-Insufficient_Transport_Layer_Protection'
|
|
101
|
+
},
|
|
102
|
+
:targets => { 'Generic' => 'all' },
|
|
103
|
+
:issue => {
|
|
104
|
+
:name => %q{Unencrypted password form.},
|
|
105
|
+
:description => %q{Transmission of password does not use an encrypted channel.},
|
|
106
|
+
:tags => [ 'unencrypted', 'password', 'form' ],
|
|
107
|
+
:cwe => '319',
|
|
108
|
+
:severity => Issue::Severity::MEDIUM,
|
|
109
|
+
:cvssv2 => '',
|
|
110
|
+
:remedy_guidance => '',
|
|
111
|
+
:remedy_code => '',
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
}
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
@@ -0,0 +1,126 @@
|
|
|
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
|
+
module Arachni
|
|
12
|
+
|
|
13
|
+
module Modules
|
|
14
|
+
|
|
15
|
+
#
|
|
16
|
+
# WebDAV detection recon module.
|
|
17
|
+
#
|
|
18
|
+
# It doesn't check for a functional DAV implementation but uses the
|
|
19
|
+
# OPTIONS HTTP method to see if 'PROPFIND' is allowed.
|
|
20
|
+
#
|
|
21
|
+
# @author: Tasos "Zapotek" Laskos
|
|
22
|
+
# <tasos.laskos@gmail.com>
|
|
23
|
+
# <zapotek@segfault.gr>
|
|
24
|
+
# @version: 0.1
|
|
25
|
+
#
|
|
26
|
+
# @see http://en.wikipedia.org/wiki/WebDAV
|
|
27
|
+
# @see http://www.webdav.org/specs/rfc4918.html
|
|
28
|
+
#
|
|
29
|
+
class WebDav < Arachni::Module::Base
|
|
30
|
+
|
|
31
|
+
include Arachni::Module::Utilities
|
|
32
|
+
|
|
33
|
+
def initialize( page )
|
|
34
|
+
super( page )
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def prepare
|
|
38
|
+
#
|
|
39
|
+
# Because Dav may be enabled on a per directory basis we will check
|
|
40
|
+
# all directories but only report the first one we find.
|
|
41
|
+
#
|
|
42
|
+
# If it is enabled for all dirs then we'll end up swimming in
|
|
43
|
+
# noise.
|
|
44
|
+
#
|
|
45
|
+
# Result aggregation will be implemented at some point though...
|
|
46
|
+
#
|
|
47
|
+
@@__found ||= false
|
|
48
|
+
|
|
49
|
+
@__check = 'PROPFIND'
|
|
50
|
+
|
|
51
|
+
@@__auditted ||= Set.new
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def run( )
|
|
55
|
+
|
|
56
|
+
path = get_path( @page.url )
|
|
57
|
+
|
|
58
|
+
return if @@__found || @@__auditted.include?( path )
|
|
59
|
+
|
|
60
|
+
print_status( "Checking: #{path}" )
|
|
61
|
+
|
|
62
|
+
@http.request( path, :method => :options ).on_complete {
|
|
63
|
+
|res|
|
|
64
|
+
begin
|
|
65
|
+
allowed = res.headers_hash['Allow'].split( ',' ).map{ |method| method.strip }
|
|
66
|
+
__log_results( res ) if allowed.include?( @__check )
|
|
67
|
+
rescue
|
|
68
|
+
end
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@@__auditted << path
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def self.info
|
|
75
|
+
{
|
|
76
|
+
:name => 'WebDav',
|
|
77
|
+
:description => %q{Checks for WebDAV enabled directories.},
|
|
78
|
+
:elements => [ ],
|
|
79
|
+
:author => 'Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>',
|
|
80
|
+
:version => '0.1',
|
|
81
|
+
:references => {
|
|
82
|
+
'WebDAV.org' => 'http://www.webdav.org/specs/rfc4918.html',
|
|
83
|
+
'Wikipedia' => 'http://en.wikipedia.org/wiki/WebDAV',
|
|
84
|
+
},
|
|
85
|
+
:targets => { 'Generic' => 'all' },
|
|
86
|
+
:issue => {
|
|
87
|
+
:name => %q{WebDAV},
|
|
88
|
+
:description => %q{WebDAV is enabled on the server.
|
|
89
|
+
Consider auditing further using a specialised tool.},
|
|
90
|
+
:tags => [ 'webdav', 'options', 'methods', 'server' ],
|
|
91
|
+
:cwe => '',
|
|
92
|
+
:severity => Issue::Severity::INFORMATIONAL,
|
|
93
|
+
:cvssv2 => '',
|
|
94
|
+
:remedy_guidance => '',
|
|
95
|
+
:remedy_code => '',
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
}
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def __log_results( res )
|
|
102
|
+
return if @@__found
|
|
103
|
+
|
|
104
|
+
@@__found = true
|
|
105
|
+
|
|
106
|
+
issue = Issue.new( {
|
|
107
|
+
:url => res.effective_url,
|
|
108
|
+
:method => res.request.method.to_s.upcase,
|
|
109
|
+
:elem => Issue::Element::SERVER,
|
|
110
|
+
:response => res.body,
|
|
111
|
+
:headers => {
|
|
112
|
+
:request => res.request.headers,
|
|
113
|
+
:response => res.headers,
|
|
114
|
+
}
|
|
115
|
+
}.merge( self.class.info ) )
|
|
116
|
+
|
|
117
|
+
# register our results with the system
|
|
118
|
+
register_results( [issue] )
|
|
119
|
+
|
|
120
|
+
# inform the user that we have a match
|
|
121
|
+
print_ok( "Enabled for: #{res.effective_url}" )
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
@@ -0,0 +1,107 @@
|
|
|
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
|
+
module Arachni
|
|
12
|
+
|
|
13
|
+
module Modules
|
|
14
|
+
|
|
15
|
+
#
|
|
16
|
+
# Cross-Site tracing recon module.
|
|
17
|
+
#
|
|
18
|
+
# But not really...it only checks if the TRACE HTTP method is enabled.
|
|
19
|
+
#
|
|
20
|
+
# @author: Tasos "Zapotek" Laskos
|
|
21
|
+
# <tasos.laskos@gmail.com>
|
|
22
|
+
# <zapotek@segfault.gr>
|
|
23
|
+
# @version: 0.1.1
|
|
24
|
+
#
|
|
25
|
+
# @see http://cwe.mitre.org/data/definitions/693.html
|
|
26
|
+
# @see http://capec.mitre.org/data/definitions/107.html
|
|
27
|
+
# @see http://www.owasp.org/index.php/Cross_Site_Tracing
|
|
28
|
+
#
|
|
29
|
+
class XST < Arachni::Module::Base
|
|
30
|
+
|
|
31
|
+
include Arachni::Module::Utilities
|
|
32
|
+
|
|
33
|
+
def initialize( page )
|
|
34
|
+
super( page )
|
|
35
|
+
|
|
36
|
+
# we need to run only once
|
|
37
|
+
@@__ran ||= false
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def run( )
|
|
41
|
+
return if @@__ran
|
|
42
|
+
|
|
43
|
+
print_status( "Checking..." )
|
|
44
|
+
|
|
45
|
+
@http.trace( URI( normalize_url( @page.url ) ).host ).on_complete {
|
|
46
|
+
|res|
|
|
47
|
+
# checking for a 200 code is not enought, there are some weird
|
|
48
|
+
# webservers out there that don't give a flying fuck about standards
|
|
49
|
+
__log_results( res ) if res.code == 200 && !res.body.empty?
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def clean_up
|
|
55
|
+
@@__ran = true
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def self.info
|
|
59
|
+
{
|
|
60
|
+
:name => 'XST',
|
|
61
|
+
:description => %q{Sends an HTTP TRACE request and checks if it succeeded.},
|
|
62
|
+
:elements => [ ],
|
|
63
|
+
:author => 'Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>',
|
|
64
|
+
:version => '0.1.1',
|
|
65
|
+
:references => {
|
|
66
|
+
'CAPEC' => 'http://capec.mitre.org/data/definitions/107.html',
|
|
67
|
+
'OWASP' => 'http://www.owasp.org/index.php/Cross_Site_Tracing'
|
|
68
|
+
},
|
|
69
|
+
:targets => { 'Generic' => 'all' },
|
|
70
|
+
:issue => {
|
|
71
|
+
:name => %q{The TRACE HTTP method is enabled.},
|
|
72
|
+
:description => %q{This type of attack can occur when the there
|
|
73
|
+
is an XSS vulnerability and the server supports HTTP TRACE. },
|
|
74
|
+
:tags => [ 'xst', 'methods', 'trace', 'server' ],
|
|
75
|
+
:cwe => '693',
|
|
76
|
+
:severity => Issue::Severity::MEDIUM,
|
|
77
|
+
:cvssv2 => '',
|
|
78
|
+
:remedy_guidance => '',
|
|
79
|
+
:remedy_code => '',
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
}
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def __log_results( res )
|
|
86
|
+
|
|
87
|
+
issue = Issue.new( {
|
|
88
|
+
:url => res.effective_url,
|
|
89
|
+
:method => res.request.method.to_s.upcase,
|
|
90
|
+
:elem => Issue::Element::SERVER,
|
|
91
|
+
:response => res.body,
|
|
92
|
+
:headers => {
|
|
93
|
+
:request => res.request.headers,
|
|
94
|
+
:response => res.headers,
|
|
95
|
+
}
|
|
96
|
+
}.merge( self.class.info ) )
|
|
97
|
+
|
|
98
|
+
# register our results with the system
|
|
99
|
+
register_results( [issue] )
|
|
100
|
+
|
|
101
|
+
# inform the user that we have a match
|
|
102
|
+
print_ok( "TRACE is enabled." )
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|