cms_scanner 0.0.32 → 0.0.33

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5e7b45d83448abe095a219641c27db1ccb6c62d3
4
- data.tar.gz: c0a503b8cb376ce46bd620017e33c72d64b2f439
3
+ metadata.gz: 1f93aa617ff534c907d09aed61fc22f2cebb924d
4
+ data.tar.gz: cbb4ade08697eaec5c6dbdc8c1a73ec950093a85
5
5
  SHA512:
6
- metadata.gz: 1c5889f4ba15eac53f58a60037ee7a28e2c99a95ca8b520c880b0feef81d038817e2bcccefe423dabe3506ee93b7bb9d10bfba53bfc7a4a8dafe809a83ee3005
7
- data.tar.gz: 0565e658a23e0f67cbb4dff6abfd2cb438277c3cec173c5cdaec40d0a3d1c10e07b05011b0936cb735c31f028c3fd72d8bd25d8146878d1c5a7df6bf62717277
6
+ metadata.gz: eccfe8a5c8748f6230e8ab5ac0c6d71ffdc1d1ad2e6946436f27407ee9b5878d7eaebcd3c637fe8ee6a7104cfd376cfe8f86cf33d8e69efadebc234b85d1799a
7
+ data.tar.gz: a407110fcb4b2e2f4460b167a7112c099890a874f0bde0b3ebf5a3b66d19e065525c2bcb7c7f87585624b0274862e96c11981e7ae62839737650542b69a3145b
@@ -6,18 +6,18 @@ module CMSScanner
6
6
  formats = NS::Formatter.availables
7
7
 
8
8
  [
9
- OptURL.new(['-u', '--url URL'], required: true, default_protocol: 'http'),
9
+ OptURL.new(['-u', '--url URL', 'The URL to scan'], required: true, default_protocol: 'http'),
10
10
  OptBoolean.new(['--ignore-main-redirect', 'Ignore the main redirect if any and scan the target url']),
11
11
  OptBoolean.new(%w(-v --verbose)),
12
12
  OptFilePath.new(['-o', '--output FILE', 'Output to FILE'], writable: true, exists: false),
13
13
  OptChoice.new(['-f', '--format FORMAT',
14
- "Available formats: #{formats.join(', ')}"], choices: formats),
15
- OptChoice.new(['--detection-mode MODE', 'Modes: mixed (default), passive, aggressive'],
14
+ 'Output results in the format supplied'], choices: formats),
15
+ OptChoice.new(['--detection-mode MODE'],
16
16
  choices: %w(mixed passive aggressive),
17
17
  normalize: :to_sym,
18
18
  default: :mixed),
19
19
  OptArray.new(['--scope DOMAINS',
20
- 'Comma separated (sub-)domains to consider in scope. ' \
20
+ 'Comma separated (sub-)domains to consider in scope. ',
21
21
  'Wildcard(s) allowed in the trd of valid domains, e.g: *.target.tld'])
22
22
  ] + cli_browser_options
23
23
  end
@@ -66,7 +66,7 @@ module CMSScanner
66
66
  # @return [ Array<OptParseValidator::OptBase> ]
67
67
  def cli_browser_cache_options
