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