wpscan 3.5.0 → 3.5.1

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: f64d1fca83669eeb095fb99cbcbbc2a57a8967ef680bda9d754074b771bfc8dd
4
- data.tar.gz: f6835052a919b6dcbefade7ec3e47e0719bdad7192e91061b742082031378886
3
+ metadata.gz: 4413068dee1847959f5b7af58b99c89ebef29818b654f3dd85a2f381d6972813
4
+ data.tar.gz: 42ee69a95fec668215c4979ef516305b68d06c04f07dbeb2b991d33044f6e676
5
5
  SHA512:
6
- metadata.gz: 148e26a2d52135e120e47cc557c7fe79a1f96c42ad3f15f6ac92eb020900fcea1dc94056c2cf8a0731fe4d60541a79e1d1353e5fd597464b92ae3dad8f18cbad
7
- data.tar.gz: fcb7e45a14d14728824761e075d55a76174972be46311957cb724c85b29a05b460a80fa21012c832585fc3351ab4a34a8932c777b34fc3c7c12a5dc708ead417
6
+ metadata.gz: 1e4ef3233047f35cafa1bd25de163e1f77f5f17c17bde45be5a5582fa8ba3d51705e4b96a0f53041472e85fe82c26ca340b911a29427b95e7abf9ca04b118d08
7
+ data.tar.gz: 5969b2f008d030f3528ad776f3791fba42d6a118105e28cbc5973faef64cd723a85f9085cf5460703e2fd36519b9fa4471746e934d930c9401f516b5131a7377
@@ -27,38 +27,41 @@ module WPScan
27
27
  # @return [ Boolean ]
28
28
  def update_db_required?
29
29
  if local_db.missing_files?
30
- raise Error::MissingDatabaseFile if parsed_options[:update] == false
30
+ raise Error::MissingDatabaseFile if ParsedCli.update == false
31
31
 
32
32
  return true
33
33
  end
34
34
 
35
- return parsed_options[:update] unless parsed_options[:update].nil?
35
+ return ParsedCli.update unless ParsedCli.update.nil?
36
36
 
37
37
  return false unless user_interaction? && local_db.outdated?
38
38
 
39
39
  output('@notice', msg: 'It seems like you have not updated the database for some time.')
40
40
  print '[?] Do you want to update now? [Y]es [N]o, default: [N]'
41
41
 
42
- Readline.readline =~ /^y/i ? true : false
42
+ /^y/i.match?(Readline.readline) ? true : false
43
43
  end
44
44
 
45
45
  def update_db
46
46
  output('db_update_started')
47
- output('db_update_finished', updated: local_db.update, verbose: parsed_options[:verbose])
47
+ output('db_update_finished', updated: local_db.update, verbose: ParsedCli.verbose)
48
48
 
49
- exit(0) unless parsed_options[:url]
49
+ exit(0) unless ParsedCli.url
50
50
  end
51
51
 
52
52
  def before_scan
53
53
  @last_update = local_db.last_update
54
54
 
55
- maybe_output_banner_help_and_version # From CMS Scanner
55
+ maybe_output_banner_help_and_version # From CMSScanner
56
56
 
57
57
  update_db if update_db_required?
58
58
  setup_cache
59
59
  check_target_availability
60
60
  load_server_module
61
61
  check_wordpress_state
62
+ rescue Error::NotWordPress => e
63
+ target.maybe_add_cookies
64
+ raise e unless target.wordpress?(ParsedCli.detection_mode)
62
65
  end
63
66
 
64
67
  # Raises errors if the target is hosted on wordpress.com or is not running WordPress
@@ -66,14 +69,14 @@ module WPScan
66
69
  def check_wordpress_state
67
70
  raise Error::WordPressHosted if target.wordpress_hosted?
68
71
 
69
- if Addressable::URI.parse(target.homepage_url).path =~ %r{/wp-admin/install.php$}i
72
+ if %r{/wp-admin/install.php$}i.match?(Addressable::URI.parse(target.homepage_url).path)
70
73
 
71
74
  output('not_fully_configured', url: target.homepage_url)
72
75
 
