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