wpscan 3.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 +7 -0
- data/Gemfile.lock +139 -0
- data/LICENSE +74 -0
- data/README.md +146 -0
- data/app/app.rb +3 -0
- data/app/controllers.rb +6 -0
- data/app/controllers/brute_force.rb +126 -0
- data/app/controllers/core.rb +104 -0
- data/app/controllers/custom_directories.rb +23 -0
- data/app/controllers/enumeration.rb +53 -0
- data/app/controllers/enumeration/cli_options.rb +126 -0
- data/app/controllers/enumeration/enum_methods.rb +157 -0
- data/app/controllers/main_theme.rb +27 -0
- data/app/controllers/wp_version.rb +30 -0
- data/app/finders.rb +13 -0
- data/app/finders/config_backups.rb +17 -0
- data/app/finders/config_backups/known_filenames.rb +46 -0
- data/app/finders/interesting_findings.rb +33 -0
- data/app/finders/interesting_findings/backup_db.rb +25 -0
- data/app/finders/interesting_findings/debug_log.rb +20 -0
- data/app/finders/interesting_findings/duplicator_installer_log.rb +23 -0
- data/app/finders/interesting_findings/full_path_disclosure.rb +23 -0
- data/app/finders/interesting_findings/mu_plugins.rb +48 -0
- data/app/finders/interesting_findings/multisite.rb +29 -0
- data/app/finders/interesting_findings/readme.rb +26 -0
- data/app/finders/interesting_findings/registration.rb +31 -0
- data/app/finders/interesting_findings/tmm_db_migrate.rb +24 -0
- data/app/finders/interesting_findings/upload_directory_listing.rb +24 -0
- data/app/finders/interesting_findings/upload_sql_dump.rb +28 -0
- data/app/finders/main_theme.rb +22 -0
- data/app/finders/main_theme/css_style.rb +43 -0
- data/app/finders/main_theme/urls_in_homepage.rb +25 -0
- data/app/finders/main_theme/woo_framework_meta_generator.rb +22 -0
- data/app/finders/medias.rb +17 -0
- data/app/finders/medias/attachment_brute_forcing.rb +44 -0
- data/app/finders/plugin_version.rb +44 -0
- data/app/finders/plugin_version/layer_slider/translation_file.rb +40 -0
- data/app/finders/plugin_version/readme.rb +79 -0
- data/app/finders/plugin_version/revslider/release_log.rb +35 -0
- data/app/finders/plugin_version/sitepress_multilingual_cms/meta_generator.rb +27 -0
- data/app/finders/plugin_version/sitepress_multilingual_cms/version_parameter.rb +31 -0
- data/app/finders/plugin_version/w3_total_cache/headers.rb +28 -0
- data/app/finders/plugins.rb +24 -0
- data/app/finders/plugins/comments.rb +31 -0
- data/app/finders/plugins/headers.rb +36 -0
- data/app/finders/plugins/known_locations.rb +48 -0
- data/app/finders/plugins/urls_in_homepage.rb +29 -0
- data/app/finders/theme_version.rb +41 -0
- data/app/finders/theme_version/style.rb +43 -0
- data/app/finders/theme_version/woo_framework_meta_generator.rb +19 -0
- data/app/finders/themes.rb +20 -0
- data/app/finders/themes/known_locations.rb +48 -0
- data/app/finders/themes/urls_in_homepage.rb +23 -0
- data/app/finders/timthumb_version.rb +17 -0
- data/app/finders/timthumb_version/bad_request.rb +21 -0
- data/app/finders/timthumbs.rb +17 -0
- data/app/finders/timthumbs/known_locations.rb +56 -0
- data/app/finders/users.rb +24 -0
- data/app/finders/users/author_id_brute_forcing.rb +111 -0
- data/app/finders/users/author_posts.rb +61 -0
- data/app/finders/users/login_error_messages.rb +50 -0
- data/app/finders/users/wp_json_api.rb +31 -0
- data/app/finders/wp_items.rb +1 -0
- data/app/finders/wp_items/urls_in_homepage.rb +68 -0
- data/app/finders/wp_version.rb +34 -0
- data/app/finders/wp_version/atom_generator.rb +40 -0
- data/app/finders/wp_version/meta_generator.rb +27 -0
- data/app/finders/wp_version/opml_generator.rb +23 -0
- data/app/finders/wp_version/rdf_generator.rb +38 -0
- data/app/finders/wp_version/readme.rb +28 -0
- data/app/finders/wp_version/rss_generator.rb +43 -0
- data/app/finders/wp_version/sitemap_generator.rb +23 -0
- data/app/finders/wp_version/stylesheets.rb +55 -0
- data/app/finders/wp_version/unique_fingerprinting.rb +64 -0
- data/app/models.rb +10 -0
- data/app/models/config_backup.rb +5 -0
- data/app/models/interesting_finding.rb +6 -0
- data/app/models/media.rb +5 -0
- data/app/models/plugin.rb +25 -0
- data/app/models/theme.rb +99 -0
- data/app/models/timthumb.rb +74 -0
- data/app/models/user.rb +31 -0
- data/app/models/wp_item.rb +142 -0
- data/app/models/wp_version.rb +49 -0
- data/app/models/xml_rpc.rb +19 -0
- data/app/views/cli/brute_force/error.erb +1 -0
- data/app/views/cli/brute_force/found.erb +2 -0
- data/app/views/cli/brute_force/users.erb +9 -0
- data/app/views/cli/core/banner.erb +14 -0
- data/app/views/cli/core/db_update_finished.erb +8 -0
- data/app/views/cli/core/db_update_started.erb +1 -0
- data/app/views/cli/core/not_fully_configured.erb +1 -0
- data/app/views/cli/enumeration/config_backups.erb +11 -0
- data/app/views/cli/enumeration/medias.erb +11 -0
- data/app/views/cli/enumeration/plugins.erb +35 -0
- data/app/views/cli/enumeration/themes.erb +11 -0
- data/app/views/cli/enumeration/timthumbs.erb +18 -0
- data/app/views/cli/enumeration/users.erb +11 -0
- data/app/views/cli/finding.erb +32 -0
- data/app/views/cli/info.erb +1 -0
- data/app/views/cli/main_theme/theme.erb +6 -0
- data/app/views/cli/notice.erb +1 -0
- data/app/views/cli/theme.erb +64 -0
- data/app/views/cli/usage.erb +3 -0
- data/app/views/cli/vulnerability.erb +14 -0
- data/app/views/cli/wp_version/version.erb +6 -0
- data/app/views/json/brute_force/users.erb +10 -0
- data/app/views/json/core/banner.erb +12 -0
- data/app/views/json/core/db_update_finished.erb +2 -0
- data/app/views/json/core/db_update_started.erb +1 -0
- data/app/views/json/core/not_fully_configured.erb +1 -0
- data/app/views/json/enumeration/config_backups.erb +10 -0
- data/app/views/json/enumeration/medias.erb +10 -0
- data/app/views/json/enumeration/plugins.erb +25 -0
- data/app/views/json/enumeration/themes.erb +10 -0
- data/app/views/json/enumeration/timthumbs.erb +19 -0
- data/app/views/json/enumeration/users.erb +11 -0
- data/app/views/json/finding.erb +26 -0
- data/app/views/json/main_theme/theme.erb +7 -0
- data/app/views/json/theme.erb +38 -0
- data/app/views/json/wp_version/version.erb +8 -0
- data/bin/wpscan +15 -0
- data/coverage/assets/0.10.0/application.css +799 -0
- data/coverage/assets/0.10.0/application.js +1707 -0
- data/coverage/assets/0.10.0/colorbox/border.png +0 -0
- data/coverage/assets/0.10.0/colorbox/controls.png +0 -0
- data/coverage/assets/0.10.0/colorbox/loading.gif +0 -0
- data/coverage/assets/0.10.0/colorbox/loading_background.png +0 -0
- data/coverage/assets/0.10.0/favicon_green.png +0 -0
- data/coverage/assets/0.10.0/favicon_red.png +0 -0
- data/coverage/assets/0.10.0/favicon_yellow.png +0 -0
- data/coverage/assets/0.10.0/loading.gif +0 -0
- data/coverage/assets/0.10.0/magnify.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/coverage/assets/0.10.0/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/coverage/index.html +27510 -0
- data/lib/wpscan.rb +44 -0
- data/lib/wpscan/browser.rb +16 -0
- data/lib/wpscan/controller.rb +8 -0
- data/lib/wpscan/controllers.rb +8 -0
- data/lib/wpscan/db.rb +28 -0
- data/lib/wpscan/db/dynamic_finders.rb +63 -0
- data/lib/wpscan/db/plugin.rb +11 -0
- data/lib/wpscan/db/plugins.rb +11 -0
- data/lib/wpscan/db/schema.rb +39 -0
- data/lib/wpscan/db/theme.rb +11 -0
- data/lib/wpscan/db/themes.rb +11 -0
- data/lib/wpscan/db/updater.rb +148 -0
- data/lib/wpscan/db/wp_item.rb +18 -0
- data/lib/wpscan/db/wp_items.rb +21 -0
- data/lib/wpscan/db/wp_version.rb +11 -0
- data/lib/wpscan/errors/http.rb +34 -0
- data/lib/wpscan/errors/update.rb +8 -0
- data/lib/wpscan/errors/wordpress.rb +22 -0
- data/lib/wpscan/finders.rb +14 -0
- data/lib/wpscan/finders/finder/plugin_version/comments.rb +25 -0
- data/lib/wpscan/finders/finder/wp_version/smart_url_checker.rb +23 -0
- data/lib/wpscan/helper.rb +6 -0
- data/lib/wpscan/references.rb +31 -0
- data/lib/wpscan/target.rb +81 -0
- data/lib/wpscan/target/platform/wordpress.rb +74 -0
- data/lib/wpscan/target/platform/wordpress/custom_directories.rb +93 -0
- data/lib/wpscan/version.rb +4 -0
- data/lib/wpscan/vulnerability.rb +25 -0
- data/lib/wpscan/vulnerable.rb +10 -0
- data/wpscan-v3.sublime-project +8 -0
- data/wpscan-v3.sublime-workspace +895 -0
- data/wpscan.gemspec +55 -0
- metadata +419 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module PluginVersion
|
|
4
|
+
module W3TotalCache
|
|
5
|
+
# Version from Headers
|
|
6
|
+
class Headers < CMSScanner::Finders::Finder
|
|
7
|
+
PATTERN = %r{W3 Total Cache/([0-9.]+)}i
|
|
8
|
+
|
|
9
|
+
# @param [ Hash ] opts
|
|
10
|
+
#
|
|
11
|
+
# @return [ Version ]
|
|
12
|
+
def passive(_opts = {})
|
|
13
|
+
headers = target.target.headers
|
|
14
|
+
|
|
15
|
+
return unless headers && headers['X-Powered-By'].to_s =~ PATTERN
|
|
16
|
+
|
|
17
|
+
WPScan::Version.new(
|
|
18
|
+
Regexp.last_match[1],
|
|
19
|
+
found_by: found_by,
|
|
20
|
+
confidence: 80,
|
|
21
|
+
interesting_entries: ["#{target.target.url}, Match: '#{Regexp.last_match}'"]
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require_relative 'plugins/urls_in_homepage'
|
|
2
|
+
require_relative 'plugins/headers'
|
|
3
|
+
require_relative 'plugins/comments'
|
|
4
|
+
require_relative 'plugins/known_locations'
|
|
5
|
+
|
|
6
|
+
module WPScan
|
|
7
|
+
module Finders
|
|
8
|
+
module Plugins
|
|
9
|
+
# Plugins Finder
|
|
10
|
+
class Base
|
|
11
|
+
include CMSScanner::Finders::SameTypeFinder
|
|
12
|
+
|
|
13
|
+
# @param [ WPScan::Target ] target
|
|
14
|
+
def initialize(target)
|
|
15
|
+
finders <<
|
|
16
|
+
Plugins::UrlsInHomepage.new(target) <<
|
|
17
|
+
Plugins::Headers.new(target) <<
|
|
18
|
+
Plugins::Comments.new(target) <<
|
|
19
|
+
Plugins::KnownLocations.new(target)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module Plugins
|
|
4
|
+
# Plugins from Comments Finder
|
|
5
|
+
class Comments < CMSScanner::Finders::Finder
|
|
6
|
+
# @param [ Hash ] opts
|
|
7
|
+
# @option opts [ Boolean ] :unique Default: true
|
|
8
|
+
#
|
|
9
|
+
# @return [ Array<Plugin> ]
|
|
10
|
+
def passive(opts = {})
|
|
11
|
+
found = []
|
|
12
|
+
opts[:unique] = true unless opts.key?(:unique)
|
|
13
|
+
|
|
14
|
+
target.homepage_res.html.xpath('//comment()').each do |node|
|
|
15
|
+
comment = node.text.to_s.strip
|
|
16
|
+
|
|
17
|
+
DB::DynamicPluginFinders.comments.each do |name, config|
|
|
18
|
+
next unless comment =~ config['pattern']
|
|
19
|
+
|
|
20
|
+
plugin = WPScan::Plugin.new(name, target, opts.merge(found_by: found_by, confidence: 70))
|
|
21
|
+
|
|
22
|
+
found << plugin unless opts[:unique] && found.include?(plugin)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
found
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module Plugins
|
|
4
|
+
# Plugins from Headers Finder
|
|
5
|
+
class Headers < CMSScanner::Finders::Finder
|
|
6
|
+
# @param [ Hash ] opts
|
|
7
|
+
#
|
|
8
|
+
# @return [ Array<Plugin> ]
|
|
9
|
+
def passive(opts = {})
|
|
10
|
+
plugin_names_from_headers(opts).reduce([]) do |a, e|
|
|
11
|
+
a << WPScan::Plugin.new(e, target, opts.merge(found_by: found_by, confidence: 60))
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# X-Powered-By: W3 Total Cache/0.9.2.5
|
|
16
|
+
# WP-Super-Cache: Served supercache file from PHP
|
|
17
|
+
#
|
|
18
|
+
# @return [ Array<String> ]
|
|
19
|
+
def plugin_names_from_headers(_opts = {})
|
|
20
|
+
found = []
|
|
21
|
+
headers = target.homepage_res.headers
|
|
22
|
+
|
|
23
|
+
if headers
|
|
24
|
+
powered_by = headers['X-Powered-By'].to_s
|
|
25
|
+
wp_super_cache = headers['wp-super-cache'].to_s
|
|
26
|
+
|
|
27
|
+
found << 'w3-total-cache' if powered_by =~ Finders::PluginVersion::W3TotalCache::Headers::PATTERN
|
|
28
|
+
found << 'wp-super-cache' if wp_super_cache =~ /supercache/i
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
found
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module Plugins
|
|
4
|
+
# Known Locations Plugins Finder
|
|
5
|
+
class KnownLocations < CMSScanner::Finders::Finder
|
|
6
|
+
include CMSScanner::Finders::Finder::Enumerator
|
|
7
|
+
|
|
8
|
+
# @param [ Hash ] opts
|
|
9
|
+
# @option opts [ String ] :list
|
|
10
|
+
#
|
|
11
|
+
# @return [ Array<Plugin> ]
|
|
12
|
+
def aggressive(opts = {})
|
|
13
|
+
found = []
|
|
14
|
+
|
|
15
|
+
enumerate(target_urls(opts), opts) do |res, name|
|
|
16
|
+
# TODO: follow the location (from enumerate()) and remove the 301 here ?
|
|
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(name, target, opts.merge(found_by: found_by, confidence: 80))
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
found
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @param [ Hash ] opts
|
|
27
|
+
# @option opts [ String ] :list
|
|
28
|
+
#
|
|
29
|
+
# @return [ Hash ]
|
|
30
|
+
def target_urls(opts = {})
|
|
31
|
+
names = opts[:list] || DB::Plugins.vulnerable_slugs
|
|
32
|
+
urls = {}
|
|
33
|
+
plugins_url = target.plugins_url
|
|
34
|
+
|
|
35
|
+
names.each do |name|
|
|
36
|
+
urls["#{plugins_url}#{URI.encode(name)}/"] = name
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
urls
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def create_progress_bar(opts = {})
|
|
43
|
+
super(opts.merge(title: ' Checking Known Locations -'))
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module Plugins
|
|
4
|
+
# URLs In Homepage Finder
|
|
5
|
+
class UrlsInHomepage < CMSScanner::Finders::Finder
|
|
6
|
+
include WpItems::URLsInHomepage
|
|
7
|
+
|
|
8
|
+
# @param [ Hash ] opts
|
|
9
|
+
#
|
|
10
|
+
# @return [ Array<Plugin> ]
|
|
11
|
+
def passive(opts = {})
|
|
12
|
+
found = []
|
|
13
|
+
|
|
14
|
+
(items_from_links('plugins') + items_from_codes('plugins')).uniq.sort.each do |name|
|
|
15
|
+
found << Plugin.new(name, target, opts.merge(found_by: found_by, confidence: 80))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
DB::DynamicPluginFinders.urls_in_page.each do |name, config|
|
|
19
|
+
next unless target.homepage_res.html.xpath(config['xpath']).any?
|
|
20
|
+
|
|
21
|
+
found << Plugin.new(name, target, opts.merge(found_by: found_by, confidence: 100))
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
found
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require_relative 'theme_version/style'
|
|
2
|
+
require_relative 'theme_version/woo_framework_meta_generator'
|
|
3
|
+
|
|
4
|
+
module WPScan
|
|
5
|
+
module Finders
|
|
6
|
+
module ThemeVersion
|
|
7
|
+
# Theme Version Finder
|
|
8
|
+
class Base
|
|
9
|
+
include CMSScanner::Finders::UniqueFinder
|
|
10
|
+
|
|
11
|
+
# @param [ WPScan::Theme ] theme
|
|
12
|
+
def initialize(theme)
|
|
13
|
+
finders <<
|
|
14
|
+
ThemeVersion::Style.new(theme) <<
|
|
15
|
+
ThemeVersion::WooFrameworkMetaGenerator.new(theme)
|
|
16
|
+
|
|
17
|
+
load_specific_finders(theme)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Load the finders associated with the theme
|
|
21
|
+
#
|
|
22
|
+
# @param [ WPScan::Theme ] theme
|
|
23
|
+
def load_specific_finders(theme)
|
|
24
|
+
module_name = theme.classify_name.to_sym
|
|
25
|
+
|
|
26
|
+
return unless Finders::ThemeVersion.constants.include?(module_name)
|
|
27
|
+
|
|
28
|
+
mod = Finders::ThemeVersion.const_get(module_name)
|
|
29
|
+
|
|
30
|
+
mod.constants.each do |constant|
|
|
31
|
+
c = mod.const_get(constant)
|
|
32
|
+
|
|
33
|
+
next unless c.is_a?(Class)
|
|
34
|
+
|
|
35
|
+
finders << c.new(theme)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module ThemeVersion
|
|
4
|
+
# Theme Version Finder from the style.css file
|
|
5
|
+
class Style < CMSScanner::Finders::Finder
|
|
6
|
+
# @param [ Hash ] opts
|
|
7
|
+
#
|
|
8
|
+
# @return [ Version ]
|
|
9
|
+
def passive(_opts = {})
|
|
10
|
+
return unless cached_style?
|
|
11
|
+
|
|
12
|
+
style_version
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @param [ Hash ] opts
|
|
16
|
+
#
|
|
17
|
+
# @return [ Version ]
|
|
18
|
+
def aggressive(_opts = {})
|
|
19
|
+
return if cached_style?
|
|
20
|
+
|
|
21
|
+
style_version
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @return [ Boolean ]
|
|
25
|
+
def cached_style?
|
|
26
|
+
Typhoeus::Config.cache.get(browser.forge_request(target.style_url)) ? true : false
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @return [ Version ]
|
|
30
|
+
def style_version
|
|
31
|
+
return unless Browser.get(target.style_url).body =~ /Version:[\t ]*(?!trunk)([0-9a-z\.-]+)/i
|
|
32
|
+
|
|
33
|
+
WPScan::Version.new(
|
|
34
|
+
Regexp.last_match[1],
|
|
35
|
+
found_by: found_by,
|
|
36
|
+
confidence: 80,
|
|
37
|
+
interesting_entries: ["#{target.style_url}, Match: '#{Regexp.last_match}'"]
|
|
38
|
+
)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module ThemeVersion
|
|
4
|
+
# Theme Version Finder from the WooFramework generators
|
|
5
|
+
class WooFrameworkMetaGenerator < CMSScanner::Finders::Finder
|
|
6
|
+
# @param [ Hash ] opts
|
|
7
|
+
#
|
|
8
|
+
# @return [ Version ]
|
|
9
|
+
def passive(_opts = {})
|
|
10
|
+
return unless target.target.homepage_res.body =~ Finders::MainTheme::WooFrameworkMetaGenerator::PATTERN
|
|
11
|
+
|
|
12
|
+
return unless Regexp.last_match[1] == target.name
|
|
13
|
+
|
|
14
|
+
WPScan::Version.new(Regexp.last_match[2], found_by: found_by, confidence: 80)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require_relative 'themes/urls_in_homepage'
|
|
2
|
+
require_relative 'themes/known_locations'
|
|
3
|
+
|
|
4
|
+
module WPScan
|
|
5
|
+
module Finders
|
|
6
|
+
module Themes
|
|
7
|
+
# themes Finder
|
|
8
|
+
class Base
|
|
9
|
+
include CMSScanner::Finders::SameTypeFinder
|
|
10
|
+
|
|
11
|
+
# @param [ WPScan::Target ] target
|
|
12
|
+
def initialize(target)
|
|
13
|
+
finders <<
|
|
14
|
+
Themes::UrlsInHomepage.new(target) <<
|
|
15
|
+
Themes::KnownLocations.new(target)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module Themes
|
|
4
|
+
# Known Locations Themes Finder
|
|
5
|
+
class KnownLocations < CMSScanner::Finders::Finder
|
|
6
|
+
include CMSScanner::Finders::Finder::Enumerator
|
|
7
|
+
|
|
8
|
+
# @param [ Hash ] opts
|
|
9
|
+
# @option opts [ String ] :list
|
|
10
|
+
#
|
|
11
|
+
# @return [ Array<Theme> ]
|
|
12
|
+
def aggressive(opts = {})
|
|
13
|
+
found = []
|
|
14
|
+
|
|
15
|
+
enumerate(target_urls(opts), opts) do |res, name|
|
|
16
|
+
# TODO: follow the location (from enumerate()) and remove the 301 here ?
|
|
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(name, target, opts.merge(found_by: found_by, confidence: 80))
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
found
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @param [ Hash ] opts
|
|
27
|
+
# @option opts [ String ] :list
|
|
28
|
+
#
|
|
29
|
+
# @return [ Hash ]
|
|
30
|
+
def target_urls(opts = {})
|
|
31
|
+
names = opts[:list] || DB::Themes.vulnerable_slugs
|
|
32
|
+
urls = {}
|
|
33
|
+
themes_url = target.url('wp-content/themes/')
|
|
34
|
+
|
|
35
|
+
names.each do |name|
|
|
36
|
+
urls["#{themes_url}#{URI.encode(name)}/"] = name
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
urls
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def create_progress_bar(opts = {})
|
|
43
|
+
super(opts.merge(title: ' Checking Known Locations -'))
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module Themes
|
|
4
|
+
# URLs In Homepage Finder
|
|
5
|
+
class UrlsInHomepage < CMSScanner::Finders::Finder
|
|
6
|
+
include WpItems::URLsInHomepage
|
|
7
|
+
|
|
8
|
+
# @param [ Hash ] opts
|
|
9
|
+
#
|
|
10
|
+
# @return [ Array<Theme> ]
|
|
11
|
+
def passive(opts = {})
|
|
12
|
+
found = []
|
|
13
|
+
|
|
14
|
+
(items_from_links('themes') + items_from_codes('themes')).uniq.sort.each do |name|
|
|
15
|
+
found << WPScan::Theme.new(name, target, opts.merge(found_by: found_by, confidence: 80))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
found
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require_relative 'timthumb_version/bad_request'
|
|
2
|
+
|
|
3
|
+
module WPScan
|
|
4
|
+
module Finders
|
|
5
|
+
module TimthumbVersion
|
|
6
|
+
# Timthumb Version Finder
|
|
7
|
+
class Base
|
|
8
|
+
include CMSScanner::Finders::UniqueFinder
|
|
9
|
+
|
|
10
|
+
# @param [ WPScan::Timthumb ] target
|
|
11
|
+
def initialize(target)
|
|
12
|
+
finders << TimthumbVersion::BadRequest.new(target)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module TimthumbVersion
|
|
4
|
+
# Timthumb Version Finder from the body of a bad request
|
|
5
|
+
# See https://code.google.com/p/timthumb/source/browse/trunk/timthumb.php#435
|
|
6
|
+
class BadRequest < CMSScanner::Finders::Finder
|
|
7
|
+
# @return [ Version ]
|
|
8
|
+
def aggressive(_opts = {})
|
|
9
|
+
return unless Browser.get(target.url).body =~ /(TimThumb version\s*: ([^<]+))/
|
|
10
|
+
|
|
11
|
+
WPScan::Version.new(
|
|
12
|
+
Regexp.last_match[2],
|
|
13
|
+
found_by: 'Bad Request (Aggressive Detection)',
|
|
14
|
+
confidence: 90,
|
|
15
|
+
interesting_entries: ["#{target.url}, Match: '#{Regexp.last_match[1]}'"]
|
|
16
|
+
)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|