HELLO v3!!!

This commit is contained in:
Ryan Dewhurst
2018-09-26 21:12:01 +02:00
parent 28b9c15256
commit d268a86795
1871 changed files with 988118 additions and 0 deletions

31
spec/lib/browser_spec.rb Normal file
View File

@@ -0,0 +1,31 @@
require 'spec_helper'
describe WPScan::Browser do
subject(:browser) { described_class.instance(options) }
before { described_class.reset }
let(:options) { {} }
describe '#user_agents_list' do
context 'when not set' do
its(:user_agents_list) { should eql File.join(WPScan::DB_DIR, 'user-agents.txt') }
end
context 'when set' do
let(:options) { super().merge(user_agents_list: 'test.txt') }
its(:user_agents_list) { should eql 'test.txt' }
end
end
describe '#user_agent' do
context 'when not set' do
its(:user_agent) { should eq "WPScan v#{WPScan::VERSION} (https://wpscan.org/)" }
end
context 'when set' do
let(:options) { super().merge(user_agent: 'Custom UA') }
its(:user_agent) { should eq options[:user_agent] }
end
end
end

View File

@@ -0,0 +1,7 @@
require 'spec_helper'
describe WPScan::DB::DynamicFinders::Base do
subject(:dynamic_finders) { described_class }
# Handled in spec/lib/db/dynamic_finders/plugin and wordpress
end

View File

@@ -0,0 +1,72 @@
require 'spec_helper'
describe WPScan::DB::DynamicFinders::Plugin do
subject(:dynamic_finders) { described_class }
describe '.finders_configs' do
context 'when the given class is not allowed' do
it 'returns an empty hash' do
expect(subject.finder_configs('aaaa')).to eql({})
end
end
context 'when the given class is allowed' do
context 'when aggressive argument is false' do
it 'returns only the configs w/o a path parameter' do
configs = subject.finder_configs(:Xpath)
expect(configs.keys).to include('wordpress-mobile-pack', 'shareaholic')
expect(configs.keys).to_not include('simple-share-button-adder')
expect(configs['sitepress-multilingual-cms']['MetaGenerator']['pattern']).to be_a Regexp
expect(configs['sitepress-multilingual-cms']['MetaGenerator']['version']).to eql true
end
end
context 'when aggressive argument is true' do
it 'returns only the configs with a path parameter' do
configs = subject.finder_configs(:Xpath, true)
expect(configs.keys).to include('revslider')
expect(configs.keys).to_not include('shareaholic')
end
end
end
end
describe '.versions_finders_configs' do
# Just test a sample here
its('versions_finders_configs.keys') { should include('shareaholic') }
its('versions_finders_configs.keys') { should_not include('wordpress-mobile-pack') }
end
describe '.maybe_create_module' do
xit
end
describe '.create_versions_finders' do
# handled and tested in spec/lib/finders/dynamic_finders/plugin_version_spec
end
describe '.version_finder_super_class' do
# handled and tested in spec/lib/finders/dynamic_finders/plugin_version_spec
end
describe '.method_missing' do
context 'when the method matches a valid call' do
its('passive_comment_finder_configs.keys') { should include('addthis') }
its('passive_comment_finder_configs.keys') { should_not include('shareaholic') }
its('passive_xpath_finder_configs.keys') { should include('shareaholic') }
its('passive_xpath_finder_configs.keys') { should_not include('simple-share-button-adder') }
its('aggressive_xpath_finder_configs.keys') { should_not include('wordpress-mobile-pack') }
its('aggressive_xpath_finder_configs.keys') { should include('revslider') }
end
context 'when the method does not match a valid call' do
it 'raises an error' do
expect { subject.aaa }.to raise_error(NoMethodError)
end
end
end
end

View File

@@ -0,0 +1,7 @@
require 'spec_helper'
describe WPScan::DB::DynamicFinders::Theme do
subject(:dynamic_finders) { described_class }
xit
end

View File

@@ -0,0 +1,7 @@
require 'spec_helper'
describe WPScan::DB::DynamicFinders::Wordpress do
subject(:dynamic_finders) { described_class }
xit
end

View File

@@ -0,0 +1,27 @@
require 'spec_helper'
describe WPScan::DB::Fingerprints do
describe '#unique_fingerprints' do
# Handled in #wp_unique_fingerprints
end
describe '.wp_fingerprints' do
it 'returns the expected value' do
expect(described_class.wp_fingerprints).to eql(
'path-1' => {
'hash-1' => %w[4.0 3.8],
'hash-2' => ['4.4']
},
'path-2' => {
'hash-3' => %w[3.8.1 3.8.2 3.9.1]
}
)
end
end
describe '.wp_unique_fingerprints' do
it 'returns the expected value' do
expect(described_class.wp_unique_fingerprints).to eql('path-1' => { 'hash-2' => '4.4' })
end
end
end

