wpscan 3.4.5 → 3.5.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 (140) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +21 -14
  3. data/app/app.rb +2 -0
  4. data/app/controllers.rb +2 -0
  5. data/app/controllers/aliases.rb +2 -0
  6. data/app/controllers/core.rb +6 -4
  7. data/app/controllers/custom_directories.rb +3 -1
  8. data/app/controllers/enumeration.rb +6 -0
  9. data/app/controllers/enumeration/cli_options.rb +2 -0
  10. data/app/controllers/enumeration/enum_methods.rb +2 -0
  11. data/app/controllers/main_theme.rb +2 -0
  12. data/app/controllers/password_attack.rb +6 -4
  13. data/app/controllers/wp_version.rb +2 -0
  14. data/app/finders.rb +2 -0
  15. data/app/finders/config_backups.rb +2 -0
  16. data/app/finders/config_backups/known_filenames.rb +4 -3
  17. data/app/finders/db_exports.rb +2 -0
  18. data/app/finders/db_exports/known_locations.rb +15 -3
  19. data/app/finders/interesting_findings.rb +2 -0
  20. data/app/finders/interesting_findings/backup_db.rb +5 -4
  21. data/app/finders/interesting_findings/debug_log.rb +3 -1
  22. data/app/finders/interesting_findings/duplicator_installer_log.rb +6 -5
  23. data/app/finders/interesting_findings/emergency_pwd_reset_script.rb +6 -4
  24. data/app/finders/interesting_findings/full_path_disclosure.rb +3 -1
  25. data/app/finders/interesting_findings/mu_plugins.rb +4 -2
  26. data/app/finders/interesting_findings/multisite.rb +3 -1
  27. data/app/finders/interesting_findings/readme.rb +8 -6
  28. data/app/finders/interesting_findings/registration.rb +3 -1
  29. data/app/finders/interesting_findings/tmm_db_migrate.rb +4 -2
  30. data/app/finders/interesting_findings/upload_directory_listing.rb +3 -1
  31. data/app/finders/interesting_findings/upload_sql_dump.rb +8 -10
  32. data/app/finders/interesting_findings/wp_cron.rb +3 -1
  33. data/app/finders/main_theme.rb +2 -0
  34. data/app/finders/main_theme/css_style.rb +3 -1
  35. data/app/finders/main_theme/urls_in_homepage.rb +3 -1
  36. data/app/finders/main_theme/woo_framework_meta_generator.rb +3 -1
  37. data/app/finders/medias.rb +2 -0
  38. data/app/finders/medias/attachment_brute_forcing.rb +3 -1
  39. data/app/finders/passwords.rb +2 -0
  40. data/app/finders/passwords/wp_login.rb +4 -1
  41. data/app/finders/passwords/xml_rpc.rb +2 -0
  42. data/app/finders/passwords/xml_rpc_multicall.rb +4 -2
  43. data/app/finders/plugin_version.rb +4 -2
  44. data/app/finders/plugin_version/readme.rb +9 -5
  45. data/app/finders/plugins.rb +2 -0
  46. data/app/finders/plugins/body_pattern.rb +3 -1
  47. data/app/finders/plugins/comment.rb +3 -1
  48. data/app/finders/plugins/config_parser.rb +3 -1
  49. data/app/finders/plugins/header_pattern.rb +3 -1
  50. data/app/finders/plugins/javascript_var.rb +3 -1
  51. data/app/finders/plugins/known_locations.rb +10 -8
  52. data/app/finders/plugins/query_parameter.rb +2 -0
  53. data/app/finders/plugins/urls_in_homepage.rb +3 -1
  54. data/app/finders/plugins/xpath.rb +3 -1
  55. data/app/finders/theme_version.rb +4 -2
  56. data/app/finders/theme_version/style.rb +3 -1
  57. data/app/finders/theme_version/woo_framework_meta_generator.rb +3 -1
  58. data/app/finders/themes.rb +2 -0
  59. data/app/finders/themes/known_locations.rb +12 -10
  60. data/app/finders/themes/urls_in_homepage.rb +3 -1
  61. data/app/finders/timthumb_version.rb +3 -1
  62. data/app/finders/timthumb_version/bad_request.rb +3 -1
  63. data/app/finders/timthumbs.rb +2 -0
  64. data/app/finders/timthumbs/known_locations.rb +12 -3
  65. data/app/finders/users.rb +2 -0
  66. data/app/finders/users/author_id_brute_forcing.rb +3 -1
  67. data/app/finders/users/author_posts.rb +3 -1
  68. data/app/finders/users/login_error_messages.rb +3 -1
  69. data/app/finders/users/oembed_api.rb +6 -4
  70. data/app/finders/users/rss_generator.rb +7 -5
  71. data/app/finders/users/wp_json_api.rb +16 -6
  72. data/app/finders/users/yoast_seo_author_sitemap.rb +6 -4
  73. data/app/finders/wp_items.rb +2 -0
  74. data/app/finders/wp_items/urls_in_homepage.rb +2 -0
  75. data/app/finders/wp_version.rb +2 -0
  76. data/app/finders/wp_version/atom_generator.rb +2 -0
  77. data/app/finders/wp_version/rdf_generator.rb +2 -0
  78. data/app/finders/wp_version/readme.rb +4 -2
  79. data/app/finders/wp_version/rss_generator.rb +2 -0
  80. data/app/finders/wp_version/unique_fingerprinting.rb +3 -1
  81. data/app/models.rb +8 -0
  82. data/app/models/config_backup.rb +6 -2
  83. data/app/models/db_export.rb +6 -2
  84. data/app/models/interesting_finding.rb +36 -32
  85. data/app/models/media.rb +6 -2
  86. data/app/models/plugin.rb +25 -17
  87. data/app/models/theme.rb +83 -75
  88. data/app/models/timthumb.rb +58 -54
  89. data/app/models/wp_item.rb +140 -128
  90. data/app/models/wp_version.rb +47 -44
  91. data/app/models/xml_rpc.rb +18 -14
  92. data/app/views/cli/wp_item.erb +0 -3
  93. data/app/views/json/wp_item.erb +0 -1
  94. data/bin/wpscan +1 -0
  95. data/lib/wpscan.rb +2 -0
  96. data/lib/wpscan/browser.rb +2 -0
  97. data/lib/wpscan/controller.rb +2 -0
  98. data/lib/wpscan/controllers.rb +2 -0
  99. data/lib/wpscan/db.rb +2 -0
  100. data/lib/wpscan/db/dynamic_finders/base.rb +2 -0
  101. data/lib/wpscan/db/dynamic_finders/plugin.rb +4 -5
  102. data/lib/wpscan/db/dynamic_finders/theme.rb +2 -0
  103. data/lib/wpscan/db/dynamic_finders/wordpress.rb +2 -0
  104. data/lib/wpscan/db/fingerprints.rb +2 -0
  105. data/lib/wpscan/db/plugin.rb +2 -0
  106. data/lib/wpscan/db/plugins.rb +2 -0
  107. data/lib/wpscan/db/theme.rb +2 -0
  108. data/lib/wpscan/db/themes.rb +2 -0
  109. data/lib/wpscan/db/updater.rb +4 -2
  110. data/lib/wpscan/db/wp_item.rb +2 -0
  111. data/lib/wpscan/db/wp_items.rb +2 -0
  112. data/lib/wpscan/db/wp_version.rb +2 -0
  113. data/lib/wpscan/errors.rb +7 -1
  114. data/lib/wpscan/errors/http.rb +27 -23
  115. data/lib/wpscan/errors/update.rb +8 -4
  116. data/lib/wpscan/errors/wordpress.rb +24 -14
  117. data/lib/wpscan/errors/xmlrpc.rb +8 -4
  118. data/lib/wpscan/finders.rb +2 -0
  119. data/lib/wpscan/finders/dynamic_finder/finder.rb +2 -0
  120. data/lib/wpscan/finders/dynamic_finder/version/body_pattern.rb +2 -0
  121. data/lib/wpscan/finders/dynamic_finder/version/comment.rb +2 -0
  122. data/lib/wpscan/finders/dynamic_finder/version/config_parser.rb +2 -0
  123. data/lib/wpscan/finders/dynamic_finder/version/finder.rb +4 -2
  124. data/lib/wpscan/finders/dynamic_finder/version/header_pattern.rb +2 -0
  125. data/lib/wpscan/finders/dynamic_finder/version/javascript_var.rb +2 -0
  126. data/lib/wpscan/finders/dynamic_finder/version/query_parameter.rb +2 -0
  127. data/lib/wpscan/finders/dynamic_finder/version/xpath.rb +2 -0
  128. data/lib/wpscan/finders/dynamic_finder/wp_item_version.rb +2 -0
  129. data/lib/wpscan/finders/dynamic_finder/wp_items/finder.rb +4 -2
  130. data/lib/wpscan/finders/dynamic_finder/wp_version.rb +4 -2
  131. data/lib/wpscan/finders/finder/wp_version/smart_url_checker.rb +4 -2
  132. data/lib/wpscan/helper.rb +2 -0
  133. data/lib/wpscan/references.rb +2 -0
  134. data/lib/wpscan/target.rb +12 -1
  135. data/lib/wpscan/target/platform/wordpress.rb +15 -1
  136. data/lib/wpscan/target/platform/wordpress/custom_directories.rb +23 -3
  137. data/lib/wpscan/version.rb +3 -1
  138. data/lib/wpscan/vulnerability.rb +2 -0
  139. data/lib/wpscan/vulnerable.rb +2 -0
  140. metadata +35 -8
