Fix #54 False positive when a plugin directory redirects to the homepage

This commit is contained in:
erwanlr
2012-12-21 12:21:40 +01:00
parent c0a05a4119
commit 9b14a8d038
5 changed files with 85 additions and 43 deletions

View File

@@ -18,8 +18,6 @@
module WebSite module WebSite
#@error_404_hash = nil
# Checks if the remote website is up. # Checks if the remote website is up.
def online? def online?
Browser.instance.get(@uri.to_s).code != 0 Browser.instance.get(@uri.to_s).code != 0

View File

@@ -57,11 +57,12 @@ class WpEnumerator
request_count += 1 request_count += 1
request.on_complete do |response| 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] 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 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] if options[:exclude_content_based]
unless response.body[exclude_regexp] unless response.body[exclude_regexp]
found << target found << target

View File

@@ -29,12 +29,15 @@ shared_examples_for "WpPlugins" do
before :each do before :each do
@module = WpScanModuleSpec.new(@wp_url) @module = WpScanModuleSpec.new(@wp_url)
@module.error_404_hash = Digest::MD5.hexdigest("Error 404!") @module.error_404_hash = Digest::MD5.hexdigest("Error 404!")
@module.homepage_hash = Digest::MD5.hexdigest("Homepage!")
@module.extend(WpPlugins) @module.extend(WpPlugins)
@options = {:base_url => @wp_url, @options = {
:base_url => @wp_url,
:only_vulnerable_ones => false, :only_vulnerable_ones => false,
:show_progress_bar => false, :show_progress_bar => false,
:error_404_hash => Digest::MD5.hexdigest("Error 404!"), :error_404_hash => @module.error_404_hash,
:homepage_hash => @module.homepage_hash,
:vulns_file => @plugin_vulns_file, :vulns_file => @plugin_vulns_file,
:file => @plugins_file, :file => @plugins_file,
:type => "plugins", :type => "plugins",
@@ -43,30 +46,53 @@ shared_examples_for "WpPlugins" do
} }
File.exist?(@plugin_vulns_file).should == true File.exist?(@plugin_vulns_file).should == true
File.exist?(@plugins_file).should == true File.exist?(@plugins_file).should == true
@targets = [WpPlugin.new({:base_url => "http://example.localhost/",
# 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", :path => "exclude-pages/exclude_pages.php",
:wp_content_dir => "wp-content", :wp_content_dir => "wp-content",
:name => "exclude-pages"}), :name => "exclude-pages"
WpPlugin.new({:base_url => "http://example.localhost/", }),
WpPlugin.new(
{
:base_url => "http://example.localhost/",
:path => "display-widgets/display-widgets.php", :path => "display-widgets/display-widgets.php",
:wp_content_dir => "wp-content", :wp_content_dir => "wp-content",
:name => "display-widgets"}), :name => "display-widgets"
WpPlugin.new({:base_url => "http://example.localhost/", }),
WpPlugin.new(
{
:base_url => "http://example.localhost/",
:path => "media-library", :path => "media-library",
:wp_content_dir => "wp-content", :wp_content_dir => "wp-content",
:name => "media-library"}), :name => "media-library"
WpPlugin.new({:base_url => "http://example.localhost/", }),
WpPlugin.new(
{
:base_url => "http://example.localhost/",
:path => "deans", :path => "deans",
:wp_content_dir => "wp-content", :wp_content_dir => "wp-content",
:name => "deans"}), :name => "deans"
WpPlugin.new({:base_url => "http://example.localhost/", }),
WpPlugin.new(
{
:base_url => "http://example.localhost/",
:path => "formidable/formidable.php", :path => "formidable/formidable.php",
:wp_content_dir => "wp-content", :wp_content_dir => "wp-content",
:name => "formidable"}), :name => "formidable"
WpPlugin.new({:base_url => "http://example.localhost/", }),
WpPlugin.new(
{
:base_url => "http://example.localhost/",
:path => "regenerate-thumbnails/readme.txt", :path => "regenerate-thumbnails/readme.txt",
:wp_content_dir => "wp-content", :wp_content_dir => "wp-content",
:name => "regenerate-thumbnails"})] :name => "regenerate-thumbnails"
})
]
end end
describe "#plugins_from_passive_detection" do describe "#plugins_from_passive_detection" do
@@ -92,9 +118,11 @@ shared_examples_for "WpPlugins" do
} }
expected_plugins = [] expected_plugins = []
expected_plugin_names.each do |plugin_name| expected_plugin_names.each do |plugin_name|
expected_plugins << WpPlugin.new(:base_url => @module.url, expected_plugins << WpPlugin.new(
:base_url => @module.url,
:path => "/plugins/#{plugin_name}/", :path => "/plugins/#{plugin_name}/",
:name => plugin_name) :name => plugin_name
)
end end
plugins = @module.plugins_from_passive_detection(:base_url => @module.url, :wp_content_dir => "wp-content") 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| @expected_plugins.each do |p|
stub_request(:get, p.get_full_url.to_s).to_return(:status => 200) stub_request(:get, p.get_full_url.to_s).to_return(:status => 200)
end end
new_plugin = WpPlugin.new(:base_url => "http://example.localhost/", new_plugin = WpPlugin.new(
:base_url => "http://example.localhost/",
:path => "/plugins/comment-info-tip/", :path => "/plugins/comment-info-tip/",
:name => "comment-info-tip") :name => "comment-info-tip"
)
stub_request(:get, new_plugin.readme_url.to_s).to_return(:status => 200) stub_request(:get, new_plugin.readme_url.to_s).to_return(:status => 200)
@expected_plugins << new_plugin @expected_plugins << new_plugin
end 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) stub_request(:get, plugin_url[0].get_full_url.to_s).to_return(:status => valid_response_code)
end end
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
end end