View File

@@ -0,0 +1,7 @@
require 'spec_helper'
describe WPScan::DB::Plugin do
describe '#vulnerabilities' do
# Handled in spec/app/models/plugin_spec
end
end

View File

@@ -0,0 +1,17 @@
require 'spec_helper'
describe WPScan::DB::Plugins do
subject(:plugins) { described_class }
describe '#all_slugs' do
its(:all_slugs) { should eql %w[no-vulns-popular vulnerable-not-popular] }
end
describe '#popular_slugs' do
its(:popular_slugs) { should eql %w[no-vulns-popular] }
end
describe '#vulnerable_slugs' do
its(:vulnerable_slugs) { should eql %w[vulnerable-not-popular] }
end
end

View File

@@ -0,0 +1,7 @@
require 'spec_helper'
describe WPScan::DB::Theme do
describe '#vulnerabilities' do
# Handled in spec/app/models/theme_spec
end
end

View File

@@ -0,0 +1,17 @@
require 'spec_helper'
describe WPScan::DB::Themes do
subject(:themes) { described_class }
describe '#all_slugs' do
its(:all_slugs) { should eql %w[no-vulns-popular dignitas-themes yaaburnee-themes] }
end
describe '#popular_slugs' do
its(:popular_slugs) { should eql %w[no-vulns-popular dignitas-themes] }
end
describe '#vulnerable_slugs' do
its(:vulnerable_slugs) { should eql %w[dignitas-themes yaaburnee-themes] }
end
end

View File

@@ -0,0 +1,7 @@
require 'spec_helper'
describe WPScan::DB::WpItem do
describe '#vulnerabilities' do
# Handled in spec/app/models/plugin_spec
end
end

View File

@@ -0,0 +1,5 @@
require 'spec_helper'
describe WPScan::DB::WpItems do
# Handled in plugins_spec & themes_spec
end

View File

@@ -0,0 +1,7 @@
require 'spec_helper'
describe WPScan::DB::Version do
describe '#vulnerabilities' do
# Handled in spec/app/models/wp_version_spec
end
end

View File

