cms_scanner 0.0.43.2 → 0.0.44.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c08759ffe67a08d3d1d2a605b909e2005b2236fcb64d2cb5d676a5285b518e47
4
- data.tar.gz: 628124941d9ebde290372e860b36b4f38df9fd860ce54edebe2deb92e6faa3e8
3
+ metadata.gz: 36cf3a147ed137b39e8b2d7f1663bfd454639cce4b8d0f45764af3e3ab0b4b48
4
+ data.tar.gz: a4e4d72d4b8951a04c4f619cc20d1e1293eba77b15533e668738a2e0e62d3306
5
5
  SHA512:
6
- metadata.gz: 39ecc93cb5446fc7d8223c9a397b21e5ff30728c85c5808e47c8a7600c1efe658e4b68dfb8d6f30b916fb7f2103a00af6d752cc0f8e3010c8f3e88ab768e8a46
7
- data.tar.gz: 643282fcf51cab0b08cf09741113fb53ca11f4fdd982bb162d0bd56ad039b4cfe411620ab6a25de2862a9d68d4d4cd23e8681e9416a70820a9dd8f8ab9004b0a
6
+ metadata.gz: cadfdee997e1ef6c7f10ce9f7b8b841acdb1fd5818b5682070f3a07dd5ea34658d55ffd9d86055ac6b7ccf60b5fd965213ba61f22f138873fc6852e137997f0f
7
+ data.tar.gz: 4a37dc5d1eae53a72894f6317cb72132dc07541f76d48ce9067d15fdf4e89d026b074cc4314163883dce3d2006305ff7c607831d8d0cb9c1c4d22e4978b53a91
@@ -7,12 +7,12 @@ module CMSScanner
7
7
  # Core Controller
8
8
  class Core < Base
9
9
  def setup_cache
10
- return unless parsed_options[:cache_dir]
10
+ return unless NS::ParsedCli.cache_dir
11
11
 
12
- storage_path = File.join(parsed_options[:cache_dir], Digest::MD5.hexdigest(target.url))
12
+ storage_path = File.join(NS::ParsedCli.cache_dir, Digest::MD5.hexdigest(target.url))
13
13
 
14
14
  Typhoeus::Config.cache = Cache::Typhoeus.new(storage_path)
15
- Typhoeus::Config.cache.clean if parsed_options[:clear_cache]
15
+ Typhoeus::Config.cache.clean if NS::ParsedCli.clear_cache
16
16
  end
17
17
 
18
18
  def before_scan
@@ -23,12 +23,12 @@ module CMSScanner
23
23
  end
24
24
 
25
25
  def maybe_output_banner_help_and_version
26
- output('banner') if parsed_options[:banner]
27
- output('help', help: option_parser.simple_help, simple: true) if parsed_options[:help]
28
- output('help', help: option_parser.full_help, simple: false) if parsed_options[:hh]
29
- output('version') if parsed_options[:version]
26
+ output('banner') if NS::ParsedCli.banner
27
+ output('help', help: option_parser.simple_help, simple: true) if NS::ParsedCli.help
28
+ output('help', help: option_parser.full_help, simple: false) if NS::ParsedCli.hh
29
+ output('version') if NS::ParsedCli.version
30
30
 
31
- exit(NS::ExitCode::OK) if parsed_options[:help] || parsed_options[:hh] || parsed_options[:version]
31
+ exit(NS::ExitCode::OK) if NS::ParsedCli.help || NS::ParsedCli.hh || NS::ParsedCli.version
32
32
  end
33
33
 
34
34
  # Checks that the target is accessible, raises related errors otherwise
@@ -43,7 +43,7 @@ module CMSScanner
43
43
  when 401
44
44
  raise Error::HTTPAuthRequired
45
45
  when 403
46
- raise Error::AccessForbidden, parsed_options[:random_user_agent]
46
+ raise Error::AccessForbidden, NS::ParsedCli.random_user_agent
47
47
  when 407
48
48
  raise Error::ProxyAuthRequired