@@ -1,12 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module Finders
3
5
  module DynamicFinder
4
6
  module WpVersion
5
7
  module Finder
6
8
  def create_version(number, finding_opts)
7
- return unless WPScan::WpVersion.valid?(number)
9
+ return unless Model::WpVersion.valid?(number)
8
10
 
9
- WPScan::WpVersion.new(number, version_finding_opts(finding_opts))
11
+ Model::WpVersion.new(number, version_finding_opts(finding_opts))
10
12
  end
11
13
  end
12
14
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module Finders
3
5
  class Finder
@@ -7,13 +9,13 @@ module WPScan
7
9
  include CMSScanner::Finders::Finder::SmartURLChecker
8
10
 
9
11
  def create_version(number, opts = {})
10
- WPScan::WpVersion.new(
12
+ Model::WpVersion.new(
11
13
  number,
12
14
  found_by: opts[:found_by] || found_by,
13
15
  confidence: opts[:confidence] || 80,
14
16
  interesting_entries: opts[:entries]
15
17
  )
16
- rescue WPScan::InvalidWordPressVersion
18
+ rescue WPScan::Error::InvalidWordPressVersion
17
19
  nil # Invalid Version returned as nil and will be ignored by Finders
18
20
  end
19
21
  end
data/lib/wpscan/helper.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  def read_json_file(file)
2
4
  JSON.parse(File.read(file))
3
5
  rescue StandardError => e
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  # References module (which should be included along with the CMSScanner::References)
3
5
  # to allow the use of the wpvulndb reference
data/lib/wpscan/target.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'wpscan/target/platform/wordpress'
2
4
 
3
5
  module WPScan
@@ -5,6 +7,15 @@ module WPScan
5
7
  class Target < CMSScanner::Target
6
8
  include Platform::WordPress
7
9
 
10
+ # @return [ Hash ]
11
+ def head_or_get_request_params
12
+ @head_or_get_request_params ||= if Browser.head(url).code == 405
13
+ { method: :get, maxfilesize: 1 }
14
+ else
15
+ { method: :head }
16
+ end
17
+ end
18
+
8
19
  # @return [ Boolean ]
9
20
  def vulnerable?
10
21
  [@wp_version, @main_theme, @plugins, @themes, @timthumbs].each do |e|
@@ -21,7 +32,7 @@ module WPScan
21
32
 
22
33
  # @return [ XMLRPC, nil ]
23
34
  def xmlrpc
24
- @xmlrpc ||= interesting_findings&.select { |f| f.is_a?(WPScan::XMLRPC) }&.first
35
+ @xmlrpc ||= interesting_findings&.select { |f| f.is_a?(Model::XMLRPC) }&.first
25
36
  end
26
37
 
27
38
  # @param [ Hash ] opts
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  %w[custom_directories].each do |required|
2
4
  require "wpscan/target/platform/wordpress/#{required}"
3
5
  end
@@ -72,9 +74,21 @@ module WPScan
72
74
  )
