Fix #54 False positive when a plugin directory redirects to the homepage
This commit is contained in:
@@ -18,8 +18,6 @@
|
||||
|
||||
module WebSite
|
||||
|
||||
#@error_404_hash = nil
|
||||
|
||||
# Checks if the remote website is up.
|
||||
def online?
|
||||
Browser.instance.get(@uri.to_s).code != 0
|
||||
|
||||
@@ -57,11 +57,12 @@ class WpEnumerator
|
||||
request_count += 1
|
||||
|
||||
request.on_complete do |response|
|
||||
page_hash = Digest::MD5.hexdigest(response.body)
|
||||
|
||||
print "\rChecking for #{enumerate_size} total #{options[:type]}... #{(request_count * 100) / enumerate_size}% complete." if options[:show_progress_bar]
|
||||
|
||||
if WpTarget.valid_response_codes.include?(response.code)
|
||||
if Digest::MD5.hexdigest(response.body) != options[:error_404_hash]
|
||||
if page_hash != options[:error_404_hash] and page_hash != options[:homepage_hash]
|
||||
if options[:exclude_content_based]
|
||||
unless response.body[exclude_regexp]
|
||||
found << target
|
||||
|
||||
@@ -29,44 +29,70 @@ shared_examples_for "WpPlugins" do
|
||||
before :each do
|
||||
@module = WpScanModuleSpec.new(@wp_url)
|
||||
@module.error_404_hash = Digest::MD5.hexdigest("Error 404!")
|
||||
@module.homepage_hash = Digest::MD5.hexdigest("Homepage!")
|
||||
@module.extend(WpPlugins)
|
||||
|
||||
@options = {:base_url => @wp_url,
|
||||
:only_vulnerable_ones => false,
|
||||
:show_progress_bar => false,
|
||||
:error_404_hash => Digest::MD5.hexdigest("Error 404!"),
|
||||
:vulns_file => @plugin_vulns_file,
|
||||
:file => @plugins_file,
|
||||
:type => "plugins",
|
||||
:wp_content_dir => "wp-content",
|
||||
:vulns_xpath_2 => "//plugin"
|
||||
@options = {
|
||||
:base_url => @wp_url,
|
||||
:only_vulnerable_ones => false,
|
||||
:show_progress_bar => false,
|
||||
:error_404_hash => @module.error_404_hash,
|
||||
:homepage_hash => @module.homepage_hash,
|
||||
:vulns_file => @plugin_vulns_file,
|
||||
:file => @plugins_file,
|
||||
:type => "plugins",
|
||||
:wp_content_dir => "wp-content",
|
||||
:vulns_xpath_2 => "//plugin"
|
||||
}
|
||||
File.exist?(@plugin_vulns_file).should == true
|
||||
File.exist?(@plugins_file).should == true
|
||||
@targets = [WpPlugin.new({:base_url => "http://example.localhost/",
|
||||
:path => "exclude-pages/exclude_pages.php",
|
||||
:wp_content_dir => "wp-content",
|
||||
:name => "exclude-pages"}),
|
||||
WpPlugin.new({:base_url => "http://example.localhost/",
|
||||
:path => "display-widgets/display-widgets.php",
|
||||
:wp_content_dir => "wp-content",
|
||||
:name => "display-widgets"}),
|
||||
WpPlugin.new({:base_url => "http://example.localhost/",
|
||||
:path => "media-library",
|
||||
:wp_content_dir => "wp-content",
|
||||
:name => "media-library"}),
|
||||
WpPlugin.new({:base_url => "http://example.localhost/",
|
||||
:path => "deans",
|
||||
:wp_content_dir => "wp-content",
|
||||
:name => "deans"}),
|
||||
WpPlugin.new({:base_url => "http://example.localhost/",
|
||||
:path => "formidable/formidable.php",
|
||||
:wp_content_dir => "wp-content",
|
||||
:name => "formidable"}),
|
||||
WpPlugin.new({:base_url => "http://example.localhost/",
|
||||
:path => "regenerate-thumbnails/readme.txt",
|
||||
:wp_content_dir => "wp-content",
|
||||
:name => "regenerate-thumbnails"})]
|
||||
|
||||
# These targets are listed in @fixtures_dir + "/plugins.txt"
|
||||
# TODO : load them directly from the fixture file
|
||||
@targets = [
|
||||
WpPlugin.new(
|
||||
{
|
||||
:base_url => "http://example.localhost/",
|
||||
:path => "exclude-pages/exclude_pages.php",
|
||||
:wp_content_dir => "wp-content",
|
||||
:name => "exclude-pages"
|
||||
}),
|
||||
WpPlugin.new(
|
||||
{
|
||||
:base_url => "http://example.localhost/",
|
||||
:path => "display-widgets/display-widgets.php",
|
||||
:wp_content_dir => "wp-content",
|
||||
:name => "display-widgets"
|
||||
}),
|
||||
WpPlugin.new(
|
||||
{
|
||||
:base_url => "http://example.localhost/",
|
||||
:path => "media-library",
|
||||
:wp_content_dir => "wp-content",
|
||||
:name => "media-library"
|
||||
}),
|
||||
WpPlugin.new(
|
||||
{
|
||||
:base_url => "http://example.localhost/",
|
||||
:path => "deans",
|
||||
:wp_content_dir => "wp-content",
|
||||
:name => "deans"
|
||||
}),
|
||||
WpPlugin.new(
|
||||
{
|
||||
:base_url => "http://example.localhost/",
|
||||
:path => "formidable/formidable.php",
|
||||
:wp_content_dir => "wp-content",
|
||||
:name => "formidable"
|
||||
}),
|
||||
WpPlugin.new(
|
||||
{
|
||||
:base_url => "http://example.localhost/",
|
||||
:path => "regenerate-thumbnails/readme.txt",
|
||||
:wp_content_dir => "wp-content",
|
||||
:name => "regenerate-thumbnails"
|
||||
})
|
||||
]
|
||||
end
|
||||
|
||||
describe "#plugins_from_passive_detection" do
|
||||
@@ -92,9 +118,11 @@ shared_examples_for "WpPlugins" do
|
||||
}
|
||||
expected_plugins = []
|
||||
expected_plugin_names.each do |plugin_name|
|
||||
expected_plugins << WpPlugin.new(:base_url => @module.url,
|
||||
:path => "/plugins/#{plugin_name}/",
|
||||
:name => plugin_name)
|
||||
expected_plugins << WpPlugin.new(
|
||||
:base_url => @module.url,
|
||||
:path => "/plugins/#{plugin_name}/",
|
||||
:name => plugin_name
|
||||
)
|
||||
end
|
||||
|
||||
plugins = @module.plugins_from_passive_detection(:base_url => @module.url, :wp_content_dir => "wp-content")
|
||||
@@ -134,9 +162,11 @@ shared_examples_for "WpPlugins" do
|
||||
@expected_plugins.each do |p|
|
||||
stub_request(:get, p.get_full_url.to_s).to_return(:status => 200)
|
||||
end
|
||||
new_plugin = WpPlugin.new(:base_url => "http://example.localhost/",
|
||||
:path => "/plugins/comment-info-tip/",
|
||||
:name => "comment-info-tip")
|
||||
new_plugin = WpPlugin.new(
|
||||
:base_url => "http://example.localhost/",
|
||||
:path => "/plugins/comment-info-tip/",
|
||||
:name => "comment-info-tip"
|
||||
)
|
||||
stub_request(:get, new_plugin.readme_url.to_s).to_return(:status => 200)
|
||||
@expected_plugins << new_plugin
|
||||
end
|
||||
@@ -152,5 +182,15 @@ shared_examples_for "WpPlugins" do
|
||||
stub_request(:get, plugin_url[0].get_full_url.to_s).to_return(:status => valid_response_code)
|
||||
end
|
||||
end
|
||||
|
||||
it "should not detect the plugin if there is a redirection to the homepage" do
|
||||
# Let's pick up 2 plugins (The first one will redirect to the homepage)
|
||||
plugins = @targets.sample(2)
|
||||
stub_request(:get, plugins[0].get_full_url.to_s).to_return(:status => 200, :body => "Homepage!")
|
||||
stub_request(:get, plugins[1].get_full_url.to_s).to_return(:status => 200)
|
||||
|
||||
@expected_plugins = [plugins[1]]
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -30,7 +30,7 @@ SPEC_FIXTURES_WPSCAN_WP_VERSION_DIR = SPEC_FIXTURES_WPSCAN_DIR + '/wp_versio
|
||||
|
||||
class WpScanModuleSpec
|
||||
attr_reader :uri
|
||||
attr_accessor :error_404_hash, :wp_content_dir, :verbose
|
||||
attr_accessor :error_404_hash, :homepage_hash, :wp_content_dir, :verbose
|
||||
|
||||
def initialize(target_url)
|
||||
@uri = URI.parse(add_http_protocol(target_url))
|
||||
|
||||
@@ -216,6 +216,7 @@ begin
|
||||
:show_progress_bar => true,
|
||||
:wp_content_dir => wp_target.wp_content_dir,
|
||||
:error_404_hash => wp_target.error_404_hash,
|
||||
:homepage_hash => wp_target.homepage_hash,
|
||||
:wp_plugins_dir => wp_target.wp_plugins_dir,
|
||||
:full => wpscan_options.enumerate_all_plugins,
|
||||
:exclude_content_based => wpscan_options.exclude_content_based
|
||||
@@ -274,6 +275,7 @@ begin
|
||||
:show_progress_bar => true,
|
||||
:wp_content_dir => wp_target.wp_content_dir,
|
||||
:error_404_hash => wp_target.error_404_hash,
|
||||
:homepage_hash => wp_target.homepage_hash,
|
||||
:full => wpscan_options.enumerate_all_themes,
|
||||
:exclude_content_based => wpscan_options.exclude_content_based
|
||||
}
|
||||
@@ -322,6 +324,7 @@ begin
|
||||
:show_progress_bar => true,
|
||||
:wp_content_dir => wp_target.wp_content_dir,
|
||||
:error_404_hash => wp_target.error_404_hash,
|
||||
:homepage_hash => wp_target.homepage_hash,
|
||||
:exclude_content_based => wpscan_options.exclude_content_based
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user