@@ -0,0 +1,145 @@
require 'spec_helper'
# All Plugin Dynamic Finders returning a Version are tested here.
# When adding one to the spec/fixtures/db/dynamic_finder.yml, a few files have
# to be edited/created
#
# - spec/fixtures/dynamic_finder/plugin_version/expected.yml with the expected result/s
# - Then, depending on the finder class used: spec/fixtures/dynamic_finder/plugin_version/
#
# Furthermore, the fixtures files _passive_all.html are also used by plugins/themes
# finders in spec/app/finders/plugins|themes to check the items existence from the homepage
#
# In case of a failure, it's recommended to use rspec -e "<Full Description>" while fixing.
# e.g: rspec -e "WPScan::Finders::PluginVersion::Cardealerpress::HeaderPattern#passive"
# The -e option can also be used to test all HeaderPattern, for example: rspec -e "::HeaderPattern"
expected_all = df_expected_all['plugins']
WPScan::DB::DynamicFinders::Plugin.create_versions_finders
describe 'Try to create the finders twice' do
it 'does not raise an error when the class already exists' do
expect { WPScan::DB::DynamicFinders::Plugin.create_versions_finders }.to_not raise_error
end
end
WPScan::DB::DynamicFinders::Plugin.versions_finders_configs.each do |slug, configs|
configs.each do |finder_class, config|
finder_super_class = config['class'] || finder_class
# The QueryParameter specs are slow given the huge fixture file
# If someone find a fix for that, please share!
describe df_tested_class_constant('PluginVersion', finder_class, slug), slow: true do
subject(:finder) { described_class.new(plugin) }
let(:plugin) { WPScan::Plugin.new(slug, target) }
let(:target) { WPScan::Target.new('http://wp.lab/') }
let(:fixtures) { File.join(DYNAMIC_FINDERS_FIXTURES, 'plugin_version') }
let(:expected) do
if expected_all[slug][finder_class].is_a?(Hash)
[expected_all[slug][finder_class]]
else
expected_all[slug][finder_class]
end
end
let(:stubbed_response) { { body: 'aa' } }
describe '#passive', slow: true do
before do
stub_request(:get, target.url).to_return(stubbed_response)
expect(target).to receive(:content_dir).at_least(1).and_return('wp-content')
end
if config['path']
context 'when PATH' do
it 'returns nil' do
expect(finder.passive).to eql nil
end
end
else
context 'when no PATH' do
context 'when the version is detected' do
let(:stubbed_response) do
df_stubbed_response(
File.join(fixtures, "#{finder_super_class.underscore}_passive_all.html"),
finder_super_class
)
end
it 'returns the expected version/s from the homepage' do
found = [*finder.passive]
expect(found).to_not be_empty
found.each_with_index do |version, index|
expected_version = expected.at(index)
expect(version).to be_a WPScan::Version
expect(version.number).to eql expected_version['number'].to_s
expect(version.found_by).to eql expected_version['found_by']
expect(version.interesting_entries).to match_array expected_version['interesting_entries']
expect(version.confidence).to eql expected_version['confidence'] if expected_version['confidence']
end
end
end
context 'when the version is not detected' do
it 'returns nil or an empty array' do
expect(finder.passive).to eql finder_super_class == 'QueryParameter' ? [] : nil
end
end
end
end
end
describe '#aggressive' do
let(:fixtures) { File.join(super(), slug, finder_class.underscore) }
before do
expect(target).to receive(:content_dir).at_least(1).and_return('wp-content')
stub_request(:get, plugin.url(config['path'])).to_return(stubbed_response) if config['path']
end
if config['path']
context 'when the version is detected' do
let(:stubbed_response) do
df_stubbed_response(File.join(fixtures, config['path']), finder_super_class)
end
it 'returns the expected version' do
found = [*finder.aggressive]
expect(found).to_not be_empty
found.each_with_index do |version, index|
expected_version = expected.at(index)
expect(version).to be_a WPScan::Version
expect(version.number).to eql expected_version['number'].to_s
expect(version.found_by).to eql expected_version['found_by']
expect(version.interesting_entries).to match_array expected_version['interesting_entries']
expect(version.confidence).to eql expected_version['confidence'] if expected_version['confidence']
end
end
end
context 'when the version is not detected' do
it 'returns nil or an empty array' do
expect(finder.aggressive).to eql finder_super_class == 'QueryParameter' ? [] : nil
end
end
else
it 'returns nil' do
expect(finder.aggressive).to eql nil
end
end
end
end
end
end

View File

@@ -0,0 +1,62 @@
require 'spec_helper'
describe WPScan::Finders::DynamicFinder::Version::BodyPattern do
module WPScan
module Finders
module Version
# Needed to be able to test the below
module Rspec
end
end
end
end
let(:finder_module) { WPScan::Finders::Version::Rspec }
let(:finder_class) { WPScan::Finders::Version::Rspec::BodyPattern }
let(:finder_config) { { 'pattern' => /aaa/i } }
let(:default) { { 'confidence' => 60 } }
before { described_class.create_child_class(finder_module, :BodyPattern, finder_config) }
after { finder_module.send(:remove_const, :BodyPattern) }
describe '.create_child_class' do
context 'when no PATH and CONFIDENCE' do
it 'contains the expected constants to their default values' do
# Doesn't work, dunno why
# expect(finder_module.const_get(:BodyPattern)).to be_a described_class
# expect(finder_class.is_a?(described_class)).to eql true
# expect(finder_class).to be_a described_class
expect(finder_class::PATTERN).to eql finder_config['pattern']
expect(finder_class::CONFIDENCE).to eql default['confidence']
expect(finder_class::PATH).to eql nil
end
end
context 'when CONFIDENCE' do
let(:finder_config) { super().merge('confidence' => 50) }
it 'contains the expected constants' do
expect(finder_class::PATTERN).to eql finder_config['pattern']
expect(finder_class::CONFIDENCE).to eql finder_config['confidence']
expect(finder_class::PATH).to eql nil
end
end
context 'when PATH' do
let(:finder_config) { super().merge('path' => 'changelog.txt') }
it 'contains the expected constants' do
expect(finder_class::PATTERN).to eql finder_config['pattern']
expect(finder_class::PATH).to eql finder_config['path']
expect(finder_class::CONFIDENCE).to eql default['confidence']
end
end
end
describe '#passive, #aggressive' do
# Handled in spec/lib/finders/dynamic_finder/plugin_version_spec
end
end

View File

