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,99 @@
1
+ =begin
2
+ Arachni
3
+ Copyright (c) 2010-2011 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
4
+
5
+ This is free software; you can copy and distribute and modify
6
+ this program under the term of the GPL v2.0 License
7
+ (See LICENSE file for details)
8
+
9
+ =end
10
+
11
+ module Arachni
12
+ module Plugins
13
+
14
+ #
15
+ #
16
+ # @author: Tasos "Zapotek" Laskos
17
+ # <tasos.laskos@gmail.com>
18
+ # <zapotek@segfault.gr>
19
+ # @version: 0.1
20
+ #
21
+ class CookieCollector < Arachni::Plugin::Base
22
+
23
+ #
24
+ # @param [Arachni::Framework] framework
25
+ # @param [Hash] options options passed to the plugin
26
+ #
27
+ def initialize( framework, options )
28
+ super( framework, options )
29
+ end
30
+
31
+ def prepare
32
+ @cookies = []
33
+ end
34
+
35
+ def run( )
36
+ @framework.http.on_complete {
37
+ |res|
38
+ update( extract_cookies( res ), res )
39
+ }
40
+ end
41
+
42
+ def update( cookies, res )
43
+ return if cookies.empty? || !update?( cookies )
44
+
45
+ @cookies << {
46
+ :time => Time.now,
47
+ :res => res.to_hash,
48
+ :cookies => cookies
49
+ }
50
+ end
51
+
52
+ def update?( cookies )
53
+ return true if @cookies.empty?
54
+
55
+ cookies.each_pair {
56
+ |k, v|
57
+ return true if @cookies.last[:cookies][k] != v
58
+ }
59
+
60
+ return false
61
+ end
62
+
63
+ def extract_cookies( res )
64
+ cookies = {}
65
+
66
+ Arachni::Parser.new( @framework.opts, res ).run.cookies.each {
67
+ |cookie|
68
+ cookies.merge!( cookie.simple )
69
+ }
70
+
71
+ return cookies
72
+ end
73
+
74
+ def clean_up
75
+ while( @framework.running? )
76
+ ::IO.select( nil, nil, nil, 1 )
77
+ end
78
+
79
+ register_results( @cookies )
80
+ end
81
+
82
+
83
+ def self.info
84
+ {
85
+ :name => 'Cookie collector',
86
+ :description => %q{Monitors and collects cookies while establishing a timeline of changes.
87
+
88
+ WARNING: Highly discouraged when the audit includes cookies.
89
+ It will log thousands of results leading to a huge report,
90
+ highly increased memory and CPU usage.},
91
+ :author => 'Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>',
92
+ :version => '0.1',
93
+ }
94
+ end
95
+
96
+ end
97
+
98
+ end
99
+ end
@@ -0,0 +1,185 @@
1
+ =begin
2
+ Arachni
3
+ Copyright (c) 2010-2011 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
4
+
5
+ This is free software; you can copy and distribute and modify
6
+ this program under the term of the GPL v2.0 License
7
+ (See LICENSE file for details)
8
+
9
+ =end
10
+
11
+ module Arachni
12
+ module Plugins
13
+
14
+ #
15
+ # @author: Tasos "Zapotek" Laskos
16
+ # <tasos.laskos@gmail.com>
17
+ # <zapotek@segfault.gr>
18
+ # @version: 0.1
19
+ #
20
+ class FormDicattack < Arachni::Plugin::Base
21
+
22
+ attr_accessor :http
23
+
24
+ #
25
+ # @param [Arachni::Framework] framework
26
+ # @param [Hash] options options passed to the plugin
27
+ #
28
+ def initialize( framework, options )
29
+ @framework = framework
30
+ @options = options
31
+
32
+ # disable spidering and the subsequent audit
33
+ # @framework.opts.link_count_limit = 0
34
+
35
+ # don't scan the website just yet
36
+ @framework.pause!
37
+ print_info( "System paused." )
38
+ end
39
+
40
+ def prepare
41
+ @url = @framework.opts.url.to_s
42
+ @users = File.read( @options['username_list'] ).split( "\n" )
43
+ @passwds = File.read( @options['password_list'] ).split( "\n" )
44
+ @user_field = @options['username_field']
45
+ @passwd_field = @options['password_field']
46
+ @verifier = Regexp.new( @options['login_verifier'] )
47
+
48
+ # we need to declare this in order to pass ourselves
49
+ # as the auditor to the form later in order to submit it.
50
+ @http = @framework.http
51
+
52
+ @found = false
53
+ end
54
+
55
+ def run( )
56
+
57
+ if !form = login_form
58
+ print_error( 'Could not find a form suiting the provided params at: ' +
59
+ @url )
60
+ return
61
+ end
62
+
63
+ name = form.raw['attrs']['name'] ? form.raw['attrs']['name'] : '<n/a>'
64
+ print_status( "Found log-in form with name: " + name )
65
+
66
+ print_status( "Building the request queue..." )
67
+
68
+ total_req = @users.size * @passwds.size
69
+ print_status( "Number of requests to be transmitted: #{total_req}" )
70
+
71
+ # register us as the auditor
72
+ form.auditor( self )
73
+ @users.each {
74
+ |user|
75
+ @passwds.each {
76
+ |pass|
77
+
78
+ params = {
79
+ @user_field => user,
80
+ @passwd_field => pass
81
+ }
82
+
83
+ # merge the input fields of the form with our own params
84
+ form.auditable.merge!( params.dup )
85
+
86
+ # we need a clean cookie slate for each request
87
+ opts = {
88
+ :headers => {
89
+ 'cookie' => ''
90
+ }
91
+ }
92
+ form.submit( opts ).on_complete {
93
+ |res|
94
+
95
+ next if @found
96
+
97
+ print_status( "#{@user_field}: '#{res.request.params[@user_field]}'" +
98
+ " -- #{@passwd_field}: '#{res.request.params[@passwd_field]}'" )
99
+
100
+ next if !res.body.match( @verifier )
101
+
102
+ @found = true
103
+
104
+ print_ok( "Found a match. #{@user_field}: '#{res.request.params[@user_field]}'" +
105
+ " -- #{@passwd_field}: '#{res.request.params[@passwd_field]}'" )
106
+
107
+ # register our findings...
108
+ register_results( { :username => user, :password => pass } )
109
+ clean_up( )
110
+
111
+ raise "Stopping the attack."
112
+ }
113
+
114
+ }
115
+ }
116
+
117
+ print_status( "Waiting for the requests to complete..." )
118
+ @http.run
119
+ print_error( "Couldn't find a match." )
120
+
121
+ end
122
+
123
+ def clean_up
124
+ # abort the rest of the queued requests
125
+ @http.abort
126
+
127
+ # continue with the scan
128
+ @framework.resume!
129
+ end
130
+
131
+ def login_form
132
+ # grab the page containing the login form
133
+ res = @http.get( @url, :async => false ).response
134
+
135
+ # parse the response as a Page object
136
+ page = Arachni::Parser.new( @framework.opts, res ).run
137
+
138
+ # find the login form
139
+ form = nil
140
+ page.forms.each {
141
+ |cform|
142
+ form = cform if login_form?( cform )
143
+ }
144
+
145
+ return form
146
+ end
147
+
148
+
149
+ def login_form?( form )
150
+ avail = form.auditable.keys
151
+ provided = [ @user_field, @passwd_field ]
152
+
153
+ provided.each {
154
+ |name|
155
+ return false if !avail.include?( name )
156
+ }
157
+
158
+ return true
159
+ end
160
+
161
+
162
+ def self.info
163
+ {
164
+ :name => 'Form dictionary attacker',
165
+ :description => %q{Uses wordlists to crack login forms.
166
+ If the cracking process is successful the found credentials will be set
167
+ framework-wide and used for the duration of the audit.
168
+ If that's not what you want set the crawler's link-count limit to "0".},
169
+ :author => 'Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>',
170
+ :version => '0.1',
171
+ :options => [
172
+ Arachni::OptPath.new( 'username_list', [ true, 'File with a list of usernames (newline separated).' ] ),
173
+ Arachni::OptPath.new( 'password_list', [ true, 'File with a list of passwords (newline separated).' ] ),
174
+ Arachni::OptString.new( 'username_field', [ true, 'The name of the username form field.'] ),
175
+ Arachni::OptString.new( 'password_field', [ true, 'The name of the password form field.'] ),
176
+ Arachni::OptString.new( 'login_verifier', [ true, 'A string that will be used to verify a successful login.
177
+ For example, if a logout link only appears when a user is logged in then it can be a perfect choice.'] ),
178
+ ]
179
+ }
180
+ end
181
+
182
+ end
183
+
184
+ end
185
+ end
@@ -0,0 +1,94 @@
1
+ =begin
2
+ Arachni
3
+ Copyright (c) 2010-2011 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
4
+
5
+ This is free software; you can copy and distribute and modify
6
+ this program under the term of the GPL v2.0 License
7
+ (See LICENSE file for details)
8
+
9
+ =end
10
+
11
+ module Arachni
12
+ module Plugins
13
+
14
+ #
15
+ # Generates a simple list of safe/unsafe URLs.
16
+ #
17
+ # @author: Tasos "Zapotek" Laskos
18
+ # <tasos.laskos@gmail.com>
19
+ # <zapotek@segfault.gr>
20
+ # @version: 0.1
21
+ #
22
+ class HealthMap < Arachni::Plugin::Base
23
+
24
+ include Arachni::Module::Utilities
25
+
26
+ #
27
+ # @param [Arachni::Framework] framework
28
+ # @param [Hash] options options passed to the plugin
29
+ #
30
+ def initialize( framework, options )
31
+ @framework = framework
32
+ @options = options
33
+ end
34
+
35
+ def prepare
36
+ while( @framework.running? )
37
+ ::IO.select( nil, nil, nil, 1 )
38
+ end
39
+
40
+ @audit_store = @framework.audit_store( true )
41
+ end
42
+
43
+ def run( )
44
+
45
+ sitemap = @audit_store.sitemap.map{ |url| normalize( url ) }.uniq
46
+ sitemap |= issue_urls = @audit_store.issues.map { |issue| issue.url }.uniq
47
+
48
+ return if sitemap.size == 0
49
+
50
+ issue = 0
51
+ map = []
52
+ sitemap.each {
53
+ |url|
54
+
55
+ next if !url
56
+
57
+ if issue_urls.include?( url )
58
+ map << { :unsafe => url }
59
+ issue += 1
60
+ else
61
+ map << { :safe => url }
62
+ end
63
+ }
64
+
65
+ register_results( {
66
+ :map => map,
67
+ :total => map.size,
68
+ :safe => map.size - issue,
69
+ :unsafe => issue,
70
+ :issue_percentage => ( ( Float( issue ) / map.size ) * 100 ).round
71
+ } )
72
+
73
+ end
74
+
75
+ def normalize( url )
76
+ query = URI( normalize_url( url ) ).query
77
+ return url if !query
78
+
79
+ url.gsub( '?' + query, '' )
80
+ end
81
+
82
+ def self.info
83
+ {
84
+ :name => 'Health map',
85
+ :description => %q{Generates a simple list of safe/unsafe URLs.},
86
+ :author => 'Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>',
87
+ :version => '0.1',
88
+ }
89
+ end
90
+
91
+ end
92
+
93
+ end
94
+ end
@@ -0,0 +1,133 @@
1
+ =begin
2
+ Arachni
3
+ Copyright (c) 2010-2011 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
4
+
5
+ This is free software; you can copy and distribute and modify
6
+ this program under the term of the GPL v2.0 License
7
+ (See LICENSE file for details)
8
+
9
+ =end
10
+
11
+ module Arachni
12
+ module Plugins
13
+
14
+ #
15
+ # @author: Tasos "Zapotek" Laskos
16
+ # <tasos.laskos@gmail.com>
17
+ # <zapotek@segfault.gr>
18
+ # @version: 0.1
19
+ #
20
+ class HTTPDicattack < Arachni::Plugin::Base
21
+
22
+ #
23
+ # @param [Arachni::Framework] framework
24
+ # @param [Hash] options options passed to the plugin
25
+ #
26
+ def initialize( framework, options )
27
+ @framework = framework
28
+ @options = options
29
+
30
+ # disable spidering and the subsequent audit
31
+ # @framework.opts.link_count_limit = 0
32
+
33
+ # don't scan the website just yet
34
+ @framework.pause!
35
+ print_info( "System paused." )
36
+ end
37
+
38
+ def prepare
39
+ @url = @framework.opts.url.to_s
40
+ @users = File.read( @options['username_list'] ).split( "\n" )
41
+ @passwds = File.read( @options['password_list'] ).split( "\n" )
42
+
43
+ @found = false
44
+ end
45
+
46
+ def run( )
47
+
48
+ if !protected?( @url )
49
+ print_info( "The URL you provided doesn't seem to be protected." )
50
+ print_info( "Aborting..." )
51
+ return
52
+ end
53
+
54
+ url = URI( @url )
55
+
56
+ print_status( "Building the request queue..." )
57
+
58
+ total_req = @users.size * @passwds.size
59
+ print_status( "Number of requests to be transmitted: #{total_req}" )
60
+
61
+ @users.each {
62
+ |user|
63
+
64
+ url.user = user
65
+ @passwds.each {
66
+ |pass|
67
+
68
+ url.password = pass
69
+ @framework.http.get( url.to_s ).on_complete {
70
+ |res|
71
+
72
+ next if @found
73
+
74
+ print_status( "Username: '#{user}' -- Password: '#{pass}'" )
75
+ next if res.code != 200
76
+
77
+ @found = true
78
+
79
+ print_ok( "Found a match. Username: '#{user}' -- Password: '#{pass}'" )
80
+ print_info( "URL: #{res.effective_url}" )
81
+
82
+ @framework.opts.url = res.effective_url
83
+
84
+ # register our findings...
85
+ register_results( { :username => user, :password => pass } )
86
+ clean_up
87
+
88
+ raise "Stopping the attack."
89
+
90
+ }
91
+
92
+ }
93
+ }
94
+
95
+ print_status( "Waiting for the requests to complete..." )
96
+ @framework.http.run
97
+ print_error( "Couldn't find a match." )
98
+
99
+ end
100
+
101
+ def clean_up
102
+ # abort the rest of the queued requests
103
+ @framework.http.abort
104
+
105
+ # continue with the scan
106
+ @framework.resume!
107
+ end
108
+
109
+
110
+ def protected?( url )
111
+ @framework.http.get( url, :async => false ).response.code == 401
112
+ end
113
+
114
+ def self.info
115
+ {
116
+ :name => 'HTTP dictionary attacker',
117
+ :description => %q{Uses wordlists to crack password protected directories.
118
+ If the cracking process is successful the found credentials will be set
119
+ framework-wide and used for the duration of the audit.
120
+ If that's not what you want set the crawler's link-count limit to "0".},
121
+ :author => 'Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>',
122
+ :version => '0.1',
123
+ :options => [
124
+ Arachni::OptPath.new( 'username_list', [ true, 'File with a list of usernames (newline separated).' ] ),
125
+ Arachni::OptPath.new( 'password_list', [ true, 'File with a list of passwords (newline separated).' ] )
126
+ ]
127
+ }
128
+ end
129
+
130
+ end
131
+
132
+ end
133
+ end