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 InterestingFindings
|
|
4
|
+
# UploadSQLDump finder
|
|
5
|
+
class UploadSQLDump < CMSScanner::Finders::Finder
|
|
6
|
+
SQL_PATTERN = /(?:(?:(?:DROP|CREATE) TABLE)|INSERT INTO)/
|
|
7
|
+
|
|
8
|
+
# @return [ InterestingFinding ]
|
|
9
|
+
def aggressive(_opts = {})
|
|
10
|
+
url = dump_url
|
|
11
|
+
res = Browser.get(url)
|
|
12
|
+
|
|
13
|
+
return unless res.code == 200 && res.body =~ SQL_PATTERN
|
|
14
|
+
|
|
15
|
+
WPScan::InterestingFinding.new(
|
|
16
|
+
url,
|
|
17
|
+
confidence: 100,
|
|
18
|
+
found_by: DIRECT_ACCESS
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def dump_url
|
|
23
|
+
target.url('wp-content/uploads/dump.sql')
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require_relative 'main_theme/css_style'
|
|
2
|
+
require_relative 'main_theme/woo_framework_meta_generator'
|
|
3
|
+
require_relative 'main_theme/urls_in_homepage'
|
|
4
|
+
|
|
5
|
+
module WPScan
|
|
6
|
+
module Finders
|
|
7
|
+
module MainTheme
|
|
8
|
+
# Main Theme Finder
|
|
9
|
+
class Base
|
|
10
|
+
include CMSScanner::Finders::UniqueFinder
|
|
11
|
+
|
|
12
|
+
# @param [ WPScan::Target ] target
|
|
13
|
+
def initialize(target)
|
|
14
|
+
finders <<
|
|
15
|
+
MainTheme::CssStyle.new(target) <<
|
|
16
|
+
MainTheme::WooFrameworkMetaGenerator.new(target) <<
|
|
17
|
+
MainTheme::UrlsInHomepage.new(target)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module MainTheme
|
|
4
|
+
# From the css style
|
|
5
|
+
class CssStyle < CMSScanner::Finders::Finder
|
|
6
|
+
include Finders::WpItems::URLsInHomepage
|
|
7
|
+
|
|
8
|
+
def create_theme(name, style_url, opts)
|
|
9
|
+
WPScan::Theme.new(
|
|
10
|
+
name,
|
|
11
|
+
target,
|
|
12
|
+
opts.merge(found_by: found_by, confidence: 70, style_url: style_url)
|
|
13
|
+
)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def passive(opts = {})
|
|
17
|
+
passive_from_css_href(target.homepage_res, opts) || passive_from_style_code(target.homepage_res, opts)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def passive_from_css_href(res, opts)
|
|
21
|
+
target.in_scope_urls(res, '//style|//link') do |url|
|
|
22
|
+
next unless Addressable::URI.parse(url).path =~ %r{/themes/([^\/]+)/style.css\z}i
|
|
23
|
+
|
|
24
|
+
return create_theme(Regexp.last_match[1], url, opts)
|
|
25
|
+
end
|
|
26
|
+
nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def passive_from_style_code(res, opts)
|
|
30
|
+
res.html.css('style').each do |tag|
|
|
31
|
+
code = tag.text.to_s
|
|
32
|
+
next if code.empty?
|
|
33
|
+
|
|
34
|
+
next unless code =~ %r{#{item_code_pattern('themes')}\\?/style\.css[^"'\( ]*}i
|
|
35
|
+
|
|
36
|
+
return create_theme(Regexp.last_match[1], Regexp.last_match[0].strip, opts)
|
|
37
|
+
end
|
|
38
|
+
nil
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module MainTheme
|
|
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
|
+
names = items_from_links('themes', false) + items_from_codes('themes', false)
|
|
15
|
+
|
|
16
|
+
names.each_with_object(Hash.new(0)) { |name, counts| counts[name] += 1 }.each do |name, occurences|
|
|
17
|
+
found << WPScan::Theme.new(name, target, opts.merge(found_by: found_by, confidence: 2 * occurences))
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
found
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module MainTheme
|
|
4
|
+
# From the WooFramework meta generators
|
|
5
|
+
class WooFrameworkMetaGenerator < CMSScanner::Finders::Finder
|
|
6
|
+
THEME_PATTERN = %r{<meta name="generator" content="([^\s"]+)\s?([^"]+)?"\s+/?>}
|
|
7
|
+
FRAMEWORK_PATTERN = %r{<meta name="generator" content="WooFramework\s?([^"]+)?"\s+/?>}
|
|
8
|
+
PATTERN = /#{THEME_PATTERN}\s+#{FRAMEWORK_PATTERN}/i
|
|
9
|
+
|
|
10
|
+
def passive(opts = {})
|
|
11
|
+
return unless target.homepage_res.body =~ PATTERN
|
|
12
|
+
|
|
13
|
+
WPScan::Theme.new(
|
|
14
|
+
Regexp.last_match[1],
|
|
15
|
+
target,
|
|
16
|
+
opts.merge(found_by: found_by, confidence: 80)
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require_relative 'medias/attachment_brute_forcing'
|
|
2
|
+
|
|
3
|
+
module WPScan
|
|
4
|
+
module Finders
|
|
5
|
+
module Medias
|
|
6
|
+
# Medias Finder
|
|
7
|
+
class Base
|
|
8
|
+
include CMSScanner::Finders::SameTypeFinder
|
|
9
|
+
|
|
10
|
+
# @param [ WPScan::Target ] target
|
|
11
|
+
def initialize(target)
|
|
12
|
+
finders << Medias::AttachmentBruteForcing.new(target)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module Medias
|
|
4
|
+
# Medias Finder
|
|
5
|
+
class AttachmentBruteForcing < CMSScanner::Finders::Finder
|
|
6
|
+
include CMSScanner::Finders::Finder::Enumerator
|
|
7
|
+
|
|
8
|
+
# @param [ Hash ] opts
|
|
9
|
+
# @option opts [ Range ] :range Mandatory
|
|
10
|
+
#
|
|
11
|
+
# @return [ Array<Media> ]
|
|
12
|
+
def aggressive(opts = {})
|
|
13
|
+
found = []
|
|
14
|
+
|
|
15
|
+
enumerate(target_urls(opts), opts) do |res|
|
|
16
|
+
next unless res.code == 200
|
|
17
|
+
|
|
18
|
+
found << WPScan::Media.new(res.effective_url, opts.merge(found_by: found_by, confidence: 100))
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
found
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @param [ Hash ] opts
|
|
25
|
+
# @option opts [ Range ] :range Mandatory
|
|
26
|
+
#
|
|
27
|
+
# @return [ Hash ]
|
|
28
|
+
def target_urls(opts = {})
|
|
29
|
+
urls = {}
|
|
30
|
+
|
|
31
|
+
opts[:range].each do |id|
|
|
32
|
+
urls[target.uri.join("?attachment_id=#{id}").to_s] = id
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
urls
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def create_progress_bar(opts = {})
|
|
39
|
+
super(opts.merge(title: ' Brute Forcing Attachment Ids -'))
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require_relative 'plugin_version/readme'
|
|
2
|
+
# Plugins Specific
|
|
3
|
+
require_relative 'plugin_version/layer_slider/translation_file'
|
|
4
|
+
require_relative 'plugin_version/revslider/release_log'
|
|
5
|
+
require_relative 'plugin_version/sitepress_multilingual_cms/version_parameter'
|
|
6
|
+
require_relative 'plugin_version/sitepress_multilingual_cms/meta_generator'
|
|
7
|
+
require_relative 'plugin_version/w3_total_cache/headers'
|
|
8
|
+
|
|
9
|
+
module WPScan
|
|
10
|
+
module Finders
|
|
11
|
+
module PluginVersion
|
|
12
|
+
# Plugin Version Finder
|
|
13
|
+
class Base
|
|
14
|
+
include CMSScanner::Finders::UniqueFinder
|
|
15
|
+
|
|
16
|
+
# @param [ WPScan::Plugin ] plugin
|
|
17
|
+
def initialize(plugin)
|
|
18
|
+
finders << PluginVersion::Readme.new(plugin)
|
|
19
|
+
|
|
20
|
+
load_specific_finders(plugin)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Load the finders associated with the plugin
|
|
24
|
+
#
|
|
25
|
+
# @param [ WPScan::Plugin ] plugin
|
|
26
|
+
def load_specific_finders(plugin)
|
|
27
|
+
module_name = plugin.classify_name.to_sym
|
|
28
|
+
|
|
29
|
+
return unless Finders::PluginVersion.constants.include?(module_name)
|
|
30
|
+
|
|
31
|
+
mod = Finders::PluginVersion.const_get(module_name)
|
|
32
|
+
|
|
33
|
+
mod.constants.each do |constant|
|
|
34
|
+
c = mod.const_get(constant)
|
|
35
|
+
|
|
36
|
+
next unless c.is_a?(Class)
|
|
37
|
+
|
|
38
|
+
finders << c.new(plugin)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module PluginVersion
|
|
4
|
+
module LayerSlider
|
|
5
|
+
# Version from a Translation file
|
|
6
|
+
#
|
|
7
|
+
# See https://github.com/wpscanteam/wpscan/issues/765
|
|
8
|
+
class TranslationFile < CMSScanner::Finders::Finder
|
|
9
|
+
# @param [ Hash ] opts
|
|
10
|
+
#
|
|
11
|
+
# @return [ Version ]
|
|
12
|
+
def aggressive(_opts = {})
|
|
13
|
+
potential_urls.each do |url|
|
|
14
|
+
res = Browser.get(url)
|
|
15
|
+
|
|
16
|
+
next unless res.code == 200 && res.body =~ /Project-Id-Version: LayerSlider WP v?([0-9\.][^\\\s]+)/
|
|
17
|
+
|
|
18
|
+
return WPScan::Version.new(
|
|
19
|
+
Regexp.last_match[1],
|
|
20
|
+
found_by: 'Translation File (Aggressive Detection)',
|
|
21
|
+
confidence: 90,
|
|
22
|
+
interesting_entries: ["#{url}, Match: '#{Regexp.last_match}'"]
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
nil
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @return [ Array<String> ] The potential URLs where the version is disclosed
|
|
29
|
+
def potential_urls
|
|
30
|
+
# Recent versions seem to use the 'locales' directory instead of the 'languages' one.
|
|
31
|
+
# Maybe also check other locales ?
|
|
32
|
+
%w(locales languages).reduce([]) do |a, e|
|
|
33
|
+
a << target.url("#{e}/LayerSlider-en_US.po")
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module PluginVersion
|
|
4
|
+
# Plugin Version Finder from the readme.txt file
|
|
5
|
+
class Readme < CMSScanner::Finders::Finder
|
|
6
|
+
# @return [ Version ]
|
|
7
|
+
def aggressive(_opts = {})
|
|
8
|
+
found_by_msg = 'Readme - %s (Aggressive Detection)'
|
|
9
|
+
|
|
10
|
+
WPScan::WpItem::READMES.each do |file|
|
|
11
|
+
url = target.url(file)
|
|
12
|
+
res = Browser.get(url)
|
|
13
|
+
|
|
14
|
+
next unless res.code == 200 && !(numbers = version_numbers(res.body)).empty?
|
|
15
|
+
|
|
16
|
+
return numbers.reduce([]) do |a, e|
|
|
17
|
+
a << WPScan::Version.new(
|
|
18
|
+
e[0],
|
|
19
|
+
found_by: format(found_by_msg, e[1]),
|
|
20
|
+
confidence: e[2],
|
|
21
|
+
interesting_entries: [url]
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
nil
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @return [ Array<String, String, Integer> ] number, found_by, confidence
|
|
29
|
+
def version_numbers(body)
|
|
30
|
+
numbers = []
|
|
31
|
+
|
|
32
|
+
if (number = from_stable_tag(body))
|
|
33
|
+
numbers << [number, 'Stable Tag', 80]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
if (number = from_changelog_section(body))
|
|
37
|
+
numbers << [number, 'ChangeLog Section', 50]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
numbers
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# @param [ String ] body
|
|
44
|
+
#
|
|
45
|
+
# @return [ String, nil ] The version number detected from the stable tag
|
|
46
|
+
def from_stable_tag(body)
|
|
47
|
+
return unless body =~ /\b(?:stable tag|version):\s*(?!trunk)([0-9a-z\.-]+)/i
|
|
48
|
+
|
|
49
|
+
number = Regexp.last_match[1]
|
|
50
|
+
|
|
51
|
+
number if number =~ /[0-9]+/
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# @param [ String ] body
|
|
55
|
+
#
|
|
56
|
+
# @return [ String, nil ] The best version number detected from the changelog section
|
|
57
|
+
def from_changelog_section(body)
|
|
58
|
+
extracted_versions = body.scan(%r{[=]+\s+(?:v(?:ersion)?\s*)?([0-9\.-]+)[ \ta-z0-9\(\)\.\-\/]*[=]+}i)
|
|
59
|
+
|
|
60
|
+
return if extracted_versions.nil? || extracted_versions.empty?
|
|
61
|
+
|
|
62
|
+
extracted_versions.flatten!
|
|
63
|
+
# must contain at least one number
|
|
64
|
+
extracted_versions = extracted_versions.select { |x| x =~ /[0-9]+/ }
|
|
65
|
+
|
|
66
|
+
sorted = extracted_versions.sort do |x, y|
|
|
67
|
+
begin
|
|
68
|
+
Gem::Version.new(x) <=> Gem::Version.new(y)
|
|
69
|
+
rescue
|
|
70
|
+
0
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
sorted.last
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module PluginVersion
|
|
4
|
+
module Revslider
|
|
5
|
+
# Version from the release_log.html
|
|
6
|
+
#
|
|
7
|
+
# See https://github.com/wpscanteam/wpscan/issues/817
|
|
8
|
+
class ReleaseLog < CMSScanner::Finders::Finder
|
|
9
|
+
# @param [ Hash ] opts
|
|
10
|
+
#
|
|
11
|
+
# @return [ Version ]
|
|
12
|
+
def aggressive(_opts = {})
|
|
13
|
+
res = Browser.get(release_log_url)
|
|
14
|
+
|
|
15
|
+
res.html.css('h3.version-number:first').each do |node|
|
|
16
|
+
next unless node.text =~ /\AVersion ([0-9\.]+).*\z/i
|
|
17
|
+
|
|
18
|
+
return WPScan::Version.new(
|
|
19
|
+
Regexp.last_match[1],
|
|
20
|
+
found_by: found_by,
|
|
21
|
+
confidence: 90,
|
|
22
|
+
interesting_entries: ["#{release_log_url}, Match: '#{Regexp.last_match}'"]
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
nil
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def release_log_url
|
|
29
|
+
target.url('release_log.html')
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module PluginVersion
|
|
4
|
+
module SitepressMultilingualCms
|
|
5
|
+
# Version from the meta generator
|
|
6
|
+
class MetaGenerator < CMSScanner::Finders::Finder
|
|
7
|
+
# @param [ Hash ] opts
|
|
8
|
+
#
|
|
9
|
+
# @return [ Version ]
|
|
10
|
+
def passive(_opts = {})
|
|
11
|
+
target.target.homepage_res.html.css('meta[name="generator"]').each do |node|
|
|
12
|
+
next unless node['content'] =~ /\AWPML\sver:([0-9\.]+)\sstt/i
|
|
13
|
+
|
|
14
|
+
return WPScan::Version.new(
|
|
15
|
+
Regexp.last_match(1),
|
|
16
|
+
found_by: 'Meta Generator (Passive detection)',
|
|
17
|
+
confidence: 50,
|
|
18
|
+
interesting_entries: ["#{target.target.url}, Match: '#{node}'"]
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
nil
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module WPScan
|
|
2
|
+
module Finders
|
|
3
|
+
module PluginVersion
|
|
4
|
+
module SitepressMultilingualCms
|
|
5
|
+
# Version from the v parameter in href / src of stylesheets / scripts
|
|
6
|
+
class VersionParameter < CMSScanner::Finders::Finder
|
|
7
|
+
# @param [ Hash ] opts
|
|
8
|
+
#
|
|
9
|
+
# @return [ Version ]
|
|
10
|
+
def passive(_opts = {})
|
|
11
|
+
pattern = %r{#{Regexp.escape(target.target.plugins_dir)}/sitepress-multilingual-cms/}i
|
|
12
|
+
|
|
13
|
+
target.target.in_scope_urls(target.target.homepage_res, '//link|//script') do |url|
|
|
14
|
+
uri = Addressable::URI.parse(url)
|
|
15
|
+
|
|
16
|
+
next unless uri.path =~ pattern && uri.query =~ /v=([0-9\.]+)/
|
|
17
|
+
|
|
18
|
+
return WPScan::Version.new(
|
|
19
|
+
Regexp.last_match[1],
|
|
20
|
+
found_by: found_by,
|
|
21
|
+
confidence: 50,
|
|
22
|
+
interesting_entries: [url]
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
nil
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|