@@ -0,0 +1,78 @@
require 'spec_helper'
describe WPScan::Finders::DynamicFinder::Version::Comment do
module WPScan
module Finders
module Version
# Needed to be able to test the below
module Rspec
end
end
end
end
let(:finder_module) { WPScan::Finders::Version::Rspec }
let(:finder_class) { WPScan::Finders::Version::Rspec::Comment }
let(:finder_config) { { 'pattern' => /some version: (?<v>[\d\.]+)/i } }
let(:default) { { 'xpath' => '//comment()', 'confidence' => 60 } }
before { described_class.create_child_class(finder_module, :Comment, finder_config) }
after { finder_module.send(:remove_const, :Comment) }
describe '.create_child_class' do
context 'when no PATH and CONFIDENCE' do
it 'contains the expected constants to their default values' do
# Doesn't work, dunno why
# expect(finder_module.const_get(:Comment)).to be_a described_class
# expect(finder_class.is_a?(described_class)).to eql true
# expect(finder_class).to be_a described_class
expect(finder_class::PATTERN).to eql finder_config['pattern']
expect(finder_class::XPATH).to eql default['xpath']
expect(finder_class::CONFIDENCE).to eql default['confidence']
expect(finder_class::PATH).to eql nil
end
end
context 'when CONFIDENCE' do
let(:finder_config) { super().merge('confidence' => 30) }
it 'contains the expected constants' do
expect(finder_class::PATTERN).to eql finder_config['pattern']
expect(finder_class::CONFIDENCE).to eql finder_config['confidence']
expect(finder_class::XPATH).to eql default['xpath']
expect(finder_class::PATH).to eql nil
end
end
context 'when PATH' do
let(:finder_config) { super().merge('path' => 'file.txt') }
it 'contains the expected constants' do
expect(finder_class::PATTERN).to eql finder_config['pattern']
expect(finder_class::PATH).to eql finder_config['path']
expect(finder_class::CONFIDENCE).to eql default['confidence']
expect(finder_class::XPATH).to eql default['xpath']
end
end
context 'when XPATH' do
let(:finder_config) { super().merge('xpath' => '//comment()[contains(. "aa")]') }
it 'contains the expected constants' do
expect(finder_class::PATTERN).to eql finder_config['pattern']
expect(finder_class::XPATH).to eql finder_config['xpath']
expect(finder_class::PATH).to eql nil
expect(finder_class::CONFIDENCE).to eql default['confidence']
end
end
end
describe '#passive, #aggressive' do
# Handled in spec/lib/finders/dynamic_finder/plugin_version_spec
end
end

View File

@@ -0,0 +1,51 @@
require 'spec_helper'
describe WPScan::Finders::DynamicFinder::Version::ConfigParser do
module WPScan
module Finders
module Version
# Needed to be able to test the below
module Rspec
end
end
end
end
let(:finder_module) { WPScan::Finders::Version::Rspec }
let(:finder_class) { WPScan::Finders::Version::Rspec::ConfigParser }
let(:finder_config) { { 'key' => 'some-key', 'path' => 'file.json' } }
let(:default) { { 'pattern' => /(?<v>\d+\.[\.\d]+)/, 'confidence' => 70 } }
before { described_class.create_child_class(finder_module, :ConfigParser, finder_config) }
after { finder_module.send(:remove_const, :ConfigParser) }
describe '.create_child_class' do
context 'when CONFIDENCE' do
let(:finder_config) { super().merge('confidence' => 30) }
it 'contains the expected constants' do
expect(finder_class::KEY).to eql finder_config['key']
expect(finder_class::CONFIDENCE).to eql finder_config['confidence']
expect(finder_class::PATH).to eql finder_config['path']
expect(finder_class::PATTERN).to eql default['pattern']
end
end
context 'when PATTERN' do
let(:finder_config) { super().merge('pattern' => /another pattern/i) }
it 'contains the expected constants' do
expect(finder_class::KEY).to eql finder_config['key']
expect(finder_class::PATTERN).to eql finder_config['pattern']
expect(finder_class::PATH).to eql finder_config['path']
expect(finder_class::CONFIDENCE).to eql default['confidence']
end
end
end
describe '#passive, #aggressive' do
# Handled in spec/lib/finders/dynamic_finder/plugin_version_spec
end
end

View File