68
68
  [
69
- OptInteger.new(['--cache-ttl TIME_TO_LIVE'], default: 600),
69
+ OptInteger.new(['--cache-ttl TIME_TO_LIVE', 'The cache time to live in seconds'], default: 600),
70
70
  OptBoolean.new(['--clear-cache', 'Clear the cache before the scan']),
71
71
  OptDirectoryPath.new(['--cache-dir PATH'],
72
72
  readable: true,
@@ -6,9 +6,7 @@ module CMSScanner
6
6
  [
7
7
  OptChoice.new(
8
8
  ['--interesting-findings-detection MODE',
9
- 'Use the supplied mode for the interesting findings detection. ' \
10
- 'Modes: mixed, passive, aggressive'
11
- ],
9
+ 'Use the supplied mode for the interesting findings detection. '],
12
10
  choices: %w(mixed passive aggressive),
13
11
  normalize: :to_sym)
14
12
  ]
data/cms_scanner.gemspec CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |s|
31
31
  s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
32
32
  s.require_path = 'lib'
33
33
 
34
- s.add_dependency 'opt_parse_validator', '~> 0.0.11'
34
+ s.add_dependency 'opt_parse_validator', '~> 0.0.12.1'
35
35
  s.add_dependency 'typhoeus', '~> 0.7'
36
36
  s.add_dependency 'nokogiri', '~> 1.6.6'
37
37
  s.add_dependency 'addressable', '~> 2.3.8'
data/lib/cms_scanner.rb CHANGED
@@ -17,6 +17,7 @@ require 'cms_scanner/typhoeus/hydra'
17
17
  require 'cms_scanner/public_suffix/domain'
18
18
  # Custom Libs
19
19
  require 'cms_scanner/helper'
20
+ require 'cms_scanner/exit_code'
20
21
  require 'cms_scanner/errors/http'
21
22
  require 'cms_scanner/cache/typhoeus'
22
23
  require 'cms_scanner/target'
@@ -56,9 +57,13 @@ module CMSScanner
56
57
 
57
58
  # Scan
58
59
  class Scan
60
+ attr_reader :run_error
61
+
59
62
  def initialize
60
63
  controllers << NS::Controller::Core.new
61
64
 
65
+ exit_hook
66
+
62
67
  yield self if block_given?
63
68
  end
64
69
 
@@ -70,8 +75,12 @@ module CMSScanner
70
75
  def run
71
76
  controllers.run
72
77
  rescue OptParseValidator::NoRequiredOption => e
78
+ @run_error = e
79
+
73
80
  formatter.output('@usage', msg: e.message)
74
81
  rescue => e
82
+ @run_error = e
83
+
75
84
  formatter.output('@scan_aborted',
76
85
  reason: e.message,
77
86
  trace: e.backtrace,
@@ -92,6 +101,26 @@ module CMSScanner
92
101
  def datastore
93
102
  controllers.first.datastore
94
103
  end
104
+
105
+ # Hook to be able to have an exit code returned
106
+ # depending on the findings / errors
107
+ def exit_hook
108
+ at_exit do
109
+ if run_error
110
+ exit(NS::ExitCode::CLI_OPTION_ERROR) if run_error.is_a?(OptParseValidator::Error) ||
111
+ run_error.is_a?(OptionParser::ParseError)
112
+
113
+ exit(NS::ExitCode::INTERRUPTED) if run_error.is_a?(Interrupt)
114
+ exit(NS::ExitCode::ERROR)
115
+ end
116
+
117
+ controller = controllers.first
118
+
119
+ # The parsed_option[:url] must be checked to avoid raising erros when only -h/-v are given
120
+ exit(NS::ExitCode::VULNERABLE) if controller.parsed_options[:url] && controller.target.vulnerable?
121
+ exit(NS::ExitCode::OK)
122
+ end
123
+ end
95
124
  end
96
125
  end
97
126
 
@@ -1,28 +1,37 @@
1
1
  module CMSScanner
2
+ class Error < RuntimeError
3
+ end
4
+
2
5
  # HTTP Authentication Required Error
3
- class HTTPAuthRequiredError < StandardError
6
+ class HTTPAuthRequiredError < Error
7
+ # :nocov:
4
8
  def to_s
5
9
  'HTTP authentication required (or was invalid), please provide it with --http-auth'
6
10
  end
11
+ # :nocov:
7
12
  end
8
13
 
9
14
  # Proxy Authentication Required Error
10
- class ProxyAuthRequiredError < StandardError
15
+ class ProxyAuthRequiredError < Error
16
+ # :nocov:
11
17
  def to_s
12
18
  'Proxy authentication required (or was invalid), please provide it with --proxy-auth'
13
19
  end
20
+ # :nocov:
14
21
  end
15
22
 
16
23
  # Access Forbidden Error
17
- class AccessForbiddenError < StandardError
24
+ class AccessForbiddenError < Error
25
+ # :nocov:
18
26
  def to_s
19
27
  'The target is responding with a 403, this might be due to a WAF. ' \
20
28
  'Please re-try with --random-user-agent'
21
29
  end
30
+ # :nocov:
22
31
  end
23
32
 
24
33
  # HTTP Redirect Error
25
- class HTTPRedirectError < StandardError
34
+ class HTTPRedirectError < Error
26
35
  attr_reader :redirect_uri
27
36
 
28
37
  # @param [ String ] url
@@ -31,7 +40,8 @@ module CMSScanner
31
40
  end
32
41
 
33
42
  def to_s
34
- "The URL supplied redirects to #{redirect_uri}"
43
+ "The URL supplied redirects to #{redirect_uri}. Use the --ignore-main-redirect "\
44
+ 'option to ignore the redirection and scan the target.'
35
45
  end
36
46
  end
37
47
  end
@@ -0,0 +1,20 @@
1
+ module CMSScanner
2
+ # Exit Code Values
3
+ module ExitCode
4
+ # No error, scan finished w/o any vulnerabilies found
5
+ OK = 0
6
+
7
+ # All exceptions raised by OptParseValidator and OptionParser
8
+ CLI_OPTION_ERROR = 1
9
+
10
+ # Interrupt received
11
+ INTERRUPTED = 2
12
+
13
+ # Exceptions
14
+ ERROR = 3
15
+
16
+ # The target has at least one vulnerability.
17
+ # Currently, the interesting findings do not count as vulnerable things
18
+ VULNERABLE = 4
19
+ end
20
+ end
@@ -6,28 +6,35 @@ module PublicSuffix
6
6
  name == other.name
7
7
  end
8
8
 
9
- # TODO: better code for this method
10
- # rubocop:disable all
9
+ # @return [ Boolean ]
10
+ #
11
11
  def match(pattern)
12
12
  pattern = PublicSuffix.parse(pattern) unless pattern.is_a?(PublicSuffix::Domain)
13
13
 
14
14
  return name == pattern.name unless pattern.trd
15
15
  return false unless tld == pattern.tld && sld == pattern.sld
16
16
 
17
+ matching_pattern?(pattern)
18
+ end
19
+
20
+ protected
21
+
22
+ # @rturn [ Boolean ]
23
+ def matching_pattern?(pattern)
17
24
  pattern_trds = pattern.trd.split('.')
18
25
  domain_trds = trd.split('.')
19
26
 
20
27
  case pattern_trds.first
21
28
  when '*'
22
- pattern_trds[1..pattern_trds.size] == domain_trds[1..domain_trds.size]
29
+ pattern_trds[1..-1] == domain_trds[1..-1]
23
30
  when '**'
24
- pa = pattern_trds[1..pattern_trds.size]
31
+ pa = pattern_trds[1..-1]
32
+ pa_size = pa.size
25
33
 
26
- domain_trds[domain_trds.size - pa.size, pa.size] == pa
34
+ domain_trds[domain_trds.size - pa_size, pa_size] == pa
27
35
  else
28
36
  name == pattern.name
29
37
  end
30
38
  end
31
- # rubocop:enable all
32
39
  end
33
40
  end
@@ -26,6 +26,15 @@ module CMSScanner
26
26
  @interesting_findings ||= NS::Finders::InterestingFindings::Base.find(self, opts)
27
27
  end
28
28
 
29
+ # Weteher or not vulnerabilities have been found.
30
+ # Used to set the exit code of the script
31
+ # and it should be overriden in the implementation
32
+ #
33
+ # @return [ Boolean ]
34
+ def vulnerable?
35
+ false
36
+ end
37
+
29
38
  # @param [ Regexp ] pattern
30
39
  # @param [ Typhoeus::Response, String ] page
31
40
  #
@@ -63,13 +72,14 @@ module CMSScanner
63
72
 
64
73
  next unless attr_value && !attr_value.empty?
65
74
 
66
- tag_uri = uri.join(attr_value.strip) rescue next
75
+ tag_uri = uri.join(attr_value.strip) rescue next
76
+ tag_uri_string = tag_uri.to_s
67
77
 
68
78
  next unless tag_uri.host
69
79
 
70
- yield tag_uri.to_s, tag if block_given? && !found.include?(tag_uri.to_s)
80
+ yield tag_uri_string, tag if block_given? && !found.include?(tag_uri_string)
71
81
 
72
- found << tag_uri.to_s
82
+ found << tag_uri_string
73
83
  end
74
84
  end
75
85
 
@@ -1,4 +1,4 @@
1
1
  # Version
2
2
  module CMSScanner
3
- VERSION = '0.0.32'
3
+ VERSION = '0.0.33'
4
4
  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.32
4
+ version: 0.0.33
5
5
  platform: ruby
6
6
  authors:
7
7
  - WPScanTeam - Erwan Le Rousseau
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-30 00:00:00.000000000 Z
11
+ date: 2015-07-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opt_parse_validator
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.0.11
19
+ version: 0.0.12.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.0.11
26
+ version: 0.0.12.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: typhoeus
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -261,6 +261,7 @@ files:
261
261
  - lib/cms_scanner/controller.rb
262
262
  - lib/cms_scanner/controllers.rb
263
263
  - lib/cms_scanner/errors/http.rb
264
+ - lib/cms_scanner/exit_code.rb
264
265
  - lib/cms_scanner/finders.rb
265
266
  - lib/cms_scanner/finders/finder.rb
266
267
  - lib/cms_scanner/finders/finder/enumerator.rb