View File

@@ -30,7 +30,7 @@ SPEC_FIXTURES_WPSCAN_WP_VERSION_DIR = SPEC_FIXTURES_WPSCAN_DIR + '/wp_versio
class WpScanModuleSpec class WpScanModuleSpec
attr_reader :uri 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) def initialize(target_url)
@uri = URI.parse(add_http_protocol(target_url)) @uri = URI.parse(add_http_protocol(target_url))

View File

@@ -216,6 +216,7 @@ begin
:show_progress_bar => true, :show_progress_bar => true,
:wp_content_dir => wp_target.wp_content_dir, :wp_content_dir => wp_target.wp_content_dir,
:error_404_hash => wp_target.error_404_hash, :error_404_hash => wp_target.error_404_hash,
:homepage_hash => wp_target.homepage_hash,
:wp_plugins_dir => wp_target.wp_plugins_dir, :wp_plugins_dir => wp_target.wp_plugins_dir,
:full => wpscan_options.enumerate_all_plugins, :full => wpscan_options.enumerate_all_plugins,
:exclude_content_based => wpscan_options.exclude_content_based :exclude_content_based => wpscan_options.exclude_content_based
@@ -274,6 +275,7 @@ begin
:show_progress_bar => true, :show_progress_bar => true,
:wp_content_dir => wp_target.wp_content_dir, :wp_content_dir => wp_target.wp_content_dir,
:error_404_hash => wp_target.error_404_hash, :error_404_hash => wp_target.error_404_hash,
:homepage_hash => wp_target.homepage_hash,
:full => wpscan_options.enumerate_all_themes, :full => wpscan_options.enumerate_all_themes,
:exclude_content_based => wpscan_options.exclude_content_based :exclude_content_based => wpscan_options.exclude_content_based
} }
@@ -322,6 +324,7 @@ begin
:show_progress_bar => true, :show_progress_bar => true,
:wp_content_dir => wp_target.wp_content_dir, :wp_content_dir => wp_target.wp_content_dir,
:error_404_hash => wp_target.error_404_hash, :error_404_hash => wp_target.error_404_hash,
:homepage_hash => wp_target.homepage_hash,
:exclude_content_based => wpscan_options.exclude_content_based :exclude_content_based => wpscan_options.exclude_content_based
} }