arachni 1.1 → 1.2

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 (287) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +159 -0
  3. data/LICENSE.md +126 -196
  4. data/README.md +32 -24
  5. data/arachni.gemspec +7 -7
  6. data/components/checks/active/code_injection_timing.rb +3 -3
  7. data/components/checks/active/csrf.rb +2 -2
  8. data/components/checks/active/file_inclusion.rb +6 -7
  9. data/components/checks/active/os_cmd_injection.rb +3 -3
  10. data/components/checks/active/path_traversal.rb +7 -7
  11. data/components/checks/active/response_splitting.rb +9 -4
  12. data/components/checks/active/session_fixation.rb +7 -3
  13. data/components/checks/active/source_code_disclosure.rb +5 -5
  14. data/components/checks/active/unvalidated_redirect.rb +12 -3
  15. data/components/checks/active/unvalidated_redirect_dom.rb +3 -3
  16. data/components/checks/active/xss.rb +23 -10
  17. data/components/checks/active/xss_dom_inputs.rb +113 -11
  18. data/components/checks/active/xxe.rb +3 -3
  19. data/components/checks/passive/backdoors.rb +6 -5
  20. data/components/checks/passive/backup_directories.rb +6 -6
  21. data/components/checks/passive/backup_files.rb +6 -6
  22. data/components/checks/passive/common_admin_interfaces.rb +58 -0
  23. data/components/checks/passive/common_admin_interfaces/admin-panels.txt +49 -0
  24. data/components/checks/passive/common_directories/directories.txt +0 -16
  25. data/components/checks/passive/common_files.rb +6 -5
  26. data/components/checks/passive/common_files/filenames.txt +0 -2
  27. data/components/checks/passive/directory_listing.rb +6 -6
  28. data/components/checks/passive/grep/cookie_set_for_parent_domain.rb +3 -3
  29. data/components/checks/passive/grep/hsts.rb +6 -3
  30. data/components/checks/passive/grep/http_only_cookies.rb +3 -3
  31. data/components/checks/passive/grep/insecure_cookies.rb +2 -2
  32. data/components/checks/passive/grep/insecure_cors_policy.rb +6 -4
  33. data/components/checks/passive/grep/x_frame_options.rb +6 -4
  34. data/components/checks/passive/htaccess_limit.rb +6 -2
  35. data/components/checks/passive/http_put.rb +8 -4
  36. data/components/checks/passive/interesting_responses.rb +3 -2
  37. data/components/checks/passive/localstart_asp.rb +6 -2
  38. data/components/checks/passive/origin_spoof_access_restriction_bypass.rb +5 -1
  39. data/components/checks/passive/xst.rb +6 -2
  40. data/components/fingerprinters/frameworks/aspx_mvc.rb +43 -0
  41. data/components/fingerprinters/frameworks/cakephp.rb +28 -0
  42. data/components/fingerprinters/frameworks/cherrypy.rb +31 -0
  43. data/components/fingerprinters/frameworks/django.rb +33 -0
  44. data/components/fingerprinters/frameworks/jsf.rb +30 -0
  45. data/components/fingerprinters/frameworks/rack.rb +5 -7
  46. data/components/fingerprinters/frameworks/rails.rb +43 -0
  47. data/components/fingerprinters/languages/aspx.rb +11 -11
  48. data/components/fingerprinters/languages/{jsp.rb → java.rb} +11 -7
  49. data/components/fingerprinters/languages/php.rb +6 -6
  50. data/components/fingerprinters/languages/python.rb +14 -6
  51. data/components/fingerprinters/languages/ruby.rb +3 -5
  52. data/components/fingerprinters/servers/apache.rb +5 -4
  53. data/components/fingerprinters/servers/gunicorn.rb +33 -0
  54. data/components/fingerprinters/servers/jetty.rb +1 -1
  55. data/components/fingerprinters/servers/tomcat.rb +11 -4
  56. data/components/path_extractors/anchors.rb +5 -12
  57. data/components/path_extractors/areas.rb +5 -13
  58. data/components/path_extractors/comments.rb +5 -3
  59. data/components/path_extractors/data_url.rb +21 -0
  60. data/components/path_extractors/forms.rb +5 -13
  61. data/components/path_extractors/frames.rb +6 -13
  62. data/components/path_extractors/generic.rb +3 -12
  63. data/components/path_extractors/links.rb +5 -13
  64. data/components/path_extractors/meta_refresh.rb +5 -13
  65. data/components/path_extractors/scripts.rb +8 -14
  66. data/components/plugins/autologin.rb +17 -5
  67. data/components/plugins/defaults/meta/remedies/discovery.rb +11 -29
  68. data/components/plugins/login_script.rb +40 -10
  69. data/components/plugins/metrics.rb +235 -0
  70. data/components/plugins/proxy.rb +21 -4
  71. data/components/plugins/proxy/panel/page_accordion.html.erb +34 -2
  72. data/components/plugins/restrict_to_dom_state.rb +70 -0
  73. data/components/plugins/vector_feed.rb +38 -9
  74. data/components/reporters/plugin_formatters/html/metrics.rb +290 -0
  75. data/components/reporters/plugin_formatters/stdout/metrics.rb +80 -0
  76. data/components/reporters/plugin_formatters/xml/metrics.rb +29 -0
  77. data/components/reporters/stdout.rb +4 -2
  78. data/components/reporters/xml.rb +4 -4
  79. data/components/reporters/xml/schema.xsd +95 -0
  80. data/lib/arachni.rb +2 -0
  81. data/lib/arachni/browser.rb +132 -77
  82. data/lib/arachni/browser/javascript.rb +173 -45
  83. data/lib/arachni/browser/javascript/scripts/dom_monitor.js +81 -6
  84. data/lib/arachni/browser/javascript/scripts/taint_tracer.js +31 -3
  85. data/lib/arachni/browser_cluster.rb +41 -15
  86. data/lib/arachni/browser_cluster/job.rb +4 -0
  87. data/lib/arachni/browser_cluster/jobs/resource_exploration.rb +0 -9
  88. data/lib/arachni/browser_cluster/worker.rb +8 -5
  89. data/lib/arachni/check/auditor.rb +20 -8
  90. data/lib/arachni/check/base.rb +38 -6
  91. data/lib/arachni/element/base.rb +18 -1
  92. data/lib/arachni/element/capabilities/analyzable/differential.rb +0 -1
  93. data/lib/arachni/element/capabilities/analyzable/taint.rb +40 -10
  94. data/lib/arachni/element/capabilities/analyzable/timeout.rb +27 -23
  95. data/lib/arachni/element/capabilities/auditable/dom.rb +22 -0
  96. data/lib/arachni/element/capabilities/inputtable.rb +6 -2
  97. data/lib/arachni/element/capabilities/submittable.rb +1 -1
  98. data/lib/arachni/element/cookie.rb +37 -23
  99. data/lib/arachni/element/cookie/capabilities/mutable.rb +6 -6
  100. data/lib/arachni/element/cookie/dom.rb +0 -8
  101. data/lib/arachni/element/form.rb +28 -14
  102. data/lib/arachni/element/form/capabilities/auditable.rb +2 -2
  103. data/lib/arachni/element/form/capabilities/mutable.rb +5 -5
  104. data/lib/arachni/element/form/dom.rb +0 -8
  105. data/lib/arachni/element/generic_dom.rb +1 -1
  106. data/lib/arachni/element/json.rb +2 -1
  107. data/lib/arachni/element/json/capabilities/inputtable.rb +6 -6
  108. data/lib/arachni/element/json/capabilities/mutable.rb +1 -1
  109. data/lib/arachni/element/link.rb +13 -16
  110. data/lib/arachni/element/link/dom.rb +1 -14
  111. data/lib/arachni/element/link_template.rb +3 -2
  112. data/lib/arachni/element/link_template/dom.rb +0 -16
  113. data/lib/arachni/element/server.rb +51 -9
  114. data/lib/arachni/element/xml.rb +1 -0
  115. data/lib/arachni/ethon/easy.rb +4 -1
  116. data/lib/arachni/framework/parts/audit.rb +26 -77
  117. data/lib/arachni/framework/parts/browser.rb +50 -55
  118. data/lib/arachni/framework/parts/check.rb +4 -3
  119. data/lib/arachni/framework/parts/data.rb +41 -6
  120. data/lib/arachni/framework/parts/state.rb +16 -7
  121. data/lib/arachni/http/client.rb +66 -38
  122. data/lib/arachni/http/client/dynamic_404_handler.rb +46 -14
  123. data/lib/arachni/http/headers.rb +22 -10
  124. data/lib/arachni/http/proxy_server.rb +67 -22
  125. data/lib/arachni/http/proxy_server/ssl-interceptor-cacert.pem +34 -0
  126. data/lib/arachni/http/proxy_server/ssl-interceptor-cakey.pem +51 -0
  127. data/lib/arachni/http/request.rb +71 -18
  128. data/lib/arachni/issue.rb +17 -3
  129. data/lib/arachni/option_groups/browser_cluster.rb +34 -1
  130. data/lib/arachni/option_groups/http.rb +1 -1
  131. data/lib/arachni/page.rb +26 -13
  132. data/lib/arachni/page/dom/transition.rb +2 -2
  133. data/lib/arachni/parser.rb +28 -11
  134. data/lib/arachni/platform/fingerprinter.rb +5 -0
  135. data/lib/arachni/platform/manager.rb +65 -32
  136. data/lib/arachni/plugin/base.rb +8 -0
  137. data/lib/arachni/processes/instances.rb +25 -11
  138. data/lib/arachni/reporter/manager.rb +2 -2
  139. data/lib/arachni/rpc/client/instance.rb +4 -0
  140. data/lib/arachni/rpc/server/framework/master.rb +3 -3
  141. data/lib/arachni/rpc/server/framework/multi_instance.rb +0 -8
  142. data/lib/arachni/rpc/server/instance.rb +2 -1
  143. data/lib/arachni/ruby/array.rb +5 -0
  144. data/lib/arachni/ruby/hash.rb +5 -0
  145. data/lib/arachni/ruby/string.rb +2 -3
  146. data/lib/arachni/session.rb +32 -6
  147. data/lib/arachni/state/framework.rb +6 -2
  148. data/lib/arachni/support/cache.rb +1 -0
  149. data/lib/arachni/support/cache/base.rb +12 -8
  150. data/lib/arachni/support/cache/least_recently_pushed.rb +29 -0
  151. data/lib/arachni/support/cache/least_recently_used.rb +5 -8
  152. data/lib/arachni/support/cache/preference.rb +1 -1
  153. data/lib/arachni/support/cache/random_replacement.rb +1 -25
  154. data/lib/arachni/support/database/queue.rb +21 -8
  155. data/lib/arachni/support/lookup/base.rb +7 -1
  156. data/lib/arachni/support/mixins/observable.rb +3 -1
  157. data/lib/arachni/support/profiler.rb +51 -10
  158. data/lib/arachni/support/signature.rb +11 -2
  159. data/lib/arachni/trainer.rb +8 -2
  160. data/lib/arachni/uri.rb +28 -25
  161. data/lib/arachni/uri/scope.rb +1 -1
  162. data/lib/arachni/utilities.rb +8 -0
  163. data/lib/arachni/watir/element.rb +1 -1
  164. data/lib/version +1 -1
  165. data/spec/arachni/browser/javascript/dom_monitor_spec.rb +388 -53
  166. data/spec/arachni/browser/javascript/taint_tracer_spec.rb +41 -0
  167. data/spec/arachni/browser/javascript_spec.rb +235 -61
  168. data/spec/arachni/browser_cluster/jobs/resource_exploration_spec.rb +0 -9
  169. data/spec/arachni/browser_cluster_spec.rb +58 -10
  170. data/spec/arachni/browser_spec.rb +170 -26
  171. data/spec/arachni/check/auditor_spec.rb +22 -3
  172. data/spec/arachni/check/base_spec.rb +84 -0
  173. data/spec/arachni/element/body_spec.rb +1 -1
  174. data/spec/arachni/element/capabilities/analyzable/taint_spec.rb +3 -3
  175. data/spec/arachni/element/capabilities/analyzable/timeout_spec.rb +1 -1
  176. data/spec/arachni/element/cookie/dom_spec.rb +0 -9
  177. data/spec/arachni/element/cookie_spec.rb +85 -0
  178. data/spec/arachni/element/form/dom_spec.rb +0 -9
  179. data/spec/arachni/element/form_spec.rb +46 -3
  180. data/spec/arachni/element/json_spec.rb +20 -0
  181. data/spec/arachni/element/link/dom_spec.rb +0 -9
  182. data/spec/arachni/element/link_spec.rb +40 -15
  183. data/spec/arachni/element/link_template/dom_spec.rb +0 -8
  184. data/spec/arachni/element/link_template_spec.rb +2 -6
  185. data/spec/arachni/element/server_spec.rb +94 -8
  186. data/spec/arachni/element/xml_spec.rb +20 -0
  187. data/spec/arachni/framework/parts/audit_spec.rb +12 -14
  188. data/spec/arachni/framework/parts/browser_spec.rb +0 -171
  189. data/spec/arachni/framework/parts/platform_spec.rb +14 -8
  190. data/spec/arachni/framework/parts/report_spec.rb +1 -1
  191. data/spec/arachni/framework/parts/state_spec.rb +0 -9
  192. data/spec/arachni/http/client/dynamic_404_handlers_spec.rb +19 -0
  193. data/spec/arachni/http/client_spec.rb +169 -42
  194. data/spec/arachni/http/headers_spec.rb +18 -0
  195. data/spec/arachni/http/request_spec.rb +23 -0
  196. data/spec/arachni/issue_spec.rb +17 -6
  197. data/spec/arachni/page_spec.rb +22 -2
  198. data/spec/arachni/parser_spec.rb +5 -0
  199. data/spec/arachni/platform/manager_spec.rb +57 -25
  200. data/spec/arachni/reporter/manager_spec.rb +26 -0
  201. data/spec/arachni/rpc/server/active_options_spec.rb +9 -4
  202. data/spec/arachni/state/framework_spec.rb +2 -8
  203. data/spec/arachni/support/cache/least_recently_pushed_spec.rb +90 -0
  204. data/spec/arachni/support/cache/least_recently_used_spec.rb +5 -13
  205. data/spec/arachni/support/database/queue_spec.rb +7 -0
  206. data/spec/arachni/support/mixins/observable_spec.rb +15 -1
  207. data/spec/arachni/trainer_spec.rb +2 -2
  208. data/spec/components/checks/active/code_injection_timing_spec.rb +1 -1
  209. data/spec/components/checks/active/file_inclusion_spec.rb +6 -6
  210. data/spec/components/checks/active/path_traversal_spec.rb +2 -2
  211. data/spec/components/checks/active/source_code_disclosure_spec.rb +2 -2
  212. data/spec/components/checks/active/unvalidated_redirect_spec.rb +6 -6
  213. data/spec/components/checks/active/xss_dom_inputs_spec.rb +3 -5
  214. data/spec/components/checks/active/xss_dom_script_context_spec.rb +1 -1
  215. data/spec/components/checks/active/xss_spec.rb +5 -5
  216. data/spec/components/checks/passive/common_admin_interfaces_spec.rb +15 -0
  217. data/spec/components/checks/passive/interesting_responses_spec.rb +14 -1
  218. data/spec/components/fingerprinters/frameworks/aspx_mvc_spec.rb +31 -0
  219. data/spec/components/fingerprinters/frameworks/cakephp_spec.rb +22 -0
  220. data/spec/components/fingerprinters/frameworks/cherrypy_spec.rb +28 -0
  221. data/spec/components/fingerprinters/frameworks/django_spec.rb +37 -0
  222. data/spec/components/fingerprinters/frameworks/jsf_spec.rb +27 -0
  223. data/spec/components/fingerprinters/frameworks/rack_spec.rb +11 -14
  224. data/spec/components/fingerprinters/frameworks/rails_spec.rb +53 -0
  225. data/spec/components/fingerprinters/languages/asp_spec.rb +7 -9
  226. data/spec/components/fingerprinters/languages/aspx_spec.rb +10 -24
  227. data/spec/components/fingerprinters/languages/java_spec.rb +88 -0
  228. data/spec/components/fingerprinters/languages/php_spec.rb +19 -12
  229. data/spec/components/fingerprinters/languages/python_spec.rb +22 -9
  230. data/spec/components/fingerprinters/languages/ruby.rb +6 -4
  231. data/spec/components/fingerprinters/os/bsd_spec.rb +6 -4
  232. data/spec/components/fingerprinters/os/linux_spec.rb +6 -4
  233. data/spec/components/fingerprinters/os/solaris_spec.rb +6 -4
  234. data/spec/components/fingerprinters/os/unix_spec.rb +6 -4
  235. data/spec/components/fingerprinters/os/windows_spec.rb +6 -4
  236. data/spec/components/fingerprinters/servers/apache_spec.rb +15 -4
  237. data/spec/components/fingerprinters/servers/gunicorn_spec.rb +28 -0
  238. data/spec/components/fingerprinters/servers/iis_spec.rb +6 -6
  239. data/spec/components/fingerprinters/servers/jetty_spec.rb +6 -6
  240. data/spec/components/fingerprinters/servers/nginx_spec.rb +6 -4
  241. data/spec/components/fingerprinters/servers/tomcat_spec.rb +15 -6
  242. data/spec/components/path_extractors/data_url_spec.rb +19 -0
  243. data/spec/components/plugins/autologin_spec.rb +23 -0
  244. data/spec/components/plugins/login_script_spec.rb +112 -24
  245. data/spec/components/plugins/restrict_to_dom_state_spec.rb +16 -0
  246. data/spec/components/plugins/vector_feed_spec.rb +39 -1
  247. data/spec/support/factories/page/dom.rb +9 -4
  248. data/spec/support/factories/page/dom/transition.rb +31 -9
  249. data/spec/support/factories/scan_report.rb +8 -6
  250. data/spec/support/fixtures/empty/placeholder +0 -0
  251. data/spec/support/fixtures/report.afr +0 -0
  252. data/spec/support/fixtures/reporters/manager_spec/error.rb +18 -0
  253. data/spec/support/servers/arachni/browser.rb +117 -11
  254. data/spec/support/servers/arachni/browser/javascript/dom_monitor.rb +148 -4
  255. data/spec/support/servers/arachni/check/auditor.rb +4 -0
  256. data/spec/support/servers/arachni/element/cookie/cookie_dom.rb +1 -1
  257. data/spec/support/servers/arachni/http/client.rb +5 -0
  258. data/spec/support/servers/arachni/http/client/dynamic_404_handler.rb +13 -0
  259. data/spec/support/servers/checks/active/code_injection_timing.rb +1 -1
  260. data/spec/support/servers/checks/active/file_inclusion.rb +2 -2
  261. data/spec/support/servers/checks/active/path_traversal.rb +2 -2
  262. data/spec/support/servers/checks/active/source_code_disclosure.rb +40 -33
  263. data/spec/support/servers/checks/active/trainer_check.rb +9 -10
  264. data/spec/support/servers/checks/active/unvalidated_redirect_dom.rb +7 -4
  265. data/spec/support/servers/checks/active/xss.rb +35 -0
  266. data/spec/support/servers/checks/active/xss_dom.rb +1 -1
  267. data/spec/support/servers/checks/active/xss_dom_inputs.rb +24 -0
  268. data/spec/support/servers/checks/active/xss_dom_script_context.rb +1 -1
  269. data/spec/support/servers/checks/passive/common_admin_interfaces.rb +6 -0
  270. data/spec/support/servers/plugins/autologin.rb +9 -0
  271. data/spec/support/servers/plugins/restrict_to_dom_state.rb +4 -0
  272. data/spec/support/shared/element/base.rb +42 -0
  273. data/spec/support/shared/element/capabilities/auditable.rb +4 -4
  274. data/spec/support/shared/element/capabilities/auditable/dom.rb +26 -0
  275. data/spec/support/shared/element/capabilities/inputtable.rb +16 -11
  276. data/spec/support/shared/element/capabilities/submitable.rb +7 -2
  277. data/spec/support/shared/fingerprinter.rb +8 -0
  278. data/spec/support/shared/path_extractor.rb +1 -1
  279. data/ui/cli/framework.rb +3 -3
  280. data/ui/cli/framework/option_parser.rb +9 -0
  281. data/ui/cli/output.rb +9 -0
  282. data/ui/cli/reporter.rb +5 -2
  283. data/ui/cli/utilities.rb +4 -2
  284. metadata +76 -17
  285. data/lib/arachni/http/proxy_server/ssl-interceptor-cert.pem +0 -34
  286. data/lib/arachni/http/proxy_server/ssl-interceptor-pkey.pem +0 -51
  287. data/spec/components/fingerprinters/languages/jsp_spec.rb +0 -56
