cms_scanner 0.0.41.10 → 0.0.42.0

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 (78) hide show
  1. checksums.yaml +4 -4
  2. data/app/app.rb +23 -4
  3. data/app/controllers/core.rb +8 -6
  4. data/app/controllers/core/cli_options.rb +2 -0
  5. data/app/controllers/interesting_findings.rb +2 -0
  6. data/app/finders/interesting_findings.rb +2 -0
  7. data/app/finders/interesting_findings/fantastico_fileslist.rb +6 -8
  8. data/app/finders/interesting_findings/headers.rb +3 -1
  9. data/app/finders/interesting_findings/robots_txt.rb +5 -7
  10. data/app/finders/interesting_findings/search_replace_db_2.rb +8 -10
  11. data/app/finders/interesting_findings/xml_rpc.rb +8 -6
  12. data/app/formatters/cli.rb +2 -0
  13. data/app/formatters/cli_no_color.rb +2 -0
  14. data/app/formatters/cli_no_colour.rb +2 -0
  15. data/app/formatters/json.rb +2 -0
  16. data/app/models/fantastico_fileslist.rb +16 -12
  17. data/app/models/headers.rb +29 -25
  18. data/app/models/interesting_finding.rb +44 -40
  19. data/app/models/robots_txt.rb +18 -14
  20. data/app/models/user.rb +25 -21
  21. data/app/models/version.rb +45 -41
  22. data/app/models/xml_rpc.rb +58 -54
  23. data/lib/cms_scanner.rb +5 -85
  24. data/lib/cms_scanner/browser.rb +2 -0
  25. data/lib/cms_scanner/browser/actions.rb +13 -13
  26. data/lib/cms_scanner/browser/options.rb +2 -0
  27. data/lib/cms_scanner/cache/file_store.rb +2 -0
  28. data/lib/cms_scanner/cache/typhoeus.rb +2 -0
  29. data/lib/cms_scanner/controller.rb +2 -0
  30. data/lib/cms_scanner/controllers.rb +3 -1
  31. data/lib/cms_scanner/errors.rb +11 -0
  32. data/lib/cms_scanner/errors/http.rb +52 -51
  33. data/lib/cms_scanner/errors/scan.rb +10 -6
  34. data/lib/cms_scanner/exit_code.rb +2 -0
  35. data/lib/cms_scanner/finders.rb +2 -0
  36. data/lib/cms_scanner/finders/base_finders.rb +2 -0
  37. data/lib/cms_scanner/finders/finder.rb +3 -1
  38. data/lib/cms_scanner/finders/finder/breadth_first_dictionary_attack.rb +3 -1
  39. data/lib/cms_scanner/finders/finder/enumerator.rb +44 -15
  40. data/lib/cms_scanner/finders/finder/fingerprinter.rb +9 -21
  41. data/lib/cms_scanner/finders/finder/smart_url_checker.rb +2 -0
  42. data/lib/cms_scanner/finders/finder/smart_url_checker/findings.rb +2 -0
  43. data/lib/cms_scanner/finders/finding.rb +2 -0
  44. data/lib/cms_scanner/finders/findings.rb +2 -0
  45. data/lib/cms_scanner/finders/independent_finder.rb +2 -0
  46. data/lib/cms_scanner/finders/independent_finders.rb +2 -0
  47. data/lib/cms_scanner/finders/same_type_finder.rb +2 -0
  48. data/lib/cms_scanner/finders/same_type_finders.rb +2 -0
  49. data/lib/cms_scanner/finders/unique_finder.rb +2 -0
  50. data/lib/cms_scanner/finders/unique_finders.rb +2 -0
  51. data/lib/cms_scanner/formatter.rb +2 -0
  52. data/lib/cms_scanner/formatter/buffer.rb +3 -1
  53. data/lib/cms_scanner/helper.rb +2 -0
  54. data/lib/cms_scanner/numeric.rb +2 -0
  55. data/lib/cms_scanner/progressbar_null_output.rb +2 -0
  56. data/lib/cms_scanner/public_suffix/domain.rb +2 -0
  57. data/lib/cms_scanner/references.rb +2 -0
  58. data/lib/cms_scanner/scan.rb +86 -0
  59. data/lib/cms_scanner/target.rb +2 -0
  60. data/lib/cms_scanner/target/hashes.rb +2 -0
  61. data/lib/cms_scanner/target/platform.rb +2 -0
  62. data/lib/cms_scanner/target/platform/php.rb +4 -2
  63. data/lib/cms_scanner/target/scope.rb +2 -0
  64. data/lib/cms_scanner/target/server.rb +2 -0
  65. data/lib/cms_scanner/target/server/apache.rb +2 -0
  66. data/lib/cms_scanner/target/server/generic.rb +2 -0
  67. data/lib/cms_scanner/target/server/iis.rb +2 -0
  68. data/lib/cms_scanner/target/server/nginx.rb +2 -0
  69. data/lib/cms_scanner/typhoeus/hydra.rb +2 -0
  70. data/lib/cms_scanner/typhoeus/response.rb +2 -0
  71. data/lib/cms_scanner/version.rb +3 -1
  72. data/lib/cms_scanner/vulnerability.rb +2 -0
  73. data/lib/cms_scanner/web_site.rb +34 -2
  74. metadata +4 -6
  75. data/app/controllers.rb +0 -2
  76. data/app/finders.rb +0 -1
  77. data/app/formatters.rb +0 -4
  78. data/app/models.rb +0 -7
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  module Finders
3
5
  # Unique Finder
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  module Finders
3
5
  # This class is designed to return a unique result such as a version
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'cms_scanner/formatter/buffer'
2
4
 
