Checks default wp-content dir regardless of detection mode if not found passively
This commit is contained in:
@@ -18,7 +18,7 @@ module WPScan
|
||||
target.content_dir = ParsedCli.wp_content_dir if ParsedCli.wp_content_dir
|
||||
target.plugins_dir = ParsedCli.wp_plugins_dir if ParsedCli.wp_plugins_dir
|
||||
|
||||
return if target.content_dir(ParsedCli.detection_mode)
|
||||
return if target.content_dir
|
||||
|
||||
raise Error::WpContentDirNotDetected
|
||||
end
|
||||
|
||||
@@ -90,7 +90,7 @@ module WPScan
|
||||
def wordpress_hosted?
|
||||
return true if /\.wordpress\.com$/i.match?(uri.host)
|
||||
|
||||
unless content_dir(:passive)
|
||||
unless content_dir
|
||||
pattern = %r{https?://s\d\.wp\.com#{WORDPRESS_PATTERN}}i.freeze
|
||||
|
||||
uris_from_page(homepage_res) do |uri|
|
||||
|
||||
@@ -13,9 +13,8 @@ module WPScan
|
||||
@plugins_dir = dir.chomp('/')
|
||||
end
|
||||
|
||||
# @param [ Symbol ] detection_mode
|
||||
# @return [ String ] The wp-content directory
|
||||
def content_dir(detection_mode = :mixed)
|
||||
def content_dir
|
||||
unless @content_dir
|
||||
# scope_url_pattern is from CMSScanner::Target
|
||||
pattern = %r{#{scope_url_pattern}([\w\s\-/]+)\\?/(?:themes|plugins|uploads|cache)\\?/}i
|
||||
@@ -29,9 +28,7 @@ module WPScan
|
||||
return @content_dir = match[1]
|
||||
end
|
||||
|
||||
unless detection_mode == :passive
|
||||
return @content_dir = 'wp-content' if default_content_dir_exists?
|
||||
end
|
||||
return @content_dir = 'wp-content' if default_content_dir_exists?
|
||||
end
|
||||
|
||||
@content_dir
|
||||
|
||||
@@ -166,6 +166,8 @@ describe WPScan::Controller::Core do
|
||||
before do
|
||||
expect(core).to receive(:load_server_module)
|
||||
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(true)
|
||||
expect(core.target).to receive(:wordpress_hosted?).and_return(false)
|
||||
# expect(core.target).to receive(:content_dir).and_return('wp-content')
|
||||
end
|
||||
|
||||
it 'calls the formatter when started and finished to update the db' do
|
||||
@@ -174,56 +176,6 @@ describe WPScan::Controller::Core do
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a redirect occurs' do
|
||||
before do
|
||||
stub_request(:any, target_url)
|
||||
|
||||
expect(core.target).to receive(:homepage_res)
|
||||
.at_least(1)
|
||||
.and_return(Typhoeus::Response.new(effective_url: redirection, body: ''))
|
||||
end
|
||||
|
||||
context 'to the wp-admin/install.php' do
|
||||
let(:redirection) { "#{target_url}wp-admin/install.php" }
|
||||
|
||||
it 'calls the formatter with the correct parameters and exit' do
|
||||
expect(core.formatter).to receive(:output)
|
||||
.with('not_fully_configured', hash_including(url: redirection), 'core').ordered
|
||||
|
||||
# TODO: Would be cool to be able to test the exit code
|
||||
expect { core.before_scan }.to raise_error(SystemExit)
|
||||
end
|
||||
end
|
||||
|
||||
context 'to something else' do
|
||||
let(:redirection) { 'http://g.com/' }
|
||||
|
||||
it 'raises an error' do
|
||||
expect { core.before_scan }.to raise_error(CMSScanner::Error::HTTPRedirect)
|
||||
end
|
||||
end
|
||||
|
||||
context 'to another path with the wp-admin/install.php in the query' do
|
||||
let(:redirection) { "#{target_url}index.php?a=/wp-admin/install.php" }
|
||||
|
||||
context 'when wordpress' do
|
||||
it 'does not raise an error' do
|
||||
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(true)
|
||||
|
||||
expect { core.before_scan }.to_not raise_error
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not wordpress' 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
|
||||
end
|
||||
end
|
||||
|
||||
context 'when hosted on wordpress.com' do
|
||||
let(:target_url) { 'http://ex.wordpress.com' }
|
||||
|
||||
@@ -234,52 +186,106 @@ describe WPScan::Controller::Core do
|
||||
end
|
||||
end
|
||||
|
||||
context 'when wordpress' do
|
||||
before do
|
||||
expect(core).to receive(:load_server_module)
|
||||
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(true)
|
||||
end
|
||||
context 'when not hosted on wordpress.com' do
|
||||
before { allow(core.target).to receive(:wordpress_hosted?).and_return(false) }
|
||||
|
||||
it 'does not raise any error' do
|
||||
expect { core.before_scan }.to_not raise_error
|
||||
end
|
||||
end
|
||||
context 'when a redirect occurs' do
|
||||
before do
|
||||
stub_request(:any, target_url)
|
||||
|
||||
context 'when not wordpress' do
|
||||
before do
|
||||
expect(core).to receive(:load_server_module)
|
||||
end
|
||||
expect(core.target).to receive(:homepage_res)
|
||||
.at_least(1)
|
||||
.and_return(Typhoeus::Response.new(effective_url: redirection, body: ''))
|
||||
end
|
||||
|
||||
context 'when no --force' do
|
||||
before { expect(core.target).to receive(:maybe_add_cookies) }
|
||||
context 'to the wp-admin/install.php' do
|
||||
let(:redirection) { "#{target_url}wp-admin/install.php" }
|
||||
|
||||
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)
|
||||
it 'calls the formatter with the correct parameters and exit' do
|
||||
expect(core.formatter).to receive(:output)
|
||||
.with('not_fully_configured', hash_including(url: redirection), 'core').ordered
|
||||
|
||||
expect { core.before_scan }.to raise_error(WPScan::Error::NotWordPress)
|
||||
# TODO: Would be cool to be able to test the exit code
|
||||
expect { core.before_scan }.to raise_error(SystemExit)
|
||||
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
|
||||
context 'to something else' do
|
||||
let(:redirection) { 'http://g.com/' }
|
||||
|
||||
it 'raises an error' do
|
||||
expect { core.before_scan }.to raise_error(CMSScanner::Error::HTTPRedirect)
|
||||
end
|
||||
end
|
||||
|
||||
context 'to another path with the wp-admin/install.php in the query' do
|
||||
let(:redirection) { "#{target_url}index.php?a=/wp-admin/install.php" }
|
||||
|
||||
context 'when wordpress' do
|
||||
it 'does not raise an error' do
|
||||
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(true)
|
||||
|
||||
expect { core.before_scan }.to_not raise_error
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not wordpress' 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
|
||||
end
|
||||
end
|
||||
|
||||
context 'when wordpress' do
|
||||
before do
|
||||
expect(core).to receive(:load_server_module)
|
||||
expect(core.target).to receive(:wordpress?).with(:mixed).and_return(true)
|
||||
end
|
||||
|
||||
it 'does not raise any error' do
|
||||
expect { core.before_scan }.to_not raise_error
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not wordpress' do
|
||||
before do
|
||||
expect(core).to receive(:load_server_module)
|
||||
end
|
||||
|
||||
context 'when no --force' do
|
||||
before { expect(core.target).to receive(:maybe_add_cookies) }
|
||||
|
||||
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
|
||||
|
||||
context 'when --force' do
|
||||
let(:cli_args) { "#{super()} --force" }
|
||||
|
||||
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
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when --force' do
|
||||
let(:cli_args) { "#{super()} --force" }
|
||||
|
||||
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
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -20,7 +20,7 @@ describe WPScan::Controller::CustomDirectories do
|
||||
|
||||
describe '#before_scan' do
|
||||
context 'when the content_dir is not found and not supplied' do
|
||||
before { expect(controller.target).to receive(:content_dir).with(:mixed) }
|
||||
before { expect(controller.target).to receive(:content_dir).and_return(nil) }
|
||||
|
||||
it 'raises an exception' do
|
||||
expect { controller.before_scan }.to raise_error(WPScan::Error::WpContentDirNotDetected)
|
||||
|
||||
@@ -152,7 +152,7 @@ shared_examples WPScan::Target::Platform::WordPress do
|
||||
|
||||
context 'when wp-content not detected' do
|
||||
before do
|
||||
expect(target).to receive(:content_dir).with(:passive).and_return(nil)
|
||||
expect(target).to receive(:content_dir).and_return(nil)
|
||||
stub_request(:get, target.url).to_return(body: File.read(fixtures.join(fixture).to_s))
|
||||
end
|
||||
|
||||
@@ -170,7 +170,7 @@ shared_examples WPScan::Target::Platform::WordPress do
|
||||
end
|
||||
|
||||
context 'when wp-content detected' do
|
||||
before { expect(target).to receive(:content_dir).with(:passive).and_return('wp-content') }
|
||||
before { expect(target).to receive(:content_dir).and_return('wp-content') }
|
||||
|
||||
its(:wordpress_hosted?) { should be false }
|
||||
end
|
||||
|
||||
@@ -42,35 +42,25 @@ shared_examples 'WordPress::CustomDirectories' do
|
||||
end
|
||||
|
||||
context 'when not found via the homepage' do
|
||||
before { stub_request(:get, target.url).to_return(body: '') }
|
||||
before do
|
||||
stub_request(:get, target.url).to_return(body: '')
|
||||
|
||||
expect(target).to receive(:default_content_dir_exists?).and_return(dir_exist)
|
||||
end
|
||||
|
||||
context 'when default dir does not exist' do
|
||||
let(:dir_exist) { false }
|
||||
|
||||
context 'when detection mode is passive' do
|
||||
it 'returns nil' do
|
||||
expect(target).not_to receive(:default_content_dir_exist?)
|
||||
|
||||
expect(target.content_dir(:passive)).to eql nil
|
||||
expect(target.content_dir).to eql nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when detection mode is mixed or aggressive' do
|
||||
before { expect(target).to receive(:default_content_dir_exists?).and_return(dir_exist) }
|
||||
context 'when default dir exists' do
|
||||
let(:dir_exist) { true }
|
||||
|
||||
%i[mixed aggressive].each do |mode|
|
||||
context 'when default content dir exists' do
|
||||
let(:dir_exist) { true }
|
||||
|
||||
it 'returns wp-content' do
|
||||
expect(target.content_dir(mode)).to eql 'wp-content'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when default content dir does not exist' do
|
||||
let(:dir_exist) { false }
|
||||
|
||||
it 'returns nil' do
|
||||
expect(target.content_dir(mode)).to eql nil
|
||||
end
|
||||
end
|
||||
it 'returns wp-content' do
|
||||
expect(target.content_dir).to eql 'wp-content'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user