@@ -0,0 +1,78 @@
require 'spec_helper'
describe WPScan::Finders::DynamicFinder::Version::HeaderPattern do
module WPScan
module Finders
module Version
# Needed to be able to test the below
module Rspec
end
end
end
end
let(:finder_module) { WPScan::Finders::Version::Rspec }
let(:finder_class) { WPScan::Finders::Version::Rspec::HeaderPattern }
let(:finder_config) { { 'header' => 'Location' } }
let(:default) { { 'confidence' => 60 } }
before { described_class.create_child_class(finder_module, :HeaderPattern, finder_config) }
after { finder_module.send(:remove_const, :HeaderPattern) }
describe '.create_child_class' do
context 'when no PATH and CONFIDENCE' do
it 'contains the expected constants to their default values' do
# Doesn't work, dunno why
# expect(finder_module.const_get(:HeaderPattern)).to be_a described_class
# expect(finder_class.is_a?(described_class)).to eql true
# expect(finder_class).to be_a described_class
expect(finder_class::HEADER).to eql finder_config['header']
expect(finder_class::PATTERN).to eql nil
expect(finder_class::CONFIDENCE).to eql default['confidence']
expect(finder_class::PATH).to eql nil
end
end
context 'when CONFIDENCE' do
let(:finder_config) { super().merge('confidence' => 50) }
it 'contains the expected constants' do
expect(finder_class::HEADER).to eql finder_config['header']
expect(finder_class::CONFIDENCE).to eql finder_config['confidence']
expect(finder_class::PATTERN).to eql nil
expect(finder_class::PATH).to eql nil
end
end
context 'when PATH' do
let(:finder_config) { super().merge('path' => 'index.php') }
it 'contains the expected constants' do
expect(finder_class::HEADER).to eql finder_config['header']
expect(finder_class::PATH).to eql finder_config['path']
expect(finder_class::PATTERN).to eql nil
expect(finder_class::CONFIDENCE).to eql default['confidence']
end
end
context 'when PATTERN' do
let(:finder_config) { super().merge('pattern' => /Version: (?<v>[\d\.]+)/i) }
it 'contains the expected constants' do
expect(finder_class::HEADER).to eql finder_config['header']
expect(finder_class::PATTERN).to eql finder_config['pattern']
expect(finder_class::PATH).to eql nil
expect(finder_class::CONFIDENCE).to eql default['confidence']
end
end
end
describe '#passive, #aggressive' do
# Handled in spec/lib/finders/dynamic_finder/plugin_version_spec
end
end

View File

@@ -0,0 +1,78 @@
require 'spec_helper'
describe WPScan::Finders::DynamicFinder::Version::JavascriptVar do
module WPScan
module Finders
module Version
# Needed to be able to test the below
module Rspec
end
end
end
end
let(:finder_module) { WPScan::Finders::Version::Rspec }
let(:finder_class) { WPScan::Finders::Version::Rspec::JavascriptVar }
let(:finder_config) { { 'pattern' => /some version: (?<v>[\d\.]+)/i } }
let(:default) { { 'xpath' => '//script[not(@src)]', 'confidence' => 60 } }
before { described_class.create_child_class(finder_module, :JavascriptVar, finder_config) }
after { finder_module.send(:remove_const, :JavascriptVar) }
describe '.create_child_class' do
context 'when no PATH and CONFIDENCE' do
it 'contains the expected constants to their default values' do
# Doesn't work, dunno why
# expect(finder_module.const_get(:JavascriptVar)).to be_a described_class
# expect(finder_class.is_a?(described_class)).to eql true
# expect(finder_class).to be_a described_class
expect(finder_class::PATTERN).to eql finder_config['pattern']
expect(finder_class::XPATH).to eql default['xpath']
expect(finder_class::CONFIDENCE).to eql default['confidence']
expect(finder_class::PATH).to eql nil
end
end
context 'when CONFIDENCE' do
let(:finder_config) { super().merge('confidence' => 30) }
it 'contains the expected constants' do
expect(finder_class::PATTERN).to eql finder_config['pattern']
expect(finder_class::CONFIDENCE).to eql finder_config['confidence']
expect(finder_class::XPATH).to eql default['xpath']
expect(finder_class::PATH).to eql nil
end
end
context 'when PATH' do
let(:finder_config) { super().merge('path' => 'file.html') }
it 'contains the expected constants' do
expect(finder_class::PATTERN).to eql finder_config['pattern']
expect(finder_class::PATH).to eql finder_config['path']
expect(finder_class::CONFIDENCE).to eql default['confidence']
expect(finder_class::XPATH).to eql default['xpath']
end
end
context 'when XPATH' do
let(:finder_config) { super().merge('xpath' => '//script') }
it 'contains the expected constants' do
expect(finder_class::PATTERN).to eql finder_config['pattern']
expect(finder_class::XPATH).to eql finder_config['xpath']
expect(finder_class::PATH).to eql nil
expect(finder_class::CONFIDENCE).to eql default['confidence']
end
end
end
describe '#passive, #aggressive' do
# Handled in spec/lib/finders/dynamic_finder/plugin_version_spec
end
end