3
5
  module CMSScanner
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  module Formatter
3
5
  # Module used to output the rendered views into a buffer
@@ -8,7 +10,7 @@ module CMSScanner
8
10
  end
9
11
 
10
12
  def buffer
11
- @buffer ||= ''
13
+ @buffer ||= +''
12
14
  end
13
15
  end
14
16
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # @param [ String ] file The file path
2
4
  def redirect_output_to_file(file)
3
5
  $stdout.reopen(file, 'w')
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Hack of the Numeric class
2
4
  class Numeric
3
5
  # @return [ String ] A human readable string of the value
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'ruby-progressbar/outputs/null'
2
4
 
3
5
  module CMSScanner
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PublicSuffix
2
4
  # Monkey Patch to include the match logic
3
5
  class Domain
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  # References related to the issue
3
5
  module References
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CMSScanner
4
+ # Scan
5
+ class Scan
6
+ attr_reader :run_error
7
+
8
+ def initialize
9
+ controllers << NS::Controller::Core.new
10
+
11
+ exit_hook
12
+
13
+ yield self if block_given?
14
+ end
15
+
16
+ # @return [ Controllers ]
17
+ def controllers
18
+ @controllers ||= NS::Controllers.new
19
+ end
20
+
21
+ def run
22
+ controllers.run
23
+ rescue OptParseValidator::NoRequiredOption => e
24
+ @run_error = e
25
+
26
+ formatter.output('@usage', msg: e.message)
27
+ rescue NoMemoryError, ScriptError, SecurityError, SignalException, StandardError, SystemStackError => e
28
+ @run_error = e
29
+
30
+ formatter.output('@scan_aborted',
31
+ reason: e.is_a?(Interrupt) ? 'Canceled by User' : e.message,
32
+ trace: e.backtrace,
33
+ verbose: controllers.first.parsed_options[:verbose] ||
34
+ run_error_exit_code == NS::ExitCode::EXCEPTION)
35
+ ensure
36
+ Browser.instance.hydra.abort
37
+
38
+ formatter.beautify
39
+ end
40
+
41
+ # Used for convenience
42
+ # @See Formatter
43
+ def formatter
44
+ controllers.first.formatter
45
+ end
46
+
47
+ # @return [ Hash ]
48
+ def datastore
49
+ controllers.first.datastore
50
+ end
51
+
52
+ # Hook to be able to have an exit code returned
53
+ # depending on the findings / errors
54
+ # :nocov:
55
+ def exit_hook
56
+ # Avoid hooking the exit when rspec is running, otherwise it will always return 0
57
+ # and Travis won't detect failed builds. Couldn't find a better way, even though
58
+ # some people managed to https://github.com/rspec/rspec-core/pull/410
59
+ return if defined?(RSpec)
60
+
61
+ at_exit do
62
+ exit(run_error_exit_code) if run_error
63
+
64
+ controller = controllers.first
65
+
66
+ # The parsed_option[:url] must be checked to avoid raising erros when only -h/-v are given
67
+ exit(NS::ExitCode::VULNERABLE) if controller.parsed_options[:url] && controller.target.vulnerable?
68
+ exit(NS::ExitCode::OK)
69
+ end
70
+ end
71
+ # :nocov:
72
+
73
+ # @return [ Integer ] The exit code related to the run_error
74
+ def run_error_exit_code
75
+ return NS::ExitCode::CLI_OPTION_ERROR if run_error.is_a?(OptParseValidator::Error) ||
76
+ run_error.is_a?(OptionParser::ParseError)
77
+
78
+ return NS::ExitCode::INTERRUPTED if run_error.is_a?(Interrupt)
79
+
80
+ return NS::ExitCode::ERROR if run_error.is_a?(NS::Error::Standard) ||
81
+ run_error.is_a?(CMSScanner::Error::Standard)
82
+
83
+ NS::ExitCode::EXCEPTION
84
+ end
85
+ end
86
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'cms_scanner/web_site'
2
4
  require 'cms_scanner/target/platform'
