HELLO v3!!!
This commit is contained in:
52
spec/app/finders/config_backups/known_filenames_spec.rb
Normal file
52
spec/app/finders/config_backups/known_filenames_spec.rb
Normal file
@@ -0,0 +1,52 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::ConfigBackups::KnownFilenames do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'config_backups') }
|
||||
let(:opts) { { list: File.join(WPScan::DB_DIR, 'config_backups.txt') } }
|
||||
|
||||
describe '#aggressive' do
|
||||
before do
|
||||
expect(target).to receive(:sub_dir).at_least(1).and_return(false)
|
||||
expect(target).to receive(:homepage_or_404?).at_least(1).and_return(false)
|
||||
|
||||
finder.potential_urls(opts).each_key do |url|
|
||||
stub_request(:get, url).to_return(status: 404)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when all files are 404s' do
|
||||
it 'returns an empty array' do
|
||||
expect(finder.aggressive(opts)).to eql []
|
||||
end
|
||||
end
|
||||
|
||||
context 'when some files exist' do
|
||||
let(:files) { ['%23wp-config.php%23', 'wp-config.bak'] }
|
||||
let(:config_backup) { File.read(File.join(fixtures, 'wp-config.php')) }
|
||||
|
||||
before do
|
||||
files.each do |file|
|
||||
stub_request(:get, "#{url}#{file}").to_return(body: config_backup)
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns the expected Array<ConfigBackup>' do
|
||||
expected = []
|
||||
|
||||
files.each do |file|
|
||||
url = "#{target.url}#{file}"
|
||||
expected << WPScan::ConfigBackup.new(
|
||||
url,
|
||||
confidence: 100,
|
||||
found_by: described_class::DIRECT_ACCESS
|
||||
)
|
||||
end
|
||||
|
||||
expect(finder.aggressive(opts)).to eql expected
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
13
spec/app/finders/config_backups_spec.rb
Normal file
13
spec/app/finders/config_backups_spec.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::ConfigBackups::Base do
|
||||
subject(:config_backups) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
|
||||
describe '#finders' do
|
||||
it 'contains the expected finders' do
|
||||
expect(config_backups.finders.map { |f| f.class.to_s.demodulize }).to eq %w[KnownFilenames]
|
||||
end
|
||||
end
|
||||
end
|
||||
69
spec/app/finders/db_exports/known_locations_spec.rb
Normal file
69
spec/app/finders/db_exports/known_locations_spec.rb
Normal file
@@ -0,0 +1,69 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::DbExports::KnownLocations do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://ex.lo/aa/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'db_exports') }
|
||||
let(:opts) { { list: File.join(WPScan::DB_DIR, 'db_exports.txt') } }
|
||||
|
||||
describe '#potential_urls' do
|
||||
before do
|
||||
expect(target).to receive(:sub_dir).at_least(1).and_return(false)
|
||||
end
|
||||
|
||||
it 'replace {domain_name} by its value' do
|
||||
expect(finder.potential_urls(opts).keys).to eql %w[
|
||||
http://ex.lo/aa/ex.sql
|
||||
http://ex.lo/aa/wordpress.sql
|
||||
http://ex.lo/aa/backup/ex.zip
|
||||
http://ex.lo/aa/backup/mysql.sql
|
||||
http://ex.lo/aa/backups/ex.sql.gz
|
||||
http://ex.lo/aa/backups/db_backup.sql
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
describe '#aggressive' do
|
||||
before do
|
||||
expect(target).to receive(:sub_dir).at_least(1).and_return(false)
|
||||
expect(target).to receive(:homepage_or_404?).at_least(1).and_return(false)
|
||||
|
||||
finder.potential_urls(opts).each_key do |url|
|
||||
stub_request(:get, url).to_return(status: 404)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when all files are 404s' do
|
||||
it 'returns an empty array' do
|
||||
expect(finder.aggressive(opts)).to eql []
|
||||
end
|
||||
end
|
||||
|
||||
context 'when some files exist' do
|
||||
let(:files) { %w[ex.sql backups/db_backup.sql] }
|
||||
let(:db_export) { File.read(File.join(fixtures, 'dump.sql')) }
|
||||
|
||||
before do
|
||||
files.each do |file|
|
||||
stub_request(:get, "#{url}#{file}").to_return(body: db_export)
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns the expected Array<DbExport>' do
|
||||
expected = []
|
||||
|
||||
files.each do |file|
|
||||
url = "#{target.url}#{file}"
|
||||
expected << WPScan::DbExport.new(
|
||||
url,
|
||||
confidence: 100,
|
||||
found_by: described_class::DIRECT_ACCESS
|
||||
)
|
||||
end
|
||||
|
||||
expect(finder.aggressive(opts)).to eql expected
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
13
spec/app/finders/db_exports_spec.rb
Normal file
13
spec/app/finders/db_exports_spec.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::DbExports::Base do
|
||||
subject(:db_exports) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
|
||||
describe '#finders' do
|
||||
it 'contains the expected finders' do
|
||||
expect(db_exports.finders.map { |f| f.class.to_s.demodulize }).to eq %w[KnownLocations]
|
||||
end
|
||||
end
|
||||
end
|
||||
64
spec/app/finders/interesting_findings/backup_db_spec.rb
Normal file
64
spec/app/finders/interesting_findings/backup_db_spec.rb
Normal file
@@ -0,0 +1,64 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::InterestingFindings::BackupDB do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'backup_db') }
|
||||
let(:wp_content) { 'wp-content' }
|
||||
let(:dir_url) { target.url("#{wp_content}/backup-db/") }
|
||||
|
||||
before { expect(target).to receive(:content_dir).at_least(1).and_return(wp_content) }
|
||||
|
||||
describe '#aggressive' do
|
||||
before { stub_request(:get, dir_url).to_return(status: status, body: body) }
|
||||
|
||||
let(:body) { '' }
|
||||
|
||||
context 'when not a 200 or 403' do
|
||||
let(:status) { 404 }
|
||||
|
||||
its(:aggressive) { should be_nil }
|
||||
end
|
||||
|
||||
context 'when 200 and matching the homepage' do
|
||||
before { expect(target).to receive(:homepage_or_404?).and_return(true) }
|
||||
|
||||
let(:status) { 200 }
|
||||
|
||||
its(:aggressive) { should be_nil }
|
||||
end
|
||||
|
||||
context 'when 200 or 403' do
|
||||
before { expect(target).to receive(:homepage_or_404?).and_return(false) }
|
||||
|
||||
let(:status) { 200 }
|
||||
|
||||
after do
|
||||
found = finder.aggressive
|
||||
|
||||
expect(found).to eql WPScan::InterestingFinding.new(
|
||||
dir_url,
|
||||
confidence: 70,
|
||||
found_by: described_class::DIRECT_ACCESS
|
||||
)
|
||||
|
||||
expect(found.interesting_entries).to eq @expected_entries
|
||||
end
|
||||
|
||||
context 'when no directory listing' do
|
||||
it 'returns an empty interesting_findings attribute' do
|
||||
@expected_entries = []
|
||||
end
|
||||
end
|
||||
|
||||
context 'when directory listing enabled' do
|
||||
let(:body) { File.read(File.join(fixtures, 'dir_listing.html')) }
|
||||
|
||||
it 'returns the expected interesting_findings attribute' do
|
||||
@expected_entries = %w[sqldump.sql test.txt]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
34
spec/app/finders/interesting_findings/debug_log_spec.rb
Normal file
34
spec/app/finders/interesting_findings/debug_log_spec.rb
Normal file
@@ -0,0 +1,34 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::InterestingFindings::DebugLog do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'debug_log') }
|
||||
let(:wp_content) { 'wp-content' }
|
||||
let(:log_url) { target.url("#{wp_content}/debug.log") }
|
||||
|
||||
before { expect(target).to receive(:content_dir).at_least(1).and_return(wp_content) }
|
||||
|
||||
describe '#aggressive' do
|
||||
before { stub_request(:get, log_url).to_return(body: body) }
|
||||
|
||||
context 'when empty file' do
|
||||
let(:body) { '' }
|
||||
|
||||
its(:aggressive) { should be_nil }
|
||||
end
|
||||
|
||||
context 'when a log file' do
|
||||
let(:body) { File.read(File.join(fixtures, 'debug.log')) }
|
||||
|
||||
it 'returns the InterestingFinding' do
|
||||
expect(finder.aggressive).to eql WPScan::InterestingFinding.new(
|
||||
log_url,
|
||||
confidence: 100,
|
||||
found_by: described_class::DIRECT_ACCESS
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,35 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::InterestingFindings::DuplicatorInstallerLog do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'duplicator_installer_log') }
|
||||
let(:filename) { 'installer-log.txt' }
|
||||
let(:log_url) { target.url(filename) }
|
||||
|
||||
describe '#aggressive' do
|
||||
before do
|
||||
expect(target).to receive(:sub_dir).at_least(1).and_return(false)
|
||||
stub_request(:get, log_url).to_return(body: body)
|
||||
end
|
||||
|
||||
context 'when the body does not match' do
|
||||
let(:body) { '' }
|
||||
|
||||
its(:aggressive) { should be_nil }
|
||||
end
|
||||
|
||||
context 'when the body matches' do
|
||||
let(:body) { File.read(File.join(fixtures, filename)) }
|
||||
|
||||
it 'returns the InterestingFinding' do
|
||||
expect(finder.aggressive).to eql WPScan::InterestingFinding.new(
|
||||
log_url,
|
||||
confidence: 100,
|
||||
found_by: described_class::DIRECT_ACCESS
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,12 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::InterestingFindings::EmergencyPwdResetScript do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'emergency_pwd_reset_script') }
|
||||
|
||||
describe '#aggressive' do
|
||||
xit
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,37 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::InterestingFindings::FullPathDisclosure do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'fpd') }
|
||||
let(:file_url) { target.url('wp-includes/rss-functions.php') }
|
||||
|
||||
describe '#aggressive' do
|
||||
before do
|
||||
expect(target).to receive(:sub_dir).at_least(1).and_return(false)
|
||||
stub_request(:get, file_url).to_return(body: body)
|
||||
end
|
||||
|
||||
context 'when empty file' do
|
||||
let(:body) { '' }
|
||||
|
||||
its(:aggressive) { should be_nil }
|
||||
end
|
||||
|
||||
context 'when a log file' do
|
||||
let(:body) { File.read(File.join(fixtures, 'rss_functions.php')) }
|
||||
|
||||
it 'returns the InterestingFinding' do
|
||||
found = finder.aggressive
|
||||
|
||||
expect(found).to eql WPScan::InterestingFinding.new(
|
||||
file_url,
|
||||
confidence: 100,
|
||||
found_by: described_class::DIRECT_ACCESS
|
||||
)
|
||||
expect(found.interesting_entries).to eql %w[/blog/wp-includes/rss-functions.php]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
16
spec/app/finders/interesting_findings/mu_plugins_spec.rb
Normal file
16
spec/app/finders/interesting_findings/mu_plugins_spec.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::InterestingFindings::MuPlugins do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'mu_plugins') }
|
||||
|
||||
describe '#passive' do
|
||||
xit
|
||||
end
|
||||
|
||||
describe '#aggressive' do
|
||||
xit
|
||||
end
|
||||
end
|
||||
12
spec/app/finders/interesting_findings/multisite_spec.rb
Normal file
12
spec/app/finders/interesting_findings/multisite_spec.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::InterestingFindings::Multisite do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'multisite') }
|
||||
|
||||
describe '#aggressive' do
|
||||
xit
|
||||
end
|
||||
end
|
||||
46
spec/app/finders/interesting_findings/readme_spec.rb
Normal file
46
spec/app/finders/interesting_findings/readme_spec.rb
Normal file
@@ -0,0 +1,46 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::InterestingFindings::Readme do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'readme') }
|
||||
|
||||
describe '#aggressive' do
|
||||
before do
|
||||
expect(target).to receive(:sub_dir).at_least(1).and_return(false)
|
||||
|
||||
finder.potential_files.each do |file|
|
||||
stub_request(:get, target.url(file)).to_return(status: 404)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no file present' do
|
||||
its(:aggressive) { should be_nil }
|
||||
end
|
||||
|
||||
# TODO: case when multiple files are present ? (should return only the first one found)
|
||||
context 'when a file exists' do
|
||||
let(:file) { finder.potential_files.sample }
|
||||
let(:readme) { File.read(File.join(fixtures, 'readme-3.9.2.html')) }
|
||||
|
||||
before { stub_request(:get, target.url(file)).to_return(body: readme) }
|
||||
|
||||
it 'returns the expected InterestingFinding' do
|
||||
expected = WPScan::InterestingFinding.new(
|
||||
target.url(file),
|
||||
confidence: 100,
|
||||
found_by: described_class::DIRECT_ACCESS
|
||||
)
|
||||
|
||||
expect(finder.aggressive).to eql expected
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#potential_files' do
|
||||
it 'does not contain duplicates' do
|
||||
expect(finder.potential_files.flatten.uniq.length).to eql finder.potential_files.length
|
||||
end
|
||||
end
|
||||
end
|
||||
12
spec/app/finders/interesting_findings/registration_spec.rb
Normal file
12
spec/app/finders/interesting_findings/registration_spec.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::InterestingFindings::Registration do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'registration') }
|
||||
|
||||
describe '#aggressive' do
|
||||
xit
|
||||
end
|
||||
end
|
||||
12
spec/app/finders/interesting_findings/tmm_db_migrate_spec.rb
Normal file
12
spec/app/finders/interesting_findings/tmm_db_migrate_spec.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::InterestingFindings::TmmDbMigrate do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'tmm_db_migrate') }
|
||||
|
||||
describe '#aggressive' do
|
||||
xit
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,13 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::InterestingFindings::UploadDirectoryListing do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'upload_directory_listing') }
|
||||
let(:wp_content) { 'wp-content' }
|
||||
|
||||
describe '#aggressive' do
|
||||
xit
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,50 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::InterestingFindings::UploadSQLDump do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'interesting_findings', 'upload_sql_dump') }
|
||||
let(:wp_content) { 'wp-content' }
|
||||
|
||||
describe '#aggressive' do
|
||||
before { expect(target).to receive(:content_dir).at_least(1).and_return(wp_content) }
|
||||
|
||||
after { expect(finder.aggressive).to eql @expected }
|
||||
|
||||
context 'when not a 200' do
|
||||
it 'returns nil' do
|
||||
stub_request(:get, finder.dump_url).to_return(status: 404)
|
||||
|
||||
@expected = nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a 200' do
|
||||
before do
|
||||
stub_request(:get, finder.dump_url)
|
||||
.to_return(status: 200, body: File.read(File.join(fixtures, fixture)))
|
||||
end
|
||||
|
||||
context 'when the body does not match a SQL dump' do
|
||||
let(:fixture) { 'not_sql.txt' }
|
||||
|
||||
it 'returns nil' do
|
||||
@expected = nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the body matches a SQL dump' do
|
||||
let(:fixture) { 'dump.sql' }
|
||||
|
||||
it 'returns the interesting findings' do
|
||||
@expected = WPScan::InterestingFinding.new(
|
||||
finder.dump_url,
|
||||
confidence: 100,
|
||||
found_by: described_class::DIRECT_ACCESS
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
21
spec/app/finders/interesting_findings_spec.rb
Normal file
21
spec/app/finders/interesting_findings_spec.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::InterestingFindings::Base do
|
||||
subject(:files) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
|
||||
describe '#finders' do
|
||||
let(:expected) do
|
||||
%w[
|
||||
Readme DebugLog FullPathDisclosure
|
||||
Multisite MuPlugins Registration UploadDirectoryListing TmmDbMigrate
|
||||
UploadSQLDump
|
||||
]
|
||||
end
|
||||
|
||||
it 'contains the expected finders' do
|
||||
expect(files.finders.map { |f| f.class.to_s.demodulize }).to include(*expected)
|
||||
end
|
||||
end
|
||||
end
|
||||
58
spec/app/finders/main_theme/css_style_spec.rb
Normal file
58
spec/app/finders/main_theme/css_style_spec.rb
Normal file
@@ -0,0 +1,58 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::MainTheme::CssStyle do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
|
||||
let(:url) { 'http://wp.lab/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'main_theme', 'css_style') }
|
||||
|
||||
describe '#passive' do
|
||||
after do
|
||||
stub_request(:get, url).to_return(body: File.read(File.join(fixtures, fixture)))
|
||||
expect(finder.passive).to eql @expected
|
||||
end
|
||||
|
||||
context 'when no in scope style' do
|
||||
let(:fixture) { 'no_in_scope_style.html' }
|
||||
|
||||
it 'returns nil' do
|
||||
@expected = nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when in scope style' do
|
||||
before do
|
||||
expect(target).to receive(:content_dir).at_least(1).and_return('wp-content')
|
||||
stub_request(:get, /.*.css/)
|
||||
end
|
||||
|
||||
context 'when in a link href' do
|
||||
let(:fixture) { 'link_href.html' }
|
||||
|
||||
it 'returns the expected theme' do
|
||||
@expected = WPScan::Theme.new(
|
||||
'twentyfifteen',
|
||||
target,
|
||||
found_by: 'Css Style (Passive Detection)',
|
||||
confidence: 70,
|
||||
style_url: 'http://wp.lab/wp-content/themes/twentyfifteen/style.css?ver=4.1.1'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when in the style code' do
|
||||
let(:fixture) { 'style_code.html' }
|
||||
|
||||
it 'returns the expected theme' do
|
||||
@expected = WPScan::Theme.new(
|
||||
'custom',
|
||||
target,
|
||||
found_by: 'Css Style (Passive Detection)',
|
||||
confidence: 70,
|
||||
style_url: 'http://wp.lab/wp-content/themes/custom/style.css'
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
35
spec/app/finders/main_theme/urls_in_homepage_spec.rb
Normal file
35
spec/app/finders/main_theme/urls_in_homepage_spec.rb
Normal file
@@ -0,0 +1,35 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::MainTheme::UrlsInHomepage do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://wp.lab/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'main_theme', 'urls_in_homepage') }
|
||||
|
||||
it_behaves_like 'App::Finders::WpItems::URLsInHomepage' do
|
||||
let(:type) { 'themes' }
|
||||
let(:uniq_links) { false }
|
||||
let(:uniq_codes) { false }
|
||||
let(:expected_from_links) { %w[twentyfifteen twentyfifteen twentyfifteen yolo] }
|
||||
let(:expected_from_codes) { %w[test yolo] }
|
||||
end
|
||||
|
||||
describe '#passive' do
|
||||
before do
|
||||
stub_request(:get, /.*.css/)
|
||||
stub_request(:get, target.url).to_return(body: File.read(File.join(fixtures, 'found.html')))
|
||||
end
|
||||
|
||||
it 'returns the expected Themes' do
|
||||
@expected = []
|
||||
|
||||
{ 'twentyfifteen' => 6, 'yolo' => 4, 'test' => 2 }.each do |slug, confidence|
|
||||
@expected << WPScan::Theme.new(
|
||||
slug, target, found_by: 'Urls In Homepage (Passive Detection)', confidence: confidence
|
||||
)
|
||||
end
|
||||
|
||||
expect(finder.passive).to eql @expected
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,39 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::MainTheme::WooFrameworkMetaGenerator do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
|
||||
let(:url) { 'http://wp.lab/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'main_theme', 'woo_framework_meta_generator') }
|
||||
|
||||
describe '#passive' do
|
||||
after do
|
||||
stub_request(:get, url).to_return(body: File.read(File.join(fixtures, @file)))
|
||||
|
||||
expect(finder.passive).to eql @expected
|
||||
end
|
||||
|
||||
context 'when no Woo generator' do
|
||||
it 'returns nil' do
|
||||
@file = 'no_woo_generator.html'
|
||||
@expected = nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when Woo generator' do
|
||||
before do
|
||||
expect(target).to receive(:content_dir).at_least(1).and_return('wp-content')
|
||||
stub_request(:get, "#{url}wp-content/themes/Merchant/style.css")
|
||||
end
|
||||
|
||||
it 'returns the expected theme' do
|
||||
@file = 'woo_generator.html'
|
||||
@expected = WPScan::Theme.new(
|
||||
'Merchant', target,
|
||||
found_by: 'Woo Framework Meta Generator (Passive Detection)',
|
||||
confidence: 80
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
14
spec/app/finders/main_theme_spec.rb
Normal file
14
spec/app/finders/main_theme_spec.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::MainTheme::Base do
|
||||
subject(:main_theme) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
|
||||
describe '#finders' do
|
||||
it 'contains the expected finders' do
|
||||
expect(main_theme.finders.map { |f| f.class.to_s.demodulize })
|
||||
.to eq %w[CssStyle WooFrameworkMetaGenerator UrlsInHomepage]
|
||||
end
|
||||
end
|
||||
end
|
||||
21
spec/app/finders/medias/attachment_brute_forcing_spec.rb
Normal file
21
spec/app/finders/medias/attachment_brute_forcing_spec.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Medias::AttachmentBruteForcing do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'medias', 'attachment_brute_forcing') }
|
||||
|
||||
describe '#aggressive' do
|
||||
xit
|
||||
end
|
||||
|
||||
describe '#target_urls' do
|
||||
it 'returns the expected urls' do
|
||||
expect(finder.target_urls(range: (1..2))).to eql(
|
||||
url + '?attachment_id=1' => 1,
|
||||
url + '?attachment_id=2' => 2
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
13
spec/app/finders/medias_spec.rb
Normal file
13
spec/app/finders/medias_spec.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Medias::Base do
|
||||
subject(:media) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
|
||||
describe '#finders' do
|
||||
it 'contains the expected finders' do
|
||||
expect(media.finders.map { |f| f.class.to_s.demodulize }).to eq %w[AttachmentBruteForcing]
|
||||
end
|
||||
end
|
||||
end
|
||||
116
spec/app/finders/plugin_version/readme_spec.rb
Normal file
116
spec/app/finders/plugin_version/readme_spec.rb
Normal file
@@ -0,0 +1,116 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::PluginVersion::Readme do
|
||||
subject(:finder) { described_class.new(plugin) }
|
||||
let(:plugin) { WPScan::Plugin.new('spec', target) }
|
||||
let(:target) { WPScan::Target.new('http://wp.lab/') }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'plugin_version', 'readme') }
|
||||
|
||||
def version(number, found_by, confidence)
|
||||
WPScan::Version.new(
|
||||
number,
|
||||
found_by: format('Readme - %s (Aggressive Detection)', found_by),
|
||||
confidence: confidence,
|
||||
interesting_entries: [readme_url]
|
||||
)
|
||||
end
|
||||
|
||||
def stable_tag(number)
|
||||
version(number, 'Stable Tag', 80)
|
||||
end
|
||||
|
||||
def changelog_section(number)
|
||||
version(number, 'ChangeLog Section', 50)
|
||||
end
|
||||
|
||||
describe '#aggressive' do
|
||||
before { expect(target).to receive(:content_dir).and_return('wp-content') }
|
||||
|
||||
after do
|
||||
stub_request(:get, /.*/).to_return(status: 404)
|
||||
stub_request(:get, readme_url).to_return(body: File.read(File.join(fixtures, @file)))
|
||||
|
||||
expect(finder.aggressive).to eql @expected
|
||||
end
|
||||
|
||||
let(:readme_url) { plugin.url(WPScan::WpItem::READMES.sample) }
|
||||
|
||||
context 'when no version' do
|
||||
it 'returns nil' do
|
||||
@file = 'no_version.txt'
|
||||
@expected = nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the stable tag does not contain numbers' do
|
||||
it 'returns nil' do
|
||||
@file = 'aa-health-calculator.txt'
|
||||
@expected = nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when empty changelog section' do
|
||||
it 'returns nil' do
|
||||
@file = 'all-in-one-facebook.txt'
|
||||
@expected = nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no changelog section' do
|
||||
it 'returns nil' do
|
||||
@file = 'blog-reordering.txt'
|
||||
@expected = nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when leaked from the stable tag' do
|
||||
it 'returns the expected versions' do
|
||||
@file = 'simple-login-lockdown-0.4.txt'
|
||||
@expected = [stable_tag('0.4'), changelog_section('04')]
|
||||
end
|
||||
end
|
||||
|
||||
context 'when leaked from the version' do
|
||||
it 'returns it' do
|
||||
@file = 'wp-photo-plus-5.1.15.txt'
|
||||
@expected = [stable_tag('5.1.15')]
|
||||
end
|
||||
end
|
||||
|
||||
context 'when version is in a release date format' do
|
||||
it 'detects and returns it' do
|
||||
@file = 's2member.txt'
|
||||
@expected = [stable_tag('141007')]
|
||||
end
|
||||
end
|
||||
|
||||
context 'when version contains letters' do
|
||||
it 'returns it' do
|
||||
@file = 'beta1.txt'
|
||||
@expected = [stable_tag('2.0.0-beta1')]
|
||||
end
|
||||
end
|
||||
|
||||
context 'when parsing the changelog for version numbers' do
|
||||
{
|
||||
'changelog_version' => '1.3',
|
||||
'wp_polls' => '2.64',
|
||||
'nextgen_gallery' => '2.0.66.33',
|
||||
'wp_user_frontend' => '1.2.3',
|
||||
'my_calendar' => '2.1.5',
|
||||
'nextgen_gallery_2' => '1.9.13',
|
||||
'advanced-most-recent-posts-mod' => '1.6.5.2',
|
||||
'a-lead-capture-contact-form-and-tab-button-by-awebvoicecom' => '3.1',
|
||||
'backup-scheduler' => '1.5.9',
|
||||
'release_date_slash' => '1.0.4'
|
||||
}. each do |file, version_number|
|
||||
context "whith #{file}.txt" do
|
||||
it 'returns the expected version' do
|
||||
@file = "#{file}.txt"
|
||||
@expected = [changelog_section(version_number)]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
46
spec/app/finders/plugin_version_spec.rb
Normal file
46
spec/app/finders/plugin_version_spec.rb
Normal file
@@ -0,0 +1,46 @@
|
||||
require 'spec_helper'
|
||||
|
||||
# If this file is tested alone (rspec path-to-this-file), then there will be an error about
|
||||
# constants not being intilialized. This is due to the Dynamic Finders.
|
||||
|
||||
describe WPScan::Finders::PluginVersion::Base do
|
||||
subject(:plugin_version) { described_class.new(plugin) }
|
||||
let(:plugin) { WPScan::Plugin.new(slug, target) }
|
||||
let(:target) { WPScan::Target.new('http://wp.lab/') }
|
||||
let(:default_finders) { %w[Readme] }
|
||||
|
||||
describe '#finders' do
|
||||
after do
|
||||
expect(target).to receive(:content_dir).and_return('wp-content')
|
||||
expect(plugin_version.finders.map { |f| f.class.to_s.demodulize }).to match_array @expected
|
||||
end
|
||||
|
||||
context 'when no related specific finders' do
|
||||
let(:slug) { 'spec' }
|
||||
|
||||
it 'contains the default finders' do
|
||||
@expected = default_finders
|
||||
end
|
||||
end
|
||||
|
||||
# Dynamic Version Finders are not tested here, they are in
|
||||
# spec/lib/finders/dynamic_finder/plugin_versions_spec
|
||||
context 'when specific finders' do
|
||||
let(:specific) do
|
||||
{
|
||||
# None so far
|
||||
}
|
||||
end
|
||||
|
||||
WPScan::DB::DynamicFinders::Plugin.versions_finders_configs.each do |plugin_slug, configs|
|
||||
context "when #{plugin_slug} plugin" do
|
||||
let(:slug) { plugin_slug }
|
||||
|
||||
it 'contains the expected finders (default + specific + the dynamic ones)' do
|
||||
@expected = default_finders + [*specific[plugin_slug]] + configs.keys
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
13
spec/app/finders/plugins/body_pattern_spec.rb
Normal file
13
spec/app/finders/plugins/body_pattern_spec.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Plugins::BodyPattern do
|
||||
it_behaves_like WPScan::Finders::DynamicFinder::WpItems::Finder do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://wp.lab/' }
|
||||
let(:fixtures) { File.join(DYNAMIC_FINDERS_FIXTURES, 'plugin_version') }
|
||||
|
||||
let(:expected_all) { df_expected_all['plugins'] }
|
||||
let(:item_class) { WPScan::Plugin }
|
||||
end
|
||||
end
|
||||
13
spec/app/finders/plugins/comment_spec.rb
Normal file
13
spec/app/finders/plugins/comment_spec.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Plugins::Comment do
|
||||
it_behaves_like WPScan::Finders::DynamicFinder::WpItems::Finder do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://wp.lab/' }
|
||||
let(:fixtures) { File.join(DYNAMIC_FINDERS_FIXTURES, 'plugin_version') }
|
||||
|
||||
let(:expected_all) { df_expected_all['plugins'] }
|
||||
let(:item_class) { WPScan::Plugin }
|
||||
end
|
||||
end
|
||||
15
spec/app/finders/plugins/config_parser_spec.rb
Normal file
15
spec/app/finders/plugins/config_parser_spec.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Plugins::ConfigParser do
|
||||
xit
|
||||
|
||||
# it_behaves_like WPScan::Finders::DynamicFinder::WpItems::Finder do
|
||||
# subject(:finder) { described_class.new(target) }
|
||||
# let(:target) { WPScan::Target.new(url) }
|
||||
# let(:url) { 'http://wp.lab/' }
|
||||
# let(:fixtures) { File.join(DYNAMIC_FINDERS_FIXTURES, 'plugin_version') }
|
||||
#
|
||||
# let(:expected_all) { df_expected_all['plugins'] }
|
||||
# let(:item_class) { WPScan::Plugin }
|
||||
# end
|
||||
end
|
||||
45
spec/app/finders/plugins/header_pattern_spec.rb
Normal file
45
spec/app/finders/plugins/header_pattern_spec.rb
Normal file
@@ -0,0 +1,45 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Plugins::HeaderPattern do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://wp.lab/' }
|
||||
let(:fixtures) { File.join(DYNAMIC_FINDERS_FIXTURES, 'plugin_version') }
|
||||
|
||||
def plugin(slug)
|
||||
WPScan::Plugin.new(slug, target)
|
||||
end
|
||||
|
||||
describe '#passive' do
|
||||
after do
|
||||
stub_request(:get, target.url).to_return(headers: headers)
|
||||
|
||||
found = finder.passive
|
||||
|
||||
expect(found).to match_array @expected
|
||||
expect(found.first.found_by).to eql 'Header Pattern (Passive Detection)' unless found.empty?
|
||||
end
|
||||
|
||||
context 'when empty headers' do
|
||||
let(:headers) { {} }
|
||||
|
||||
it 'returns an empty array' do
|
||||
@expected = []
|
||||
end
|
||||
end
|
||||
|
||||
context 'when headers' do
|
||||
before { expect(target).to receive(:content_dir).and_return('wp-content') }
|
||||
|
||||
let(:headers) { JSON.parse(File.read(File.join(fixtures, 'header_pattern_passive_all.html'))) }
|
||||
|
||||
it 'returns the expected plugins' do
|
||||
@expected = []
|
||||
|
||||
WPScan::DB::DynamicFinders::Plugin.passive_header_pattern_finder_configs.each_key do |slug|
|
||||
@expected << plugin(slug)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
13
spec/app/finders/plugins/javascript_var_spec.rb
Normal file
13
spec/app/finders/plugins/javascript_var_spec.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Plugins::JavascriptVar do
|
||||
it_behaves_like WPScan::Finders::DynamicFinder::WpItems::Finder do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://wp.lab/' }
|
||||
let(:fixtures) { File.join(DYNAMIC_FINDERS_FIXTURES, 'plugin_version') }
|
||||
|
||||
let(:expected_all) { df_expected_all['plugins'] }
|
||||
let(:item_class) { WPScan::Plugin }
|
||||
end
|
||||
end
|
||||
12
spec/app/finders/plugins/known_locations_spec.rb
Normal file
12
spec/app/finders/plugins/known_locations_spec.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Plugins::KnownLocations do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'plugins', 'known_locations') }
|
||||
|
||||
describe '#aggressive' do
|
||||
xit
|
||||
end
|
||||
end
|
||||
16
spec/app/finders/plugins/query_parameter_spec.rb
Normal file
16
spec/app/finders/plugins/query_parameter_spec.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Plugins::QueryParameter do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://wp.lab/' }
|
||||
let(:fixtures) { File.join(DYNAMIC_FINDERS_FIXTURES, 'plugin_version') }
|
||||
|
||||
describe '#passive' do
|
||||
its(:passive) { should be nil }
|
||||
end
|
||||
|
||||
describe '#aggressive' do
|
||||
xit
|
||||
end
|
||||
end
|
||||
27
spec/app/finders/plugins/urls_in_homepage_spec.rb
Normal file
27
spec/app/finders/plugins/urls_in_homepage_spec.rb
Normal file
@@ -0,0 +1,27 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Plugins::UrlsInHomepage do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://wp.lab/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'plugins', 'urls_in_homepage') }
|
||||
|
||||
it_behaves_like 'App::Finders::WpItems::URLsInHomepage' do
|
||||
let(:type) { 'plugins' }
|
||||
let(:uniq_links) { true }
|
||||
let(:uniq_codes) { true }
|
||||
let(:expected_from_links) { (1..4).map { |i| "dl-#{i}" } }
|
||||
let(:expected_from_codes) { (1..6).map { |i| "dc-#{i}" } }
|
||||
end
|
||||
|
||||
describe '#passive' do
|
||||
before do
|
||||
stub_request(:get, finder.target.url)
|
||||
.to_return(body: File.read(File.join(fixtures, 'found.html')))
|
||||
|
||||
expect(finder.target).to receive(:content_dir).at_least(1).and_return('wp-content')
|
||||
end
|
||||
|
||||
xit
|
||||
end
|
||||
end
|
||||
13
spec/app/finders/plugins/xpath_spec.rb
Normal file
13
spec/app/finders/plugins/xpath_spec.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Plugins::Xpath do
|
||||
it_behaves_like WPScan::Finders::DynamicFinder::WpItems::Finder do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://wp.lab/' }
|
||||
let(:fixtures) { File.join(DYNAMIC_FINDERS_FIXTURES, 'plugin_version') }
|
||||
|
||||
let(:expected_all) { df_expected_all['plugins'] }
|
||||
let(:item_class) { WPScan::Plugin }
|
||||
end
|
||||
end
|
||||
14
spec/app/finders/plugins_spec.rb
Normal file
14
spec/app/finders/plugins_spec.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Plugins::Base do
|
||||
subject(:plugins) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
|
||||
describe '#finders' do
|
||||
it 'contains the expected finders' do
|
||||
expect(plugins.finders.map { |f| f.class.to_s.demodulize })
|
||||
.to eq %w[UrlsInHomepage HeaderPattern Comment Xpath BodyPattern JavascriptVar KnownLocations]
|
||||
end
|
||||
end
|
||||
end
|
||||
98
spec/app/finders/theme_version/style_spec.rb
Normal file
98
spec/app/finders/theme_version/style_spec.rb
Normal file
@@ -0,0 +1,98 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::ThemeVersion::Style do
|
||||
subject(:finder) { described_class.new(theme) }
|
||||
let(:theme) { WPScan::Theme.new('spec', target) }
|
||||
let(:target) { WPScan::Target.new('http://wp.lab/') }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'theme_version', 'style') }
|
||||
|
||||
before :all do
|
||||
Typhoeus::Config.cache = WPScan::Cache::Typhoeus.new(File.join(SPECS, 'cache'))
|
||||
end
|
||||
|
||||
before do
|
||||
expect(target).to receive(:content_dir).at_least(1).and_return('wp-content')
|
||||
stub_request(:get, /.*.css/).and_return(body: defined?(style_body) ? style_body : '')
|
||||
end
|
||||
|
||||
describe '#passive' do
|
||||
before { expect(finder).to receive(:cached_style?).and_return(cached?) }
|
||||
after { finder.passive }
|
||||
|
||||
context 'when the style_url request has been cached' do
|
||||
let(:cached?) { true }
|
||||
|
||||
it 'calls the style_version' do
|
||||
expect(finder).to receive(:style_version)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the style_url request has not been cached' do
|
||||
let(:cached?) { false }
|
||||
|
||||
it 'returns nil' do
|
||||
expect(finder).to_not receive(:style_version)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#aggressive' do
|
||||
before { expect(finder).to receive(:cached_style?).and_return(cached?) }
|
||||
after { finder.aggressive }
|
||||
|
||||
context 'when the style_url request has been cached' do
|
||||
let(:cached?) { true }
|
||||
|
||||
it 'returns nil' do
|
||||
expect(finder).to_not receive(:style_version)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the style_url request has not been cached' do
|
||||
let(:cached?) { false }
|
||||
|
||||
it 'calls the style_version' do
|
||||
expect(finder).to receive(:style_version)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#cached_style?' do
|
||||
it 'calls the Cache with the correct arguments' do
|
||||
expected = Typhoeus::Request.new(
|
||||
theme.style_url,
|
||||
finder.browser.default_request_params.merge(method: :get)
|
||||
)
|
||||
|
||||
expect(Typhoeus::Config.cache).to receive(:get) { |arg| expect(arg).to eql expected }
|
||||
finder.cached_style?
|
||||
end
|
||||
end
|
||||
|
||||
describe '#style_version' do
|
||||
{
|
||||
'inline' => '1.5.1',
|
||||
'firefart' => '1.0.0',
|
||||
'tralling_quote' => '1.3',
|
||||
'no_version_tag' => nil,
|
||||
'trunk_version' => nil,
|
||||
'no_version' => nil
|
||||
}.each do |file, expected_version|
|
||||
context "when #{file}" do
|
||||
let(:style_body) { File.new(File.join(fixtures, "#{file}.css")) }
|
||||
|
||||
it 'returns the expected version' do
|
||||
expected = if expected_version
|
||||
WPScan::Version.new(
|
||||
expected_version,
|
||||
confidence: 80,
|
||||
interesting_entries: ["#{theme.style_url}, Version: #{expected_version}"]
|
||||
)
|
||||
end
|
||||
|
||||
expect(finder.style_version).to eql expected
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,41 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::ThemeVersion::WooFrameworkMetaGenerator do
|
||||
subject(:finder) { described_class.new(theme) }
|
||||
let(:theme) { WPScan::Theme.new(slug, target) }
|
||||
let(:target) { WPScan::Target.new('http://wp.lab/') }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'theme_version', 'woo_framework_meta_generator') }
|
||||
|
||||
before do
|
||||
expect(target).to receive(:content_dir).and_return('wp-content')
|
||||
stub_request(:get, /\.css\z/)
|
||||
end
|
||||
|
||||
describe '#passive' do
|
||||
after do
|
||||
stub_request(:get, target.url).to_return(body: File.read(File.join(fixtures, 'editorial-1.3.5.html')))
|
||||
|
||||
expect(finder.passive).to eql @expected
|
||||
end
|
||||
|
||||
context 'when the theme slug does not match' do
|
||||
let(:slug) { 'spec' }
|
||||
|
||||
it 'returns nil' do
|
||||
@expected = nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the theme slug matches' do
|
||||
let(:slug) { 'Editorial' }
|
||||
|
||||
it 'return the expected version' do
|
||||
@expected = WPScan::Version.new(
|
||||
'1.3.5',
|
||||
found_by: 'Woo Framework Meta Generator (Passive Detection)',
|
||||
confidence: 80
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
35
spec/app/finders/theme_version_spec.rb
Normal file
35
spec/app/finders/theme_version_spec.rb
Normal file
@@ -0,0 +1,35 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::ThemeVersion::Base do
|
||||
subject(:theme_version) { described_class.new(theme) }
|
||||
let(:theme) { WPScan::Plugin.new(slug, target) }
|
||||
let(:target) { WPScan::Target.new('http://wp.lab/') }
|
||||
let(:slug) { 'spec' }
|
||||
let(:default_finders) { %w[Style WooFrameworkMetaGenerator] }
|
||||
|
||||
describe '#finders' do
|
||||
after do
|
||||
expect(target).to receive(:content_dir).and_return('wp-content')
|
||||
expect(theme_version.finders.map { |f| f.class.to_s.demodulize }).to eql @expected
|
||||
end
|
||||
|
||||
context 'when no related specific finders' do
|
||||
it 'contains the default finders' do
|
||||
@expected = default_finders
|
||||
end
|
||||
end
|
||||
|
||||
context 'when specific finders' do
|
||||
{
|
||||
}.each do |theme_slug, specific_finders|
|
||||
context "when #{theme_slug} theme" do
|
||||
let(:slug) { theme_slug }
|
||||
|
||||
it 'contains the expected finders' do
|
||||
@expected = default_finders + specific_finders
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
12
spec/app/finders/themes/known_locations_spec.rb
Normal file
12
spec/app/finders/themes/known_locations_spec.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Themes::KnownLocations do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'themes', 'known_locations') }
|
||||
|
||||
describe '#aggressive' do
|
||||
xit
|
||||
end
|
||||
end
|
||||
20
spec/app/finders/themes/urls_in_homepage_spec.rb
Normal file
20
spec/app/finders/themes/urls_in_homepage_spec.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Themes::UrlsInHomepage do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://wp.lab/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'themes', 'urls_in_homepage') }
|
||||
|
||||
it_behaves_like 'App::Finders::WpItems::URLsInHomepage' do
|
||||
let(:type) { 'themes' }
|
||||
let(:uniq_links) { true }
|
||||
let(:uniq_codes) { true }
|
||||
let(:expected_from_links) { %w[dl-1] }
|
||||
let(:expected_from_codes) { %w[dc-1] }
|
||||
end
|
||||
|
||||
describe '#passive' do
|
||||
xit
|
||||
end
|
||||
end
|
||||
14
spec/app/finders/themes_spec.rb
Normal file
14
spec/app/finders/themes_spec.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Themes::Base do
|
||||
subject(:themes) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
|
||||
describe '#finders' do
|
||||
it 'contains the expected finders' do
|
||||
expect(themes.finders.map { |f| f.class.to_s.demodulize })
|
||||
.to eq %w[UrlsInHomepage KnownLocations]
|
||||
end
|
||||
end
|
||||
end
|
||||
36
spec/app/finders/timthumb_version/bad_request_spec.rb
Normal file
36
spec/app/finders/timthumb_version/bad_request_spec.rb
Normal file
@@ -0,0 +1,36 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::TimthumbVersion::BadRequest do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Timthumb.new(url) }
|
||||
let(:url) { 'http://ex.lo/timthumb.php' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'timthumb_version', 'bad_request') }
|
||||
|
||||
describe '#aggressive' do
|
||||
before { stub_request(:get, url).to_return(body: File.read(File.join(fixtures, file))) }
|
||||
after { expect(finder.aggressive).to eql @expected }
|
||||
|
||||
context 'when no version' do
|
||||
let(:file) { 'no_version.php' }
|
||||
|
||||
it 'returns nil' do
|
||||
@expected = nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a version' do
|
||||
let(:file) { '2.8.14.php' }
|
||||
|
||||
it 'returns the expected version' do
|
||||
@expected = WPScan::Version.new(
|
||||
'2.8.14',
|
||||
confidence: 90,
|
||||
found_by: 'Bad Request (Aggressive Detection)',
|
||||
interesting_entries: [
|
||||
"#{url}, TimThumb version : 2.8.14"
|
||||
]
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
13
spec/app/finders/timthumb_version_spec.rb
Normal file
13
spec/app/finders/timthumb_version_spec.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::TimthumbVersion::Base do
|
||||
subject(:timthumb_version) { described_class.new(target) }
|
||||
let(:target) { WPScan::Timthumb.new(url) }
|
||||
let(:url) { 'http://ex.lo/timthumb.php' }
|
||||
|
||||
describe '#finders' do
|
||||
it 'contains the expected finders' do
|
||||
expect(timthumb_version.finders.map { |f| f.class.to_s.demodulize }).to eq %w[BadRequest]
|
||||
end
|
||||
end
|
||||
end
|
||||
12
spec/app/finders/timthumbs/known_locations_spec.rb
Normal file
12
spec/app/finders/timthumbs/known_locations_spec.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Timthumbs::KnownLocations do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'timthumbs', 'known_locations') }
|
||||
|
||||
describe '#aggressive' do
|
||||
xit
|
||||
end
|
||||
end
|
||||
13
spec/app/finders/timthumbs_spec.rb
Normal file
13
spec/app/finders/timthumbs_spec.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Timthumbs::Base do
|
||||
subject(:timthumb) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
|
||||
describe '#finders' do
|
||||
it 'contains the expected finders' do
|
||||
expect(timthumb.finders.map { |f| f.class.to_s.demodulize }).to eq %w[KnownLocations]
|
||||
end
|
||||
end
|
||||
end
|
||||
62
spec/app/finders/users/author_id_brute_forcing_spec.rb
Normal file
62
spec/app/finders/users/author_id_brute_forcing_spec.rb
Normal file
@@ -0,0 +1,62 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Users::AuthorIdBruteForcing do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://wp.lab/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'users', 'author_id_brute_forcing') }
|
||||
|
||||
describe '#aggressive' do
|
||||
xit
|
||||
end
|
||||
|
||||
describe '#target_urls' do
|
||||
it 'returns the correct URLs' do
|
||||
expect(finder.target_urls(range: (1..2))).to eql(
|
||||
url + '?author=1' => 1,
|
||||
url + '?author=2' => 2
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#potential_username' do
|
||||
[
|
||||
'4.1.1', '4.1.1-permalink',
|
||||
'3.0', '3.0-permalink',
|
||||
'2.9.2', '2.9.2-permalink'
|
||||
].each do |file|
|
||||
it "returns 'admin' from #{file}.html" do
|
||||
body = File.read(File.join(fixtures, "#{file}.html"))
|
||||
res = Typhoeus::Response.new(body: body)
|
||||
|
||||
expect(finder.username_from_response(res)).to eql 'admin'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#display_name_from_body' do
|
||||
context 'when display name' do
|
||||
[
|
||||
'4.1.1', '4.1.1-permalink',
|
||||
'3.0', '3.0-permalink',
|
||||
'2.9.2', '2.9.2-permalink'
|
||||
].each do |file|
|
||||
it "returns 'admin display_name' from #{file}.html" do
|
||||
body = File.read(File.join(fixtures, "#{file}.html"))
|
||||
|
||||
expect(finder.display_name_from_body(body)).to eql 'admin display_name'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no display_name' do
|
||||
['4.1.1', '3.0', '2.9.2'].each do |file|
|
||||
it "returns nil for #{file}-empty.html" do
|
||||
body = File.read(File.join(fixtures, "#{file}-empty.html"))
|
||||
|
||||
expect(finder.display_name_from_body(body)).to eql nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
27
spec/app/finders/users/author_posts_spec.rb
Normal file
27
spec/app/finders/users/author_posts_spec.rb
Normal file
@@ -0,0 +1,27 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Users::AuthorPosts do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://wp.lab/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'users', 'author_posts') }
|
||||
|
||||
describe '#passive' do
|
||||
xit
|
||||
end
|
||||
|
||||
describe '#potential_usernames' do
|
||||
it 'returns the expected usernames' do
|
||||
res = Typhoeus::Response.new(body: File.read(File.join(fixtures, 'potential_usernames.html')))
|
||||
|
||||
results = finder.potential_usernames(res)
|
||||
|
||||
expect(results).to eql([
|
||||
['admin', 'Author Pattern', 100],
|
||||
['admin display_name', 'Display Name', 30],
|
||||
['editor', 'Author Pattern', 100],
|
||||
['editor', 'Display Name', 30]
|
||||
])
|
||||
end
|
||||
end
|
||||
end
|
||||
32
spec/app/finders/users/login_error_messages_spec.rb
Normal file
32
spec/app/finders/users/login_error_messages_spec.rb
Normal file
@@ -0,0 +1,32 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Users::LoginErrorMessages do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://wp.lab/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'users', 'login_error_messages') }
|
||||
|
||||
describe '#aggressive' do
|
||||
xit
|
||||
end
|
||||
|
||||
describe '#usernames' do
|
||||
let(:opts) { { found: [] } }
|
||||
|
||||
after { expect(subject.usernames(opts)).to eql @expected }
|
||||
|
||||
context 'when no :list provided' do
|
||||
it 'returns an empty list' do
|
||||
@expected = []
|
||||
end
|
||||
end
|
||||
|
||||
context 'when :list provided' do
|
||||
let(:opts) { super().merge(list: %w[u1 u2]) }
|
||||
|
||||
it 'returns the expected array' do
|
||||
@expected = opts[:list]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
12
spec/app/finders/users/oembed_api_spec.rb
Normal file
12
spec/app/finders/users/oembed_api_spec.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Users::OembedApi do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://wp.lab/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'users', 'oembed_api') }
|
||||
|
||||
describe '#aggressive' do
|
||||
xit
|
||||
end
|
||||
end
|
||||
102
spec/app/finders/users/rss_generator_spec.rb
Normal file
102
spec/app/finders/users/rss_generator_spec.rb
Normal file
@@ -0,0 +1,102 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Users::RSSGenerator do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { Pathname.new(FINDERS_FIXTURES).join('users', 'rss_generator') }
|
||||
let(:rss_fixture) { File.read(fixtures.join('feed.xml')) }
|
||||
|
||||
describe '#passive, #aggressive' do
|
||||
before do
|
||||
allow(target).to receive(:sub_dir).and_return(false)
|
||||
|
||||
stub_request(:get, target.url).to_return(body: File.read(homepage_fixture))
|
||||
end
|
||||
|
||||
context 'when no RSS link in homepage' do
|
||||
let(:homepage_fixture) { fixtures.join('homepage_no_links.html') }
|
||||
|
||||
its(:passive) { should eql [] }
|
||||
|
||||
it 'returns the expected from #aggressive' do
|
||||
stub_request(:get, target.url('feed/')).to_return(body: rss_fixture)
|
||||
stub_request(:get, target.url('comments/feed/'))
|
||||
stub_request(:get, target.url('feed/rss/'))
|
||||
stub_request(:get, target.url('feed/rss2/'))
|
||||
|
||||
expect(finder.aggressive).to eql [
|
||||
CMSScanner::User.new(
|
||||
'admin',
|
||||
confidence: 50,
|
||||
found_by: 'Rss Generator (Aggressive Detection)'
|
||||
),
|
||||
CMSScanner::User.new(
|
||||
'Aa Días-Gildés',
|
||||
confidence: 50,
|
||||
found_by: 'Rss Generator (Aggressive Detection)'
|
||||
)
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
context 'when RSS link in homepage' do
|
||||
let(:homepage_fixture) { File.join(fixtures, 'homepage_links.html') }
|
||||
|
||||
it 'returns the expected from #passive' do
|
||||
stub_request(:get, target.url('feed/')).to_return(body: rss_fixture)
|
||||
|
||||
expect(finder.passive).to eql [
|
||||
CMSScanner::User.new(
|
||||
'admin',
|
||||
confidence: 50,
|
||||
found_by: 'Rss Generator (Passive Detection)'
|
||||
),
|
||||
CMSScanner::User.new(
|
||||
'Aa Días-Gildés',
|
||||
confidence: 50,
|
||||
found_by: 'Rss Generator (Passive Detection)'
|
||||
)
|
||||
]
|
||||
end
|
||||
|
||||
context 'when :mixed mode' do
|
||||
it 'avoids checking existing URL/s from #passive' do
|
||||
stub_request(:get, target.url('comments/feed/')).to_return(body: rss_fixture)
|
||||
|
||||
expect(finder.aggressive(mode: :mixed)).to eql [
|
||||
CMSScanner::User.new(
|
||||
'admin',
|
||||
confidence: 50,
|
||||
found_by: 'Rss Generator (Aggressive Detection)'
|
||||
),
|
||||
CMSScanner::User.new(
|
||||
'Aa Días-Gildés',
|
||||
confidence: 50,
|
||||
found_by: 'Rss Generator (Aggressive Detection)'
|
||||
)
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no mode' do
|
||||
it 'checks the first URL detected from the URLs' do
|
||||
stub_request(:get, target.url('feed/')).to_return(body: rss_fixture)
|
||||
|
||||
expect(finder.aggressive).to eql [
|
||||
CMSScanner::User.new(
|
||||
'admin',
|
||||
confidence: 50,
|
||||
found_by: 'Rss Generator (Aggressive Detection)'
|
||||
),
|
||||
CMSScanner::User.new(
|
||||
'Aa Días-Gildés',
|
||||
confidence: 50,
|
||||
found_by: 'Rss Generator (Aggressive Detection)'
|
||||
)
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
47
spec/app/finders/users/wp_json_api_spec.rb
Normal file
47
spec/app/finders/users/wp_json_api_spec.rb
Normal file
@@ -0,0 +1,47 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Users::WpJsonApi do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://wp.lab/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'users', 'wp_json_api') }
|
||||
|
||||
describe '#aggressive' do
|
||||
before do
|
||||
# allow(target).to receive(:content_dir).and_return('wp-content')
|
||||
allow(target).to receive(:sub_dir).and_return(false)
|
||||
stub_request(:get, finder.api_url).to_return(body: body)
|
||||
end
|
||||
|
||||
context 'when not a JSON response' do
|
||||
let(:body) { '' }
|
||||
|
||||
its(:aggressive) { should eql([]) }
|
||||
end
|
||||
|
||||
context 'when a JSON response' do
|
||||
context 'when unauthorised' do
|
||||
let(:body) { File.read(File.join(fixtures, '401.json')) }
|
||||
|
||||
its(:aggressive) { should eql([]) }
|
||||
end
|
||||
|
||||
context 'when limited exposure (WP >= 4.7.1)' do
|
||||
let(:body) { File.read(File.join(fixtures, '4.7.2.json')) }
|
||||
|
||||
it 'returns the expected array of users' do
|
||||
users = finder.aggressive
|
||||
|
||||
expect(users.size).to eql 1
|
||||
|
||||
user = users.first
|
||||
|
||||
expect(user.id).to eql 1
|
||||
expect(user.username).to eql 'admin'
|
||||
expect(user.confidence).to eql 100
|
||||
expect(user.interesting_entries).to eql ['http://wp.lab/wp-json/wp/v2/users/']
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
14
spec/app/finders/users_spec.rb
Normal file
14
spec/app/finders/users_spec.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::Users::Base do
|
||||
subject(:user) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
|
||||
describe '#finders' do
|
||||
it 'contains the expected finders' do
|
||||
expect(user.finders.map { |f| f.class.to_s.demodulize })
|
||||
.to eq %w[AuthorPosts WpJsonApi OembedApi RSSGenerator AuthorIdBruteForcing LoginErrorMessages]
|
||||
end
|
||||
end
|
||||
end
|
||||
97
spec/app/finders/wp_version/atom_generator_spec.rb
Normal file
97
spec/app/finders/wp_version/atom_generator_spec.rb
Normal file
@@ -0,0 +1,97 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::WpVersion::AtomGenerator do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { Pathname.new(FINDERS_FIXTURES).join('wp_version', 'atom_generator') }
|
||||
let(:atom_fixture) { File.read(fixtures.join('feed', 'atom')) }
|
||||
|
||||
describe '#passive, #aggressive' do
|
||||
before do
|
||||
allow(target).to receive(:sub_dir).and_return(false)
|
||||
|
||||
stub_request(:get, target.url).to_return(body: File.read(homepage_fixture))
|
||||
end
|
||||
|
||||
context 'when no atom links in homepage' do
|
||||
let(:homepage_fixture) { fixtures.join('no_links.html') }
|
||||
|
||||
its(:passive) { should eql [] }
|
||||
|
||||
it 'returns the expected from #aggressive' do
|
||||
stub_request(:get, target.url('feed/atom/')).to_return(body: atom_fixture)
|
||||
stub_request(:get, target.url('?feed=atom'))
|
||||
|
||||
expect(finder.aggressive).to eql [
|
||||
WPScan::WpVersion.new(
|
||||
'4.0',
|
||||
confidence: 80,
|
||||
found_by: 'Atom Generator (Aggressive Detection)',
|
||||
interesting_entries: [
|
||||
"#{target.url('feed/atom/')}, Match: '<generator uri=\"https://wordpress.org/\" version=\"4.0\">" \
|
||||
"WordPress</generator>'"
|
||||
]
|
||||
)
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
context 'when atom links in homepage' do
|
||||
let(:homepage_fixture) { File.join(fixtures, 'links.html') }
|
||||
|
||||
it 'returns the expected from #passive' do
|
||||
stub_request(:get, target.url('?feed=atom')).to_return(body: atom_fixture)
|
||||
|
||||
expect(finder.passive).to eql [
|
||||
WPScan::WpVersion.new(
|
||||
'4.0',
|
||||
confidence: 80,
|
||||
found_by: 'Atom Generator (Passive Detection)',
|
||||
interesting_entries: [
|
||||
"#{target.url('?feed=atom')}, Match: '<generator uri=\"https://wordpress.org/\" version=\"4.0\">" \
|
||||
"WordPress</generator>'"
|
||||
]
|
||||
)
|
||||
]
|
||||
end
|
||||
|
||||
context 'when :mixed mode' do
|
||||
it 'avoids checking existing URL/s from #passive' do
|
||||
stub_request(:get, target.url('feed/atom/')).to_return(body: atom_fixture)
|
||||
|
||||
expect(finder.aggressive(mode: :mixed)).to eql [
|
||||
WPScan::WpVersion.new(
|
||||
'4.0',
|
||||
confidence: 80,
|
||||
found_by: 'Atom Generator (Aggressive Detection)',
|
||||
interesting_entries: [
|
||||
"#{target.url('feed/atom/')}, Match: '<generator uri=\"https://wordpress.org/\" version=\"4.0\">" \
|
||||
"WordPress</generator>'"
|
||||
]
|
||||
)
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no mode' do
|
||||
it 'checks all the URLs' do
|
||||
stub_request(:get, target.url('feed/atom/')).to_return(body: atom_fixture)
|
||||
stub_request(:get, target.url('?feed=atom'))
|
||||
|
||||
expect(finder.aggressive).to eql [
|
||||
WPScan::WpVersion.new(
|
||||
'4.0',
|
||||
confidence: 80,
|
||||
found_by: 'Atom Generator (Aggressive Detection)',
|
||||
interesting_entries: [
|
||||
"#{target.url('feed/atom/')}, Match: '<generator uri=\"https://wordpress.org/\" version=\"4.0\">" \
|
||||
"WordPress</generator>'"
|
||||
]
|
||||
)
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
10
spec/app/finders/wp_version/rdf_generator_spec.rb
Normal file
10
spec/app/finders/wp_version/rdf_generator_spec.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::WpVersion::RDFGenerator do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'wp_version', 'rdf_generator') }
|
||||
|
||||
xit
|
||||
end
|
||||
49
spec/app/finders/wp_version/readme_spec.rb
Normal file
49
spec/app/finders/wp_version/readme_spec.rb
Normal file
@@ -0,0 +1,49 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::WpVersion::Readme do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'wp_version', 'readme') }
|
||||
let(:readme_url) { url + 'readme.html' }
|
||||
|
||||
describe '#aggressive' do
|
||||
before { stub_request(:get, readme_url).to_return(body: File.read(File.join(fixtures, file))) }
|
||||
|
||||
after do
|
||||
expect(target).to receive(:sub_dir).and_return(false)
|
||||
expect(finder.aggressive).to eql @expected
|
||||
end
|
||||
|
||||
context 'when no version' do
|
||||
let(:file) { 'no_version.html' }
|
||||
|
||||
it 'returns nil' do
|
||||
@expected = nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when invalid version number' do
|
||||
let(:file) { 'invalid.html' }
|
||||
|
||||
it 'returns nil' do
|
||||
@expected = nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when present and valid' do
|
||||
let(:file) { '4.0.html' }
|
||||
|
||||
it 'returns the expected version' do
|
||||
@expected = WPScan::WpVersion.new(
|
||||
'4.0',
|
||||
confidence: 90,
|
||||
found_by: 'Readme (Aggressive Detection)',
|
||||
interesting_entries: [
|
||||
"#{readme_url}, Match: 'Version 4.0'"
|
||||
]
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
10
spec/app/finders/wp_version/rss_generator_spec.rb
Normal file
10
spec/app/finders/wp_version/rss_generator_spec.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::WpVersion::RSSGenerator do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'wp_version', 'rss_generator') }
|
||||
|
||||
xit
|
||||
end
|
||||
10
spec/app/finders/wp_version/unique_fingerprinting_spec.rb
Normal file
10
spec/app/finders/wp_version/unique_fingerprinting_spec.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe WPScan::Finders::WpVersion::UniqueFingerprinting do
|
||||
subject(:finder) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url).extend(CMSScanner::Target::Server::Apache) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
let(:fixtures) { File.join(FINDERS_FIXTURES, 'wp_version', 'unique_fingerprinting') }
|
||||
|
||||
xit
|
||||
end
|
||||
25
spec/app/finders/wp_version_spec.rb
Normal file
25
spec/app/finders/wp_version_spec.rb
Normal file
@@ -0,0 +1,25 @@
|
||||
require 'spec_helper'
|
||||
|
||||
# If this file is tested alone (rspec path-to-this-file), then there will be an error about
|
||||
# constants not being intilialized. This is due to the Dynamic Finders.
|
||||
|
||||
describe WPScan::Finders::WpVersion::Base do
|
||||
subject(:wp_version) { described_class.new(target) }
|
||||
let(:target) { WPScan::Target.new(url) }
|
||||
let(:url) { 'http://ex.lo/' }
|
||||
|
||||
describe '#finders' do
|
||||
let(:expected) { %w[RSSGenerator AtomGenerator RDFGenerator Readme UniqueFingerprinting] }
|
||||
|
||||
let(:expected_dynamic_finders) { WPScan::DB::DynamicFinders::Wordpress.versions_finders_configs.keys }
|
||||
|
||||
it 'contains the expected finders' do
|
||||
finders = wp_version.finders.map { |f| f.class.to_s.demodulize }
|
||||
|
||||
expect(finders).to match_array expected + expected_dynamic_finders
|
||||
|
||||
expect(finders.first).to eql 'RSSGenerator'
|
||||
expect(finders.last).to eql 'UniqueFingerprinting'
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user