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
@@ -4,6 +4,5 @@
4
4
  "last_updated": <%= @wp_item.last_updated.to_json %>,
5
5
  "outdated": <%= @wp_item.outdated?.to_json %>,
6
6
  "readme_url": <%= @wp_item.readme_url.to_json %>,
7
- "changelog_url": <%= @wp_item.changelog_url.to_json %>,
8
7
  "directory_listing": <%= @wp_item.directory_listing?.to_json %>,
9
8
  "error_log_url": <% if @wp_item.error_log? %><%= @wp_item.url('error_log').to_json %><% else %>null<% end %>
data/bin/wpscan CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'wpscan'
4
5
 
data/lib/wpscan.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Gems
2
4
  # Believe it or not, active_support MUST be the first one,
3
5
  # otherwise encoding issues can happen when using JSON format.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  # Custom Browser
3
5
  class Browser < CMSScanner::Browser
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  # Needed to load at least the Core controller
3
5
  # Otherwise, the following error will be raised:
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  # Override to set the OptParser's summary width to 45 (instead of 40 from the CMSScanner)
3
5
  class Controllers < CMSScanner::Controllers
data/lib/wpscan/db.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'db/wp_item'
2
4
  require_relative 'db/updater'
3
5
  require_relative 'db/wp_items'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module DB
3
5
  module DynamicFinders
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module DB
3
5
  module DynamicFinders
@@ -60,7 +62,7 @@ module WPScan
60
62
 
61
63
  # @param [ String ] slug
62
64
  # @return [ Constant ]
63
- def self.maybe_create_modudle(slug)
65
+ def self.maybe_create_module(slug)
64
66
  # What about slugs such as js_composer which will be done as JsComposer, just like js-composer
65
67
  constant_name = classify_slug(slug)
66
68
 
@@ -73,10 +75,7 @@ module WPScan
73
75
 
74
76
  def self.create_versions_finders
75
77
  versions_finders_configs.each do |slug, finders|
76
- # Kind of an issue here, module is created even if there is no valid classes
77
- # Could put the #maybe_ directly in the #send() BUT it would be checked everytime,
78
- # which is kind of a waste
79
- mod = maybe_create_modudle(slug)
78
+ mod = maybe_create_module(slug)
80
79
 
81
80
  finders.each do |finder_class, config|
82
81
  klass = config['class'] || finder_class
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module DB
3
5
  module DynamicFinders
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module DB
3
5
  module DynamicFinders
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module DB
3
5
  # Fingerprints class
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module DB
3
5
  # Plugin DB
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module DB
3
5
  # WP Plugins
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module DB
3
5
  # Theme DB
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module DB
3
5
  # WP Themes
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module DB
3
5
  # Class used to perform DB updates
@@ -80,7 +82,7 @@ module WPScan
80
82
  url = "#{remote_file_url(filename)}.sha512"
81
83
 
82
84
  res = Browser.get(url, request_params)
83
- raise DownloadError, res if res.timed_out? || res.code != 200
85
+ raise Error::Download, res if res.timed_out? || res.code != 200
84
86
 
85
87
  res.body.chomp
86
88
  end
@@ -121,7 +123,7 @@ module WPScan
121
123
  file_url = remote_file_url(filename)
122
124
 
123
125
  res = Browser.get(file_url, request_params)
124
- raise DownloadError, res if res.timed_out? || res.code != 200
126
+ raise Error::Download, res if res.timed_out? || res.code != 200
125
127
 
126
128
  File.open(file_path, 'wb') { |f| f.write(res.body) }
127
129
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module DB
3
5
  # WpItem - super DB class for Plugin, Theme and Version
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module DB
3
5
  # WP Items
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module DB
3
5
  # WP Version
data/lib/wpscan/errors.rb CHANGED
@@ -1,5 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
- class Error < StandardError
4
+ module Error
5
+ include CMSScanner::Error
6
+
7
+ class Standard < StandardError
8
+ end
3
9
  end
4
10
  end
5
11
 
@@ -1,34 +1,38 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
- # HTTP Error
3
- class HTTPError < Error
4
- attr_reader :response
4
+ module Error
5
+ # HTTP Error
6
+ class HTTP < Standard
7
+ attr_reader :response
5
8
 
6
- # @param [ Typhoeus::Response ] res
7
- def initialize(response)
8
- @response = response
9
- end
9
+ # @param [ Typhoeus::Response ] res
10
+ def initialize(response)
11
+ @response = response
12
+ end
10
13
 
11
- def failure_details
12
- msg = response.effective_url
14
+ def failure_details
15
+ msg = response.effective_url
13
16
 
14
- msg += if response.code.zero? || response.timed_out?
15
- " (#{response.return_message})"
16
- else
17
- " (status: #{response.code})"
18
- end
17
+ msg += if response.code.zero? || response.timed_out?
18
+ " (#{response.return_message})"
19
+ else
20
+ " (status: #{response.code})"
21
+ end
19
22
 