49
49
  end
@@ -54,7 +54,7 @@ module CMSScanner
54
54
 
55
55
  return if target.in_scope?(effective_url)
56
56
 
57
- raise Error::HTTPRedirect, effective_url unless parsed_options[:ignore_main_redirect]
57
+ raise Error::HTTPRedirect, effective_url unless NS::ParsedCli.ignore_main_redirect
58
58
 
59
59
  target.homepage_res = res
60
60
  end
@@ -46,7 +46,10 @@ module CMSScanner
46
46
  OptBoolean.new(['--random-user-agent', '--rua',
47
47
  'Use a random user-agent for each scan']),
48
48
  OptFilePath.new(['--user-agents-list FILE-PATH',
49
- 'List of agents to use with --random-user-agent'], exists: true, advanced: true),
49
+ 'List of agents to use with --random-user-agent'],
50
+ exists: true,
51
+ advanced: true,
52
+ default: APP_DIR.join('user_agents.txt')),
50
53
  OptCredentials.new(['--http-auth login:password']),
51
54
  OptPositiveInteger.new(['-t', '--max-threads VALUE', 'The max threads to use'],
52
55
  default: 5),
@@ -15,7 +15,7 @@ module CMSScanner
15
15
  end
16
16
 
17
17
  def run
18
- mode = parsed_options[:interesting_findings_detection] || parsed_options[:detection_mode]
18
+ mode = NS::ParsedCli.interesting_findings_detection || NS::ParsedCli.detection_mode
19
19
  findings = target.interesting_findings(mode: mode)
20
20
 
21
21
  output('findings', findings: findings) unless findings.empty?
@@ -24,6 +24,7 @@ require 'cms_scanner/public_suffix/domain' # Adds a Domain#match method and logi
24
24
  require 'cms_scanner/numeric' # Adds a Numeric#bytes_to_human
25
25
  # Custom Libs
26
26
  require 'cms_scanner/scan'
27
+ require 'cms_scanner/parsed_cli'
27
28
  require 'cms_scanner/helper'
28
29
  require 'cms_scanner/exit_code'
29
30
  require 'cms_scanner/errors'
@@ -14,7 +14,7 @@ module CMSScanner
14
14
  def initialize(parsed_options = {})
15
15
  self.throttle = 0
16
16
 
17
- load_options(parsed_options)
17
+ load_options(parsed_options.dup)
18
18
  end
19
19
 
20
20
  private_class_method :new
@@ -62,6 +62,8 @@ module CMSScanner
62
62
 
63
63
  @user_agents = []
64
64
 
65
+ # The user_agents_list is managed by the CLI options, with the default being
66
+ # APP_DIR/user_agents.txt
65
67
  File.open(user_agents_list).each do |line|
66
68
  next if line == "\n" || line[0, 1] == '#'
67
69
 
@@ -71,11 +73,6 @@ module CMSScanner
71
73
  @user_agents
72
74
  end
73
75
 
74
- # @return [ String ] The path to the user agents list
75
- def user_agents_list
76
- @user_agents_list ||= File.join(APP_DIR, 'user_agents.txt')
77
- end
78
-
79
76
  # @param [ value ] The throttle time in milliseconds
80
77
  #
81
78
  # if value > 0, the max_threads will be set to 1
@@ -22,15 +22,14 @@ module CMSScanner
22
22
  # Reset all the class attibutes
23
23
  # Currently only used in specs
24
24
  def self.reset
25
- @@target = nil
26
- @@parsed_options = nil
27
- @@datastore = nil
28
- @@formatter = nil
25
+ @@target = nil
26
+ @@datastore = nil
27
+ @@formatter = nil
29
28
  end
30
29
 
31
30
  # @return [ Target ]
32
31
  def target
33
- @@target ||= NS::Target.new(parsed_options[:url], parsed_options)
32
+ @@target ||= NS::Target.new(NS::ParsedCli.url, NS::ParsedCli.options)
34
33
  end
