Fixes #1365
This commit is contained in:
@@ -77,9 +77,22 @@ module WPScan
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [ Boolean ]
|
||||||
|
def xmlrpc_get_users_blogs_enabled?
|
||||||
|
if xmlrpc&.enabled? &&
|
||||||
|
xmlrpc.available_methods.include?('wp.getUsersBlogs') &&
|
||||||
|
xmlrpc.method_call('wp.getUsersBlogs', [SecureRandom.hex[0, 6], SecureRandom.hex[0, 4]])
|
||||||
|
.run.body !~ /XML\-RPC services are disabled/
|
||||||
|
|
||||||
|
true
|
||||||
|
else
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# @return [ CMSScanner::Finders::Finder ]
|
# @return [ CMSScanner::Finders::Finder ]
|
||||||
def attacker_from_automatic_detection
|
def attacker_from_automatic_detection
|
||||||
if xmlrpc&.enabled? && xmlrpc.available_methods.include?('wp.getUsersBlogs')
|
if xmlrpc_get_users_blogs_enabled?
|
||||||
wp_version = target.wp_version
|
wp_version = target.wp_version
|
||||||
|
|
||||||
if wp_version && wp_version < '4.4'
|
if wp_version && wp_version < '4.4'
|
||||||
|
|||||||
@@ -52,6 +52,60 @@ describe WPScan::Controller::PasswordAttack do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#xmlrpc_get_users_blogs_enabled?' do
|
||||||
|
before { expect(controller.target).to receive(:xmlrpc).and_return(xmlrpc) }
|
||||||
|
|
||||||
|
context 'when xmlrpc not found' do
|
||||||
|
let(:xmlrpc) { nil }
|
||||||
|
|
||||||
|
its(:xmlrpc_get_users_blogs_enabled?) { should be false }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when xmlrpc not enabled' do
|
||||||
|
let(:xmlrpc) { WPScan::Model::XMLRPC.new("#{target_url}xmlrpc.php") }
|
||||||
|
|
||||||
|
it 'returns false' do
|
||||||
|
expect(xmlrpc).to receive(:enabled?).and_return(false)
|
||||||
|
|
||||||
|
expect(controller.xmlrpc_get_users_blogs_enabled?).to be false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when xmlrpc enabled' do
|
||||||
|
let(:xmlrpc) { WPScan::Model::XMLRPC.new("#{target_url}xmlrpc.php") }
|
||||||
|
|
||||||
|
before { expect(xmlrpc).to receive(:enabled?).and_return(true) }
|
||||||
|
|
||||||
|
context 'when wp.getUsersBlogs methods not listed' do
|
||||||
|
it 'returns false' do
|
||||||
|
expect(xmlrpc).to receive(:available_methods).and_return(%w[m1 m2])
|
||||||
|
|
||||||
|
expect(controller.xmlrpc_get_users_blogs_enabled?).to be false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when wp.getUsersBlogs method listed' do
|
||||||
|
before { expect(xmlrpc).to receive(:available_methods).and_return(%w[wp.getUsersBlogs m2]) }
|
||||||
|
|
||||||
|
context 'when wp.getUsersBlogs method disabled' do
|
||||||
|
it 'returns false' do
|
||||||
|
stub_request(:post, xmlrpc.url).to_return(body: 'XML-RPC services are disabled on this site.')
|
||||||
|
|
||||||
|
expect(controller.xmlrpc_get_users_blogs_enabled?).to be false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when wp.getUsersBlogs method enabled' do
|
||||||
|
it 'returns true' do
|
||||||
|
stub_request(:post, xmlrpc.url).to_return(body: 'Incorrect username or password.')
|
||||||
|
|
||||||
|
expect(controller.xmlrpc_get_users_blogs_enabled?).to be true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#attacker' do
|
describe '#attacker' do
|
||||||
context 'when --password-attack provided' do
|
context 'when --password-attack provided' do
|
||||||
let(:cli_args) { "#{super()} --password-attack #{attack}" }
|
let(:cli_args) { "#{super()} --password-attack #{attack}" }
|
||||||
@@ -92,7 +146,7 @@ describe WPScan::Controller::PasswordAttack do
|
|||||||
before do
|
before do
|
||||||
expect(controller.target)
|
expect(controller.target)
|
||||||
.to receive(:xmlrpc)
|
.to receive(:xmlrpc)
|
||||||
.and_return(WPScan::Model::XMLRPC.new("#{target_url}/xmlrpc.php"))
|
.and_return(WPScan::Model::XMLRPC.new("#{target_url}xmlrpc.php"))
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when single xmlrpc' do
|
context 'when single xmlrpc' do
|
||||||
@@ -117,73 +171,50 @@ describe WPScan::Controller::PasswordAttack do
|
|||||||
end
|
end
|
||||||
|
|
||||||
context 'when automatic detection' do
|
context 'when automatic detection' do
|
||||||
before { expect(controller.target).to receive(:xmlrpc).and_return(xmlrpc) }
|
context 'when xmlrpc_get_users_blogs_enabled? is false' do
|
||||||
|
|
||||||
context 'when xmlrpc not found' do
|
|
||||||
let(:xmlrpc) { nil }
|
|
||||||
|
|
||||||
it 'returns the WpLogin' do
|
it 'returns the WpLogin' do
|
||||||
expect(controller.attacker).to be_a WPScan::Finders::Passwords::WpLogin
|
expect(controller).to receive(:xmlrpc_get_users_blogs_enabled?).and_return(false)
|
||||||
expect(controller.attacker.target).to be_a WPScan::Target
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when xmlrpc not enabled' do
|
|
||||||
let(:xmlrpc) { WPScan::Model::XMLRPC.new("#{target_url}/xmlrpc.php") }
|
|
||||||
|
|
||||||
it 'returns the WpLogin' do
|
|
||||||
expect(xmlrpc).to receive(:enabled?).and_return(false)
|
|
||||||
|
|
||||||
expect(controller.attacker).to be_a WPScan::Finders::Passwords::WpLogin
|
expect(controller.attacker).to be_a WPScan::Finders::Passwords::WpLogin
|
||||||
expect(controller.attacker.target).to be_a WPScan::Target
|
expect(controller.attacker.target).to be_a WPScan::Target
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when xmlrpc enabled' do
|
context 'when xmlrpc_get_users_blogs_enabled? is true' do
|
||||||
let(:xmlrpc) { WPScan::Model::XMLRPC.new("#{target_url}/xmlrpc.php") }
|
before do
|
||||||
|
expect(controller).to receive(:xmlrpc_get_users_blogs_enabled?).and_return(true)
|
||||||
|
|
||||||
before { expect(xmlrpc).to receive(:enabled?).and_return(true) }
|
expect(controller.target)
|
||||||
|
.to receive(:xmlrpc).and_return(WPScan::Model::XMLRPC.new("#{target_url}xmlrpc.php"))
|
||||||
|
end
|
||||||
|
|
||||||
context 'when wp.getUsersBlogs methods not available' do
|
context 'when WP version not found' do
|
||||||
it 'returns the WpLogin' do
|
it 'returns the XMLRPC' do
|
||||||
expect(xmlrpc).to receive(:available_methods).and_return(%w[m1 m2])
|
expect(controller.target).to receive(:wp_version).and_return(false)
|
||||||
|
|
||||||
expect(controller.attacker).to be_a WPScan::Finders::Passwords::WpLogin
|
expect(controller.attacker).to be_a WPScan::Finders::Passwords::XMLRPC
|
||||||
expect(controller.attacker.target).to be_a WPScan::Target
|
expect(controller.attacker.target).to be_a WPScan::Model::XMLRPC
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when wp.getUsersBlogs method evailable' do
|
context 'when WP version found' do
|
||||||
before { expect(xmlrpc).to receive(:available_methods).and_return(%w[wp.getUsersBlogs m2]) }
|
before { expect(controller.target).to receive(:wp_version).and_return(wp_version) }
|
||||||
|
|
||||||
context 'when WP version not found' do
|
context 'when WP < 4.4' do
|
||||||
it 'returns the XMLRPC' do
|
let(:wp_version) { WPScan::Model::WpVersion.new('3.8.1') }
|
||||||
expect(controller.target).to receive(:wp_version).and_return(false)
|
|
||||||
|
|
||||||
expect(controller.attacker).to be_a WPScan::Finders::Passwords::XMLRPC
|
it 'returns the XMLRPCMulticall' do
|
||||||
|
expect(controller.attacker).to be_a WPScan::Finders::Passwords::XMLRPCMulticall
|
||||||
expect(controller.attacker.target).to be_a WPScan::Model::XMLRPC
|
expect(controller.attacker.target).to be_a WPScan::Model::XMLRPC
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when WP version found' do
|
context 'when WP >= 4.4' do
|
||||||
before { expect(controller.target).to receive(:wp_version).and_return(wp_version) }
|
let(:wp_version) { WPScan::Model::WpVersion.new('4.4') }
|
||||||
|
|
||||||
context 'when WP < 4.4' do
|
it 'returns the XMLRPC' do
|
||||||
let(:wp_version) { WPScan::Model::WpVersion.new('3.8.1') }
|
expect(controller.attacker).to be_a WPScan::Finders::Passwords::XMLRPC
|
||||||
|
expect(controller.attacker.target).to be_a WPScan::Model::XMLRPC
|
||||||
it 'returns the XMLRPCMulticall' do
|
|
||||||
expect(controller.attacker).to be_a WPScan::Finders::Passwords::XMLRPCMulticall
|
|
||||||
expect(controller.attacker.target).to be_a WPScan::Model::XMLRPC
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when WP >= 4.4' do
|
|
||||||
let(:wp_version) { WPScan::Model::WpVersion.new('4.4') }
|
|
||||||
|
|
||||||
it 'returns the XMLRPC' do
|
|
||||||
expect(controller.attacker).to be_a WPScan::Finders::Passwords::XMLRPC
|
|
||||||
expect(controller.attacker.target).to be_a WPScan::Model::XMLRPC
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user