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 +4 -4
- data/app/controllers/core/cli_options.rb +5 -5
- data/app/controllers/interesting_findings.rb +1 -3
- data/cms_scanner.gemspec +1 -1
- data/lib/cms_scanner.rb +29 -0
- data/lib/cms_scanner/errors/http.rb +15 -5
- data/lib/cms_scanner/exit_code.rb +20 -0
- data/lib/cms_scanner/public_suffix/domain.rb +13 -6
- data/lib/cms_scanner/target.rb +13 -3
- data/lib/cms_scanner/version.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f93aa617ff534c907d09aed61fc22f2cebb924d
|
4
|
+
data.tar.gz: cbb4ade08697eaec5c6dbdc8c1a73ec950093a85
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
15
|
-
OptChoice.new(['--detection-mode MODE'
|
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.
|
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 <
|
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 <
|
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 <
|
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 <
|
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
|
-
#
|
10
|
-
#
|
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
|
29
|
+
pattern_trds[1..-1] == domain_trds[1..-1]
|
23
30
|
when '**'
|
24
|
-
pa = pattern_trds[1
|
31
|
+
pa = pattern_trds[1..-1]
|
32
|
+
pa_size = pa.size
|
25
33
|
|
26
|
-
domain_trds[domain_trds.size -
|
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
|
data/lib/cms_scanner/target.rb
CHANGED
@@ -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
|
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
|
80
|
+
yield tag_uri_string, tag if block_given? && !found.include?(tag_uri_string)
|
71
81
|
|
72
|
-
found <<
|
82
|
+
found << tag_uri_string
|
73
83
|
end
|
74
84
|
end
|
75
85
|
|
data/lib/cms_scanner/version.rb
CHANGED
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.
|
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
|
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.
|
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.
|
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
|