20
- msg
21
- end
23
+ msg
24
+ end
22
25
 
23
- def to_s
24
- "HTTP Error: #{failure_details}"
26
+ def to_s
27
+ "HTTP Error: #{failure_details}"
28
+ end
25
29
  end
26
- end
27
30
 
28
- # Used in the Updater
29
- class DownloadError < HTTPError
30
- def to_s
31
- "Unable to get #{failure_details}"
31
+ # Used in the Updater
32
+ class Download < HTTP
33
+ def to_s
34
+ "Unable to get #{failure_details}"
35
+ end
32
36
  end
33
37
  end
34
38
  end
@@ -1,8 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
- # Error raised when there is a missing DB file and --no-update supplied
3
- class MissingDatabaseFile < Error
4
- def to_s
5
- 'Update required, you can not run a scan if a database file is missing.'
4
+ module Error
5
+ # Error raised when there is a missing DB file and --no-update supplied
6
+ class MissingDatabaseFile < Standard
7
+ def to_s
8
+ 'Update required, you can not run a scan if a database file is missing.'
9
+ end
6
10
  end
7
11
  end
8
12
  end
@@ -1,22 +1,32 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
- # WordPress hosted (*.wordpress.com)
3
- class WordPressHostedError < Error
4
- def to_s
5
- 'Scanning *.wordpress.com hosted blogs is not supported.'
4
+ module Error
5
+ # WordPress hosted (*.wordpress.com)
6
+ class WordPressHosted < Standard
7
+ def to_s
8
+ 'Scanning *.wordpress.com hosted blogs is not supported.'
9
+ end
6
10
  end
7
- end
8
11
 
9
- # Not WordPress Error
10
- class NotWordPressError < Error
11
- def to_s
12
- 'The remote website is up, but does not seem to be running WordPress.'
12
+ # Not WordPress Error
13
+ class NotWordPress < Standard
14
+ def to_s
15
+ 'The remote website is up, but does not seem to be running WordPress.'
16
+ end
17
+ end
18
+
19
+ # Invalid Wp Version (used in the WpVersion#new)
20
+ class InvalidWordPressVersion < Standard
21
+ def to_s
22
+ 'The WordPress version is invalid'
23
+ end
13
24
  end
14
- end
15
25
 
16
- # Invalid Wp Version (used in the WpVersion#new)
17
- class InvalidWordPressVersion < Error
18
- def to_s
19
- 'The WordPress version is invalid'
26
+ class WpContentDirNotDetected < Standard
27
+ def to_s
28
+ 'Unable to identify the wp-content dir, please supply it with --wp-content-dir'
29
+ end
20
30
  end
21
31
  end
22
32
  end
@@ -1,8 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
- # XML-RPC Not Detected
3
- class XMLRPCNotDetected < Error
4
- def to_s
5
- 'The XML-RPC Interface was not detected.'
4
+ module Error
5
+ # XML-RPC Not Detected
6
+ class XMLRPCNotDetected < Standard
7
+ def to_s
8
+ 'The XML-RPC Interface was not detected.'
9
+ end
6
10
  end
7
11
  end
8
12
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'wpscan/finders/finder/wp_version/smart_url_checker'
2
4
 
3
5
  require 'wpscan/finders/dynamic_finder/finder'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module Finders
3
5
  module DynamicFinder
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module Finders
3
5
  module DynamicFinder
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module Finders
3
5
  module DynamicFinder
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module Finders
3
5
  module DynamicFinder
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module Finders
3
5
  module DynamicFinder
@@ -9,9 +11,9 @@ module WPScan
9
11
 
10
12
  # @param [ String ] number
11
13
  # @param [ Hash ] finding_opts
12
- # @return [ WPScan::Version ]
14
+ # @return [ Model::Version ]
13
15
  def create_version(number, finding_opts)
14
- WPScan::Version.new(number, version_finding_opts(finding_opts))
16
+ Model::Version.new(number, version_finding_opts(finding_opts))
15
17
  end
16
18
 
17
19
  # @param [ Hash ] opts
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module Finders
3
5
  module DynamicFinder
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module Finders
3
5
  module DynamicFinder
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module Finders
3
5
  module DynamicFinder
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module Finders
3
5
  module DynamicFinder
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module Finders
3
5
  module DynamicFinder
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module WPScan
2
4
  module Finders
3
5
  module DynamicFinder
@@ -31,7 +33,7 @@ module WPScan
31
33
  configs.each do |klass, config|
32
34
  item = process_response(opts, target.homepage_res, slug, klass, config)
33
35
 
34
- found << item if item.is_a?(WpItem)
36
+ found << item if item.is_a?(Model::WpItem)
35
37
  end
36
38
  end
37
39
 
@@ -70,7 +72,7 @@ module WPScan
70
72
 
71
73
  item = process_response(opts, response, slug, klass, config)
72
74
 
73
- found << item if item.is_a?(WpItem)
75
+ found << item if item.is_a?(Model::WpItem)
74
76
  end
75
77
  end
76
78