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.
Files changed (180) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile.lock +139 -0
  3. data/LICENSE +74 -0
  4. data/README.md +146 -0
  5. data/app/app.rb +3 -0
  6. data/app/controllers.rb +6 -0
  7. data/app/controllers/brute_force.rb +126 -0
  8. data/app/controllers/core.rb +104 -0
  9. data/app/controllers/custom_directories.rb +23 -0
  10. data/app/controllers/enumeration.rb +53 -0
  11. data/app/controllers/enumeration/cli_options.rb +126 -0
  12. data/app/controllers/enumeration/enum_methods.rb +157 -0
  13. data/app/controllers/main_theme.rb +27 -0
  14. data/app/controllers/wp_version.rb +30 -0
  15. data/app/finders.rb +13 -0
  16. data/app/finders/config_backups.rb +17 -0
  17. data/app/finders/config_backups/known_filenames.rb +46 -0
  18. data/app/finders/interesting_findings.rb +33 -0
  19. data/app/finders/interesting_findings/backup_db.rb +25 -0
  20. data/app/finders/interesting_findings/debug_log.rb +20 -0
  21. data/app/finders/interesting_findings/duplicator_installer_log.rb +23 -0
  22. data/app/finders/interesting_findings/full_path_disclosure.rb +23 -0
  23. data/app/finders/interesting_findings/mu_plugins.rb +48 -0
  24. data/app/finders/interesting_findings/multisite.rb +29 -0
  25. data/app/finders/interesting_findings/readme.rb +26 -0
  26. data/app/finders/interesting_findings/registration.rb +31 -0
  27. data/app/finders/interesting_findings/tmm_db_migrate.rb +24 -0
  28. data/app/finders/interesting_findings/upload_directory_listing.rb +24 -0
  29. data/app/finders/interesting_findings/upload_sql_dump.rb +28 -0
  30. data/app/finders/main_theme.rb +22 -0
  31. data/app/finders/main_theme/css_style.rb +43 -0
  32. data/app/finders/main_theme/urls_in_homepage.rb +25 -0
  33. data/app/finders/main_theme/woo_framework_meta_generator.rb +22 -0
  34. data/app/finders/medias.rb +17 -0
  35. data/app/finders/medias/attachment_brute_forcing.rb +44 -0
  36. data/app/finders/plugin_version.rb +44 -0
  37. data/app/finders/plugin_version/layer_slider/translation_file.rb +40 -0
  38. data/app/finders/plugin_version/readme.rb +79 -0
  39. data/app/finders/plugin_version/revslider/release_log.rb +35 -0
  40. data/app/finders/plugin_version/sitepress_multilingual_cms/meta_generator.rb +27 -0
  41. data/app/finders/plugin_version/sitepress_multilingual_cms/version_parameter.rb +31 -0
  42. data/app/finders/plugin_version/w3_total_cache/headers.rb +28 -0
  43. data/app/finders/plugins.rb +24 -0
  44. data/app/finders/plugins/comments.rb +31 -0
  45. data/app/finders/plugins/headers.rb +36 -0
  46. data/app/finders/plugins/known_locations.rb +48 -0
  47. data/app/finders/plugins/urls_in_homepage.rb +29 -0
  48. data/app/finders/theme_version.rb +41 -0
  49. data/app/finders/theme_version/style.rb +43 -0
  50. data/app/finders/theme_version/woo_framework_meta_generator.rb +19 -0
  51. data/app/finders/themes.rb +20 -0
  52. data/app/finders/themes/known_locations.rb +48 -0
  53. data/app/finders/themes/urls_in_homepage.rb +23 -0
  54. data/app/finders/timthumb_version.rb +17 -0
  55. data/app/finders/timthumb_version/bad_request.rb +21 -0
  56. data/app/finders/timthumbs.rb +17 -0
  57. data/app/finders/timthumbs/known_locations.rb +56 -0
  58. data/app/finders/users.rb +24 -0
  59. data/app/finders/users/author_id_brute_forcing.rb +111 -0
  60. data/app/finders/users/author_posts.rb +61 -0
  61. data/app/finders/users/login_error_messages.rb +50 -0
  62. data/app/finders/users/wp_json_api.rb +31 -0
  63. data/app/finders/wp_items.rb +1 -0
  64. data/app/finders/wp_items/urls_in_homepage.rb +68 -0
  65. data/app/finders/wp_version.rb +34 -0
  66. data/app/finders/wp_version/atom_generator.rb +40 -0
  67. data/app/finders/wp_version/meta_generator.rb +27 -0
  68. data/app/finders/wp_version/opml_generator.rb +23 -0
  69. data/app/finders/wp_version/rdf_generator.rb +38 -0
  70. data/app/finders/wp_version/readme.rb +28 -0
  71. data/app/finders/wp_version/rss_generator.rb +43 -0
  72. data/app/finders/wp_version/sitemap_generator.rb +23 -0
  73. data/app/finders/wp_version/stylesheets.rb +55 -0
  74. data/app/finders/wp_version/unique_fingerprinting.rb +64 -0
  75. data/app/models.rb +10 -0
  76. data/app/models/config_backup.rb +5 -0
  77. data/app/models/interesting_finding.rb +6 -0
  78. data/app/models/media.rb +5 -0
  79. data/app/models/plugin.rb +25 -0
  80. data/app/models/theme.rb +99 -0
  81. data/app/models/timthumb.rb +74 -0
  82. data/app/models/user.rb +31 -0
  83. data/app/models/wp_item.rb +142 -0
  84. data/app/models/wp_version.rb +49 -0
  85. data/app/models/xml_rpc.rb +19 -0
  86. data/app/views/cli/brute_force/error.erb +1 -0
  87. data/app/views/cli/brute_force/found.erb +2 -0
  88. data/app/views/cli/brute_force/users.erb +9 -0
  89. data/app/views/cli/core/banner.erb +14 -0
  90. data/app/views/cli/core/db_update_finished.erb +8 -0
  91. data/app/views/cli/core/db_update_started.erb +1 -0
  92. data/app/views/cli/core/not_fully_configured.erb +1 -0
  93. data/app/views/cli/enumeration/config_backups.erb +11 -0
  94. data/app/views/cli/enumeration/medias.erb +11 -0
  95. data/app/views/cli/enumeration/plugins.erb +35 -0
  96. data/app/views/cli/enumeration/themes.erb +11 -0
  97. data/app/views/cli/enumeration/timthumbs.erb +18 -0
  98. data/app/views/cli/enumeration/users.erb +11 -0
  99. data/app/views/cli/finding.erb +32 -0
  100. data/app/views/cli/info.erb +1 -0
  101. data/app/views/cli/main_theme/theme.erb +6 -0
  102. data/app/views/cli/notice.erb +1 -0
  103. data/app/views/cli/theme.erb +64 -0
  104. data/app/views/cli/usage.erb +3 -0
  105. data/app/views/cli/vulnerability.erb +14 -0
  106. data/app/views/cli/wp_version/version.erb +6 -0
  107. data/app/views/json/brute_force/users.erb +10 -0
  108. data/app/views/json/core/banner.erb +12 -0
  109. data/app/views/json/core/db_update_finished.erb +2 -0
  110. data/app/views/json/core/db_update_started.erb +1 -0
  111. data/app/views/json/core/not_fully_configured.erb +1 -0
  112. data/app/views/json/enumeration/config_backups.erb +10 -0
  113. data/app/views/json/enumeration/medias.erb +10 -0
  114. data/app/views/json/enumeration/plugins.erb +25 -0
  115. data/app/views/json/enumeration/themes.erb +10 -0
  116. data/app/views/json/enumeration/timthumbs.erb +19 -0
  117. data/app/views/json/enumeration/users.erb +11 -0
  118. data/app/views/json/finding.erb +26 -0
  119. data/app/views/json/main_theme/theme.erb +7 -0
  120. data/app/views/json/theme.erb +38 -0
  121. data/app/views/json/wp_version/version.erb +8 -0
  122. data/bin/wpscan +15 -0
  123. data/coverage/assets/0.10.0/application.css +799 -0
  124. data/coverage/assets/0.10.0/application.js +1707 -0
  125. data/coverage/assets/0.10.0/colorbox/border.png +0 -0
  126. data/coverage/assets/0.10.0/colorbox/controls.png +0 -0
  127. data/coverage/assets/0.10.0/colorbox/loading.gif +0 -0
  128. data/coverage/assets/0.10.0/colorbox/loading_background.png +0 -0
  129. data/coverage/assets/0.10.0/favicon_green.png +0 -0
  130. data/coverage/assets/0.10.0/favicon_red.png +0 -0
  131. data/coverage/assets/0.10.0/favicon_yellow.png +0 -0
  132. data/coverage/assets/0.10.0/loading.gif +0 -0
  133. data/coverage/assets/0.10.0/magnify.png +0 -0
  134. data/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  135. data/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  136. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  137. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  138. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  139. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  140. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  141. data/coverage/assets/0.10.0/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  142. data/coverage/assets/0.10.0/smoothness/images/ui-icons_222222_256x240.png +0 -0
  143. data/coverage/assets/0.10.0/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  144. data/coverage/assets/0.10.0/smoothness/images/ui-icons_454545_256x240.png +0 -0
  145. data/coverage/assets/0.10.0/smoothness/images/ui-icons_888888_256x240.png +0 -0
  146. data/coverage/assets/0.10.0/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  147. data/coverage/index.html +27510 -0
  148. data/lib/wpscan.rb +44 -0
  149. data/lib/wpscan/browser.rb +16 -0
  150. data/lib/wpscan/controller.rb +8 -0
  151. data/lib/wpscan/controllers.rb +8 -0
  152. data/lib/wpscan/db.rb +28 -0
  153. data/lib/wpscan/db/dynamic_finders.rb +63 -0
  154. data/lib/wpscan/db/plugin.rb +11 -0
  155. data/lib/wpscan/db/plugins.rb +11 -0
  156. data/lib/wpscan/db/schema.rb +39 -0
  157. data/lib/wpscan/db/theme.rb +11 -0
  158. data/lib/wpscan/db/themes.rb +11 -0
  159. data/lib/wpscan/db/updater.rb +148 -0
  160. data/lib/wpscan/db/wp_item.rb +18 -0
  161. data/lib/wpscan/db/wp_items.rb +21 -0
  162. data/lib/wpscan/db/wp_version.rb +11 -0
  163. data/lib/wpscan/errors/http.rb +34 -0
  164. data/lib/wpscan/errors/update.rb +8 -0
  165. data/lib/wpscan/errors/wordpress.rb +22 -0
  166. data/lib/wpscan/finders.rb +14 -0
  167. data/lib/wpscan/finders/finder/plugin_version/comments.rb +25 -0
  168. data/lib/wpscan/finders/finder/wp_version/smart_url_checker.rb +23 -0
  169. data/lib/wpscan/helper.rb +6 -0
  170. data/lib/wpscan/references.rb +31 -0
  171. data/lib/wpscan/target.rb +81 -0
  172. data/lib/wpscan/target/platform/wordpress.rb +74 -0
  173. data/lib/wpscan/target/platform/wordpress/custom_directories.rb +93 -0
  174. data/lib/wpscan/version.rb +4 -0
  175. data/lib/wpscan/vulnerability.rb +25 -0
  176. data/lib/wpscan/vulnerable.rb +10 -0
  177. data/wpscan-v3.sublime-project +8 -0
  178. data/wpscan-v3.sublime-workspace +895 -0
  179. data/wpscan.gemspec +55 -0
  180. 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