3
5
  require 'cms_scanner/target/server'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  # Scope system logic
3
5
  class Target < WebSite
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'cms_scanner/target/platform/php'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  class Target < WebSite
3
5
  module Platform
@@ -14,9 +16,9 @@ module CMSScanner
14
16
  #
15
17
  # @return [ Boolean ]
16
18
  def log_file?(path, pattern, params = {})
17
- # Only the first 700 bytes of the file are retrieved to avoid getting enture log file
19
+ # Only the first 700 bytes of the file are retrieved to avoid getting entire log file
18
20
  # which can be huge (~ 2Go)
19
- res = NS::Browser.get(url(path), params.merge(headers: { 'range' => 'bytes=0-700' }))
21
+ res = head_and_get(path, [200], get: params.merge(headers: { 'Range' => 'bytes=0-700' }))
20
22
 
21
23
  res.body =~ pattern ? true : false
22
24
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  # Scope system logic
3
5
  class Target < WebSite
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'cms_scanner/target/server/generic'
2
4
  require 'cms_scanner/target/server/apache'
3
5
  require 'cms_scanner/target/server/iis'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  class Target < WebSite
3
5
  module Server
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  class Target < WebSite
3
5
  module Server
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  class Target < WebSite
3
5
  module Server
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  class Target < WebSite
3
5
  module Server
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Typhoeus
2
4
  # Ensure a clean abort of hydra
3
5
  # See https://github.com/typhoeus/typhoeus/issues/439
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Typhoeus
2
4
  # Custom Response class
3
5
  class Response
@@ -1,4 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Version
2
4
  module CMSScanner
3
- VERSION = '0.0.41.10'.freeze
5
+ VERSION = '0.0.42.0'
4
6
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  # Generic Vulnerability
3
5
  class Vulnerability
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CMSScanner
2
4
  # WebSite Implementation
3
5
  class WebSite
@@ -6,13 +8,14 @@ module CMSScanner
6
8
  # @param [ String ] site_url
7
9
  # @param [ Hash ] opts
8
10
  def initialize(site_url, opts = {})
9
- self.url = site_url.dup
11
+ self.url = +site_url
10
12
  @opts = opts
11
13
  end
12
14
 
13
15
  def url=(site_url)
14
16
  # Add a trailing slash to the site url
15
- site_url << '/' if site_url[-1, 1] != '/'
17
+ # Making also sure the site_url is unfrozen
18
+ +site_url << '/' if site_url[-1, 1] != '/'
16
19
 
17
20
  # Use the validator to ensure the site_url has a correct format
18
21
  OptParseValidator::OptURL.new([]).validate(site_url)
@@ -98,5 +101,34 @@ module CMSScanner
98
101
  res.effective_url == url ? nil : res.effective_url
99
102
  end
100
103
  # :nocov:
