Fix #54 False positive when a plugin directory redirects to the homepage
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -29,44 +29,70 @@ 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 = {
|
||||||
:only_vulnerable_ones => false,
|
:base_url => @wp_url,
|
||||||
:show_progress_bar => false,
|
:only_vulnerable_ones => false,
|
||||||
:error_404_hash => Digest::MD5.hexdigest("Error 404!"),
|
:show_progress_bar => false,
|
||||||
:vulns_file => @plugin_vulns_file,
|
:error_404_hash => @module.error_404_hash,
|
||||||
:file => @plugins_file,
|
:homepage_hash => @module.homepage_hash,
|
||||||
:type => "plugins",
|
:vulns_file => @plugin_vulns_file,
|
||||||
:wp_content_dir => "wp-content",
|
:file => @plugins_file,
|
||||||
:vulns_xpath_2 => "//plugin"
|
:type => "plugins",
|
||||||
|
:wp_content_dir => "wp-content",
|
||||||
|
:vulns_xpath_2 => "//plugin"
|
||||||
}
|
}
|
||||||
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/",
|
|
||||||
:path => "exclude-pages/exclude_pages.php",
|
# These targets are listed in @fixtures_dir + "/plugins.txt"
|
||||||
:wp_content_dir => "wp-content",
|
# TODO : load them directly from the fixture file
|
||||||
:name => "exclude-pages"}),
|
@targets = [
|
||||||
WpPlugin.new({:base_url => "http://example.localhost/",
|
WpPlugin.new(
|
||||||
:path => "display-widgets/display-widgets.php",
|
{
|
||||||
:wp_content_dir => "wp-content",
|
:base_url => "http://example.localhost/",
|
||||||
:name => "display-widgets"}),
|
:path => "exclude-pages/exclude_pages.php",
|
||||||
WpPlugin.new({:base_url => "http://example.localhost/",
|
:wp_content_dir => "wp-content",
|
||||||
:path => "media-library",
|
:name => "exclude-pages"
|
||||||
:wp_content_dir => "wp-content",
|
}),
|
||||||
:name => "media-library"}),
|
WpPlugin.new(
|
||||||
WpPlugin.new({:base_url => "http://example.localhost/",
|
{
|
||||||
:path => "deans",
|
:base_url => "http://example.localhost/",
|
||||||
:wp_content_dir => "wp-content",
|
:path => "display-widgets/display-widgets.php",
|
||||||
:name => "deans"}),
|
:wp_content_dir => "wp-content",
|
||||||
WpPlugin.new({:base_url => "http://example.localhost/",
|
:name => "display-widgets"
|
||||||
:path => "formidable/formidable.php",
|
}),
|
||||||
:wp_content_dir => "wp-content",
|
WpPlugin.new(
|
||||||
:name => "formidable"}),
|
{
|
||||||
WpPlugin.new({:base_url => "http://example.localhost/",
|
:base_url => "http://example.localhost/",
|
||||||
:path => "regenerate-thumbnails/readme.txt",
|
:path => "media-library",
|
||||||
:wp_content_dir => "wp-content",
|
:wp_content_dir => "wp-content",
|
||||||
:name => "regenerate-thumbnails"})]
|
: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
|
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(
|
||||||
:path => "/plugins/#{plugin_name}/",
|
:base_url => @module.url,
|
||||||
:name => plugin_name)
|
:path => "/plugins/#{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(
|
||||||
:path => "/plugins/comment-info-tip/",
|
:base_url => "http://example.localhost/",
|
||||||
:name => "comment-info-tip")
|
:path => "/plugins/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
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user