@@ -12,7 +12,7 @@
12
12
  # header field to determine whether the attack was successful.
13
13
  #
14
14
  # @author Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>
15
- # @version 0.2.2
15
+ # @version 0.2.3
16
16
  #
17
17
  # @see https://www.owasp.org/index.php/Top_10_2010-A10-Unvalidated_Redirects_and_Forwards
18
18
  class Arachni::Checks::UnvalidatedRedirect < Arachni::Check::Base
@@ -32,8 +32,17 @@ class Arachni::Checks::UnvalidatedRedirect < Arachni::Check::Base
32
32
  self.class.payload? url
33
33
  end
34
34
 
35
+ def self.options
36
+ @options ||= {
37
+ format: [ Format::STRAIGHT ],
38
+ submit: {
39
+ follow_location: false
40
+ }
41
+ }
42
+ end
43
+
35
44
  def run
36
- audit( self.class.payloads, submit: { follow_location: false } ) do |response, element|
45
+ audit( self.class.payloads, self.class.options ) do |response, element|
37
46
  # If this was a sample/default value submission ignore it, we only
38
47
  # care about our payloads.
39
48
  next if !payload? element.seed
@@ -68,7 +77,7 @@ URL to determine whether the attack was successful.
68
77
  },
69
78
  elements: ELEMENTS_WITH_INPUTS - [Element::LinkTemplate],
