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.
- checksums.yaml +5 -5
- data/README.md +21 -14
- data/app/app.rb +2 -0
- data/app/controllers.rb +2 -0
- data/app/controllers/aliases.rb +2 -0
- data/app/controllers/core.rb +6 -4
- data/app/controllers/custom_directories.rb +3 -1
- data/app/controllers/enumeration.rb +6 -0
- data/app/controllers/enumeration/cli_options.rb +2 -0
- data/app/controllers/enumeration/enum_methods.rb +2 -0
- data/app/controllers/main_theme.rb +2 -0
- data/app/controllers/password_attack.rb +6 -4
- data/app/controllers/wp_version.rb +2 -0
- data/app/finders.rb +2 -0
- data/app/finders/config_backups.rb +2 -0
- data/app/finders/config_backups/known_filenames.rb +4 -3
- data/app/finders/db_exports.rb +2 -0
- data/app/finders/db_exports/known_locations.rb +15 -3
- data/app/finders/interesting_findings.rb +2 -0
- data/app/finders/interesting_findings/backup_db.rb +5 -4
- data/app/finders/interesting_findings/debug_log.rb +3 -1
- data/app/finders/interesting_findings/duplicator_installer_log.rb +6 -5
- data/app/finders/interesting_findings/emergency_pwd_reset_script.rb +6 -4
- data/app/finders/interesting_findings/full_path_disclosure.rb +3 -1
- data/app/finders/interesting_findings/mu_plugins.rb +4 -2
- data/app/finders/interesting_findings/multisite.rb +3 -1
- data/app/finders/interesting_findings/readme.rb +8 -6
- data/app/finders/interesting_findings/registration.rb +3 -1
- data/app/finders/interesting_findings/tmm_db_migrate.rb +4 -2
- data/app/finders/interesting_findings/upload_directory_listing.rb +3 -1
- data/app/finders/interesting_findings/upload_sql_dump.rb +8 -10
- data/app/finders/interesting_findings/wp_cron.rb +3 -1
- data/app/finders/main_theme.rb +2 -0
- data/app/finders/main_theme/css_style.rb +3 -1
- data/app/finders/main_theme/urls_in_homepage.rb +3 -1
- data/app/finders/main_theme/woo_framework_meta_generator.rb +3 -1
- data/app/finders/medias.rb +2 -0
- data/app/finders/medias/attachment_brute_forcing.rb +3 -1
- data/app/finders/passwords.rb +2 -0
- data/app/finders/passwords/wp_login.rb +4 -1
- data/app/finders/passwords/xml_rpc.rb +2 -0
- data/app/finders/passwords/xml_rpc_multicall.rb +4 -2
- data/app/finders/plugin_version.rb +4 -2
- data/app/finders/plugin_version/readme.rb +9 -5
- data/app/finders/plugins.rb +2 -0
- data/app/finders/plugins/body_pattern.rb +3 -1
- data/app/finders/plugins/comment.rb +3 -1
- data/app/finders/plugins/config_parser.rb +3 -1
- data/app/finders/plugins/header_pattern.rb +3 -1
- data/app/finders/plugins/javascript_var.rb +3 -1
- data/app/finders/plugins/known_locations.rb +10 -8
- data/app/finders/plugins/query_parameter.rb +2 -0
- data/app/finders/plugins/urls_in_homepage.rb +3 -1
- data/app/finders/plugins/xpath.rb +3 -1
- data/app/finders/theme_version.rb +4 -2
- data/app/finders/theme_version/style.rb +3 -1
- data/app/finders/theme_version/woo_framework_meta_generator.rb +3 -1
- data/app/finders/themes.rb +2 -0
- data/app/finders/themes/known_locations.rb +12 -10
- data/app/finders/themes/urls_in_homepage.rb +3 -1
- data/app/finders/timthumb_version.rb +3 -1
- data/app/finders/timthumb_version/bad_request.rb +3 -1
- data/app/finders/timthumbs.rb +2 -0
- data/app/finders/timthumbs/known_locations.rb +12 -3
- data/app/finders/users.rb +2 -0
- data/app/finders/users/author_id_brute_forcing.rb +3 -1
- data/app/finders/users/author_posts.rb +3 -1
- data/app/finders/users/login_error_messages.rb +3 -1
- data/app/finders/users/oembed_api.rb +6 -4
- data/app/finders/users/rss_generator.rb +7 -5
- data/app/finders/users/wp_json_api.rb +16 -6
- data/app/finders/users/yoast_seo_author_sitemap.rb +6 -4
- data/app/finders/wp_items.rb +2 -0
- data/app/finders/wp_items/urls_in_homepage.rb +2 -0
- data/app/finders/wp_version.rb +2 -0
- data/app/finders/wp_version/atom_generator.rb +2 -0
- data/app/finders/wp_version/rdf_generator.rb +2 -0
- data/app/finders/wp_version/readme.rb +4 -2
- data/app/finders/wp_version/rss_generator.rb +2 -0
- data/app/finders/wp_version/unique_fingerprinting.rb +3 -1
- data/app/models.rb +8 -0
- data/app/models/config_backup.rb +6 -2
- data/app/models/db_export.rb +6 -2
- data/app/models/interesting_finding.rb +36 -32
- data/app/models/media.rb +6 -2
- data/app/models/plugin.rb +25 -17
- data/app/models/theme.rb +83 -75
- data/app/models/timthumb.rb +58 -54
- data/app/models/wp_item.rb +140 -128
- data/app/models/wp_version.rb +47 -44
- data/app/models/xml_rpc.rb +18 -14
- data/app/views/cli/wp_item.erb +0 -3
- data/app/views/json/wp_item.erb +0 -1
- data/bin/wpscan +1 -0
- data/lib/wpscan.rb +2 -0
- data/lib/wpscan/browser.rb +2 -0
- data/lib/wpscan/controller.rb +2 -0
- data/lib/wpscan/controllers.rb +2 -0
- data/lib/wpscan/db.rb +2 -0
- data/lib/wpscan/db/dynamic_finders/base.rb +2 -0
- data/lib/wpscan/db/dynamic_finders/plugin.rb +4 -5
- data/lib/wpscan/db/dynamic_finders/theme.rb +2 -0
- data/lib/wpscan/db/dynamic_finders/wordpress.rb +2 -0
- data/lib/wpscan/db/fingerprints.rb +2 -0
- data/lib/wpscan/db/plugin.rb +2 -0
- data/lib/wpscan/db/plugins.rb +2 -0
- data/lib/wpscan/db/theme.rb +2 -0
- data/lib/wpscan/db/themes.rb +2 -0
- data/lib/wpscan/db/updater.rb +4 -2
- data/lib/wpscan/db/wp_item.rb +2 -0
- data/lib/wpscan/db/wp_items.rb +2 -0
- data/lib/wpscan/db/wp_version.rb +2 -0
- data/lib/wpscan/errors.rb +7 -1
- data/lib/wpscan/errors/http.rb +27 -23
- data/lib/wpscan/errors/update.rb +8 -4
- data/lib/wpscan/errors/wordpress.rb +24 -14
- data/lib/wpscan/errors/xmlrpc.rb +8 -4
- data/lib/wpscan/finders.rb +2 -0
- data/lib/wpscan/finders/dynamic_finder/finder.rb +2 -0
- data/lib/wpscan/finders/dynamic_finder/version/body_pattern.rb +2 -0
- data/lib/wpscan/finders/dynamic_finder/version/comment.rb +2 -0
- data/lib/wpscan/finders/dynamic_finder/version/config_parser.rb +2 -0
- data/lib/wpscan/finders/dynamic_finder/version/finder.rb +4 -2
- data/lib/wpscan/finders/dynamic_finder/version/header_pattern.rb +2 -0
- data/lib/wpscan/finders/dynamic_finder/version/javascript_var.rb +2 -0
- data/lib/wpscan/finders/dynamic_finder/version/query_parameter.rb +2 -0
- data/lib/wpscan/finders/dynamic_finder/version/xpath.rb +2 -0
- data/lib/wpscan/finders/dynamic_finder/wp_item_version.rb +2 -0
- data/lib/wpscan/finders/dynamic_finder/wp_items/finder.rb +4 -2
- data/lib/wpscan/finders/dynamic_finder/wp_version.rb +4 -2
- data/lib/wpscan/finders/finder/wp_version/smart_url_checker.rb +4 -2
- data/lib/wpscan/helper.rb +2 -0
- data/lib/wpscan/references.rb +2 -0
- data/lib/wpscan/target.rb +12 -1
- data/lib/wpscan/target/platform/wordpress.rb +15 -1
- data/lib/wpscan/target/platform/wordpress/custom_directories.rb +23 -3
- data/lib/wpscan/version.rb +3 -1
- data/lib/wpscan/vulnerability.rb +2 -0
- data/lib/wpscan/vulnerable.rb +2 -0
- metadata +35 -8
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module Plugins
|
|
@@ -14,7 +16,7 @@ module WPScan
|
|
|
14
16
|
found = []
|
|
15
17
|
|
|
16
18
|
(items_from_links('plugins') + items_from_codes('plugins')).uniq.sort.each do |slug|
|
|
17
|
-
found << Plugin.new(slug, target, opts.merge(found_by: found_by, confidence: 80))
|
|
19
|
+
found << Model::Plugin.new(slug, target, opts.merge(found_by: found_by, confidence: 80))
|
|
18
20
|
end
|
|
19
21
|
|
|
20
22
|
found
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module Plugins
|
|
@@ -16,7 +18,7 @@ module WPScan
|
|
|
16
18
|
response.html.xpath(config['xpath']).each do |node|
|
|
17
19
|
next if config['pattern'] && !node.text.match(config['pattern'])
|
|
18
20
|
|
|
19
|
-
return Plugin.new(
|
|
21
|
+
return Model::Plugin.new(
|
|
20
22
|
slug,
|
|
21
23
|
target,
|
|
22
24
|
opts.merge(found_by: found_by(klass), confidence: config['confidence'] || DEFAULT_CONFIDENCE)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require_relative 'theme_version/style'
|
|
2
4
|
require_relative 'theme_version/woo_framework_meta_generator'
|
|
3
5
|
|
|
@@ -8,7 +10,7 @@ module WPScan
|
|
|
8
10
|
class Base
|
|
9
11
|
include CMSScanner::Finders::UniqueFinder
|
|
10
12
|
|
|
11
|
-
# @param [
|
|
13
|
+
# @param [ Model::Theme ] theme
|
|
12
14
|
def initialize(theme)
|
|
13
15
|
finders <<
|
|
14
16
|
ThemeVersion::Style.new(theme) <<
|
|
@@ -19,7 +21,7 @@ module WPScan
|
|
|
19
21
|
|
|
20
22
|
# Load the finders associated with the theme
|
|
21
23
|
#
|
|
22
|
-
# @param [
|
|
24
|
+
# @param [ Model::Theme ] theme
|
|
23
25
|
def load_specific_finders(theme)
|
|
24
26
|
module_name = theme.classify
|
|
25
27
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module ThemeVersion
|
|
@@ -30,7 +32,7 @@ module WPScan
|
|
|
30
32
|
def style_version
|
|
31
33
|
return unless Browser.get(target.style_url).body =~ /Version:[\t ]*(?!trunk)([0-9a-z\.-]+)/i
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
Model::Version.new(
|
|
34
36
|
Regexp.last_match[1],
|
|
35
37
|
found_by: found_by,
|
|
36
38
|
confidence: 80,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module ThemeVersion
|
|
@@ -11,7 +13,7 @@ module WPScan
|
|
|
11
13
|
|
|
12
14
|
return unless Regexp.last_match[1] == target.slug
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
Model::Version.new(Regexp.last_match[2], found_by: found_by, confidence: 80)
|
|
15
17
|
end
|
|
16
18
|
end
|
|
17
19
|
end
|
data/app/finders/themes.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module Themes
|
|
@@ -5,6 +7,11 @@ module WPScan
|
|
|
5
7
|
class KnownLocations < CMSScanner::Finders::Finder
|
|
6
8
|
include CMSScanner::Finders::Finder::Enumerator
|
|
7
9
|
|
|
10
|
+
# @return [ Array<Integer> ]
|
|
11
|
+
def valid_response_codes
|
|
12
|
+
@valid_response_codes ||= [200, 401, 403, 301, 500].freeze
|
|
13
|
+
end
|
|
14
|
+
|
|
8
15
|
# @param [ Hash ] opts
|
|
9
16
|
# @option opts [ String ] :list
|
|
10
17
|
#
|
|
@@ -12,12 +19,8 @@ module WPScan
|
|
|
12
19
|
def aggressive(opts = {})
|
|
13
20
|
found = []
|
|
14
21
|
|
|
15
|
-
enumerate(target_urls(opts), opts) do |
|
|
16
|
-
|
|
17
|
-
# As a result, it might remove false positive due to redirection to the homepage
|
|
18
|
-
next unless [200, 401, 403, 301].include?(res.code)
|
|
19
|
-
|
|
20
|
-
found << WPScan::Theme.new(slug, target, opts.merge(found_by: found_by, confidence: 80))
|
|
22
|
+
enumerate(target_urls(opts), opts.merge(check_full_response: [200, 401, 403, 500])) do |_res, slug|
|
|
23
|
+
found << Model::Theme.new(slug, target, opts.merge(found_by: found_by, confidence: 80))
|
|
21
24
|
end
|
|
22
25
|
|
|
23
26
|
found
|
|
@@ -28,12 +31,11 @@ module WPScan
|
|
|
28
31
|
#
|
|
29
32
|
# @return [ Hash ]
|
|
30
33
|
def target_urls(opts = {})
|
|
31
|
-
slugs
|
|
32
|
-
urls
|
|
33
|
-
themes_url = target.url('wp-content/themes/')
|
|
34
|
+
slugs = opts[:list] || DB::Themes.vulnerable_slugs
|
|
35
|
+
urls = {}
|
|
34
36
|
|
|
35
37
|
slugs.each do |slug|
|
|
36
|
-
urls[
|
|
38
|
+
urls[target.theme_url(slug)] = slug
|
|
37
39
|
end
|
|
38
40
|
|
|
39
41
|
urls
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module Themes
|
|
@@ -12,7 +14,7 @@ module WPScan
|
|
|
12
14
|
found = []
|
|
13
15
|
|
|
14
16
|
(items_from_links('themes') + items_from_codes('themes')).uniq.sort.each do |slug|
|
|
15
|
-
found <<
|
|
17
|
+
found << Model::Theme.new(slug, target, opts.merge(found_by: found_by, confidence: 80))
|
|
16
18
|
end
|
|
17
19
|
|
|
18
20
|
found
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require_relative 'timthumb_version/bad_request'
|
|
2
4
|
|
|
3
5
|
module WPScan
|
|
@@ -7,7 +9,7 @@ module WPScan
|
|
|
7
9
|
class Base
|
|
8
10
|
include CMSScanner::Finders::UniqueFinder
|
|
9
11
|
|
|
10
|
-
# @param [
|
|
12
|
+
# @param [ Model::Timthumb ] target
|
|
11
13
|
def initialize(target)
|
|
12
14
|
finders << TimthumbVersion::BadRequest.new(target)
|
|
13
15
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module TimthumbVersion
|
|
@@ -8,7 +10,7 @@ module WPScan
|
|
|
8
10
|
def aggressive(_opts = {})
|
|
9
11
|
return unless Browser.get(target.url).body =~ /(TimThumb version\s*: ([^<]+))/
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
Model::Version.new(
|
|
12
14
|
Regexp.last_match[2],
|
|
13
15
|
found_by: 'Bad Request (Aggressive Detection)',
|
|
14
16
|
confidence: 90,
|
data/app/finders/timthumbs.rb
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module Timthumbs
|
|
4
6
|
# Known Locations Timthumbs Finder
|
|
7
|
+
# Note: A vulnerable version, 2.8.13 can be found here:
|
|
8
|
+
# https://github.com/GabrielGil/TimThumb/blob/980c3d6a823477761570475e8b83d3e9fcd2d7ae/timthumb.php
|
|
5
9
|
class KnownLocations < CMSScanner::Finders::Finder
|
|
6
10
|
include CMSScanner::Finders::Finder::Enumerator
|
|
7
11
|
|
|
12
|
+
# @return [ Array<Integer> ]
|
|
13
|
+
def valid_response_codes
|
|
14
|
+
@valid_response_codes ||= [400]
|
|
15
|
+
end
|
|
16
|
+
|
|
8
17
|
# @param [ Hash ] opts
|
|
9
18
|
# @option opts [ String ] :list Mandatory
|
|
10
19
|
#
|
|
@@ -12,10 +21,10 @@ module WPScan
|
|
|
12
21
|
def aggressive(opts = {})
|
|
13
22
|
found = []
|
|
14
23
|
|
|
15
|
-
enumerate(target_urls(opts), opts) do |res|
|
|
16
|
-
next unless res.
|
|
24
|
+
enumerate(target_urls(opts), opts.merge(check_full_response: 400)) do |res|
|
|
25
|
+
next unless res.body =~ /no image specified/i
|
|
17
26
|
|
|
18
|
-
found <<
|
|
27
|
+
found << Model::Timthumb.new(res.request.url, opts.merge(found_by: found_by, confidence: 100))
|
|
19
28
|
end
|
|
20
29
|
|
|
21
30
|
found
|
data/app/finders/users.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module Users
|
|
@@ -18,7 +20,7 @@ module WPScan
|
|
|
18
20
|
|
|
19
21
|
next unless username
|
|
20
22
|
|
|
21
|
-
found <<
|
|
23
|
+
found << Model::User.new(
|
|
22
24
|
username,
|
|
23
25
|
id: id,
|
|
24
26
|
found_by: format(found_by_msg, found_by),
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module Users
|
|
@@ -10,7 +12,7 @@ module WPScan
|
|
|
10
12
|
found_by_msg = 'Author Posts - %s (Passive Detection)'
|
|
11
13
|
|
|
12
14
|
usernames(opts).reduce([]) do |a, e|
|
|
13
|
-
a <<
|
|
15
|
+
a << Model::User.new(
|
|
14
16
|
e[0],
|
|
15
17
|
found_by: format(found_by_msg, e[1]),
|
|
16
18
|
confidence: e[2]
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module Users
|
|
@@ -24,7 +26,7 @@ module WPScan
|
|
|
24
26
|
|
|
25
27
|
next unless error =~ /The password you entered for the username|Incorrect Password/i
|
|
26
28
|
|
|
27
|
-
found <<
|
|
29
|
+
found << Model::User.new(username, found_by: found_by, confidence: 100)
|
|
28
30
|
end
|
|
29
31
|
|
|
30
32
|
found
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module Users
|
|
@@ -21,10 +23,10 @@ module WPScan
|
|
|
21
23
|
|
|
22
24
|
return [] unless details
|
|
23
25
|
|
|
24
|
-
[
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
[Model::User.new(details[0],
|
|
27
|
+
found_by: format(found_by_msg, details[1]),
|
|
28
|
+
confidence: details[2],
|
|
29
|
+
interesting_entries: [api_url])]
|
|
28
30
|
rescue JSON::ParserError
|
|
29
31
|
[]
|
|
30
32
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module Users
|
|
@@ -17,20 +19,20 @@ module WPScan
|
|
|
17
19
|
|
|
18
20
|
begin
|
|
19
21
|
res.xml.xpath('//item/dc:creator').each do |node|
|
|
20
|
-
|
|
22
|
+
username = node.text.to_s
|
|
21
23
|
|
|
22
24
|
# Ignoring potential username longer than 60 characters and containing accents
|
|
23
25
|
# as they are considered invalid. See https://github.com/wpscanteam/wpscan/issues/1215
|
|
24
|
-
next if
|
|
26
|
+
next if username.strip.empty? || username.length > 60 || username =~ /[^\x00-\x7F]/
|
|
25
27
|
|
|
26
|
-
potential_usernames <<
|
|
28
|
+
potential_usernames << username
|
|
27
29
|
end
|
|
28
30
|
rescue Nokogiri::XML::XPath::SyntaxError
|
|
29
31
|
next
|
|
30
32
|
end
|
|
31
33
|
|
|
32
|
-
potential_usernames.uniq.each do |
|
|
33
|
-
found <<
|
|
34
|
+
potential_usernames.uniq.each do |username|
|
|
35
|
+
found << Model::User.new(username, found_by: found_by, confidence: 50)
|
|
34
36
|
end
|
|
35
37
|
|
|
36
38
|
break
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module Users
|
|
@@ -41,11 +43,11 @@ module WPScan
|
|
|
41
43
|
found = []
|
|
42
44
|
|
|
43
45
|
JSON.parse(response.body)&.each do |user|
|
|
44
|
-
found <<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
found << Model::User.new(user['slug'],
|
|
47
|
+
id: user['id'],
|
|
48
|
+
found_by: found_by,
|
|
49
|
+
confidence: 100,
|
|
50
|
+
interesting_entries: [response.effective_url])
|
|
49
51
|
end
|
|
50
52
|
|
|
51
53
|
found
|
|
@@ -53,7 +55,15 @@ module WPScan
|
|
|
53
55
|
|
|
54
56
|
# @return [ String ] The URL of the API listing the Users
|
|
55
57
|
def api_url
|
|
56
|
-
@api_url
|
|
58
|
+
return @api_url if @api_url
|
|
59
|
+
|
|
60
|
+
target.in_scope_urls(target.homepage_res, "//link[@rel='https://api.w.org/']/@href").each do |url, _tag|
|
|
61
|
+
uri = Addressable::URI.parse(url.strip)
|
|
62
|
+
|
|
63
|
+
return @api_url = uri.join('wp/v2/users/').to_s if uri.path.include?('wp-json')
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
@api_url = target.url('wp-json/wp/v2/users/')
|
|
57
67
|
end
|
|
58
68
|
end
|
|
59
69
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module Users
|
|
@@ -15,10 +17,10 @@ module WPScan
|
|
|
15
17
|
|
|
16
18
|
next unless username && !username.strip.empty?
|
|
17
19
|
|
|
18
|
-
found <<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
found << Model::User.new(username,
|
|
21
|
+
found_by: found_by,
|
|
22
|
+
confidence: 100,
|
|
23
|
+
interesting_entries: [sitemap_url])
|
|
22
24
|
end
|
|
23
25
|
|
|
24
26
|
found
|
data/app/finders/wp_items.rb
CHANGED
data/app/finders/wp_version.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module WpVersion
|
|
@@ -13,9 +15,9 @@ module WPScan
|
|
|
13
15
|
|
|
14
16
|
number = Regexp.last_match(1)
|
|
15
17
|
|
|
16
|
-
return unless
|
|
18
|
+
return unless Model::WpVersion.valid?(number)
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
Model::WpVersion.new(
|
|
19
21
|
number,
|
|
20
22
|
found_by: 'Readme (Aggressive Detection)',
|
|
21
23
|
# Since WP 4.7, the Readme only contains the major version (ie 4.7, 4.8 etc)
|