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

View File

@@ -0,0 +1,9 @@
require 'spec_helper'
describe WPScan::InterestingFinding do
it_behaves_like WPScan::References do
subject(:finding) { described_class.new('http://e.org/file.php', opts) }
let(:opts) { { references: references } }
let(:references) { {} }
end
end

View File

@@ -0,0 +1,10 @@
require 'spec_helper'
describe WPScan::Media do
subject(:media) { described_class.new(url) }
let(:url) { 'http://e.oeg/?attachment_id=2' }
describe '#new' do
its(:url) { should eql url }
end
end

View File

@@ -0,0 +1,192 @@
require 'spec_helper'
describe WPScan::Plugin do
subject(:plugin) { described_class.new(slug, blog, opts) }
let(:slug) { 'spec' }
let(:blog) { WPScan::Target.new('http://wp.lab/') }
let(:opts) { {} }
before { expect(blog).to receive(:content_dir).and_return('wp-content') }
describe '#new' do
its(:url) { should eql 'http://wp.lab/wp-content/plugins/spec/' }
end
describe '#version' do
after do
expect(WPScan::Finders::PluginVersion::Base).to receive(:find).with(plugin, @expected_opts)
plugin.version(version_opts)
end
let(:default_opts) { {} }
context 'when no :detection_mode' do
context 'when no :mode opt supplied' do
let(:version_opts) { { something: 'k' } }
it 'calls the finder with the correct parameters' do
@expected_opts = version_opts
end
end
context 'when :mode supplied' do
let(:version_opts) { { mode: :passive } }
it 'calls the finder with the correct parameters' do
@expected_opts = default_opts.merge(mode: :passive)
end
end
end
context 'when :detection_mode' do
let(:opts) { super().merge(mode: :passive) }
context 'when no :mode' do
let(:version_opts) { {} }
it 'calls the finder without mode' do
@expected_opts = version_opts
end
end
context 'when :mode' do
let(:version_opts) { { mode: :mixed } }
it 'calls the finder with the :mixed mode' do
@expected_opts = default_opts.merge(mode: :mixed)
end
end
end
end
describe '#latest_version, #last_updated, #popular' do
context 'when none' do
let(:slug) { 'vulnerable-not-popular' }
its(:latest_version) { should be_nil }
its(:last_updated) { should be_nil }
its(:popular?) { should be false }
end
context 'when values' do
let(:slug) { 'no-vulns-popular' }
its(:latest_version) { should eql WPScan::Version.new('2.0') }
its(:last_updated) { should eql '2015-05-16T00:00:00.000Z' }
its(:popular?) { should be true }
end
end
describe '#outdated?' do
context 'when last_version' do
let(:slug) { 'no-vulns-popular' }
context 'when no version' do
before { expect(plugin).to receive(:version).at_least(1).and_return(nil) }
its(:outdated?) { should eql false }
end
context 'when version' do
before { expect(plugin).to receive(:version).at_least(1).and_return(WPScan::Version.new(version_number)) }
context 'when version < last_version' do
let(:version_number) { '1.2' }
its(:outdated?) { should eql true }
end
context 'when version >= last_version' do
let(:version_number) { '3.0' }
its(:outdated?) { should eql false }
end
end
end
context 'when no last_version' do
let(:slug) { 'vulnerable-not-popular' }
context 'when no version' do
before { expect(plugin).to receive(:version).at_least(1).and_return(nil) }
its(:outdated?) { should eql false }
end
context 'when version' do
before { expect(plugin).to receive(:version).at_least(1).and_return(WPScan::Version.new('1.0')) }
its(:outdated?) { should eql false }
end
end
end
describe '#vulnerabilities' do
after do
expect(plugin.vulnerabilities).to eq @expected
expect(plugin.vulnerable?).to eql @expected.empty? ? false : true
end
context 'when plugin not in the DB' do
let(:slug) { 'not-in-db' }
it 'returns an empty array' do
@expected = []
end
end
context 'when in the DB' do
context 'when no vulnerabilities' do
let(:slug) { 'no-vulns-popular' }
it 'returns an empty array' do
@expected = []
end
end
context 'when vulnerabilities' do
let(:slug) { 'vulnerable-not-popular' }
let(:all_vulns) do
[
WPScan::Vulnerability.new(
'First Vuln',
{ wpvulndb: '1' },
'LFI',
'6.3.10'
),
WPScan::Vulnerability.new('No Fixed In', wpvulndb: '2')
]
end
context 'when no plugin version' do
before { expect(plugin).to receive(:version).at_least(1).and_return(false) }
it 'returns all the vulnerabilities' do
@expected = all_vulns
end
end
context 'when plugin version' do
before { expect(plugin).to receive(:version).at_least(1).and_return(WPScan::Version.new(number)) }
context 'when < to a fixed_in' do
let(:number) { '5.0' }
it 'returns it' do
@expected = all_vulns
end
end
context 'when >= to a fixed_in' do
let(:number) { '6.3.10' }
it 'does not return it ' do
@expected = [all_vulns.last]
end
end
end
end
end
end
end