70
79
  author: 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>',
71
- version: '0.2.2',
80
+ version: '0.2.3',
72
81
 
73
82
  issue: {
74
83
  name: %q{Unvalidated redirect},
@@ -9,7 +9,7 @@
9
9
  # Unvalidated redirect DOM check.
10
10
  #
11
11
  # @author Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>
12
- # @version 0.1
12
+ # @version 0.1.1
13
13
  #
14
14
  # @see https://www.owasp.org/index.php/Top_10_2010-A10-Unvalidated_Redirects_and_Forwards
15
15
  class Arachni::Checks::UnvalidatedRedirectDOM < Arachni::Check::Base
@@ -56,7 +56,7 @@ Injects URLs and checks the browser URL to determine whether the attack was succ
56
56
  },
57
57
  elements: DOM_ELEMENTS_WITH_INPUTS - [Element::LinkTemplate::DOM],
58
58
  author: 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>',
59
- version: '0.1',
59
+ version: '0.1.1',
60
60
 
61
61
  issue: {
62
62
  name: %q{Unvalidated DOM redirect},
@@ -81,7 +81,7 @@ to redirecting the client to the injected value.
81
81
  },
82
82
  tags: %w(unvalidated redirect dom injection),
83
83
  cwe: 819,
84
- severity: Severity::MEDIUM,
84
+ severity: Severity::HIGH,
85
85
  remedy_guidance: %q{
86
86
  The application should ensure that the supplied value for a redirect is permitted.
87
87
  This can be achieved by performing whitelisting on the parameter value.
@@ -13,7 +13,7 @@
13
13
  # {BrowserCluster} for evaluation and {#trace_taint taint-tracing}.
14
14
  #
15
15
  # @author Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>
16
- # @version 0.4.1
16
+ # @version 0.4.4
17
17
  #
18
18
  # @see http://cwe.mitre.org/data/definitions/79.html
19
19
  # @see http://ha.ckers.org/xss.html
@@ -36,9 +36,9 @@ class Arachni::Checks::Xss < Arachni::Check::Base
36
36
  # Go for an error.
37
37
  "()\"&%1'-;#{tag}'",
38
38
 
39
- # Break out of HTML comments.
40
- "-->#{tag}<!--"
41
- ]
39
+ # Break out of HTML comments and text areas.
40
+ "</textarea>-->#{tag}<!--<textarea>"
41
+ ].map{ |p| [p, Form.encode( p ) ]}.flatten.uniq
42
42
  end
