From 38c81384e8c7e88cb731354554f5155a2e9abdd6 Mon Sep 17 00:00:00 2001 From: erwanlr Date: Wed, 19 Dec 2012 17:49:56 +0100 Subject: [PATCH] WebSite module reworked --- lib/wpscan/modules/web_site.rb | 32 +++---- spec/lib/wpscan/modules/web_site_spec.rb | 103 +++++++++++------------ spec/lib/wpscan/wpscan_helper.rb | 18 ++-- wpscan.rb | 4 +- 4 files changed, 75 insertions(+), 82 deletions(-) diff --git a/lib/wpscan/modules/web_site.rb b/lib/wpscan/modules/web_site.rb index cd0cf41a..f906f216 100644 --- a/lib/wpscan/modules/web_site.rb +++ b/lib/wpscan/modules/web_site.rb @@ -18,9 +18,18 @@ module WebSite + # Checks if the remote website is up. + def online? + Browser.instance.get(@uri.to_s).code != 0 + end + + def has_basic_auth? + Browser.instance.get(@uri.to_s).code == 401 + end + # check if the remote website is # actually running wordpress. - def is_wordpress? + def wordpress? wordpress = false response = Browser.instance.get( @@ -32,8 +41,8 @@ module WebSite wordpress = true else response = Browser.instance.get( - xml_rpc_url, - {:follow_location => true, :max_redirects => 2} + xml_rpc_url, + {:follow_location => true, :max_redirects => 2} ) if response.body =~ %r{XML-RPC server accepts POST requests only}i @@ -44,6 +53,10 @@ module WebSite wordpress end + def has_xml_rpc? + !xml_rpc_url.nil? + end + def xml_rpc_url unless @xmlrpc_url headers = Browser.instance.get(@uri.to_s).headers_hash @@ -57,19 +70,6 @@ module WebSite @xmlrpc_url end - def has_xml_rpc? - !xml_rpc_url.nil? - end - - # Checks if the remote website is up. - def is_online? - Browser.instance.get(@uri.to_s).code != 0 - end - - def has_basic_auth? - Browser.instance.get(@uri.to_s).code == 401 - end - # see if the remote url returns 30x redirect # return a string with the redirection or nil def redirection(url = nil) diff --git a/spec/lib/wpscan/modules/web_site_spec.rb b/spec/lib/wpscan/modules/web_site_spec.rb index c270bda4..5aac90a2 100644 --- a/spec/lib/wpscan/modules/web_site_spec.rb +++ b/spec/lib/wpscan/modules/web_site_spec.rb @@ -18,111 +18,104 @@ shared_examples_for "WebSite" do let(:fixtures_dir) { SPEC_FIXTURES_WPSCAN_MODULES_DIR + "/web_site" } + subject(:web_site) { WpScanModuleSpec.new("http://example.localhost/").extend(WebSite) } - before :each do - @module = WpScanModuleSpec.new("http://example.localhost/") - @module.extend(WebSite) + describe "#online?" do + it "should not be considered online if the status code is 0" do + stub_request(:get, web_site.url).to_return(:status => 0) + web_site.should_not be_online + end + + it "should be considered online if the status code is != 0" do + stub_request(:get, web_site.url).to_return(:status => 200) + web_site.should be_online + end end - describe "#login_url" do - it "should return the correct url : http://example.localhost/wp-login.php" do - @module.login_url.should === "http://example.localhost/wp-login.php" + describe "#has_basic_auth?" do + it "should detect that the wpsite is basic auth protected" do + stub_request(:get, web_site.url).to_return(:status => 401) + web_site.should have_basic_auth + end + + it "should not have a basic auth for a 200" do + stub_request(:get, web_site.url).to_return(:status => 200) + web_site.should_not have_basic_auth end end describe "#xml_rpc_url" do it "should return the correct url : http://example.localhost/xmlrpc.php" do xmlrpc = "http://example.localhost/xmlrpc.php" - stub_request(:get, "http://example.localhost/"). - to_return(:status => 200, :body => "", :headers => { "X-Pingback" => xmlrpc}) - @module.xml_rpc_url.should === xmlrpc + stub_request(:get, web_site.url). + to_return(:status => 200, :body => "", :headers => { "X-Pingback" => xmlrpc}) + + web_site.xml_rpc_url.should === xmlrpc end it "should return nil" do - stub_request(:get, "http://example.localhost/").to_return(:status => 200) - @module.xml_rpc_url.should be_nil + stub_request(:get, web_site.url).to_return(:status => 200) + web_site.xml_rpc_url.should be_nil end end describe "#has_xml_rpc?" do it "should return true" do - stub_request(:get, "http://example.localhost/"). - to_return(:status => 200, :body => "", :headers => { "X-Pingback" => "xmlrpc"}) - @module.has_xml_rpc?.should be_true + stub_request(:get, web_site.url). + to_return(:status => 200, :body => "", :headers => { "X-Pingback" => "xmlrpc"}) + + web_site.should have_xml_rpc end it "should return false" do - stub_request(:get, "http://example.localhost/").to_return(:status => 200) - @module.has_xml_rpc?.should be_false + stub_request(:get, web_site.url).to_return(:status => 200) + web_site.should_not have_xml_rpc end end - describe "#is_wordpress?" do + describe "#wordpress?" do # each url (wp-login and xmlrpc) pointed to a 404 before :each do - stub_request(:get, @module.uri.to_s). - to_return(:status => 200, :body => "", :headers => { "X-Pingback" => @module.uri.merge("xmlrpc.php")}) - [@module.login_url, @module.xml_rpc_url].each do |url| + stub_request(:get, web_site.url). + to_return(:status => 200, :body => "", :headers => { "X-Pingback" => web_site.uri.merge("xmlrpc.php")}) + + [web_site.login_url, web_site.xml_rpc_url].each do |url| stub_request(:get, url).to_return(:status => 404, :body => "") end end it "should return false if both files are not found (404)" do - @module.is_wordpress?.should be_false + web_site.should_not be_wordpress end it "should return true if the wp-login is found and is a valid wordpress one" do - stub_request(:get, @module.login_url). - to_return(:status => 200, :body => File.new(fixtures_dir + "/wp-login.php")) + stub_request(:get, web_site.login_url). + to_return(:status => 200, :body => File.new(fixtures_dir + "/wp-login.php")) - @module.is_wordpress?.should be_true + web_site.should be_wordpress end it "should return true if the xmlrpc is found" do - stub_request(:get, @module.xml_rpc_url). + stub_request(:get, web_site.xml_rpc_url). to_return(:status => 200, :body => File.new(fixtures_dir + "/xmlrpc.php")) - @module.is_wordpress?.should be_true - end - end - - describe "#is_online?" do - it "should return false" do - stub_request(:get, @module.url).to_return(:status => 0) - @module.is_online?.should be_false - end - - it "should return true" do - stub_request(:get, @module.url).to_return(:status => 200) - @module.is_online?.should be_true - end - end - - describe "#has_basic_auth?" do - it "should detect that the wpsite is basic auth protected" do - stub_request(:get, "http://example.localhost/").to_return(:status => 401) - @module.should have_basic_auth - end - - it "should not have a basic auth for a 200" do - stub_request(:get, "http://example.localhost/").to_return(:status => 200) - @module.should_not have_basic_auth + web_site.should be_wordpress end end describe "#redirection" do it "should return nil if no redirection detected" do - stub_request(:get, @module.url).to_return(:status => 200, :body => '') + stub_request(:get, web_site.url).to_return(:status => 200, :body => "") - @module.redirection.should be_nil + web_site.redirection.should be_nil end [301, 302].each do |status_code| it "should return http://new-location.com if the status code is #{status_code}" do - stub_request(:get, @module.url). - to_return(:status => status_code, :headers => {:location => "http://new-location.com"}) + stub_request(:get, web_site.url). + to_return(:status => status_code, :headers => {:location => "http://new-location.com"}) - @module.redirection.should === "http://new-location.com" + web_site.redirection.should === "http://new-location.com" end end end diff --git a/spec/lib/wpscan/wpscan_helper.rb b/spec/lib/wpscan/wpscan_helper.rb index f40f67bf..db902dfe 100644 --- a/spec/lib/wpscan/wpscan_helper.rb +++ b/spec/lib/wpscan/wpscan_helper.rb @@ -20,23 +20,23 @@ require 'spec_helper' require WPSCAN_LIB_DIR + '/wpscan_helper' -SPEC_FIXTURES_WPSCAN_DIR = SPEC_FIXTURES_DIR + '/wpscan' -SPEC_FIXTURES_WPSCAN_MODULES_DIR = SPEC_FIXTURES_WPSCAN_DIR + '/modules' -SPEC_FIXTURES_WPSCAN_WP_TARGET_DIR = SPEC_FIXTURES_WPSCAN_DIR + '/wp_target' +SPEC_FIXTURES_WPSCAN_DIR = SPEC_FIXTURES_DIR + '/wpscan' +SPEC_FIXTURES_WPSCAN_MODULES_DIR = SPEC_FIXTURES_WPSCAN_DIR + '/modules' +SPEC_FIXTURES_WPSCAN_WP_TARGET_DIR = SPEC_FIXTURES_WPSCAN_DIR + '/wp_target' SPEC_FIXTURES_WPSCAN_WPSCAN_OPTIONS_DIR = SPEC_FIXTURES_WPSCAN_DIR + '/wpscan_options' -SPEC_FIXTURES_WPSCAN_WP_THEME_DIR = SPEC_FIXTURES_WPSCAN_DIR + '/wp_theme' -SPEC_FIXTURES_WPSCAN_WP_PLUGIN_DIR = SPEC_FIXTURES_WPSCAN_DIR + '/wp_plugin' -SPEC_FIXTURES_WPSCAN_WP_VERSION_DIR = SPEC_FIXTURES_WPSCAN_DIR + '/wp_version' +SPEC_FIXTURES_WPSCAN_WP_THEME_DIR = SPEC_FIXTURES_WPSCAN_DIR + '/wp_theme' +SPEC_FIXTURES_WPSCAN_WP_PLUGIN_DIR = SPEC_FIXTURES_WPSCAN_DIR + '/wp_plugin' +SPEC_FIXTURES_WPSCAN_WP_VERSION_DIR = SPEC_FIXTURES_WPSCAN_DIR + '/wp_version' class WpScanModuleSpec - attr_reader :uri + attr_reader :uri attr_accessor :error_404_hash, :wp_content_dir, :verbose def initialize(target_url) @uri = URI.parse(add_http_protocol(target_url)) Browser.instance( - :config_file => SPEC_FIXTURES_CONF_DIR + '/browser/browser.conf.json', - :cache_timeout => 0 + :config_file => SPEC_FIXTURES_CONF_DIR + '/browser/browser.conf.json', + :cache_timeout => 0 ) end diff --git a/wpscan.rb b/wpscan.rb index f54119e4..ddb2d705 100755 --- a/wpscan.rb +++ b/wpscan.rb @@ -50,7 +50,7 @@ begin wp_target = WpTarget.new(wpscan_options.url, wpscan_options.to_h) # Remote website up? - unless wp_target.is_online? + unless wp_target.online? raise "The WordPress URL supplied '#{wp_target.uri}' seems to be down." end @@ -79,7 +79,7 @@ begin # Remote website is wordpress? unless wpscan_options.force - unless wp_target.is_wordpress? + unless wp_target.wordpress? raise "The remote website is up, but does not seem to be running WordPress." end end