wpscan 3.4.5 → 3.5.0

Sign up to get free protection for your applications and to get access to all the features.
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