43
43
 
44
44
  def self.options
@@ -67,6 +67,9 @@ class Arachni::Checks::Xss < Arachni::Check::Base
67
67
  return
68
68
  end
69
69
 
70
+ # No idea what was returned, but we can't work with it.
71
+ return if !response.to_page.has_script?
72
+
70
73
  with_browser_cluster do
71
74
  print_info 'Progressing to deferred browser evaluation of response.'
72
75
 
@@ -82,9 +85,19 @@ class Arachni::Checks::Xss < Arachni::Check::Base
82
85
  end
83
86
 
84
87
  def find_proof( resource )
85
- proof = Nokogiri::HTML( resource.body ).css( self.class.tag_name )
86
- return if proof.empty?
87
- proof.to_s
88
+ proof_nodes = Nokogiri::HTML( resource.body ).css( self.class.tag_name )
89
+ return if proof_nodes.empty?
90
+
91
+ proof = nil
92
+ proof_nodes.each do |e|
93
+ # Text-areas have TEXT not nodes Nokogiri!
94
+ next if e.parent.name =='textarea'
95
+ proof = e.to_s
96
+ end
97
+
98
+ return if !proof
99
+
100
+ proof
88
101
  end
89
102
 
90
103
  def self.info
@@ -97,7 +110,7 @@ tainted responses to look for proof of vulnerability.
97
110
  elements: [Element::Form, Element::Link, Element::Cookie,
98
111
  Element::Header, Element::LinkTemplate],
