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 WpVersion
|
|
@@ -11,7 +13,7 @@ module WPScan
|
|
|
11
13
|
hydra.abort
|
|
12
14
|
progress_bar.finish
|
|
13
15
|
|
|
14
|
-
return
|
|
16
|
+
return Model::WpVersion.new(
|
|
15
17
|
version_number,
|
|
16
18
|
found_by: 'Unique Fingerprinting (Aggressive Detection)',
|
|
17
19
|
confidence: 100,
|
data/app/models.rb
CHANGED
data/app/models/config_backup.rb
CHANGED
data/app/models/db_export.rb
CHANGED
|
@@ -1,48 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
module Model
|
|
5
|
+
# Custom class to include the WPScan::References module
|
|
6
|
+
class InterestingFinding < CMSScanner::Model::InterestingFinding
|
|
7
|
+
include References
|
|
8
|
+
end
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
#
|
|
11
|
+
# Empty classes for the #type to be correctly displayed (as taken from the self.class from the parent)
|
|
12
|
+
#
|
|
13
|
+
class BackupDB < InterestingFinding
|
|
14
|
+
end
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
class DebugLog < InterestingFinding
|
|
17
|
+
end
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
class DuplicatorInstallerLog < InterestingFinding
|
|
20
|
+
end
|
|
18
21
|
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
class EmergencyPwdResetScript < InterestingFinding
|
|
23
|
+
end
|
|
21
24
|
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
class FullPathDisclosure < InterestingFinding
|
|
26
|
+
end
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
class MuPlugins < InterestingFinding
|
|
29
|
+
end
|
|
27
30
|
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
class Multisite < InterestingFinding
|
|
32
|
+
end
|
|
30
33
|
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
class Readme < InterestingFinding
|
|
35
|
+
end
|
|
33
36
|
|
|
34
|
-
|
|
35
|
-
|
|
37
|
+
class Registration < InterestingFinding
|
|
38
|
+
end
|
|
36
39
|
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
class TmmDbMigrate < InterestingFinding
|
|
41
|
+
end
|
|
39
42
|
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
class UploadDirectoryListing < InterestingFinding
|
|
44
|
+
end
|
|
42
45
|
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
class UploadSQLDump < InterestingFinding
|
|
47
|
+
end
|
|
45
48
|
|
|
46
|
-
|
|
49
|
+
class WPCron < InterestingFinding
|
|
50
|
+
end
|
|
47
51
|
end
|
|
48
52
|
end
|
data/app/models/media.rb
CHANGED
data/app/models/plugin.rb
CHANGED
|
@@ -1,25 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
module Model
|
|
5
|
+
# WordPress Plugin
|
|
6
|
+
class Plugin < WpItem
|
|
7
|
+
# See WpItem
|
|
8
|
+
def initialize(slug, blog, opts = {})
|
|
9
|
+
super(slug, blog, opts)
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
# To be used by #head_and_get
|
|
12
|
+
# If custom wp-content, it will be replaced by blog#url
|
|
13
|
+
@path_from_blog = "wp-content/plugins/#{slug}/"
|
|
10
14
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
@uri = Addressable::URI.parse(blog.url(path_from_blog))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @return [ JSON ]
|
|
19
|
+
def db_data
|
|
20
|
+
@db_data ||= DB::Plugin.db_data(slug)
|
|
21
|
+
end
|
|
15
22
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
23
|
+
# @param [ Hash ] opts
|
|
24
|
+
#
|
|
25
|
+
# @return [ Model::Version, false ]
|
|
26
|
+
def version(opts = {})
|
|
27
|
+
@version = Finders::PluginVersion::Base.find(self, version_detection_opts.merge(opts)) if @version.nil?
|
|
21
28
|
|
|
22
|
-
|
|
29
|
+
@version
|
|
30
|
+
end
|
|
23
31
|
end
|
|
24
32
|
end
|
|
25
33
|
end
|
data/app/models/theme.rb
CHANGED
|
@@ -1,99 +1,107 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
module Model
|
|
5
|
+
# WordPress Theme
|
|
6
|
+
class Theme < WpItem
|
|
7
|
+
attr_reader :style_url, :style_name, :style_uri, :author, :author_uri, :template, :description,
|
|
8
|
+
:license, :license_uri, :tags, :text_domain
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
# See WpItem
|
|
11
|
+
def initialize(slug, blog, opts = {})
|
|
12
|
+
super(slug, blog, opts)
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
# To be used by #head_and_get
|
|
15
|
+
# If custom wp-content, it will be replaced by blog#url
|
|
16
|
+
@path_from_blog = "wp-content/themes/#{slug}/"
|
|
13
17
|
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
@uri = Addressable::URI.parse(blog.url(path_from_blog))
|
|
19
|
+
@style_url = opts[:style_url] || url('style.css')
|
|
16
20
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
DB::Theme.db_data(slug)
|
|
20
|
-
end
|
|
21
|
+
parse_style
|
|
22
|
+
end
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
@version = Finders::ThemeVersion::Base.find(self, version_detection_opts.merge(opts)) if @version.nil?
|
|
24
|
+
# @return [ JSON ]
|
|
25
|
+
def db_data
|
|
26
|
+
@db_data ||= DB::Theme.db_data(slug)
|
|
27
|
+
end
|
|
27
28
|
|
|
28
|
-
@
|
|
29
|
-
|
|
29
|
+
# @param [ Hash ] opts
|
|
30
|
+
#
|
|
31
|
+
# @return [ Model::Version, false ]
|
|
32
|
+
def version(opts = {})
|
|
33
|
+
@version = Finders::ThemeVersion::Base.find(self, version_detection_opts.merge(opts)) if @version.nil?
|
|
30
34
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return unless template
|
|
34
|
-
return unless style_body =~ /^@import\surl\(["']?([^"'\)]+)["']?\);\s*$/i
|
|
35
|
+
@version
|
|
36
|
+
end
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
).merge(version_detection: version_detection_opts)
|
|
38
|
+
# @return [ Theme ]
|
|
39
|
+
def parent_theme
|
|
40
|
+
return unless template
|
|
41
|
+
return unless style_body =~ /^@import\surl\(["']?([^"'\)]+)["']?\);\s*$/i
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
opts = detection_opts.merge(
|
|
44
|
+
style_url: url(Regexp.last_match[1]),
|
|
45
|
+
found_by: 'Parent Themes (Passive Detection)',
|
|
46
|
+
confidence: 100
|
|
47
|
+
).merge(version_detection: version_detection_opts)
|
|
44
48
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
# @retun [ Array<Theme> ]
|
|
48
|
-
def parent_themes(depth = 3)
|
|
49
|
-
theme = self
|
|
50
|
-
found = []
|
|
49
|
+
self.class.new(template, blog, opts)
|
|
50
|
+
end
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
# @param [ Integer ] depth
|
|
53
|
+
#
|
|
54
|
+
# @retun [ Array<Theme> ]
|
|
55
|
+
def parent_themes(depth = 3)
|
|
56
|
+
theme = self
|
|
57
|
+
found = []
|
|
54
58
|
|
|
55
|
-
|
|
59
|
+
(1..depth).each do |_|
|
|
60
|
+
parent = theme.parent_theme
|
|
56
61
|
|
|
57
|
-
|
|
58
|
-
theme = parent
|
|
59
|
-
end
|
|
62
|
+
break unless parent
|
|
60
63
|
|
|
61
|
-
|
|
62
|
-
|
|
64
|
+
found << parent
|
|
65
|
+
theme = parent
|
|
66
|
+
end
|
|
63
67
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
end
|
|
68
|
+
found
|
|
69
|
+
end
|
|
67
70
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
style_name: 'Theme Name',
|
|
71
|
-
style_uri: 'Theme URI',
|
|
72
|
-
author: 'Author',
|
|
73
|
-
author_uri: 'Author URI',
|
|
74
|
-
template: 'Template',
|
|
75
|
-
description: 'Description',
|
|
76
|
-
license: 'License',
|
|
77
|
-
license_uri: 'License URI',
|
|
78
|
-
tags: 'Tags',
|
|
79
|
-
text_domain: 'Text Domain'
|
|
80
|
-
}.each do |attribute, tag|
|
|
81
|
-
instance_variable_set(:"@#{attribute}", parse_style_tag(style_body, tag))
|
|
71
|
+
def style_body
|
|
72
|
+
@style_body ||= Browser.get(style_url).body
|
|
82
73
|
end
|
|
83
|
-
end
|
|
84
74
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
75
|
+
def parse_style
|
|
76
|
+
{
|
|
77
|
+
style_name: 'Theme Name',
|
|
78
|
+
style_uri: 'Theme URI',
|
|
79
|
+
author: 'Author',
|
|
80
|
+
author_uri: 'Author URI',
|
|
81
|
+
template: 'Template',
|
|
82
|
+
description: 'Description',
|
|
83
|
+
license: 'License',
|
|
84
|
+
license_uri: 'License URI',
|
|
85
|
+
tags: 'Tags',
|
|
86
|
+
text_domain: 'Text Domain'
|
|
87
|
+
}.each do |attribute, tag|
|
|
88
|
+
instance_variable_set(:"@#{attribute}", parse_style_tag(style_body, tag))
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
# @param [ String ] bofy
|
|
93
|
+
# @param [ String ] tag
|
|
94
|
+
#
|
|
95
|
+
# @return [ String ]
|
|
96
|
+
def parse_style_tag(body, tag)
|
|
97
|
+
value = body[/^\s*#{Regexp.escape(tag)}:[\t ]*([^\r\n]+)/i, 1]
|
|
98
|
+
|
|
99
|
+
value && !value.strip.empty? ? value.strip : nil
|
|
100
|
+
end
|
|
94
101
|
|
|
95
|
-
|
|
96
|
-
|
|
102
|
+
def ==(other)
|
|
103
|
+
super(other) && style_url == other.style_url
|
|
104
|
+
end
|
|
97
105
|
end
|
|
98
106
|
end
|
|
99
107
|
end
|
data/app/models/timthumb.rb
CHANGED
|
@@ -1,71 +1,75 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module WPScan
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
module Model
|
|
5
|
+
# Timthumb
|
|
6
|
+
class Timthumb < InterestingFinding
|
|
7
|
+
include Vulnerable
|
|
5
8
|
|
|
6
|
-
|
|
9
|
+
attr_reader :version_detection_opts
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
# @param [ String ] url
|
|
12
|
+
# @param [ Hash ] opts
|
|
13
|
+
# @option opts [ Symbol ] :mode The mode to use to detect the version
|
|
14
|
+
def initialize(url, opts = {})
|
|
15
|
+
super(url, opts)
|
|
13
16
|
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
@version_detection_opts = opts[:version_detection] || {}
|
|
18
|
+
end
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
# @param [ Hash ] opts
|
|
21
|
+
#
|
|
22
|
+
# @return [ Model::Version, false ]
|
|
23
|
+
def version(opts = {})
|
|
24
|
+
@version = Finders::TimthumbVersion::Base.find(self, version_detection_opts.merge(opts)) if @version.nil?
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
@version
|
|
27
|
+
end
|
|
25
28
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
# @return [ Array<Vulnerability> ]
|
|
30
|
+
def vulnerabilities
|
|
31
|
+
vulns = []
|
|
29
32
|
|
|
30
|
-
|
|
31
|
-
|
|
33
|
+
vulns << rce_webshot_vuln if version == false || version > '1.35' && version < '2.8.14' && webshot_enabled?
|
|
34
|
+
vulns << rce_132_vuln if version == false || version < '1.33'
|
|
32
35
|
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
vulns
|
|
37
|
+
end
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
# @return [ Vulnerability ] The RCE in the <= 1.32
|
|
40
|
+
def rce_132_vuln
|
|
41
|
+
Vulnerability.new(
|
|
42
|
+
'Timthumb <= 1.32 Remote Code Execution',
|
|
43
|
+
{ exploitdb: ['17602'] },
|
|
44
|
+
'RCE',
|
|
45
|
+
'1.33'
|
|
46
|
+
)
|
|
47
|
+
end
|
|
45
48
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
49
|
+
# @return [ Vulnerability ] The RCE due to the WebShot in the > 1.35 (or >= 2.0) and <= 2.8.13
|
|
50
|
+
def rce_webshot_vuln
|
|
51
|
+
Vulnerability.new(
|
|
52
|
+
'Timthumb <= 2.8.13 WebShot Remote Code Execution',
|
|
53
|
+
{
|
|
54
|
+
url: ['http://seclists.org/fulldisclosure/2014/Jun/117', 'https://github.com/wpscanteam/wpscan/issues/519'],
|
|
55
|
+
cve: '2014-4663'
|
|
56
|
+
},
|
|
57
|
+
'RCE',
|
|
58
|
+
'2.8.14'
|
|
59
|
+
)
|
|
60
|
+
end
|
|
58
61
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
# @return [ Boolean ]
|
|
63
|
+
def webshot_enabled?
|
|
64
|
+
res = Browser.get(url, params: { webshot: 1, src: "http://#{default_allowed_domains.sample}" })
|
|
62
65
|
|
|
63
|
-
|
|
64
|
-
|
|
66
|
+
res.body =~ /WEBSHOT_ENABLED == true/ ? false : true
|
|
67
|
+
end
|
|
65
68
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
# @return [ Array<String> ] The default allowed domains (between the 2.0 and 2.8.13)
|
|
70
|
+
def default_allowed_domains
|
|
71
|
+
%w[flickr.com picasa.com img.youtube.com upload.wikimedia.org]
|
|
72
|
+
end
|
|
69
73
|
end
|
|
70
74
|
end
|
|
71
75
|
end
|