73
76
  exit(WPScan::ExitCode::VULNERABLE)
74
77
  end
75
78
 
76
- raise Error::NotWordPress unless target.wordpress?(parsed_options[:detection_mode]) || parsed_options[:force]
79
+ raise Error::NotWordPress unless target.wordpress?(ParsedCli.detection_mode) || ParsedCli.force
77
80
  end
78
81
 
79
82
  # Loads the related server module in the target
@@ -85,7 +88,7 @@ module WPScan
85
88
  server = target.server || :Apache # Tries to auto detect the server
86
89
 
87
90
  # Force a specific server module to be loaded if supplied
88
- case parsed_options[:server]
91
+ case ParsedCli.server
89
92
  when :apache
90
93
  server = :Apache
91
94
  when :iis
@@ -13,8 +13,8 @@ module WPScan
13
13
  end
14
14
 
15
15
  def before_scan
16
- target.content_dir = parsed_options[:wp_content_dir] if parsed_options[:wp_content_dir]
17
- target.plugins_dir = parsed_options[:wp_plugins_dir] if parsed_options[:wp_plugins_dir]
16
+ target.content_dir = ParsedCli.wp_content_dir if ParsedCli.wp_content_dir
17
+ target.plugins_dir = ParsedCli.wp_plugins_dir if ParsedCli.wp_plugins_dir
18
18
 
19
19
  return if target.content_dir
20
20
 
@@ -17,7 +17,7 @@ module WPScan
17
17
  end
18
18
 
19
19
  def run
20
- enum = parsed_options[:enumerate] || {}
20
+ enum = ParsedCli.enumerate || {}
21
21
 
22
22
  enum_plugins if enum_plugins?(enum)
23
23
  enum_themes if enum_themes?(enum)
@@ -7,13 +7,13 @@ module WPScan
7
7
  # @param [ String ] type (plugins or themes)
8
8
  # @param [ Symbol ] detection_mode
9
9
  #
10
- # @return [ String ] The related enumration message depending on the parsed_options and type supplied
10
+ # @return [ String ] The related enumration message depending on the ParsedCli and type supplied
11
11
  def enum_message(type, detection_mode)
12
12
  return unless %w[plugins themes].include?(type)
13
13
 
14
- details = if parsed_options[:enumerate][:"vulnerable_#{type}"]
14
+ details = if ParsedCli.enumerate[:"vulnerable_#{type}"]
15
15
  'Vulnerable'
16
- elsif parsed_options[:enumerate][:"all_#{type}"]
16
+ elsif ParsedCli.enumerate[:"all_#{type}"]
17
17
  'All'
18
18
  else
19
19
  'Most Popular'
@@ -39,15 +39,15 @@ module WPScan
39
39
  #
40
40
  # @return [ Hash ]
41
41
  def default_opts(type)
42
- mode = parsed_options[:"#{type}_detection"] || parsed_options[:detection_mode]
42
+ mode = ParsedCli.options[:"#{type}_detection"] || ParsedCli.detection_mode
43
43
 
44
44
  {
45
45
  mode: mode,
46
- exclude_content: parsed_options[:exclude_content_based],
46
+ exclude_content: ParsedCli.exclude_content_based,
47
47
  show_progression: user_interaction?,
48
48
  version_detection: {
49
- mode: parsed_options[:"#{type}_version_detection"] || mode,
50
- confidence_threshold: parsed_options[:"#{type}_version_all"] ? 0 : 100
49
+ mode: ParsedCli.options[:"#{type}_version_detection"] || mode,
50
+ confidence_threshold: ParsedCli.options[:"#{type}_version_all"] ? 0 : 100
51
51
  }
52
52
  }
53
53
  end
@@ -61,7 +61,7 @@ module WPScan
61
61
 
62
62
  def enum_plugins
63
63
  opts = default_opts('plugins').merge(
64
- list: plugins_list_from_opts(parsed_options),
64
+ list: plugins_list_from_opts(ParsedCli.options),
65
65
  sort: true
66
66
  )
67
67
 
@@ -77,7 +77,7 @@ module WPScan
77
77
 