104
+
105
+ # @return [ Hash ] The Typhoeus params to use to perform head requests
106
+ def head_or_get_params
107
+ @head_or_get_params ||= if NS::Browser.head(homepage_url).code == 405
108
+ { method: :get, maxfilesize: 1 }
109
+ else
110
+ { method: :head }
111
+ end
112
+ end
113
+
114
+ # Perform a HEAD request to the path provided, then if its response code
115
+ # is in the array of codes given, a GET is done and the response returned. Otherwise the
116
+ # HEAD response is returned.
117
+ #
118
+ # @param [ String ] path
119
+ # @param [ Array<String> ] codes
120
+ # @param [ Hash ] params The requests params
121
+ # @option params [ Hash ] :head Request params for the HEAD
122
+ # @option params [ hash ] :get Request params for the GET
123
+ #
124
+ # @return [ Typhoeus::Response ]
125
+ def head_and_get(path, codes = [200], params = {})
126
+ url_to_get = url(path)
127
+ head_params = (params[:head] || {}).merge(head_or_get_params)
128
+
129
+ head_res = NS::Browser.forge_request(url_to_get, head_params).run
130
+
131
+ codes.include?(head_res.code) ? NS::Browser.get(url_to_get, params[:get] || {}) : head_res
132
+ end
101
133
  end
102
134
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cms_scanner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.41.10
4
+ version: 0.0.42.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - WPScanTeam
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-19 00:00:00.000000000 Z
11
+ date: 2019-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -230,23 +230,19 @@ files:
230
230
  - LICENSE
231
231
  - README.md
232
232
  - app/app.rb
233
- - app/controllers.rb
234
233
  - app/controllers/core.rb
235
234
  - app/controllers/core/cli_options.rb
236
235
  - app/controllers/interesting_findings.rb
237
- - app/finders.rb
238
236
  - app/finders/interesting_findings.rb
239
237
  - app/finders/interesting_findings/fantastico_fileslist.rb
240
238
  - app/finders/interesting_findings/headers.rb
241
239
  - app/finders/interesting_findings/robots_txt.rb
242
240
  - app/finders/interesting_findings/search_replace_db_2.rb
243
241
  - app/finders/interesting_findings/xml_rpc.rb
244
- - app/formatters.rb
245
242
  - app/formatters/cli.rb
246
243
  - app/formatters/cli_no_color.rb
247
244
  - app/formatters/cli_no_colour.rb
248
245
  - app/formatters/json.rb
249
- - app/models.rb
250
246
  - app/models/fantastico_fileslist.rb
251
247
  - app/models/headers.rb
252
248
  - app/models/interesting_finding.rb
@@ -279,6 +275,7 @@ files:
279
275
  - lib/cms_scanner/cache/typhoeus.rb
280
276
  - lib/cms_scanner/controller.rb
281
277
  - lib/cms_scanner/controllers.rb
278
+ - lib/cms_scanner/errors.rb
282
279
  - lib/cms_scanner/errors/http.rb
283
280
  - lib/cms_scanner/errors/scan.rb
284
281
  - lib/cms_scanner/exit_code.rb
@@ -305,6 +302,7 @@ files:
305
302
  - lib/cms_scanner/progressbar_null_output.rb
306
303
  - lib/cms_scanner/public_suffix/domain.rb
307
304
  - lib/cms_scanner/references.rb
305
+ - lib/cms_scanner/scan.rb
308
306
  - lib/cms_scanner/target.rb
309
307
  - lib/cms_scanner/target/hashes.rb
310
308
  - lib/cms_scanner/target/platform.rb
data/app/controllers.rb DELETED
@@ -1,2 +0,0 @@
1
- require_relative 'controllers/core'
2
- require_relative 'controllers/interesting_findings'
data/app/finders.rb DELETED
@@ -1 +0,0 @@
1
- require_relative 'finders/interesting_findings'
data/app/formatters.rb DELETED
@@ -1,4 +0,0 @@
1
- require_relative 'formatters/cli'
2
- require_relative 'formatters/cli_no_colour'
3
- require_relative 'formatters/cli_no_color'
4
- require_relative 'formatters/json'
data/app/models.rb DELETED
@@ -1,7 +0,0 @@
1
- require_relative 'models/interesting_finding'
2
- require_relative 'models/robots_txt'
3
- require_relative 'models/fantastico_fileslist'
4
- require_relative 'models/headers'
5
- require_relative 'models/xml_rpc'
6
- require_relative 'models/version'
7
- require_relative 'models/user'