Adds a #maybe_add_cookies to handle website requiring a specific cookie
This commit is contained in:
@@ -52,13 +52,16 @@ module WPScan
|
|||||||
def before_scan
|
def before_scan
|
||||||
@last_update = local_db.last_update
|
@last_update = local_db.last_update
|
||||||
|
|
||||||
maybe_output_banner_help_and_version # From CMS Scanner
|
maybe_output_banner_help_and_version # From CMSScanner
|
||||||
|
|
||||||
update_db if update_db_required?
|
update_db if update_db_required?
|
||||||
setup_cache
|
setup_cache
|
||||||
check_target_availability
|
check_target_availability
|
||||||
load_server_module
|
load_server_module
|
||||||
check_wordpress_state
|
check_wordpress_state
|
||||||
|
rescue Error::NotWordPress => e
|
||||||
|
target.maybe_add_cookies
|
||||||
|
raise e unless target.wordpress?(parsed_options[:detection_mode])
|
||||||
end
|
end
|
||||||
|
|
||||||
# Raises errors if the target is hosted on wordpress.com or is not running WordPress
|
# Raises errors if the target is hosted on wordpress.com or is not running WordPress
|
||||||
|
|||||||
@@ -45,6 +45,34 @@ module WPScan
|
|||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
COOKIE_PATTERNS = {
|
||||||
|
'vjs' => /createCookie\('vjs','(?<c_value>\d+)',\d+\);/i
|
||||||
|
}.freeze
|
||||||
|
|
||||||
|
# Sometimes there is a mechanism in place on the blog, which requires a specific
|
||||||
|
# cookie and value to be added to requests. Lets try to detect and add them
|
||||||
|
def maybe_add_cookies
|
||||||
|
COOKIE_PATTERNS.each do |cookie_key, pattern|
|
||||||
|
next unless homepage_res.body =~ pattern
|
||||||
|
|
||||||
|
browser = Browser.instance
|
||||||
|
|
||||||
|
cookie_string = "#{cookie_key}=#{Regexp.last_match[:c_value]}"
|
||||||
|
|
||||||
|
cookie_string += "; #{browser.cookie_string}" if browser.cookie_string
|
||||||
|
|
||||||
|
browser.cookie_string = cookie_string
|
||||||
|
|
||||||
|
# Force recheck of the homepage when retying wordpress?
|
||||||
|
# No need to clear the cache, as the request (which will contain the cookies)
|
||||||
|
# will be different
|
||||||
|
@homepage_res = nil
|
||||||
|
@homepage_url = nil
|
||||||
|
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# @return [ String ]
|
# @return [ String ]
|
||||||
def registration_url
|
def registration_url
|
||||||
multisite? ? url('wp-signup.php') : url('wp-login.php?action=register')
|
multisite? ? url('wp-signup.php') : url('wp-login.php?action=register')
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ describe WPScan::Controller::Core do
|
|||||||
|
|
||||||
context 'when not wordpress' do
|
context 'when not wordpress' do
|
||||||
it 'raises an error' do
|
it 'raises an error' do
|
||||||
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(false)
|
expect(core.target).to receive(:wordpress?).twice.with(:mixed).and_return(false)
|
||||||
|
|
||||||
expect { core.before_scan }.to raise_error(WPScan::Error::NotWordPress)
|
expect { core.before_scan }.to raise_error(WPScan::Error::NotWordPress)
|
||||||
end
|
end
|
||||||
@@ -250,12 +250,26 @@ describe WPScan::Controller::Core do
|
|||||||
context 'when not wordpress' do
|
context 'when not wordpress' do
|
||||||
before do
|
before do
|
||||||
expect(core).to receive(:load_server_module)
|
expect(core).to receive(:load_server_module)
|
||||||
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(false)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when no --force' do
|
context 'when no --force' do
|
||||||
it 'raises an error' do
|
before { expect(core.target).to receive(:maybe_add_cookies) }
|
||||||
expect { core.before_scan }.to raise_error(WPScan::Error::NotWordPress)
|
|
||||||
|
context 'when no cookies added or still not wordpress after being added' do
|
||||||
|
it 'raises an error' do
|
||||||
|
expect(core.target).to receive(:wordpress?).twice.with(:mixed).and_return(false)
|
||||||
|
|
||||||
|
expect { core.before_scan }.to raise_error(WPScan::Error::NotWordPress)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the added cookies solved it' do
|
||||||
|
it 'does not raise an error' do
|
||||||
|
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(false).ordered
|
||||||
|
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(true).ordered
|
||||||
|
|
||||||
|
expect { core.before_scan }.to_not raise_error
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -263,6 +277,8 @@ describe WPScan::Controller::Core do
|
|||||||
let(:cli_args) { "#{super()} --force" }
|
let(:cli_args) { "#{super()} --force" }
|
||||||
|
|
||||||
it 'does not raise any error' do
|
it 'does not raise any error' do
|
||||||
|
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(false)
|
||||||
|
|
||||||
expect { core.before_scan }.to_not raise_error
|
expect { core.before_scan }.to_not raise_error
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
24
spec/fixtures/target/platform/wordpress/maybe_add_cookies/vjs.html
vendored
Normal file
24
spec/fixtures/target/platform/wordpress/maybe_add_cookies/vjs.html
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||||
|
<meta name="robots" content="noindex">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
function createCookie(name,value,days) {
|
||||||
|
if (days) {
|
||||||
|
var date = new Date();
|
||||||
|
date.setTime(date.getTime()+(days*24*60*60*1000));
|
||||||
|
var expires = "; expires="+date.toGMTString();
|
||||||
|
}
|
||||||
|
else var expires = "";
|
||||||
|
document.cookie = name+"="+value+expires+"; path=/";
|
||||||
|
}
|
||||||
|
|
||||||
|
createCookie('vjs','2420671338',60);
|
||||||
|
</script><form id="repost" method="post" action=""></form>
|
||||||
|
<script>
|
||||||
|
if((document.cookie.indexOf('vjs=') !== -1))
|
||||||
|
location.reload();
|
||||||
|
</script>
|
||||||
|
<h1>Access to this website is possible only using browser with JavaScript and Cookies enabled.</h1>
|
||||||
@@ -68,6 +68,76 @@ shared_examples WPScan::Target::Platform::WordPress do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#maybe_add_cookies' do
|
||||||
|
let(:fixtures) { super().join('maybe_add_cookies') }
|
||||||
|
let(:browser) { WPScan::Browser.instance }
|
||||||
|
|
||||||
|
context 'when nothing matches' do
|
||||||
|
it 'does nothing' do
|
||||||
|
stub_request(:get, target.url).to_return(body: 'nothing there')
|
||||||
|
|
||||||
|
subject.maybe_add_cookies
|
||||||
|
|
||||||
|
expect(browser.cookie_string).to eql nil
|
||||||
|
expect(subject.homepage_res.body).to eql 'nothing there'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when matches' do
|
||||||
|
before do
|
||||||
|
stub_request(:get, target.url)
|
||||||
|
.to_return(
|
||||||
|
{ body: File.read(fixtures.join("#{cookie}.html")) },
|
||||||
|
body: 'Cookies Accepted!' # if we put {} there, ruobop not happy!
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
{
|
||||||
|
'vjs' => 'vjs=2420671338'
|
||||||
|
}.each do |key, expected_cookie_string|
|
||||||
|
context "when #{key} match" do
|
||||||
|
let(:cookie) { key }
|
||||||
|
|
||||||
|
context 'when the browser does not have a cookie_string already' do
|
||||||
|
before do
|
||||||
|
subject.maybe_add_cookies
|
||||||
|
|
||||||
|
# This one does not work, opened an issue
|
||||||
|
# https://github.com/bblimke/webmock/issues/813
|
||||||
|
# stub_request(:get, target.url)
|
||||||
|
# .with(headers: { 'Cookie' => expected_cookie_string })
|
||||||
|
# .to_return(body: 'Cookies Accepted!')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets the correct cookies, reset the homepage_res' do
|
||||||
|
expect(browser.cookie_string).to eql expected_cookie_string
|
||||||
|
expect(subject.homepage_res.body).to eql 'Cookies Accepted!'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the browser has cookie_string already' do
|
||||||
|
before do
|
||||||
|
browser.cookie_string = 'key=no-override'
|
||||||
|
|
||||||
|
subject.maybe_add_cookies
|
||||||
|
|
||||||
|
# This one does not work, opened an issue
|
||||||
|
# https://github.com/bblimke/webmock/issues/813
|
||||||
|
# stub_request(:get, target.url)
|
||||||
|
# .with(headers: { 'Cookie' => "#{expected_cookie_string}; key=no-override" })
|
||||||
|
# .to_return(body: 'Cookies Accepted!')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets the correct cookies, reset the homepage_res' do
|
||||||
|
expect(browser.cookie_string).to eql "#{expected_cookie_string}; key=no-override"
|
||||||
|
expect(subject.homepage_res.body).to eql 'Cookies Accepted!'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#wordpress_hosted?' do
|
describe '#wordpress_hosted?' do
|
||||||
its(:wordpress_hosted?) { should be false }
|
its(:wordpress_hosted?) { should be false }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user