99
112
  author: 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com> ',
100
- version: '0.4.1',
113
+ version: '0.4.4',
101
114
 
102
115
  issue: {
103
116
  name: %q{Cross-Site Scripting (XSS)},
@@ -121,8 +134,8 @@ HTML element content.
121
134
  references: {
122
135
  'ha.ckers' => 'http://ha.ckers.org/xss.html',
123
136
  'Secunia' => 'http://secunia.com/advisories/9716/',
124
- 'WASC' => 'http://projects.webappsec.org/w/page/13246920/Cross%20Site%20Scripting',
125
- 'OWASP' => 'https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet'
137
+ 'WASC' => 'http://projects.webappsec.org/w/page/13246920/Cross%20Site%20Scripting',
138
+ 'OWASP' => 'https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet'
126
139
  },
127
140
  tags: %w(xss regexp injection script),
128
141
  cwe: 79,
@@ -7,7 +7,7 @@
7
7
  =end
8
8
 
9
9
  # @author Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>
10
- # @version 0.1.1
10
+ # @version 0.2
11
11
  class Arachni::Checks::XssDomInputs < Arachni::Check::Base
12
12
 
13
13
  INPUTS = Set.new([:input, :textarea])
@@ -23,38 +23,132 @@ class Arachni::Checks::XssDomInputs < Arachni::Check::Base
23
23
  end
24
24
 
25
25
  def run
26
- # If the page doesn't contain any supported inputs don't bother.
27
- return if !page.document ||
28
- !INPUTS.find { |type| page.document.css( type.to_s ).any? }
26
+ return if !page.document
29
27
 
28
+ # Everything past this point requires inputs to be present.
29
+ return if !page.has_elements?( INPUTS.to_a )
30
+
31
+ # Fill in inputs and trigger their associated events.
32
+ trigger_inputs
33
+
34
+ return if !page.has_elements?( :button )
35
+
36
+ # Fill in inputs and hit buttons.
37
+ trigger_buttons
38
+ end
39
+
40
+ def trigger_inputs
30
41
  with_browser do |browser|
31
42
  browser.load( page ).each_element_with_events do |locator, events|
32
- next if !INPUTS.include? locator.tag_name
33
- events.each do |event, _|
43
+
44
+ locator_id = "#{page.url}:#{locator.css}"
45
+ next if !INPUTS.include?( locator.tag_name ) || audited?( locator_id )
46
+ audited locator_id
47
+
48
+ filter_events( locator.tag_name, events ).each do |event, _|
49
+
50
+ print_status "Scheduling '#{event}' on '#{locator}'"
34
51
 
35
52
  # Instead of working with the same browser we do it this way
36
53
  # in order to distribute the workload via the browser cluster.
37
54
  with_browser do |b|
38
- b.javascript.taint = self.tag
55
+ print_status "Triggering '#{event}' on '#{locator}'"
56
+
57
+ b.javascript.taint = self.tag_name
39
58
  b.load page
40
59
 
41
60
  transition = b.fire_event( locator, event, value: self.tag )
42
- next if !transition
61
+ if !transition
62
+ print_bad "Could not '#{event}' on '#{locator}'"
63
+ next
64
+ end
43
65
 
44
66
  # Page may be out of scope, some sort of JS redirection.
45
- next if !(p = b.to_page)
67
+ if !(p = b.to_page)
68
+ print_bad "Could not capture page snapshot after '#{event}' on '#{locator}'"
69
+ end
46
70
 
47
71
  p.dom.transitions << transition
48
72
 
49
- check_and_log p
73
+ check_and_log( p )
74
+
75
+ print_status "Finished '#{event}' on '#{locator}'"
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ def trigger_buttons
83
+ with_browser do |browser|
84
+ browser.load( page ).each_element_with_events do |locator, events|
85
+
86
+ locator_id = "#{page.url}:#{locator.css}"
87
+ next if locator.tag_name != :button || audited?( locator_id )
88
+ audited locator_id
89
+
90
+ events.each do |event, _|
91
+ print_status "Scheduling '#{event}' on '#{locator}' after filling in inputs"
92
+
93
+ with_browser do |b|
94
+ print_status "Triggering '#{event}' on '#{locator}' after filling in inputs"
95
+
96
+ b.javascript.taint = self.tag_name
97
+ b.load page
98
+
99
+ transitions = fill_in_inputs( b )
100
+ if transitions.empty?
101
+ print_bad "Could not fill in any inputs for '#{event}' on '#{locator}'"
102
+ next
103
+ end
104
+
105
+ transition = b.fire_event( locator, event )
106
+ if !transition
107
+ print_bad "Could not '#{event}' on '#{locator}'"
108
+ next
109
+ end
110
+
111
+ transitions << transition
112
+
113
+ # Page may be out of scope, some sort of JS redirection.
114
+ if !(p = b.to_page)
115
+ print_bad "Could not capture page snapshot after '#{event}' on '#{locator}'"
116
+ end
117
+
118
+ transitions.each do |t|
119
+ p.dom.transitions << t
120
+ end
121
+
122
+ check_and_log( p )
123
+
124
+ print_status "Finished '#{event}' on '#{locator}' after filling in inputs"
50
125
  end
51
126
  end
52
127
  end
53
128
  end
54
129
  end
55
130
 
131
+ def fill_in_inputs( browser )
132
+ transitions = []
133
+
134
+ INPUTS.each do |tag|
135
+ browser.watir.send("#{tag}s").each do |locator|
136
+ print_status "Filling in '#{locator.opening_tag}'"
137
+
138
+ transitions << fill_in_input( browser, locator )
139
+ end
140
+ end
141
+
142
+ transitions.compact
143
+ end
144
+
145
+ def fill_in_input( browser, locator )
146
+ browser.fire_event( locator, :input, value: self.tag )
147
+ end
148
+
56
149
  def check_and_log( page )
57
150
  return if !(proof = find_proof( page ))
151
+
58
152
  log(
59
153
  vector: Element::GenericDOM.new(
60
154
  url: page.url,
@@ -66,11 +160,19 @@ class Arachni::Checks::XssDomInputs < Arachni::Check::Base
66
160
  end
67
161
 
68
162
  def find_proof( page )
163
+ return if !page.has_elements?( self.tag_name )
164
+
69
165
  proof = page.document.css( self.tag_name )
70
166
  return if proof.empty?
167
+
71
168
  proof.to_s
72
169
  end
73
170
 
171
+ def filter_events( element, events )
172
+ supported = Set.new( Arachni::Browser::Javascript.events_for( element ) )
173
+ events.reject { |name, _| !supported.include? ('on' + name.to_s.gsub( /^on/, '' )).to_sym }
174
+ end
175
+
74
176
  def self.info
75
177
  {
76
178
  name: 'DOM XSS via input field',
@@ -79,7 +181,7 @@ Injects an HTML element into page text fields, triggers their associated events
79
181
  and inspects the DOM for proof of vulnerability.
80
182
  },
81
183
  author: 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>',
82
- version: '0.1.1',
184
+ version: '0.2',
83
185
  elements: [Element::GenericDOM],
84
186
 
85
187
  issue: {
@@ -7,7 +7,7 @@
7
7
  =end
8
8
 
9
9
  # @author Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>
10
- # @version 0.1
10
+ # @version 0.1.1
11
11
  class Arachni::Checks::Xxe < Arachni::Check::Base
12
12
 
13
13
  ENTITY = 'xxe_entity'
@@ -18,7 +18,7 @@ class Arachni::Checks::Xxe < Arachni::Check::Base
18
18
  regexp: {
19
19
  unix: [
20
20
  /DOCUMENT_ROOT.*HTTP_USER_AGENT/,
21
- /(root|mail):.+:\d+:\d+:.+:[0-9a-zA-Z\/]+/im
21
+ /:.+:\d+:\d+:.+:[0-9a-zA-Z\/]+/im
22
22
  ],
23
23
  windows: [
24
24
  /\[boot loader\].*\[operating systems\]/im,
@@ -74,7 +74,7 @@ processed based on the resulting HTTP response.
74
74
  },
75
75
  elements: [Element::XML],
76
76
  author: 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>',
77
- version: '0.1',
77
+ version: '0.1.1',
78
78
  platforms: options[:regexp].keys,
79
79
 
80
80
  issue: {
@@ -25,11 +25,12 @@ class Arachni::Checks::Backdoors < Arachni::Check::Base
25
25
 
26
26
  def self.info
27
27
  {
28
- name: 'Backdoors',
29
- description: %q{Tries to find common backdoors on the server.},
30
- elements: [Element::Server],
31
- author: 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com> ',
32
- version: '0.2.3',
28
+ name: 'Backdoors',
29
+ description: %q{Tries to find common backdoors on the server.},
30
+ elements: [Element::Server],
31
+ author: 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com> ',
32
+ version: '0.2.4',
33
+ exempt_platforms: [ :ruby, :aspx_mvc, :django, :cakephp ],
33
34
 
34
35
  issue: {
35
36
  name: %q{A backdoor file exists on the server},
@@ -7,7 +7,6 @@
7
7
  =end
8
8
 
9
9
  # @author Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>
10
- # @version 0.1
11
10
  class Arachni::Checks::BackupDirectories < Arachni::Check::Base
12
11
 
13
12
  def self.formats
@@ -35,11 +34,12 @@ class Arachni::Checks::BackupDirectories < Arachni::Check::Base
35
34
 
36
35
  def self.info
37
36
  {
38
- name: 'Backup directories',
39
- description: %q{Tries to find backed-up directories.},
40
- elements: [ Element::Server ],
41
- author: 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com> ',
42
- version: '0.1',
37
+ name: 'Backup directories',
38
+ description: %q{Tries to find backed-up directories.},
39
+ elements: [ Element::Server ],
40
+ author: 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com> ',
41
+ version: '0.1.1',
42
+ exempt_platforms: Arachni::Platform::Manager::FRAMEWORKS,
43
43
 
44
44
  issue: {
45
45
  name: %q{Backup directory},
@@ -9,7 +9,6 @@
9
9
  # Backup file discovery check.
10
10
  #
11
11
  # @author Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>
12
- # @version 0.3
13
12
  class Arachni::Checks::BackupFiles < Arachni::Check::Base
14
13
 
15
14
  def self.formats
@@ -47,11 +46,12 @@ class Arachni::Checks::BackupFiles < Arachni::Check::Base
47
46
 
48
47
  def self.info
49
48
  {
50
- name: 'Backup files',
51
- description: %q{Tries to identify backup files.},
52
- elements: [ Element::Server ],
53
- author: 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com> ',
54
- version: '0.3',
49
+ name: 'Backup files',
50
+ description: %q{Tries to identify backup files.},
51
+ elements: [ Element::Server ],
52
+ author: 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com> ',
53
+ version: '0.3.1',
54
+ exempt_platforms: Arachni::Platform::Manager::FRAMEWORKS,
55
55
 
56
56
  issue: {
57
57
  name: %q{Backup file},
@@ -0,0 +1,58 @@
1
+ =begin
2
+ Copyright 2010-2015 Tasos Laskos <tasos.laskos@arachni-scanner.com>
3
+
4
+ This file is part of the Arachni Framework project and is subject to
5
+ redistribution and commercial restrictions. Please see the Arachni Framework
6
+ web site for more information on licensing and terms of use.
7
+ =end
8
+
9
+ # Looks for common administration interfaces on the server.
10
+ #
11
+ # @author Brendan Coles <bcoles@gmail.com>
12
+ # @author Tasos Laskos <tasos.laskos@arachni-scanner.com>
13
+ # @version 0.1
14
+ class Arachni::Checks::CommonAdminInterfaces < Arachni::Check::Base
15
+
16
+ def self.resources
17
+ @filenames ||= read_file( 'admin-panels.txt' )
18
+ end
19
+
20
+ def run
21
+ path = get_path( page.url )
22
+ return if audited?( path )
23
+
24
+ self.class.resources.each do |file|
25
+ log_remote_file_if_exists( path + file )
26
+ end
27
+
28
+ audited( path )
29
+ end
30
+
31
+ def self.info
32
+ {
33
+ name: 'Common administration interfaces',
34
+ description: %q{Tries to find common admin interfaces on the server.},
35
+ elements: [ Element::Server ],
36
+ author: [
37
+ 'Brendan Coles <bcoles@gmail.com>',
38
+ 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>'
39
+ ],
40
+ version: '0.1',
41
+ targets: %w(Generic),
42
+ references: {
43
+ 'Apache.org' => 'http://httpd.apache.org/docs/2.0/mod/mod_access.html',
44
+ 'WASC' => 'http://projects.webappsec.org/w/page/13246953/Predictable%20Resource%20Location'
45
+ },
46
+ issue: {
47
+ name: %q{Common administration interface},
48
+ description: %q{An administration interface was identified and should be reviewed.},
49
+ tags: %w(common path file discovery),
50
+ severity: Severity::LOW,
51
+ remedy_guidance: %q{
52
+ Access to administration interfaces should be restricted to trusted IP addresses only.
53
+ }
54
+ }
55
+ }
56
+ end
57
+
58
+ end