View File

@@ -0,0 +1,165 @@
require 'spec_helper'
describe WPScan::Theme do
subject(:theme) { described_class.new(slug, blog, opts) }
let(:slug) { 'spec' }
let(:blog) { WPScan::Target.new('http://wp.lab/') }
let(:opts) { {} }
let(:fixtures) { File.join(FIXTURES, 'models', 'theme') }
before { expect(blog).to receive(:content_dir).at_least(1).and_return('wp-content') }
describe '#new' do
before do
stub_request(:get, /.*\.css\z/)
.to_return(body: File.read(File.join(fixtures, 'style.css')))
end
its(:url) { should eql 'http://wp.lab/wp-content/themes/spec/' }
its(:style_url) { should eql 'http://wp.lab/wp-content/themes/spec/style.css' }
its(:style_name) { should eql 'Twenty Fifteen' }
its(:style_uri) { should eql 'https://wordpress.org/themes/twentyfifteen' }
its(:author) { should eql 'the WordPress team' }
its(:author_uri) { should eql nil }
its(:template) { should eql nil }
its(:description) { should eql 'Our 2015 default theme is clean, blog-focused.' }
its(:license) { should eql 'GNU General Public License v2 or later' }
its(:license_uri) { should eql 'http://www.gnu.org/licenses/gpl-2.0.html' }
its(:tags) { should eql 'black, blue, gray, pink, purple, white, yellow.' }
its(:text_domain) { should eql 'twentyfifteen' }
context 'when opts[:style_url]' do
let(:opts) { super().merge(style_url: 'http://wp.lab/wp-content/themes/spec/custom.css') }
its(:style_url) { should eql opts[:style_url] }
end
end
describe '#version' do
after do
stub_request(:get, /.*\.css\z/)
.to_return(body: File.read(File.join(fixtures, 'style.css')))
expect(WPScan::Finders::ThemeVersion::Base).to receive(:find).with(theme, @expected_opts)
theme.version(version_opts)
end
let(:default_opts) { {} }
context 'when no :detection_mode' do
context 'when no :mode opt supplied' do
let(:version_opts) { { something: 'k' } }
it 'calls the finder with the correct parameters' do
@expected_opts = version_opts
end
end
context 'when :mode supplied' do
let(:version_opts) { { mode: :passive } }
it 'calls the finder with the correct parameters' do
@expected_opts = default_opts.merge(mode: :passive)
end
end
end
context 'when :detection_mode' do
let(:opts) { super().merge(mode: :passive) }
context 'when no :mode' do
let(:version_opts) { {} }
it 'calls the finder without mode' do
@expected_opts = version_opts
end
end
context 'when :mode' do
let(:version_opts) { { mode: :mixed } }
it 'calls the finder with the :mixed mode' do
@expected_opts = default_opts.merge(mode: :mixed)
end
end
end
end
describe '#vulnerabilities' do
xit
end
describe '#parent_theme' do
before do
stub_request(:get, blog.url('wp-content/themes/spec/style.css'))
.to_return(body: File.read(File.join(fixtures, main_theme)))
end
context 'when no template' do
let(:main_theme) { 'style.css' }
it 'returns nil' do
expect(theme.parent_theme).to eql nil
end
end
context 'when a template' do
let(:main_theme) { 'child_style.css' }
let(:parent_url) { blog.url('wp-content/themes/twentyfourteen/custom.css') }
before do
stub_request(:get, parent_url)
.to_return(body: File.read(File.join(fixtures, 'style.css')))
end
%w[child_style windows_line_endings].each do |fixture|
context "when #{fixture}" do
let(:main_theme) { "#{fixture}.css" }
it 'returns the expected theme' do
parent = theme.parent_theme
expect(parent).to eql described_class.new(
'twentyfourteen', blog,
style_url: parent_url,
confidence: 100,
found_by: 'Parent Themes (Passive Detection)'
)
expect(parent.style_url).to eql parent_url
end
end
end
end
end
describe '#parent_themes' do
xit
end
describe '#==' do
before { stub_request(:get, /.*\.css\z/) }
context 'when default style' do
it 'returns true when equal' do
expect(theme == described_class.new(slug, blog, opts)).to be true
end
it 'returns false when not equal' do
expect(theme == described_class.new(slug, blog, opts.merge(style_url: 'spec.css'))).to be false
end
end
context 'when custom style' do
let(:opts) { super().merge(style_url: 'spec.css') }
it 'returns true when equal' do
expect(theme == described_class.new(slug, blog, opts.merge(style_url: 'spec.css'))).to be true
end
it 'returns false when not equal' do
expect(theme == described_class.new(slug, blog, opts.merge(style_url: 'spec2.css'))).to be false
end
end
end
end