35
34
 
36
35
  # @param [ OptParsevalidator::OptParser ] parser
@@ -43,21 +42,6 @@ module CMSScanner
43
42
  @@option_parser
44
43
  end
45
44
 
46
- # Set the parsed options and initialize the browser
47
- # with them
48
- #
49
- # @param [ Hash ] options
50
- def self.parsed_options=(options)
51
- @@parsed_options = options
52
-
53
- NS::Browser.instance(options)
54
- end
55
-
56
- # @return [ Hash ]
57
- def parsed_options
58
- @@parsed_options ||= {}
59
- end
60
-
61
45
  # @return [ Hash ]
62
46
  def datastore
63
47
  @@datastore ||= {}
@@ -65,7 +49,7 @@ module CMSScanner
65
49
 
66
50
  # @return [ Formatter::Base ]
67
51
  def formatter
68
- @@formatter ||= NS::Formatter.load(parsed_options[:format], datastore[:views])
52
+ @@formatter ||= NS::Formatter.load(NS::ParsedCli.format, datastore[:views])
69
53
  end
70
54
 
71
55
  # @see Formatter#output
@@ -84,7 +68,7 @@ module CMSScanner
84
68
 
85
69
  # @return [ Boolean ]
86
70
  def user_interaction?
87
- formatter.user_interaction? && !parsed_options[:output]
71
+ formatter.user_interaction? && !NS::ParsedCli.output
88
72
  end
89
73
 
90
74
  # @return [ String ]
@@ -108,7 +92,7 @@ module CMSScanner
108
92
 
109
93
  # @return [ Hash ] All the instance variable keys (and their values) and the verbose value
110
94
  def instance_variable_values
111
- h = { verbose: parsed_options[:verbose] }
95
+ h = { verbose: NS::ParsedCli.verbose }
112
96
  instance_variables.each do |a|
113
97
  s = a.to_s
114
98
  n = s[1..s.size]
@@ -35,13 +35,12 @@ module CMSScanner
35
35
  end
36
36
 
37
37
  def run
38
- parsed_options = option_parser.results
39
- first.class.option_parser = option_parser
40
- first.class.parsed_options = parsed_options
38
+ NS::ParsedCli.options = option_parser.results
39
+ first.class.option_parser = option_parser # To be able to output the help when -h/--hh
41
40
 
42
- redirect_output_to_file(parsed_options[:output]) if parsed_options[:output]
41
+ redirect_output_to_file(NS::ParsedCli.output) if NS::ParsedCli.output
43
42
 
44
- Timeout.timeout(parsed_options[:max_scan_duration], NS::Error::MaxScanDurationReached) do
43
+ Timeout.timeout(NS::ParsedCli.max_scan_duration, NS::Error::MaxScanDurationReached) do
45
44
  each(&:before_scan)
46
45
 
47
46
  @running = true
@@ -49,7 +48,7 @@ module CMSScanner
49
48
  each(&:run)
50
49
  end
51
50
  ensure
52
- Browser.instance.hydra.abort
51
+ NS::Browser.instance.hydra.abort
53
52
 
54
53
  # Reverse is used here as the app/controllers/core#after_scan finishes the output
55
54
  # and must be the last one to be executed. It also guarantee that stats will be output
@@ -103,7 +103,7 @@ module CMSScanner
103
103
  'Request timed out.'
104
104
  elsif response.code.zero?
105
105
  "No response from remote server. WAF/IPS? (#{response.return_message})"
106
- elsif response.code.to_s =~ /^50/
106
+ elsif /^50/.match?(response.code.to_s)
107
107
  'Server error, try reducing the number of threads.'
108
108
  else