View File

@@ -0,0 +1,90 @@
require 'spec_helper'
describe WPScan::Finders::DynamicFinder::Version::QueryParameter do
module WPScan
module Finders
module Version
# Needed to be able to test the below
module Rspec
end
end
end
end
let(:finder_module) { WPScan::Finders::Version::Rspec }
let(:finder_class) { WPScan::Finders::Version::Rspec::QueryParameter }
let(:finder_config) { { 'files' => %w[f1 f2] } }
let(:default) { { 'pattern' => /(?:v|ver|version)\=(?<v>\d+\.[\.\d]+)/i, 'confidence_per_occurence' => 10 } }
before { described_class.create_child_class(finder_module, :QueryParameter, finder_config) }
after { finder_module.send(:remove_const, :QueryParameter) }
describe '.create_child_class' do
context 'when no XPATH, PATTERN and CONFIDENCE_PER_OCCURENCE ' do
it 'contains the expected constants to their default values' do
expect(finder_class::FILES).to eql finder_config['files']
expect(finder_class::PATTERN).to eql default['pattern']
expect(finder_class::CONFIDENCE_PER_OCCURENCE).to eql default['confidence_per_occurence']
expect(finder_class::XPATH).to eql nil
expect(finder_class::PATH).to eql nil
end
end
context 'when XPATH' do
let(:finder_config) { super().merge('xpath' => '//xpath') }
it 'contains the expected constants' do
expect(finder_class::FILES).to eql finder_config['files']
expect(finder_class::XPATH).to eql finder_config['xpath']
expect(finder_class::CONFIDENCE_PER_OCCURENCE).to eql default['confidence_per_occurence']
expect(finder_class::PATTERN).to eql default['pattern']
expect(finder_class::PATH).to eql nil
end
end
context 'when PATTERN' do
let(:finder_config) { super().merge('pattern' => /pattern/i) }
it 'contains the expected constants' do
expect(finder_class::FILES).to eql finder_config['files']
expect(finder_class::PATTERN).to eql finder_config['pattern']
expect(finder_class::CONFIDENCE_PER_OCCURENCE).to eql default['confidence_per_occurence']
expect(finder_class::XPATH).to eql nil
expect(finder_class::PATH).to eql nil
end
end
context 'when CONFIDENCE_PER_OCCURENCE' do
let(:finder_config) { super().merge('confidence_per_occurence' => 30) }
it 'contains the expected constants' do
expect(finder_class::FILES).to eql finder_config['files']
expect(finder_class::CONFIDENCE_PER_OCCURENCE).to eql finder_config['confidence_per_occurence']
expect(finder_class::PATTERN).to eql default['pattern']
expect(finder_class::XPATH).to eql nil
expect(finder_class::PATH).to eql nil
end
end
context 'when PATH' do
let(:finder_config) { super().merge('path' => 'file.html') }
it 'contains the expected constants' do
expect(finder_class::FILES).to eql finder_config['files']
expect(finder_class::PATH).to eql finder_config['path']
expect(finder_class::CONFIDENCE_PER_OCCURENCE).to eql default['confidence_per_occurence']
expect(finder_class::XPATH).to eql nil
expect(finder_class::PATTERN).to eql default['pattern']
end
end
end
describe '#passive, #aggressive' do
# Handled in spec/lib/finders/dynamic_finder/plugin_version_spec
end
end

View File