78
78
  plugins.each(&:version)
79
79
 
80
- plugins.select!(&:vulnerable?) if parsed_options[:enumerate][:vulnerable_plugins]
80
+ plugins.select!(&:vulnerable?) if ParsedCli.enumerate[:vulnerable_plugins]
81
81
 
82
82
  output('plugins', plugins: plugins)
83
83
  end
@@ -107,7 +107,7 @@ module WPScan
107
107
 
108
108
  def enum_themes
109
109
  opts = default_opts('themes').merge(
110
- list: themes_list_from_opts(parsed_options),
110
+ list: themes_list_from_opts(ParsedCli.options),
111
111
  sort: true
112
112
  )
113
113
 
@@ -123,7 +123,7 @@ module WPScan
123
123
 
124
124
  themes.each(&:version)
125
125
 
126
- themes.select!(&:vulnerable?) if parsed_options[:enumerate][:vulnerable_themes]
126
+ themes.select!(&:vulnerable?) if ParsedCli.enumerate[:vulnerable_themes]
127
127
 
128
128
  output('themes', themes: themes)
129
129
  end
@@ -145,28 +145,28 @@ module WPScan
145
145
  end
146
146
 
147
147
  def enum_timthumbs
148
- opts = default_opts('timthumbs').merge(list: parsed_options[:timthumbs_list])
148
+ opts = default_opts('timthumbs').merge(list: ParsedCli.timthumbs_list)
149
149
 
150
150
  output('@info', msg: "Enumerating Timthumbs #{enum_detection_message(opts[:mode])}") if user_interaction?
151
151
  output('timthumbs', timthumbs: target.timthumbs(opts))
152
152
  end
153
153
 
154
154
  def enum_config_backups
155
- opts = default_opts('config_backups').merge(list: parsed_options[:config_backups_list])
155
+ opts = default_opts('config_backups').merge(list: ParsedCli.config_backups_list)
156
156
 
157
157
  output('@info', msg: "Enumerating Config Backups #{enum_detection_message(opts[:mode])}") if user_interaction?
158
158
  output('config_backups', config_backups: target.config_backups(opts))
159
159
  end
160
160
 
161
161
  def enum_db_exports
162
- opts = default_opts('db_exports').merge(list: parsed_options[:db_exports_list])
162
+ opts = default_opts('db_exports').merge(list: ParsedCli.db_exports_list)
163
163
 
164
164
  output('@info', msg: "Enumerating DB Exports #{enum_detection_message(opts[:mode])}") if user_interaction?
165
165
  output('db_exports', db_exports: target.db_exports(opts))
166
166
  end
167
167
 
168
168
  def enum_medias
169
- opts = default_opts('medias').merge(range: parsed_options[:enumerate][:medias])
169
+ opts = default_opts('medias').merge(range: ParsedCli.enumerate[:medias])
170
170
 
171
171
  if user_interaction?