73
75
  end
74
76
 
77
+ # The login page is checked for a potential redirection (from http to https)
78
+ # the first time the method is called, and the effective_url is then used
79
+ # if suitable, otherwise the default wp-login will be.
80
+ #
75
81
  # @return [ String ] The URL to the login page
76
82
  def login_url
77
- url('wp-login.php')
83
+ return @login_url if @login_url
84
+
85
+ @login_url = url('wp-login.php')
86
+
87
+ res = Browser.get_and_follow_location(@login_url)
88
+
89
+ @login_url = res.effective_url if res.effective_url =~ /wp\-login\.php\z/i && in_scope?(res.effective_url)
90
+
91
+ @login_url
78
92
  end
79
93
  end
80
94
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  class Target < CMSScanner::Target
3
5
  module Platform
@@ -15,11 +17,15 @@ module WPScan
15
17
  def content_dir
16
18
  unless @content_dir
17
19
  escaped_url = Regexp.escape(url).gsub(/https?/i, 'https?')
18
- pattern = %r{#{escaped_url}(.+?)\/(?:themes|plugins|uploads|cache)\/}i
20
+ pattern = %r{#{escaped_url}([\w\s\-\/]+)\/(?:themes|plugins|uploads|cache)\/}i
19
21
 
20
22
  in_scope_urls(homepage_res) do |url|
21
23
  return @content_dir = Regexp.last_match[1] if url.match(pattern)
22
24
  end
25
+
26
+ xpath_pattern_from_page('//script[not(@src)]', pattern, homepage_res) do |match|
27
+ return @content_dir = match[1]
28
+ end
23
29
  end
24
30
 
25
31
  @content_dir
@@ -50,6 +56,13 @@ module WPScan
50
56
  plugins_uri.to_s
51
57
  end
52
58
 
59
+ # @param [ String ] slug
60
+ #
61
+ # @return [ String ]
62
+ def plugin_url(slug)
63
+ plugins_uri.join("#{URI.encode(slug)}/").to_s
64
+ end
65
+
53
66
  # @return [ String ]
54
67
  def themes_dir
55
68
  @themes_dir ||= "#{content_dir}/themes"
@@ -65,6 +78,13 @@ module WPScan
65
78
  themes_uri.to_s
66
79
  end
67
80
 
81
+ # @param [ String ] slug
82
+ #
83
+ # @return [ String ]
84
+ def theme_url(slug)
85
+ themes_uri.join("#{URI.encode(slug)}/").to_s
86
+ end
87
+
68
88
  # TODO: Factorise the code and the content_dir one ?
69
89
  # @return [ String, False ] String of the sub_dir found, false otherwise
70
90
  # @note: nil can not be returned here, otherwise if there is no sub_dir
@@ -93,9 +113,9 @@ module WPScan
93
113
  return @uri.to_s unless path
94
114
 
95
115
  if path =~ %r{wp\-content/plugins}i
96
- path.gsub!('wp-content/plugins', plugins_dir)
116
+ path = +path.gsub('wp-content/plugins', plugins_dir)
97
117
  elsif path =~ /wp\-content/i
98
- path.gsub!('wp-content', content_dir)
118
+ path = +path.gsub('wp-content', content_dir)
99
119
  elsif path[0] != '/' && sub_dir
100
120
  path = "#{sub_dir}/#{path}"
101
121
  end
@@ -1,4 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Version
2
4
  module WPScan
3
- VERSION = '3.4.5'.freeze
5
+ VERSION = '3.5.0'
4
6
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  # Specific implementation
3
5
  class Vulnerability < CMSScanner::Vulnerability
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  # Module to include in vulnerable WP item such as WpVersion.
3
5
  # the vulnerabilities method should be implemented
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.4.5
4
+ version: 3.5.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-10 00:00:00.000000000 Z
11
+ date: 2019-04-03 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.41.4
19
+ version: 0.0.43.2
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.41.4
26
+ version: 0.0.43.2
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.8.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: memory_profiler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.9.13
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.9.13
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -100,14 +114,14 @@ dependencies:
100
114
  requirements:
101
115
  - - "~>"
102
116
  - !ruby/object:Gem::Version
103
- version: 0.65.0
117
+ version: 0.66.0
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
122
  - - "~>"
109
123
  - !ruby/object:Gem::Version
110
- version: 0.65.0
124
+ version: 0.66.0
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: simplecov
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -122,6 +136,20 @@ dependencies:
122
136
  - - "~>"
123
137
  - !ruby/object:Gem::Version
124
138
  version: 0.16.1
139
+ - !ruby/object:Gem::Dependency
140
+ name: stackprof
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 0.2.12
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 0.2.12
125
153
  - !ruby/object:Gem::Dependency
126
154
  name: webmock
127
155
  requirement: !ruby/object:Gem::Requirement
@@ -340,8 +368,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
340
368
  - !ruby/object:Gem::Version
341
369
  version: '0'
342
370
  requirements: []
343
- rubyforge_project:
344
- rubygems_version: 2.6.10
371
+ rubygems_version: 3.0.3
345
372
  signing_key:
346
373
  specification_version: 4
347
374
  summary: WPScan - WordPress Vulnerability Scanner