@@ -0,0 +1,78 @@
require 'spec_helper'
describe WPScan::Finders::DynamicFinder::Version::Xpath do
module WPScan
module Finders
module Version
# Needed to be able to test the below
module Rspec
end
end
end
end
let(:finder_module) { WPScan::Finders::Version::Rspec }
let(:finder_class) { WPScan::Finders::Version::Rspec::Xpath }
let(:finder_config) { { 'xpath' => "//div/h3[@class='version-number']" } }
let(:default) { { 'pattern' => /\A(?<v>\d+\.[\.\d]+)/, 'confidence' => 60 } }
before { described_class.create_child_class(finder_module, :Xpath, finder_config) }
after { finder_module.send(:remove_const, :Xpath) }
describe '.create_child_class' do
context 'when no PATH and CONFIDENCE' do
it 'contains the expected constants to their default values' do
# Doesn't work, dunno why
# expect(finder_module.const_get(:Xpath)).to be_a described_class
# expect(finder_class.is_a?(described_class)).to eql true
# expect(finder_class).to be_a described_class
expect(finder_class::XPATH).to eql finder_config['xpath']
expect(finder_class::PATTERN).to eql default['pattern']
expect(finder_class::CONFIDENCE).to eql default['confidence']
expect(finder_class::PATH).to eql nil
end
end
context 'when CONFIDENCE' do
let(:finder_config) { super().merge('confidence' => 30) }
it 'contains the expected constants' do
expect(finder_class::XPATH).to eql finder_config['xpath']
expect(finder_class::CONFIDENCE).to eql finder_config['confidence']
expect(finder_class::PATTERN).to eql default['pattern']
expect(finder_class::PATH).to eql nil
end
end
context 'when PATH' do
let(:finder_config) { super().merge('path' => 'file.txt') }
it 'contains the expected constants' do
expect(finder_class::XPATH).to eql finder_config['xpath']
expect(finder_class::PATH).to eql finder_config['path']
expect(finder_class::PATTERN).to eql default['pattern']
expect(finder_class::CONFIDENCE).to eql default['confidence']
end
end
context 'when PATTERN' do
let(:finder_config) { super().merge('pattern' => /Version: (?<v>[\d\.]+)/i) }
it 'contains the expected constants' do
expect(finder_class::XPATH).to eql finder_config['xpath']
expect(finder_class::PATTERN).to eql finder_config['pattern']
expect(finder_class::PATH).to eql nil
expect(finder_class::CONFIDENCE).to eql default['confidence']
end
end
end
describe '#passive, #aggressive' do
# Handled in spec/lib/finders/dynamic_finder/plugin_version_spec
end
end

View File

@@ -0,0 +1,5 @@
require 'spec_helper'
describe WPScan::Finders::DynamicFinder::WpItems::Finder do
# Handled in spec/shared_examples/dynamic_finders/wp_items.rb
end

View File

@@ -0,0 +1,110 @@
require 'spec_helper'
expected_all = df_expected_all['wordpress']
WPScan::DB::DynamicFinders::Wordpress.create_versions_finders
describe 'Try to create the finders twice' do
it 'does not raise an error when the class already exists' do
expect { WPScan::DB::DynamicFinders::Wordpress.create_versions_finders }.to_not raise_error
end
end
WPScan::DB::DynamicFinders::Wordpress.versions_finders_configs.each do |finder_class, config|
finder_super_class = config['class'] || finder_class
describe df_tested_class_constant('WpVersion', finder_class) do
subject(:finder) { described_class.new(target) }
let(:target) { WPScan::Target.new('http://wp.lab/') }
let(:fixtures) { File.join(DYNAMIC_FINDERS_FIXTURES, 'wp_version') }
let(:expected) do
expected_all[finder_class].is_a?(Hash) ? [expected_all[finder_class]] : expected_all[finder_class]
end
let(:stubbed_response) { { body: '' } }
describe '#passive' do
before { stub_request(:get, target.url).to_return(stubbed_response) }
if config['path']
context 'when PATH' do
it 'returns nil' do
expect(finder.passive).to eql nil
end
end
else
context 'when no PATH' do
let(:stubbed_response) do
df_stubbed_response(
File.join(fixtures, "#{finder_super_class.underscore}_passive_all.html"),
finder_super_class
)
end
it 'returns the expected version from the homepage' do
found = [*finder.passive]
expect(found).to_not be_empty
found.each_with_index do |version, index|
expected_version = expected.at(index)
expect(version).to be_a WPScan::WpVersion
expect(version.number).to eql expected_version['number'].to_s
expect(version.found_by).to eql expected_version['found_by']
expect(version.interesting_entries).to match_array expected_version['interesting_entries']
expect(version.confidence).to eql expected_version['confidence'] if expected_version['confidence']
end
end
end
end
end
describe '#aggressive' do
let(:fixtures) { File.join(super(), finder_class.underscore) }
before do
allow(target).to receive(:sub_dir).and_return(nil)
stub_request(:get, target.url(config['path'])).to_return(stubbed_response) if config['path']
end
if config['path']
context 'when the version is detected' do
let(:stubbed_response) do
df_stubbed_response(File.join(fixtures, config['path']), finder_super_class)
end
it 'returns the expected version' do
found = [*finder.aggressive]
expect(found).to_not be_empty
found.each_with_index do |version, index|
expected_version = expected.at(index)
expect(version).to be_a WPScan::WpVersion
expect(version.number).to eql expected_version['number'].to_s
expect(version.found_by).to eql expected_version['found_by']
expect(version.interesting_entries).to match_array expected_version['interesting_entries']
expect(version.confidence).to eql expected_version['confidence'] if expected_version['confidence']
end
end
end
context 'when the version is not detected' do
it 'returns nil or an empty array' do
expect(finder.aggressive).to eql finder_super_class == 'QueryParameter' ? [] : nil
end
end
else
it 'returns nil' do
expect(finder.aggressive).to eql nil
end
end
end
end
end