172
172
  output('@info',
@@ -181,13 +181,13 @@ module WPScan
181
181
  #
182
182
  # @return [ Boolean ] Wether or not to enumerate the users
183
183
  def enum_users?(opts)
184
- opts[:users] || (parsed_options[:passwords] && !parsed_options[:username] && !parsed_options[:usernames])
184
+ opts[:users] || (ParsedCli.passwords && !ParsedCli.username && !ParsedCli.usernames)
185
185
  end
186
186
 
187
187
  def enum_users
188
188
  opts = default_opts('users').merge(
189
189
  range: enum_users_range,
190
- list: parsed_options[:users_list]
190
+ list: ParsedCli.users_list
191
191
  )
192
192
 
193
193
  output('@info', msg: "Enumerating Users #{enum_detection_message(opts[:mode])}") if user_interaction?
@@ -198,7 +198,7 @@ module WPScan
198
198
  # If the --enumerate is used, the default value is handled by the Option
199
199
  # However, when using --passwords alone, the default has to be set by the code below
200
200
  def enum_users_range
201
- parsed_options[:enumerate][:users] || cli_enum_choices[0].choices[:u].validate(nil)
201
+ ParsedCli.enumerate[:users] || cli_enum_choices[0].choices[:u].validate(nil)
202
202
  end
203
203
  end
204
204
  end
@@ -18,9 +18,9 @@ module WPScan
18
18
  output(
19
19
  'theme',
20
20
  theme: target.main_theme(
21
- mode: parsed_options[:main_theme_detection] || parsed_options[:detection_mode]
21
+ mode: ParsedCli.main_theme_detection || ParsedCli.detection_mode
22
22
  ),
23
- verbose: parsed_options[:verbose]
23
+ verbose: ParsedCli.verbose
24
24
  )
25
25
  end
26
26
  end
@@ -24,7 +24,7 @@ module WPScan
24
24
  end
25
25
 
26
26
  def run
27
- return unless parsed_options[:passwords]
27
+ return unless ParsedCli.passwords
28
28
 
29
29
  if user_interaction?
30
30
  output('@info',
@@ -33,13 +33,13 @@ module WPScan
33
33
 
34
34
  attack_opts = {
35
35
  show_progression: user_interaction?,
36
- multicall_max_passwords: parsed_options[:multicall_max_passwords]
36
+ multicall_max_passwords: ParsedCli.multicall_max_passwords
37
37
  }
38
38
 
39
39
  begin
40
40
  found = []
41
41
 
42
- attacker.attack(users, passwords(parsed_options[:passwords]), attack_opts) do |user|
42
+ attacker.attack(users, passwords(ParsedCli.passwords), attack_opts) do |user|
43
43
  found << user
44
44
 
45
45
  attacker.progress_bar.log("[SUCCESS] - #{user.username} / #{user.password}")
@@ -61,9 +61,9 @@ module WPScan
61
61
 
62
62
  # @return [ CMSScanner::Finders::Finder ]
63
63
  def attacker_from_cli_options
64
- return unless parsed_options[:password_attack]
64
+ return unless ParsedCli.password_attack
65
65
 
66
- case parsed_options[:password_attack]
66
+ case ParsedCli.password_attack
67
67
  when :wp_login
68
68
  WPScan::Finders::Passwords::WpLogin.new(target)
69
69
  when :xmlrpc
@@ -94,9 +94,9 @@ module WPScan
94
94
 
95
95
  # @return [ Array<Users> ] The users to brute force
96
96
  def users
97
- return target.users unless parsed_options[:usernames]
97
+ return target.users unless ParsedCli.usernames
98
98
 
99
- parsed_options[:usernames].reduce([]) do |acc, elem|
99
+ ParsedCli.usernames.reduce([]) do |acc, elem|
100
100
  acc << Model::User.new(elem.chomp)
101
101
  end
102
102
  end
@@ -24,8 +24,8 @@ module WPScan
24
24
  output(
25
25
  'version',
26
26
  version: target.wp_version(
27
- mode: parsed_options[:wp_version_detection] || parsed_options[:detection_mode],
28
- confidence_threshold: parsed_options[:wp_version_all] ? 0 : 100,
27
+ mode: ParsedCli.wp_version_detection || ParsedCli.detection_mode,
28
+ confidence_threshold: ParsedCli.wp_version_all ? 0 : 100,
29
29
  show_progression: user_interaction?
30
30
  )
31
31
  )
@@ -14,7 +14,7 @@ module WPScan
14
14
 
15
15
  Model::EmergencyPwdResetScript.new(
16
16
  target.url(path),
17
- confidence: res.body =~ /password/i ? 100 : 40,
17
+ confidence: /password/i.match?(res.body) ? 100 : 40,
18
18
  found_by: DIRECT_ACCESS,
19
19
  references: {
20
20
  url: 'https://codex.wordpress.org/Resetting_Your_Password#Using_the_Emergency_Password_Reset_Script'
@@ -14,6 +14,8 @@ module WPScan
14
14
 
15
15
  url = target.url('wp-content/mu-plugins/')
16
16
 
17
+ target.mu_plugins = true
18
+
17
19
  return Model::MuPlugins.new(
18
20
  url,
19
21
  confidence: 70,
@@ -33,8 +35,6 @@ module WPScan
33
35
  return unless [200, 401, 403].include?(res.code)
34
36
  return if target.homepage_or_404?(res)
35
37
 
36
- # TODO: add the check for --exclude-content once implemented ?
37
-
38
38
  target.mu_plugins = true
39
39
 
40
40
  Model::MuPlugins.new(
@@ -7,6 +7,11 @@ module WPScan
7
7
  class AuthorIdBruteForcing < CMSScanner::Finders::Finder
8
8
  include CMSScanner::Finders::Finder::Enumerator
9
9
 
10
+ # @return [ Array<Integer> ]
11
+ def valid_response_codes
12
+ @valid_response_codes ||= [200, 301, 302]
13
+ end
14
+
10
15
  # @param [ Hash ] opts
11
16
  # @option opts [ Range ] :range Mandatory
12
17
  #
@@ -15,7 +20,7 @@ module WPScan
15
20
  found = []
16
21
  found_by_msg = 'Author Id Brute Forcing - %s (Aggressive Detection)'
17
22
 
18
- enumerate(target_urls(opts), opts) do |res, id|
23
+ enumerate(target_urls(opts), opts.merge(check_full_response: true)) do |res, id|
19
24
  username, found_by, confidence = potential_username(res)
20
25
 
21
26
  next unless username
@@ -49,7 +54,7 @@ module WPScan
49
54
  super(opts.merge(title: ' Brute Forcing Author IDs -'))
50
55
  end
51
56
 
52
- def request_params
57
+ def full_request_params
53
58
  { followlocation: true }
54
59
  end
55
60
 
@@ -50,7 +50,7 @@ module WPScan
50
50
 
51
51
  if uri.path =~ %r{/author/([^/\b]+)/?\z}i
52
52
  usernames << [Regexp.last_match[1], 'Author Pattern', 100]
53
- elsif uri.query =~ /author=[0-9]+/
53
+ elsif /author=[0-9]+/.match?(uri.query)
54
54
  usernames << [node.text.to_s.strip, 'Display Name', 30]
55
55
  end
56
56
  end
@@ -63,7 +63,7 @@ module WPScan
63
63
  def webshot_enabled?
64
64
  res = Browser.get(url, params: { webshot: 1, src: "http://#{default_allowed_domains.sample}" })
65
65
 
66
- res.body =~ /WEBSHOT_ENABLED == true/ ? false : true
66
+ /WEBSHOT_ENABLED == true/.match?(res.body) ? false : true
67
67
  end
68
68
 
69
69
  # @return [ Array<String> ] The default allowed domains (between the 2.0 and 2.8.13)
data/lib/wpscan.rb CHANGED
@@ -19,6 +19,7 @@ require 'wpscan/helper'
19
19
  require 'wpscan/db'
20
20
  require 'wpscan/version'
21
21
  require 'wpscan/errors'
22
+ require 'wpscan/parsed_cli'
22
23
  require 'wpscan/browser'
23
24
  require 'wpscan/target'
24
25
  require 'wpscan/finders'
@@ -5,11 +5,6 @@ module WPScan
5
5
  class Browser < CMSScanner::Browser
6
6
  extend Actions
7
7
 
8
- # @return [ String ] The path to the user agents list
9
- def user_agents_list
10
- @user_agents_list ||= DB_DIR.join('user-agents.txt').to_s
11
- end
12
-
13
8
  # @return [ String ]
14
9
  def default_user_agent
15
10
  "WPScan v#{VERSION} (https://wpscan.org/)"
@@ -8,11 +8,11 @@ module WPScan
8
8
  # /!\ Might want to also update the Enumeration#cli_options when some filenames are changed here
9
9
  FILES = %w[
10
10
  plugins.json themes.json wordpresses.json
11
- timthumbs-v3.txt user-agents.txt config_backups.txt
12
- db_exports.txt dynamic_finders.yml wp_fingerprints.json LICENSE
11
+ timthumbs-v3.txt config_backups.txt db_exports.txt
12
+ dynamic_finders.yml wp_fingerprints.json LICENSE
13
13
  ].freeze
14
14
 
15
- OLD_FILES = %w[wordpress.db dynamic_finders_01.yml].freeze
15
+ OLD_FILES = %w[wordpress.db user-agents.txt dynamic_finders_01.yml].freeze
16
16
 
17
17
  attr_reader :repo_directory
18
18
 
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WPScan
4
+ # To be able to use ParsedCli directly, rather than having to access it via WPscan::ParsedCli
5
+ class ParsedCli < CMSScanner::ParsedCli
6
+ end
7
+ end
@@ -45,13 +45,41 @@ module WPScan
45
45
  false
46
46
  end
47
47
 
48
+ COOKIE_PATTERNS = {
49
+ 'vjs' => /createCookie\('vjs','(?<c_value>\d+)',\d+\);/i
50
+ }.freeze
51
+
52
+ # Sometimes there is a mechanism in place on the blog, which requires a specific
53
+ # cookie and value to be added to requests. Lets try to detect and add them
54
+ def maybe_add_cookies
55
+ COOKIE_PATTERNS.each do |cookie_key, pattern|
56
+ next unless homepage_res.body =~ pattern
57
+
58
+ browser = Browser.instance
59
+
60
+ cookie_string = "#{cookie_key}=#{Regexp.last_match[:c_value]}"
61
+
62
+ cookie_string += "; #{browser.cookie_string}" if browser.cookie_string
63
+
64
+ browser.cookie_string = cookie_string
65
+
66
+ # Force recheck of the homepage when retying wordpress?
67
+ # No need to clear the cache, as the request (which will contain the cookies)
68
+ # will be different
69
+ @homepage_res = nil
70
+ @homepage_url = nil
71
+
72
+ break
73
+ end
74
+ end
75
+
48
76
  # @return [ String ]
49
77
  def registration_url
50
78
  multisite? ? url('wp-signup.php') : url('wp-login.php?action=register')
51
79
  end
52
80
 
53
81
  def wordpress_hosted?
54
- uri.host =~ /\.wordpress\.com$/i ? true : false
82
+ /\.wordpress\.com$/i.match?(uri.host) ? true : false
55
83
  end
56
84
 
57
85
  # @param [ String ] username
@@ -112,9 +112,9 @@ module WPScan
112
112
  def url(path = nil)
113
113
  return @uri.to_s unless path
114
114
 
115
- if path =~ %r{wp\-content/plugins}i
115
+ if %r{wp\-content/plugins}i.match?(path)
116
116
  path = +path.gsub('wp-content/plugins', plugins_dir)
117
- elsif path =~ /wp\-content/i
117
+ elsif /wp\-content/i.match?(path)
118
118
  path = +path.gsub('wp-content', content_dir)
119
119
  elsif path[0] != '/' && sub_dir
120
120
  path = "#{sub_dir}/#{path}"
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Version
4
4
  module WPScan
5
- VERSION = '3.5.0'
5
+ VERSION = '3.5.1'
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wpscan
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.5.0
4
+ version: 3.5.1
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: cms_scanner
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.0.43.2
19
+ version: 0.0.44.0
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.43.2
26
+ version: 0.0.44.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -114,14 +114,14 @@ dependencies:
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 0.66.0
117
+ version: 0.67.1
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 0.66.0
124
+ version: 0.67.1
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: simplecov
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -342,6 +342,7 @@ files:
342
342
  - lib/wpscan/finders/dynamic_finder/wp_version.rb
343
343
  - lib/wpscan/finders/finder/wp_version/smart_url_checker.rb
344
344
  - lib/wpscan/helper.rb
345
+ - lib/wpscan/parsed_cli.rb
345
346
  - lib/wpscan/references.rb
346
347
  - lib/wpscan/target.rb
347
348
  - lib/wpscan/target/platform/wordpress.rb
@@ -361,7 +362,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
361
362
  requirements:
362
363
  - - ">="
363
364
  - !ruby/object:Gem::Version
364
- version: '2.3'
365
+ version: '2.4'
365
366
  required_rubygems_version: !ruby/object:Gem::Requirement
366
367
  requirements:
367
368
  - - ">="