lib/wpscan/target/platform/wordpress/custom_directories.rb in wpscan-3.5.2 vs lib/wpscan/target/platform/wordpress/custom_directories.rb in wpscan-3.5.3
- old
+ new
@@ -11,28 +11,40 @@
def plugins_dir=(dir)
@plugins_dir = dir.chomp('/')
end
+ # @param [ Symbol ] detection_mode
# @return [ String ] The wp-content directory
- def content_dir
+ def content_dir(detection_mode = :mixed)
unless @content_dir
- escaped_url = Regexp.escape(url).gsub(/https?/i, 'https?')
- pattern = %r{#{escaped_url}([\w\s\-\/]+)\/(?:themes|plugins|uploads|cache)\/}i
+ # scope_url_pattern is from CMSScanner::Target
+ pattern = %r{#{scope_url_pattern}([\w\s\-/]+)\\?/(?:themes|plugins|uploads|cache)\\?/}i
- in_scope_urls(homepage_res) do |url|
- return @content_dir = Regexp.last_match[1] if url.match(pattern)
+ in_scope_uris(homepage_res) do |uri|
+ return @content_dir = Regexp.last_match[1] if uri.to_s.match(pattern)
end
- xpath_pattern_from_page('//script[not(@src)]', pattern, homepage_res) do |match|
+ # Checks for the pattern in raw JS code, as well as @content attributes of meta tags
+ xpath_pattern_from_page('//script[not(@src)]|//meta/@content', pattern, homepage_res) do |match|
return @content_dir = match[1]
end
+
+ unless detection_mode == :passive
+ return @content_dir = 'wp-content' if default_content_dir_exists?
+ end
end
@content_dir
end
+ def default_content_dir_exists?
+ # url('wp-content') can't be used here as the folder has not yet been identified
+ # and the method would try to replace it by nil which would raise an error
+ [200, 401, 403].include?(Browser.forge_request(uri.join('wp-content/').to_s, head_or_get_params).run.code)
+ end
+
# @return [ Addressable::URI ]
def content_uri
uri.join("#{content_dir}/")
end
@@ -83,20 +95,19 @@
# @return [ String ]
def theme_url(slug)
themes_uri.join("#{URI.encode(slug)}/").to_s
end
- # TODO: Factorise the code and the content_dir one ?
# @return [ String, False ] String of the sub_dir found, false otherwise
# @note: nil can not be returned here, otherwise if there is no sub_dir
# the check would be done each time
def sub_dir
unless @sub_dir
- escaped_url = Regexp.escape(url).gsub(/https?/i, 'https?')
- pattern = %r{#{escaped_url}(.+?)\/(?:xmlrpc\.php|wp\-includes\/)}i
+ # url_pattern is from CMSScanner::Target
+ pattern = %r{#{url_pattern}(.+?)/(?:xmlrpc\.php|wp\-includes/)}i
- in_scope_urls(homepage_res) do |url|
- return @sub_dir = Regexp.last_match[1] if url.match(pattern)
+ in_scope_uris(homepage_res) do |uri|
+ return @sub_dir = Regexp.last_match[1] if uri.to_s.match(pattern)
end
@sub_dir = false
end