109
109
  "Unknown response received Code: #{response.code}\nBody: #{response.body}"
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CMSScanner
4
+ # Class to hold the parsed CLI options and have them available via
5
+ # methods, such as #verbose?, rather than from the hash.
6
+ # This is similar to an OpenStruct, but class wise (rather than instance), and with
7
+ # the logic to update the Browser options accordinly
8
+ class ParsedCli
9
+ @options = {}
10
+
11
+ class << self
12
+ attr_reader :options
13
+ end
14
+
15
+ # Sets the CLI options, and put them into the Browser as well
16
+ # @param [ Hash ] options
17
+ def self.options=(options)
18
+ @options = options.dup
19
+
20
+ NS::Browser.reset
21
+ NS::Browser.instance(@options)
22
+ end
23
+
24
+ # @return [ Boolean ]
25
+ def self.verbose?
26
+ options[:verbose] ? true : false
27
+ end
28
+
29
+ # Unknown methods will return nil, this is the expected behaviour
30
+ # rubocop:disable Style/MissingRespondToMissing
31
+ def self.method_missing(method_name, *_args, &_block)
32
+ super if method_name == :new
33
+
34
+ options[method_name.to_sym]
35
+ end
36
+ # rubocop:enable Style/MissingRespondToMissing
37
+ end
38
+ end
@@ -32,7 +32,7 @@ module CMSScanner
32
32
  formatter.output('@scan_aborted',
33
33
  reason: e.is_a?(Interrupt) ? 'Canceled by User' : e.message,
34
34
  trace: e.backtrace,
35
- verbose: controllers.first.parsed_options[:verbose] ||
35
+ verbose: NS::ParsedCli.verbose ||
36
36
  run_error_exit_code == NS::ExitCode::EXCEPTION)
37
37
  ensure
38
38
  formatter.beautify
@@ -61,10 +61,8 @@ module CMSScanner
61
61
  at_exit do
62
62
  exit(run_error_exit_code) if run_error
63
63
 
64
- controller = controllers.first
65
-
66
64
  # 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?
65
+ exit(NS::ExitCode::VULNERABLE) if NS::ParsedCli.url && controllers.first.target.vulnerable?
68
66
  exit(NS::ExitCode::OK)
69
67
  end
70
68
  end
@@ -20,7 +20,7 @@ module CMSScanner
20
20
  # which can be huge (~ 2Go)
21
21
  res = head_and_get(path, [200], get: params.merge(headers: { 'Range' => 'bytes=0-700' }))
22
22
 
23
- res.body =~ pattern ? true : false
23
+ res.body&.match?(pattern) ? true : false
24
24
  end
25
25
 
26
26
  # @param [ String ] path
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Version
4
4
  module CMSScanner
5
- VERSION = '0.0.43.2'
5
+ VERSION = '0.0.44.0'
6
6
  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.43.2
4
+ version: 0.0.44.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-04-03 00:00:00.000000000 Z
11
+ date: 2019-04-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -184,14 +184,14 @@ dependencies:
184
184
  requirements:
185
185
  - - "~>"
186
186
  - !ruby/object:Gem::Version
187
- version: 0.66.0
187
+ version: 0.67.1
188
188
  type: :development
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
192
192
  - - "~>"
193
193
  - !ruby/object:Gem::Version
194
- version: 0.66.0
194
+ version: 0.67.1
195
195
  - !ruby/object:Gem::Dependency
196
196
  name: simplecov
197
197
  requirement: !ruby/object:Gem::Requirement
@@ -299,6 +299,7 @@ files:
299
299
  - lib/cms_scanner/formatter/buffer.rb
300
300
  - lib/cms_scanner/helper.rb
301
301
  - lib/cms_scanner/numeric.rb
302
+ - lib/cms_scanner/parsed_cli.rb
302
303
  - lib/cms_scanner/progressbar_null_output.rb
303
304
  - lib/cms_scanner/public_suffix/domain.rb
304
305
  - lib/cms_scanner/references.rb
@@ -330,7 +331,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
330
331
  requirements:
331
332
  - - ">="
332
333
  - !ruby/object:Gem::Version
333
- version: '2.3'
334
+ version: '2.4'
334
335
  required_rubygems_version: !ruby/object:Gem::Requirement
335
336
  requirements:
336
337
  - - ">="