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 InterestingFindings
|
|
@@ -5,14 +7,14 @@ module WPScan
|
|
|
5
7
|
class Readme < CMSScanner::Finders::Finder
|
|
6
8
|
# @return [ InterestingFinding ]
|
|
7
9
|
def aggressive(_opts = {})
|
|
8
|
-
potential_files.each do |
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
potential_files.each do |path|
|
|
11
|
+
res = target.head_and_get(path)
|
|
12
|
+
|
|
13
|
+
next unless res.code == 200 && res.body =~ /wordpress/i
|
|
11
14
|
|
|
12
|
-
|
|
13
|
-
return WPScan::Readme.new(url, confidence: 100, found_by: DIRECT_ACCESS)
|
|
14
|
-
end
|
|
15
|
+
return Model::Readme.new(target.url(path), confidence: 100, found_by: DIRECT_ACCESS)
|
|
15
16
|
end
|
|
17
|
+
|
|
16
18
|
nil
|
|
17
19
|
end
|
|
18
20
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module InterestingFindings
|
|
@@ -18,7 +20,7 @@ module WPScan
|
|
|
18
20
|
|
|
19
21
|
target.registration_enabled = true
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
Model::Registration.new(
|
|
22
24
|
res.effective_url,
|
|
23
25
|
confidence: 100,
|
|
24
26
|
found_by: DIRECT_ACCESS,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module InterestingFindings
|
|
@@ -7,11 +9,11 @@ module WPScan
|
|
|
7
9
|
def aggressive(_opts = {})
|
|
8
10
|
path = 'wp-content/uploads/tmm_db_migrate/tmm_db_migrate.zip'
|
|
9
11
|
url = target.url(path)
|
|
10
|
-
res =
|
|
12
|
+
res = browser.forge_request(url, target.head_or_get_request_params).run
|
|
11
13
|
|
|
12
14
|
return unless res.code == 200 && res.headers['Content-Type'] =~ %r{\Aapplication/zip}i
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
Model::TmmDbMigrate.new(
|
|
15
17
|
url,
|
|
16
18
|
confidence: 100,
|
|
17
19
|
found_by: DIRECT_ACCESS,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module InterestingFindings
|
|
@@ -11,7 +13,7 @@ module WPScan
|
|
|
11
13
|
|
|
12
14
|
url = target.url(path)
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
Model::UploadDirectoryListing.new(
|
|
15
17
|
url,
|
|
16
18
|
confidence: 100,
|
|
17
19
|
found_by: DIRECT_ACCESS,
|
|
@@ -1,27 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module InterestingFindings
|
|
4
6
|
# UploadSQLDump finder
|
|
5
7
|
class UploadSQLDump < CMSScanner::Finders::Finder
|
|
6
|
-
SQL_PATTERN = /(?:
|
|
8
|
+
SQL_PATTERN = /(?:DROP|CREATE|(?:UN)?LOCK) TABLE|INSERT INTO/.freeze
|
|
7
9
|
|
|
8
10
|
# @return [ InterestingFinding ]
|
|
9
11
|
def aggressive(_opts = {})
|
|
10
|
-
|
|
11
|
-
res
|
|
12
|
+
path = 'wp-content/uploads/dump.sql'
|
|
13
|
+
res = target.head_and_get(path, [200], get: { headers: { 'Range' => 'bytes=0-3000' } })
|
|
12
14
|
|
|
13
|
-
return unless res.
|
|
15
|
+
return unless res.body =~ SQL_PATTERN
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
url,
|
|
17
|
+
Model::UploadSQLDump.new(
|
|
18
|
+
target.url(path),
|
|
17
19
|
confidence: 100,
|
|
18
20
|
found_by: DIRECT_ACCESS
|
|
19
21
|
)
|
|
20
22
|
end
|
|
21
|
-
|
|
22
|
-
def dump_url
|
|
23
|
-
target.url('wp-content/uploads/dump.sql')
|
|
24
|
-
end
|
|
25
23
|
end
|
|
26
24
|
end
|
|
27
25
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module InterestingFindings
|
|
@@ -9,7 +11,7 @@ module WPScan
|
|
|
9
11
|
|
|
10
12
|
return unless res.code == 200
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
Model::WPCron.new(
|
|
13
15
|
wp_cron_url,
|
|
14
16
|
confidence: 60,
|
|
15
17
|
found_by: DIRECT_ACCESS,
|
data/app/finders/main_theme.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module MainTheme
|
|
@@ -6,7 +8,7 @@ module WPScan
|
|
|
6
8
|
include Finders::WpItems::URLsInHomepage
|
|
7
9
|
|
|
8
10
|
def create_theme(slug, style_url, opts)
|
|
9
|
-
|
|
11
|
+
Model::Theme.new(
|
|
10
12
|
slug,
|
|
11
13
|
target,
|
|
12
14
|
opts.merge(found_by: found_by, confidence: 70, style_url: style_url)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module MainTheme
|
|
@@ -14,7 +16,7 @@ module WPScan
|
|
|
14
16
|
slugs = items_from_links('themes', false) + items_from_codes('themes', false)
|
|
15
17
|
|
|
16
18
|
slugs.each_with_object(Hash.new(0)) { |slug, counts| counts[slug] += 1 }.each do |slug, occurences|
|
|
17
|
-
found <<
|
|
19
|
+
found << Model::Theme.new(slug, target, opts.merge(found_by: found_by, confidence: 2 * occurences))
|
|
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 MainTheme
|
|
@@ -10,7 +12,7 @@ module WPScan
|
|
|
10
12
|
def passive(opts = {})
|
|
11
13
|
return unless target.homepage_res.body =~ PATTERN
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
Model::Theme.new(
|
|
14
16
|
Regexp.last_match[1],
|
|
15
17
|
target,
|
|
16
18
|
opts.merge(found_by: found_by, confidence: 80)
|
data/app/finders/medias.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module Medias
|
|
@@ -15,7 +17,7 @@ module WPScan
|
|
|
15
17
|
enumerate(target_urls(opts), opts) do |res|
|
|
16
18
|
next unless res.code == 200
|
|
17
19
|
|
|
18
|
-
found <<
|
|
20
|
+
found << Model::Media.new(res.effective_url, opts.merge(found_by: found_by, confidence: 100))
|
|
19
21
|
end
|
|
20
22
|
|
|
21
23
|
found
|
data/app/finders/passwords.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module Passwords
|
|
@@ -10,7 +12,8 @@ module WPScan
|
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
def valid_credentials?(response)
|
|
13
|
-
response.code == 302
|
|
15
|
+
response.code == 302 &&
|
|
16
|
+
response.headers['Set-Cookie']&.any? { |cookie| cookie =~ /wordpress_logged_in_/i }
|
|
14
17
|
end
|
|
15
18
|
|
|
16
19
|
def errored_response?(response)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module Passwords
|
|
@@ -20,13 +22,13 @@ module WPScan
|
|
|
20
22
|
target.multi_call(methods).run
|
|
21
23
|
end
|
|
22
24
|
|
|
23
|
-
# @param [ Array<
|
|
25
|
+
# @param [ Array<Model::User> ] users
|
|
24
26
|
# @param [ Array<String> ] passwords
|
|
25
27
|
# @param [ Hash ] opts
|
|
26
28
|
# @option opts [ Boolean ] :show_progression
|
|
27
29
|
# @option opts [ Integer ] :multicall_max_passwords
|
|
28
30
|
#
|
|
29
|
-
# @yield [
|
|
31
|
+
# @yield [ Model::User ] When a valid combination is found
|
|
30
32
|
#
|
|
31
33
|
# TODO: Make rubocop happy about metrics etc
|
|
32
34
|
#
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require_relative 'plugin_version/readme'
|
|
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::Plugin ] plugin
|
|
11
13
|
def initialize(plugin)
|
|
12
14
|
finders << PluginVersion::Readme.new(plugin)
|
|
13
15
|
|
|
@@ -16,7 +18,7 @@ module WPScan
|
|
|
16
18
|
|
|
17
19
|
# Load the finders associated with the plugin
|
|
18
20
|
#
|
|
19
|
-
# @param [
|
|
21
|
+
# @param [ Model::Plugin ] plugin
|
|
20
22
|
def load_specific_finders(plugin)
|
|
21
23
|
module_name = plugin.classify
|
|
22
24
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module PluginVersion
|
|
@@ -7,21 +9,23 @@ module WPScan
|
|
|
7
9
|
def aggressive(_opts = {})
|
|
8
10
|
found_by_msg = 'Readme - %s (Aggressive Detection)'
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
# The target(plugin)#readme_url can't be used directly here
|
|
13
|
+
# as if the --detection-mode is passive, it will always return nil
|
|
14
|
+
Model::WpItem::READMES.each do |file|
|
|
15
|
+
res = target.head_and_get(file)
|
|
13
16
|
|
|
14
17
|
next unless res.code == 200 && !(numbers = version_numbers(res.body)).empty?
|
|
15
18
|
|
|
16
19
|
return numbers.reduce([]) do |a, e|
|
|
17
|
-
a <<
|
|
20
|
+
a << Model::Version.new(
|
|
18
21
|
e[0],
|
|
19
22
|
found_by: format(found_by_msg, e[1]),
|
|
20
23
|
confidence: e[2],
|
|
21
|
-
interesting_entries: [
|
|
24
|
+
interesting_entries: [res.effective_url]
|
|
22
25
|
)
|
|
23
26
|
end
|
|
24
27
|
end
|
|
28
|
+
|
|
25
29
|
nil
|
|
26
30
|
end
|
|
27
31
|
|
data/app/finders/plugins.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module Plugins
|
|
@@ -15,7 +17,7 @@ module WPScan
|
|
|
15
17
|
def process_response(opts, response, slug, klass, config)
|
|
16
18
|
return unless response.body =~ config['pattern']
|
|
17
19
|
|
|
18
|
-
Plugin.new(
|
|
20
|
+
Model::Plugin.new(
|
|
19
21
|
slug,
|
|
20
22
|
target,
|
|
21
23
|
opts.merge(found_by: found_by(klass), confidence: config['confidence'] || DEFAULT_CONFIDENCE)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module Plugins
|
|
@@ -18,7 +20,7 @@ module WPScan
|
|
|
18
20
|
|
|
19
21
|
next unless comment =~ config['pattern']
|
|
20
22
|
|
|
21
|
-
return Plugin.new(
|
|
23
|
+
return Model::Plugin.new(
|
|
22
24
|
slug,
|
|
23
25
|
target,
|
|
24
26
|
opts.merge(found_by: found_by(klass), confidence: config['confidence'] || DEFAULT_CONFIDENCE)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module Plugins
|
|
@@ -19,7 +21,7 @@ module WPScan
|
|
|
19
21
|
# when checking for plugins
|
|
20
22
|
#
|
|
21
23
|
|
|
22
|
-
Plugin.new(
|
|
24
|
+
Model::Plugin.new(
|
|
23
25
|
slug,
|
|
24
26
|
target,
|
|
25
27
|
opts.merge(found_by: found_by(klass), confidence: config['confidence'] || DEFAULT_CONFIDENCE)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module Plugins
|
|
@@ -18,7 +20,7 @@ module WPScan
|
|
|
18
20
|
configs.each do |klass, config|
|
|
19
21
|
next unless headers[config['header']] && headers[config['header']].to_s =~ config['pattern']
|
|
20
22
|
|
|
21
|
-
found << Plugin.new(
|
|
23
|
+
found << Model::Plugin.new(
|
|
22
24
|
slug,
|
|
23
25
|
target,
|
|
24
26
|
opts.merge(found_by: found_by(klass), confidence: config['confidence'] || DEFAULT_CONFIDENCE)
|
|
@@ -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'] || '//script[not(@src)]').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
|
module WPScan
|
|
2
4
|
module Finders
|
|
3
5
|
module Plugins
|
|
@@ -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::Plugin.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::Plugin.new(slug, target, opts.merge(found_by: found_by, confidence: 80))
|
|
21
24
|
end
|
|
22
25
|
|
|
23
26
|
found
|
|
@@ -30,10 +33,9 @@ module WPScan
|
|
|
30
33
|
def target_urls(opts = {})
|
|
31
34
|
slugs = opts[:list] || DB::Plugins.vulnerable_slugs
|
|
32
35
|
urls = {}
|
|
33
|
-
plugins_url = target.plugins_url
|
|
34
36
|
|
|
35
37
|
slugs.each do |slug|
|
|
36
|
-
urls[
|
|
38
|
+
urls[target.plugin_url(slug)] = slug
|
|
37
39
|
end
|
|
38
40
|
|
|
39
41
|
urls
|