View File

@@ -0,0 +1,126 @@
require 'spec_helper'
describe WPScan::Timthumb do
subject(:timthumb) { described_class.new(url, opts) }
let(:url) { 'http://wp.lab/wp-content/timthumb.php' }
let(:fixtures) { File.join(FIXTURES, 'models', 'timthumb') }
let(:opts) { {} }
describe '#new' do
its(:url) { should eql url }
end
# The fact that the finders should only be called once is handled by the
# vulnerabilities, vulnerable? specs below
describe '#version' do
after do
expect(WPScan::Finders::TimthumbVersion::Base).to receive(:find).with(timthumb, @expected_opts)
timthumb.version(version_opts)
end
context 'when no :version_detection' do
context 'when no :mode opt supplied' do
let(:version_opts) { { something: 'k' } }
it 'calls the finder with the correct parameters' do
@expected_opts = version_opts
end
end
context 'when :mode supplied' do
let(:version_opts) { { mode: :passive } }
it 'calls the finder with the correct parameters' do
@expected_opts = { mode: :passive }
end
end
end
context 'when :version_detection' do
let(:opts) { super().merge(mode: :passive) }
context 'when no :mode' do
let(:version_opts) { {} }
it 'calls the finder with the :passive mode' do
@expected_opts = version_opts
end
end
context 'when :mode' do
let(:version_opts) { { mode: :mixed } }
it 'calls the finder with the :mixed mode' do
@expected_opts = { mode: :mixed }
end
end
end
end
describe '#webshot_enabled?' do
before do
stub_request(:get, /#{timthumb.url}\?src=.*&webshot=1/i)
.to_return(body: File.read(File.join(fixtures, fixture)))
end
context 'when enabled' do
let(:fixture) { '2.8.13_webshot_enabled.html' }
its(:webshot_enabled?) { should eql true }
end
context 'when disabled' do
let(:fixture) { '2.8.13_webshot_disabled.html' }
its(:webshot_enabled?) { should eql false }
end
end
describe '#vulnerabilities, #vulnerable?' do
before { expect(WPScan::Finders::TimthumbVersion::Base).to receive(:find).and_return(version) }
context 'when no version' do
let(:version) { false }
its(:vulnerabilities) { should eq([timthumb.rce_webshot_vuln, timthumb.rce_132_vuln]) }
it { should be_vulnerable }
end
context 'when version' do
let(:version) { WPScan::Version.new(version_number) }
context 'when version >= 2.8.14' do
let(:version_number) { '2.8.14' }
its(:vulnerabilities) { should eq([]) }
it { should_not be_vulnerable }
end
context 'when version < 1.33' do
let(:version_number) { '1.20' }
its(:vulnerabilities) { should eq([timthumb.rce_132_vuln]) }
it { should be_vulnerable }
end
context 'when version > 1.35 and < 2.8.13' do
let(:version_number) { '2.8.10' }
context 'when webshot enabled' do
before { expect(timthumb).to receive(:webshot_enabled?).and_return(true) }
its(:vulnerabilities) { should eq([timthumb.rce_webshot_vuln]) }
it { should be_vulnerable }
end
context 'when webshot disabled' do
before { expect(timthumb).to receive(:webshot_enabled?).and_return(false) }
its(:vulnerabilities) { should eq([]) }
it { should_not be_vulnerable }
end
end
end
end
end

View File

@@ -0,0 +1,130 @@
require 'spec_helper'
describe WPScan::WpItem do
subject(:wp_item) { described_class.new(slug, blog, opts) }
let(:slug) { 'test_item' }
let(:blog) { WPScan::Target.new(url) }
let(:url) { 'http://wp.lab/' }
let(:opts) { {} }
its(:blog) { should eql blog }
describe '#new' do
context 'when no opts' do
its(:slug) { should eql slug }
its(:detection_opts) { should eql(mode: nil) }
its(:version_detection_opts) { should eql({}) }
end
context 'when :mode' do
let(:opts) { super().merge(mode: :passive, version_detection: { mode: :aggressive }) }
its(:detection_opts) { should eql(mode: :passive) }
its(:version_detection_opts) { should eql(mode: :aggressive) }
end
context 'when the slug contains encoded chars' do
let(:slug) { 'theme%212%23a' }
its(:slug) { should eql 'theme!2#a' }
end
end
describe '#url' do
context 'when no opts[:url]' do
its(:url) { should eql nil }
end
context 'when opts[:url]' do
let(:opts) { super().merge(url: item_url) }
let(:item_url) { "#{url}item/" }
context 'when path given' do
it 'appends it' do
expect(wp_item.url('path')).to eql "#{item_url}path"
end
end
it 'encodes the path' do
expect(wp_item.url('#t#')).to eql "#{item_url}%23t%23"
expect(wp_item.url('t .txt')).to eql "#{item_url}t%20.txt"
end
end
end
describe '#==' do
context 'when the same slug' do
it 'returns true' do
other = described_class.new(slug, blog)
expect(wp_item == other).to be true
end
end
context 'when another object' do
it 'returns false' do
expect(wp_item == 'string').to be false
end
end
context 'when different slugs' do
it 'returns false' do
other = described_class.new('another', blog)
expect(wp_item == other).to be false
end
end
end
describe '#latest_version' do
# Handled in plugin_spec / theme_spec
end
describe '#popular?' do
# Handled in plugin_spec / theme_spec
end
describe '#last_updated' do
# Handled in plugin_spec / theme_spec
end
describe '#outdated?' do
# Handled in plugin_spec / theme_spec
end
describe '#to_s' do
its(:to_s) { should eql slug }
end
describe '#classify' do
its(:classify) { should eql :TestItem }
context 'when it starts with a digit' do
let(:slug) { '2test' }
its(:classify) { should eql :D_2test }
context 'when a digit and -' do
let(:slug) { '23-test' }
its(:classify) { should eql :D_23Test }
end
end
end
describe '#readme_url' do
xit
end
describe '#changelog_url' do
xit
end
describe '#directory_listing?' do
xit
end
describe '#error_log?' do
xit
end
end

View File

@@ -0,0 +1,89 @@
require 'spec_helper'
describe WPScan::WpVersion do
describe '#new' do
context 'when invalid number' do
it 'raises an error' do
expect { described_class.new('aa') }.to raise_error WPScan::InvalidWordPressVersion
end
end
context 'when valid number' do
it 'create the instance' do
version = described_class.new(4.0)
expect(version).to be_a described_class
expect(version.number).to eql '4.0'
end
end
end
describe '.all' do
it 'returns the correct values' do
expect(described_class.all).to eql %w[4.4 4.0 3.9.1 3.8.2 3.8.1 3.8]
end
end
describe '.valid?' do
after { expect(described_class.valid?(@number)).to eq @expected }
it 'returns false' do
@number = 'aaa'
@expected = false
end
it 'returns true' do
@number = '4.0'
@expected = true
end
end
describe '#vulnerabilities' do
subject(:version) { described_class.new(number) }
context 'when no vulns' do
let(:number) { '4.4' }
its(:vulnerabilities) { should eql([]) }
end
context 'when vulnerable' do
after do
expect(version.vulnerabilities).to eq @expected
expect(version).to be_vulnerable
end
context 'when a signle vuln' do
let(:number) { '3.8' }
it 'returns the expected result' do
@expected = [WPScan::Vulnerability.new(
'WP 3.8 - Vuln 1',
{ url: %w[url-4], osvdb: %w[11], wpvulndb: '3' },
'AUTHBYPASS'
)]
end
end
context 'when multiple vulns' do
let(:number) { '3.8.1' }
it 'returns the expected results' do
@expected = [
WPScan::Vulnerability.new(
'WP 3.8.1 - Vuln 1',
{ wpvulndb: '1' },
'SQLI'
),
WPScan::Vulnerability.new(
'WP 3.8.1 - Vuln 2',
{ url: %w[url-2 url-3], osvdb: %w[10], cve: %w[2014-0166], wpvulndb: '2' },
nil,
'3.8.2'
)
]
end
end
end
end
end

View File

@@ -0,0 +1,9 @@
require 'spec_helper'
describe WPScan::XMLRPC do
subject(:xml_rpc) { described_class.new('http//e.org/xmlrpc.php') }
describe '#references' do
its(:references) { should_not be_empty }
end
end