View File

@@ -0,0 +1,5 @@
require 'spec_helper'
describe WPScan::Finders::Finder::WpVersion::SmartURLChecker do
xit
end

130
spec/lib/target_spec.rb Normal file
View File

@@ -0,0 +1,130 @@
require 'spec_helper'
describe WPScan::Target do
subject(:target) { described_class.new(url) }
let(:url) { 'http://ex.lo' }
it_behaves_like WPScan::Target::Platform::WordPress
describe 'xmlrpc' do
before do
allow(target).to receive(:sub_dir)
expect(target).to receive(:interesting_findings).and_return(interesting_findings)
end
context 'when no interesting_findings' do
let(:interesting_findings) { [] }
its(:xmlrpc) { should be_nil }
end
context 'when interesting_findings' do
let(:interesting_findings) { ['aa', CMSScanner::RobotsTxt.new(target.url)] }
context 'when no XMLRPC' do
its(:xmlrpc) { should be_nil }
end
context 'when XMLRPC' do
let(:xmlrpc) { WPScan::XMLRPC.new(target.url('xmlrpc.php')) }
let(:interesting_findings) { super() << xmlrpc }
its(:xmlrpc) { should eq xmlrpc }
end
end
end
%i[wp_version main_theme plugins themes timthumbs config_backups db_exports medias users].each do |method|
describe "##{method}" do
before do
return_value = %i[wp_version main_theme].include?(method) ? false : []
expect(WPScan::Finders.const_get("#{method.to_s.camelize}::Base"))
.to receive(:find).with(target, opts).and_return(return_value)
end
after { target.send(method, opts) }
let(:opts) { {} }
context 'when no options' do
it 'calls the finder with the correct arguments' do
# handled by before hook
end
end
context 'when options' do
let(:opts) { { mode: :passive, somthing: 'k' } }
it 'calls the finder with the corect arguments' do
# handled by before hook
end
end
context 'when called multiple times' do
it 'calls the finder only once' do
target.send(method, opts)
end
end
end
end
describe '#vulnerable?' do
context 'when all attributes are nil' do
it { should_not be_vulnerable }
end
context 'when wp_version is not found' do
before { target.instance_variable_set(:@wp_version, false) }
it { should_not be_vulnerable }
end
context 'when wp_version found' do
context 'when not vulnerable' do
before { target.instance_variable_set(:@wp_version, WPScan::WpVersion.new('4.4')) }
it { should_not be_vulnerable }
end
context 'when vulnerable' do
before { target.instance_variable_set(:@wp_version, WPScan::WpVersion.new('3.8.1')) }
it { should be_vulnerable }
end
end
context 'when config_backups' do
before do
target.instance_variable_set(:@config_backups, [WPScan::ConfigBackup.new(target.url('/a-file-url'))])
end
it { should be_vulnerable }
end
context 'when db_exports' do
before do
target.instance_variable_set(:@db_exports, [WPScan::DbExport.new(target.url('/wordpress.sql'))])
end
it { should be_vulnerable }
end
context 'when users' do
before do
target.instance_variable_set(:@users, [CMSScanner::User.new('u1'), CMSScanner::User.new('u2')])
end
context 'when no passwords' do
it { should_not be_vulnerable }
end
context 'when at least one password has been found' do
before { target.users[1].password = 'owned' }
it { should be_vulnerable }
end
end
end
end

View File

@@ -0,0 +1,13 @@
require 'spec_helper'
describe WPScan::Vulnerability do
subject(:vuln) { described_class.new(title, references) }
let(:title) { 'Test Vuln' }
let(:references) { {} }
it_behaves_like WPScan::References
describe '#load_from_json' do
# Handled in spec/app/models/wp_version_spec#vulnerabilities
end
end

13
spec/lib/wpscan_spec.rb Normal file
View File

@@ -0,0 +1,13 @@
require 'spec_helper'
describe WPScan do
it 'has a version number' do
expect(WPScan::VERSION).not_to be nil
end
describe '#app_name' do
it 'returns the overriden string' do
expect(WPScan.app_name).to eql 'wpscan'
end
end
end