So long hombre

This commit is contained in:
Ryan Dewhurst
2018-09-26 21:00:28 +02:00
parent a25b493064
commit 4f594d59cc
283 changed files with 0 additions and 25871 deletions

View File

@@ -1,264 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
describe Browser do
it_behaves_like 'Browser::Actions'
it_behaves_like 'Browser::Options'
CONFIG_FILE_WITHOUT_PROXY = SPEC_FIXTURES_CONF_DIR + '/browser.conf.json'
CONFIG_FILE_WITH_PROXY = SPEC_FIXTURES_CONF_DIR + '/browser.conf_proxy.json'
#CONFIG_FILE_WITH_PROXY_AND_AUTH = SPEC_FIXTURES_CONF_DIR + '/browser.conf_proxy_auth.json'
subject(:browser) {
Browser.reset
Browser.instance(options)
}
let(:options) { {} }
let(:instance_vars_to_check) {
['proxy', 'max_threads', 'cache_ttl', 'request_timeout', 'connect_timeout']
}
let(:json_config_without_proxy) { JSON.parse(File.read(CONFIG_FILE_WITHOUT_PROXY)) }
let(:json_config_with_proxy) { JSON.parse(File.read(CONFIG_FILE_WITH_PROXY)) }
def check_instance_variables(browser, json_expected_vars)
json_expected_vars['max_threads'] ||= 20 # max_thread can not be nil
instance_vars_to_check.each do |variable_name|
expect(browser.send(:"#{variable_name}")).to be === json_expected_vars[variable_name]
end
end
describe 'Singleton' do
it 'should not allow #new' do
expect { Browser.new }.to raise_error
end
end
describe '::instance' do
after { check_instance_variables(browser, @json_expected_vars) }
context "when :config_file = #{CONFIG_FILE_WITH_PROXY}" do
let(:options) { { config_file: CONFIG_FILE_WITH_PROXY } }
it 'will check the instance vars' do
@json_expected_vars = json_config_with_proxy
end
end
context 'when options[:cache_dir]' do
let(:cache_dir) { CACHE_DIR + '/somewhere' }
let(:options) { { cache_dir: cache_dir } }
after { expect(subject.cache_dir).to eq cache_dir }
it 'sets @cache_dir' do
@json_expected_vars = json_config_without_proxy
end
end
end
describe '#load_config' do
context 'when config_file is a symlink' do
let(:config_file) { './rspec_symlink' }
it 'raises an error' do
File.symlink('./testfile', config_file)
expect { browser.load_config(config_file) }.to raise_error('[ERROR] Config file is a symlink.')
File.unlink(config_file)
end
end
context 'otherwise' do
after do
browser.load_config(@config_file)
check_instance_variables(browser, @expected)
end
it 'sets the correct variables' do
@config_file = CONFIG_FILE_WITH_PROXY
@expected = json_config_without_proxy.merge(json_config_with_proxy)
end
end
end
describe '::append_params_header_field' do
after :each do
expect(Browser.append_params_header_field(
@params,
@field,
@field_value
)).to be === @expected
end
context 'when there is no headers' do
it 'create the header and set the field' do
@params = { somekey: 'somevalue' }
@field = 'User-Agent'
@field_value = 'FakeOne'
@expected = { somekey: 'somevalue', headers: { 'User-Agent' => 'FakeOne' } }
end
end
context 'when there are headers' do
context 'when the field already exists' do
it 'does not replace it' do
@params = { somekey: 'somevalue', headers: { 'Location' => 'SomeLocation' } }
@field = 'Location'
@field_value = 'AnotherLocation'
@expected = @params
end
end
context 'when the field is not present' do
it 'sets the field' do
@params = { somekey: 'somevalue', headers: { 'Auth' => 'user:pass' } }
@field = 'UA'
@field_value = 'FF'
@expected = { somekey: 'somevalue', headers: { 'Auth' => 'user:pass', 'UA' => 'FF' } }
end
end
end
end
describe '#merge_request_params' do
let(:params) { {} }
let(:cookie_jar) { CACHE_DIR + '/browser/cookie-jar' }
let(:user_agent) { 'SomeUA' }
let(:default_expectation) {
{
cache_ttl: 250,
cookiejar: cookie_jar, cookiefile: cookie_jar,
timeout: 60, connecttimeout: 10,
maxredirs: 3,
referer: nil
}
}
after :each do
browser.user_agent = user_agent
browser.cache_ttl = 250
expect(browser.merge_request_params(params)).to eq @expected
expect(Typhoeus::Config.user_agent).to eq user_agent
end
it 'sets the User-Agent header field and cache_ttl' do
@expected = default_expectation
end
context 'when @user_agent' do
let(:user_agent) { 'test' }
it 'sets the User-Agent' do
@expected = default_expectation
end
end
context 'when @proxy' do
let(:proxy) { '127.0.0.1:9050' }
let(:proxy_expectation) { default_expectation.merge(proxy: proxy) }
it 'merges the proxy' do
browser.proxy = proxy
@expected = proxy_expectation
end
context 'when @proxy_auth' do
it 'sets the proxy_auth' do
browser.proxy = proxy
browser.proxy_auth = 'user:pass'
@expected = proxy_expectation.merge(proxyuserpwd: 'user:pass')
end
end
end
context 'when @request_timeout' do
it 'gives an Integer' do
browser.request_timeout = '10'
@expected = default_expectation.merge(timeout: 10)
end
end
context 'when @basic_auth' do
it 'appends the basic_auth' do
browser.basic_auth = 'user:pass'
@expected = default_expectation.merge(
headers: { 'Authorization' => 'Basic ' + Base64.encode64('user:pass').chomp }
)
end
end
context 'when the cache_ttl is alreday set' do
let(:params) { { cache_ttl: 500 } }
it 'does not override it' do
@expected = default_expectation.merge(params)
end
end
context 'when the maxredirs is alreday set' do
let(:params) { { maxredirs: 100 } }
it 'does not override it' do
@expected = default_expectation.merge(params)
end
end
context 'when @cookie' do
let(:cookie) { 'foor=bar;bar=foo' }
before { browser.cookie = cookie }
it 'sets the cookie' do
@expected = default_expectation.merge(cookie: cookie)
end
end
context 'when @disable_tls_checks' do
it 'disables tls checks' do
browser.disable_tls_checks = true
@expected = default_expectation.merge(ssl_verifypeer: 0, ssl_verifyhost: 0)
end
end
end
describe '#forge_request' do
let(:url) { 'http://example.localhost' }
it 'returns the correct Typhoeus::Request' do
allow(subject).to receive_messages(merge_request_params: { cache_ttl: 10 })
request = subject.forge_request(url)
expect(request).to be_a Typhoeus::Request
expect(request.url).to eq url
expect(request.cache_ttl).to eq 10
end
end
describe 'testing caching' do
it 'should only do 1 request, and retrieve the other one from the cache' do
url = 'http://example.localhost'
stub_request(:get, url).to_return(status: 200, body: 'Hello World !')
response1 = Browser.get(url)
response2 = Browser.get(url)
expect(response1.body).to eq response2.body
#WebMock.should have_requested(:get, url).times(1) # This one fail, dunno why :s (but it works without mock)
end
end
describe 'testing UTF8' do
it 'should not throw an encoding exception' do
url = SPEC_FIXTURES_DIR + '/utf8.html'
stub_request(:get, url).to_return(status: 200, body: File.read(url))
response = Browser.get(url)
expect { response.body }.to_not raise_error
end
end
end

View File

@@ -1,102 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
describe CacheFileStore do
let(:cache_dir) { SPEC_CACHE_DIR + '/cache_file_store' }
before :each do
Dir.delete(cache_dir) rescue nil
@cache = CacheFileStore.new(cache_dir)
end
after :each do
@cache.clean
end
describe '#storage_path' do
it 'returns the storage path given in the #new' do
expect(@cache.storage_path).to match(/#{cache_dir}/)
end
end
describe '#serializer' do
it 'should return the default serializer : Marshal' do
expect(@cache.serializer).to eq Marshal
expect(@cache.serializer).not_to eq YAML
end
end
describe '#clean' do
it "should remove all files from the cache dir (#{@cache_dir}" do
# clean is executed by other tests before
before = count_files_in_dir(@cache.cache_dir)
test_dir = File.expand_path("#{@cache.cache_dir}/test")
Dir.mkdir test_dir
#change the modification date
%x[ touch -t 200701310846.26 #{test_dir} ]
expect(count_files_in_dir(@cache.cache_dir)).to eq (before + 1)
@cache.clean
expect(count_files_in_dir(@cache.cache_dir)).to eq before
end
end
describe '#read_entry' do
after { expect(@cache.read_entry(key)).to eq @expected }
context 'when the entry does not exist' do
let(:key) { Digest::SHA1.hexdigest('hello world') }
it 'should return nil' do
@expected = nil
end
end
context 'when the file exist but is empty (marshal data too short error)' do
let(:key) { 'empty-file' }
it 'returns nil' do
File.new(File.join(@cache.storage_path, key), File::CREAT)
@expected = nil
end
end
end
describe '#write_entry, #read_entry' do
after :each do
@cache.write_entry(@key, @data, @timeout)
expect(@cache.read_entry(@key)).to be === @expected
end
it 'should get the correct entry (string)' do
@timeout = 10
@key = 'some_key'
@data = 'Hello World !'
@expected = @data
end
it 'should not write the entry' do
@timeout = 0
@key = 'another_key'
@data = 'Another Hello World !'
@expected = nil
end
## TODO write / read for an object
end
describe '#storage_dir' do
it 'should create a unique storage dir' do
storage_dirs = []
(1..5).each do |_|
storage_dirs << CacheFileStore.new(cache_dir).storage_path
end
expect(storage_dirs.uniq.size).to eq 5
end
end
end

View File

@@ -1,25 +0,0 @@
#encoding: UTF-8
require 'spec_helper'
describe WpItems do
it_behaves_like 'WpItems::Detectable' do
subject(:wp_items) { WpItems }
let(:item_class) { WpItem }
let(:fixtures_dir) { COLLECTIONS_FIXTURES + '/wp_items/detectable' }
let(:expected) do
{
request_params: { cache_ttl: 0, followlocation: true },
targets_items_from_file: [ WpItem.new(uri, name: 'item1'),
WpItem.new(uri, name: 'item-2'),
WpItem.new(uri, name: 'mr-smith')],
vulnerable_targets_items: [ WpItem.new(uri, name: 'mr-smith'),
WpItem.new(uri, name: 'neo')],
passive_detection: (1..15).reduce(WpItems.new) { |o, i| o << WpItem.new(uri, name: "detect-me-#{i}") }
}
end
end
end

View File

@@ -1,116 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
require WPSCAN_LIB_DIR + '/wp_target'
describe 'WpPlugins::Detectable' do
subject(:wp_plugins) { WpPlugins }
let(:wp_content_dir) { 'wp-content' }
let(:wp_plugins_dir) { wp_content_dir + '/plugins' }
let(:wp_target) { WpTarget.new(url, wp_content_dir: wp_content_dir, wp_plugins_dir: wp_plugins_dir) }
let(:url) { 'http://example.com/' }
let(:uri) { URI.parse(url) }
describe '::from_header' do
context 'when no header' do
it 'returns an empty WpPlugins' do
stub_request(:get, url).to_return(status: 200)
expect(subject.send(:from_header, wp_target)).to eq subject.new
end
end
context 'when headers' do
let(:headers) { { } }
let(:expected) { subject.new(wp_target) }
after :each do
stub_request(:get, url).to_return(status: 200, headers: headers, body: '')
expect(subject.send(:from_header, wp_target)).to eq expected
end
context 'when w3-total-cache detected' do
it 'returns the w3-total-cache' do
headers['X-Powered-BY'] = 'W3 Total Cache/0.9'
expected.add('w3-total-cache', version: '0.9')
end
end
context 'when wp-super-cache detected' do
it 'returns the wp-super-cache' do
headers['WP-Super-Cache'] = 'Served supercache file from PHP'
expected.add('wp-super-cache')
end
end
context 'when a header key with mutiple values' do
let(:headers) { { 'X-Powered-BY' => ['PHP/5.4.9', 'ASP.NET'] } }
context 'when no cache plugin' do
it 'returns an empty WpPlugins' do
# Handled
end
end
context 'when a cache plugin' do
it 'returns the correct plugin' do
headers['X-Powered-BY'] << 'W3 Total Cache/0.9.2.5'
expected.add('w3-total-cache', version: '0.9.2.5')
end
end
end
end
end
describe '::from_content' do
context 'when no body' do
it 'returns an empty WpPlugins' do
stub_request(:get, url).to_return(status: 200, body: '')
expect(subject.send(:from_content, wp_target)).to eq subject.new
end
end
context 'when body' do
@body = ''
let(:expected) { subject.new(wp_target) }
after :each do
stub_request(:get, url).to_return(status: 200, body: @body)
stub_request(:get, /readme\.txt/i).to_return(status: 404)
expect(subject.send(:from_content, wp_target)).to eq expected
end
context 'when w3 total cache detected' do
it 'returns the w3-total-cache' do
@body = 'w3 total cache'
expected.add('w3-total-cache')
end
end
context 'when wp-super-cache detected' do
it 'returns the wp-super-cache' do
@body = 'wp-super-cache'
expected.add('wp-super-cache')
end
end
context 'when all-in-one-seo-pack detected' do
it 'returns the all-in-one-seo-pack' do
@body = '<!-- All in One SEO Pack 2.0.3.1 by Michael Torbert of Semper Fi Web Design[300,342] -->'
expected.add('all-in-one-seo-pack', version: '2.0.3.1')
end
end
context 'when google-universal-analytics detected' do
it 'returns google-universal-analytics' do
@body = '<!-- Google Universal Analytics for WordPress v2.4.2 -->'
expected.add('google-universal-analytics', version: '2.4.2')
end
end
end
end
describe '::passive_detection' do
# TODO
end
end

View File

@@ -1,30 +0,0 @@
#encoding: UTF-8
require 'spec_helper'
describe WpPlugins do
it_behaves_like 'WpItems::Detectable' do
subject(:wp_plugins) { WpPlugins }
let(:item_class) { WpPlugin }
let(:fixtures_dir) { COLLECTIONS_FIXTURES + '/wp_plugins/detectable' }
let(:expected) do
{
request_params: { cache_ttl: 0, followlocation: true },
vulns_file: PLUGINS_FILE,
targets_items_from_file: [ WpPlugin.new(uri, name: 'plugin1'),
WpPlugin.new(uri, name:'plugin-2'),
WpPlugin.new(uri, name: 'mr-smith')],
vulnerable_targets_items: [ WpPlugin.new(uri, name: 'mr-smith'),
WpPlugin.new(uri, name: 'neo')],
passive_detection: WpPlugins.new << WpPlugin.new(uri, name: 'escaped-url') <<
WpPlugin.new(uri, name: 'link-tag') <<
WpPlugin.new(uri, name: 'script-tag') <<
WpPlugin.new(uri, name: 'style-tag') <<
WpPlugin.new(uri, name: 'style-tag-import')
}
end
end
end

View File

@@ -1,31 +0,0 @@
#encoding: UTF-8
require 'spec_helper'
describe WpThemes do
before { stub_request(:get, /.+\/style.css$/).to_return(status: 200) }
it_behaves_like 'WpItems::Detectable' do
subject(:wp_themes) { WpThemes }
let(:item_class) { WpTheme }
let(:fixtures_dir) { COLLECTIONS_FIXTURES + '/wp_themes/detectable' }
let(:expected) do
{
request_params: { cache_ttl: 0, followlocation: true },
vulns_file: THEMES_FILE,
targets_items_from_file: [ WpTheme.new(uri, name: '3colours'),
WpTheme.new(uri, name:'42k'),
WpTheme.new(uri, name: 'a-ri')],
vulnerable_targets_items: [ WpTheme.new(uri, name: 'shopperpress'),
WpTheme.new(uri, name: 'webfolio')],
passive_detection: WpThemes.new << WpTheme.new(uri, name: 'theme1') <<
WpTheme.new(uri, name: 'theme 2') <<
WpTheme.new(uri, name: 'theme-3') <<
WpTheme.new(uri, name: 'style-tag-import')
}
end
end
end

View File

@@ -1,123 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
require WPSCAN_LIB_DIR + '/wp_target'
describe 'WpTimthumbs::Detectable' do
subject(:wp_timthumbs) { WpTimthumbs }
let(:fixtures_dir) { COLLECTIONS_FIXTURES + '/wp_timthumbs/detectable' }
let(:targets_items_file) { fixtures_dir + '/targets.txt' }
let(:wp_content_dir) { 'wp-content' }
let(:wp_plugins_dir) { wp_content_dir + '/plugins' }
let(:wp_target) { WpTarget.new(url, wp_content_dir: wp_content_dir, wp_plugins_dir: wp_plugins_dir) }
let(:url) { 'http://example.com/' }
let(:uri) { URI.parse(url) }
let(:empty_file) { SPEC_FIXTURES_DIR + '/empty-file' }
let(:expected) do
{
targets_from_file: [WpTimthumb.new(uri, path: 'timthumb.php'),
WpTimthumb.new(uri, path: '$wp-content$/timthumb.php'),
WpTimthumb.new(uri, path: '$wp-plugins$/a-gallery/timthumb.php'),
WpTimthumb.new(uri, path: '$wp-content$/themes/theme-name/timthumb.php')]
}
end
def expected_targets_from_theme(theme_name)
expected = []
%w(
timthumb.php lib/timthumb.php inc/timthumb.php includes/timthumb.php
scripts/timthumb.php tools/timthumb.php functions/timthumb.php thumb.php
).each do |file|
path = "$wp-content$/themes/#{theme_name}/#{file}"
expected << WpTimthumb.new(uri, path: path)
end
expected
end
describe '::passive_detection' do
it 'returns an empty WpTimthumbs' do
expect(subject.passive_detection(wp_target)).to eq subject.new
end
end
describe '::targets_items_from_file' do
after do
targets = subject.send(:targets_items_from_file, file, wp_target)
expect(targets.map(&:url)).to eq @expected.map(&:url)
end
context 'when an empty file' do
let(:file) { empty_file }
it 'returns an empty Array' do
@expected = []
end
end
context 'when a non empty file' do
let(:file) { targets_items_file }
it 'returns the correct Array of WpTimthumb' do
@expected = expected[:targets_from_file]
end
end
end
describe '::theme_timthumbs' do
it 'returns the correct Array of WpTimthumb' do
theme = 'hello-world'
targets = subject.send(:theme_timthumbs, theme, wp_target)
expect(targets.map(&:url)).to eq expected_targets_from_theme(theme).map(&:url)
end
end
describe '::targets_items' do
let(:options) { {} }
after do
targets = subject.send(:targets_items, wp_target, options)
expect(targets.map(&:url)).to match_array(@expected.map(&:url))
end
context 'when no :theme_name' do
context 'when no :file' do
it 'returns an empty Array' do
@expected = []
end
end
context 'when :file' do
let(:options) { { file: targets_items_file } }
it 'returns the targets from the file' do
@expected = expected[:targets_from_file]
end
end
end
context 'when :theme_name' do
let(:theme) { 'theme-name' }
context 'when no :file' do
let(:options) { { theme_name: theme } }
it 'returns targets from the theme' do
@expected = expected_targets_from_theme(theme)
end
end
context 'when :file' do
let(:options) { { theme_name: theme, file: targets_items_file } }
it 'returns merged targets from theme and file' do
@expected = (expected_targets_from_theme('theme-name') + expected[:targets_from_file]).uniq { |i| i.url }
end
end
end
end
end

View File

@@ -1,59 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
require WPSCAN_LIB_DIR + '/wp_target'
describe 'WpUsers::Detectable' do
subject(:wp_users) { WpUsers }
let(:wp_content_dir) { 'wp-content' }
let(:wp_plugins_dir) { wp_content_dir + '/plugins' }
let(:wp_target) { WpTarget.new(url, wp_content_dir: wp_content_dir, wp_plugins_dir: wp_plugins_dir) }
let(:url) { 'http://example.com/' }
let(:uri) { URI.parse(url) }
def create_from_range(range)
result = []
range.each do |current_id|
result << WpUser.new(uri, id: current_id)
end
result
end
describe '::request_params' do
it 'return an empty Hash' do
expect(subject.request_params).to be === {}
end
end
describe '::passive_detection' do
it 'return an empty WpUsers' do
expect(subject.passive_detection(wp_target)).to eq subject.new
end
end
describe '::targets_items' do
after do
targets = subject.send(:targets_items, wp_target, options)
expect(targets).to eq @expected
end
context 'when no :range' do
let(:options) { {} }
it 'returns Array<WpUser> with id from 1 to 10' do
@expected = create_from_range((1..10))
end
end
context 'when :range' do
let(:options) { { range: (1..2) } }
it 'returns Array<WpUser> with id from 1 to 2' do
@expected = create_from_range((1..2))
end
end
end
end

View File

@@ -1,86 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
describe 'WpUsers::Output' do
subject(:wp_users) { WpUsers.new(0) }
let(:wp_content_dir) { 'wp-content' }
let(:wp_plugins_dir) { wp_content_dir + '/plugins' }
let(:wp_target) { WpTarget.new(url, wp_content_dir: wp_content_dir, wp_plugins_dir: wp_plugins_dir) }
let(:url) { 'http://example.com/' }
let(:uri) { URI.parse(url) }
describe '#remove_junk_from_display_names' do
it 'does not throw an exception' do
expect { subject.remove_junk_from_display_names }.to_not raise_error
end
end
describe '#remove_junk_from_display_names' do
before :each do
@input = WpUsers.new(0)
end
after :each do
subject.push(@input)
subject.flatten!
subject.remove_junk_from_display_names
expect(subject).to eq @expected
end
it 'returns an empty array' do
@expected = @input
end
it 'returns input object' do
@input.push(WpUser.new(nil))
@expected = @input
end
it 'returns input object' do
@input.push(WpUser.new(''))
@expected = @input
end
it 'should remove asdf' do
@input.push(WpUser.new('', login: '', id: 1, display_name: 'lkjh asdf'))
@input.push(WpUser.new('', login: '', id: 2, display_name: 'ijrjd asdf'))
@expected = WpUsers.new(0)
@expected.push(WpUser.new('', login: '', id: 1, display_name: 'lkjh'))
@expected.push(WpUser.new('', login: '', id: 2, display_name: 'ijrjd'))
end
it 'returns unmodified input object' do
@input.push(WpUser.new('', login: '', id: 1, display_name: 'lkjh asdfa'))
@input.push(WpUser.new('', login: '', id: 2, display_name: 'ijrjd asdf'))
@expected = @input
end
it 'returns input object' do
@input.push(WpUser.new('', login: '', id: 1, display_name: 'lkjh asdf'))
@expected = @input
end
it 'returns an empty display_name' do
@input.push(WpUser.new('', login: '', id: 1, display_name: 'lkhj asdf'))
@input.push(WpUser.new('', login: '', id: 2, display_name: 'lkhj asdf'))
@expected = WpUsers.new(0)
@expected.push(WpUser.new('', login: '', id: 1, display_name: ''))
@expected.push(WpUser.new('', login: '', id: 2, display_name: ''))
end
context 'when a user has no display_name' do
it 'returns an empty display_name' do
@input.push(WpUser.new('', login: '', id: 1, display_name: 'lkhj asdf'))
@input.push(WpUser.new('', login: '', id: 2, display_name: 'lkhj asdf'))
@input.push(WpUser.new('', login: '', id: 3))
@expected = WpUsers.new(0)
(1..3).each do |id|
@expected.push(WpUser.new('', login: '', id: id, display_name: ''))
end
end
end
end
end

View File

@@ -1,11 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
describe WpUsers do
it_behaves_like 'WpUsers::BruteForcable'
subject(:wp_users) { WpUsers.new }
let(:url) { 'http://example.com/' }
let(:uri) { URI.parse(url) }
end

View File

@@ -1,170 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
describe 'common_helper' do
describe '#get_equal_string' do
after :each do
output = get_equal_string_end(@input)
expect(output).to eq @expected
end
it 'returns an empty string' do
@input = %w()
@expected = ''
end
it 'returns an empty string' do
@input = []
@expected = ''
end
it 'returns an empty string' do
@input = ['asdf', nil]
@expected = ''
end
it 'returns an empty string' do
@input = [nil, 'asdf']
@expected = ''
end
it 'returns asdf' do
@input = [nil, 'a asdf', nil, 'b asdf']
@expected = ' asdf'
end
it 'returns asdf' do
@input = ['kjh asdf', 'oijr asdf']
@expected = ' asdf'
end
it 'returns &laquo; BlogName' do
@input = ['user1 &laquo; BlogName',
'user2 &laquo; BlogName',
'user3 &laquo; BlogName',
'user4 &laquo; BlogName']
@expected = ' &laquo; BlogName'
end
it 'returns an empty string' do
@input = %w{user1 user2 user3 user4}
@expected = ''
end
it 'returns an empty string' do
@input = ['user1 &laquo; BlogName',
'user2 &laquo; BlogName',
'user3 &laquo; BlogName',
'user4 &laquo; BlogNamea']
@expected = ''
end
it 'returns an empty string' do
@input = %w{ user1 }
@expected = ''
end
it 'returns | test' do
@input = ['admin | test', 'test | test']
@expected = ' | test'
end
end
describe '#remove_base64_images_from_html' do
after :each do
output = remove_base64_images_from_html(@html)
expect(output).to eq @expected
end
it 'removes the valid base64 image' do
@html = '<img alt="" src="data:image/x-png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAABLElEQVR42qSTQStFURSFP7f3XygyoAwoYSYMPCIpk2egMFSmUvwCRpSRDIwYGbwyVuYykB9y914m951z7nHe6J26dc9u77XXWmdvJLF7/audqx9JYuvyW92LL0li8K2df2r17CPEVk7ftXTclyQqAMmRCwC5I3fS42a4W7y74VYDNAAuJA8AaXIsSACsDgAdAJeFrnnyoMBygKZJJ3b1It0AmsTMDPdEgrujJqHEwCxqznMaD2KgyCDRnEuo8qJhHvx/hcQDbzGoix5Yi4G1TcwZWNEDKwJU+WDkhg2ToDaD+M65YcVB8jg3Y5IY5VQAyyf9gLJw+CqAuYNnAczsPQpgevtBU937kDexcdssj8Ti0ZskMd97CRs3u//U2sjJzbtwH1+/Cf8jS/gbAMmWc42HzdIjAAAAAElFTkSuQmCC" />'
@expected = '<img alt="" src="" />'
end
it 'ignores invalid base64 content' do
@html = '<img alt="" src="data:image/x-png;base64,iVBORw0KGgo" />'
@expected = @html
end
end
describe '#truncate' do
after :each do
output = truncate(@input, @length, @trailing)
expect(output).to eq @expected
end
it 'returns nil on no input' do
@input = nil
@length = 1
@expected = nil
@trailing = '...'
end
it 'returns input when length > input' do
@input = '1234567890'
@length = 13
@expected = @input
@trailing = '...'
end
it 'truncates the input' do
@input = '1234567890'
@length = 6
@expected = '123...'
@trailing = '...'
end
it 'adds own trailing' do
@input = '1234567890'
@length = 7
@expected = '123xxxx'
@trailing = 'xxxx'
end
it 'accepts strings as length' do
@input = '1234567890'
@length = '6'
@expected = '123...'
@trailing = '...'
end
it 'checks if trailing is longer than input' do
@input = '1234567890'
@length = 1
@expected = @input
@trailing = 'A' * 20
end
it 'returns input on negative length' do
@input = '1234567890'
@length = -1
@expected = @input
@trailing = '...'
end
it 'returns input on length == input.length' do
@input = '1234567890'
@length = '10'
@expected = @input
@trailing = '...'
end
it 'returns cut string on nil trailing' do
@input = '1234567890'
@length = 9
@expected = '123456789'
@trailing = nil
end
it 'trailing.length > length' do
@input = '1234567890'
@length = 1
@expected = @input
@trailing = 'A' * 20
end
end
end

View File

@@ -1,155 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
describe CustomOptionParser do
let(:parser) { CustomOptionParser.new }
describe '#new' do
end
describe '::option_to_symbol' do
after :each do
if @exception
expect { CustomOptionParser::option_to_symbol(@option) }.to raise_error(@exception)
else
expect(CustomOptionParser::option_to_symbol(@option)).to be === @expected
end
end
context 'without REQUIRED or OPTIONAL arguments' do
context 'with short option' do
it 'should return :test' do
@option = ['-t', '--test', 'Testing']
@expected = :test
end
it 'should :its_a_long_option' do
@option = ['-l', '--its-a-long-option', "Testing '-' replacement"]
@expected = :its_a_long_option
end
end
context 'without short option' do
it 'should return :long' do
@option = ['--long', "The method should find the option name ('long')"]
@expected = :long
end
it 'should return :long_option' do
@option = ['--long-option', 'No short !']
@expected = :long_option
end
end
context 'without long option' do
it 'should raise an arror' do
@option = ['-v', 'The long option is missing there']
@exception = 'Could not find the option name for ["-v", "The long option is missing there"]'
end
it 'should raise an error' do
@option = ['The long option is missing there']
@exception = 'Could not find the option name for ["The long option is missing there"]'
end
end
context 'with multiple long option names (like alias)' do
it 'should return :check_long and not :cl' do
@option = ['--check-long', '--cl']
@expected = :check_long
end
end
end
context 'with REQUIRED or OPTIONAL arguments' do
it 'should removed the OPTIONAL argument' do
@option = ['-p', '--page [PAGE_NUMBER]']
@expected = :page
end
it 'should removed the REQUIRED argument' do
@option = ['--url TARGET_URL']
@expected = :url
end
end
end
describe '#add_option' do
context 'exception throwing if' do
after :each do
expect { parser.add_option(@option) }.to raise_error(@exception)
end
it 'argument passed is not an Array' do
@option = 'a simple String'
@exception = "The option must be an array, String supplied : 'a simple String'"
end
it 'option name is already used' do
@option = ['-v', '--verbose', 'Verbose mode']
parser.add_option(@option)
@exception = 'The option verbose is already used !'
end
end
it 'should have had 2 symbols (:verbose, :url) to @symbols_used' do
parser.add_option(['-v', '--verbose'])
parser.add_option(['--url TARGET_URL'])
expect(parser.symbols_used.sort).to be === [:url, :verbose]
end
context 'parsing' do
before :each do
parser.add_option(['-u', '--url TARGET_URL', 'Set the target url'])
end
it 'should raise an error if an unknown option is supplied' do
expect { parser.parse!(['--verbose']) }.to raise_error(OptionParser::InvalidOption)
end
it 'should raise an error if an option require an argument which is not supplied' do
expect { parser.parse!(['--url']) }.to raise_error(OptionParser::MissingArgument)
end
it 'should retrieve the correct argument' do
parser.parse!(['-u', 'iam_the_target'])
expect(parser.results).to be === { url: 'iam_the_target' }
end
end
end
describe '#add' do
it 'should raise an error if the argument is not an Array or Array(Array)' do
expect { parser.add('Hello') }.to raise_error('Options must be at least an Array, or an Array(Array). String supplied')
end
before :each do
parser.add(['-u', '--url TARGET_URL'])
end
context 'single option' do
it 'should add the :url option, and retrieve the correct argument' do
expect(parser.symbols_used).to be === [:url]
expect(parser.results(['-u', 'target.com'])).to be === { url: 'target.com' }
end
end
context 'multiple options' do
it 'should add 2 options, and retrieve the correct arguments' do
parser.add([
['-v', '--verbose'],
['--test [TEST_NUMBER]']
])
expect(parser.symbols_used.sort).to be === [:test, :url, :verbose]
expect(parser.results(['-u', 'wp.com', '-v', '--test'])).to be === { test: nil, url: 'wp.com', verbose: true }
end
end
end
end

View File

@@ -1,11 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
describe Vulnerability::Output do
describe '#output' do
# How to test it ? oO
end
end

View File

@@ -1,55 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
describe Vulnerability do
describe '#new' do
subject(:vulnerability) { Vulnerability.new(title, type, references, fixed_version) }
let(:title) { 'A vulnerability title' }
let(:type) { 'XSS' }
let(:references) { {:url => 'example.com', :metasploit => 'm', :exploitdb => 'e'} }
context 'w/o metasploit and fixed version modules argument' do
subject(:vulnerability) { Vulnerability.new(title, type, references) }
its(:title) { should be title }
its(:references) { should be references }
its(:type) { should be type }
its(:fixed_in) { should be_empty }
end
context 'with fixed version argument' do
let(:fixed_version) { '1.0' }
its(:title) { should be title }
its(:references) { should be references }
its(:type) { should be type }
its(:fixed_in) { should be fixed_version }
end
end
describe '::load_from_json_item' do
subject(:vulnerability) { Vulnerability.load_from_json_item(item) }
let(:item) {
json(MODELS_FIXTURES + '/vulnerability/json_item.json')
}
expected_refs = {
'id' => ['3911'],
'url' => ['Ref 1,Ref 2'],
'cve' => ['2011-001'],
'secunia' => ['secunia'],
'osvdb' => ['osvdb'],
'metasploit' => ['exploit/ex1'],
'exploitdb' => ['exploitdb']
}
its(:title) { should == 'Vuln Title' }
its(:type) { should == 'CSRF' }
its(:references) { should == expected_refs}
its(:fixed_in) { should == '1.0'}
end
end

View File

@@ -1,166 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
describe WpItem do
it_behaves_like 'WpItem::Existable'
it_behaves_like 'WpItem::Findable#Found_From='
it_behaves_like 'WpItem::Infos' do
let(:changelog_url) { uri.merge('changelog.txt').to_s }
let(:error_log_url) { uri.merge('error_log').to_s }
end
it_behaves_like 'WpItem::Versionable'
it_behaves_like 'WpItem::Vulnerable' do
let(:db_file) { MODELS_FIXTURES + '/wp_item/vulnerable/items_vulns.json' }
let(:identifier) { 'neo' }
let(:expected_refs) { {
'id' => [2993],
'url' => ['Ref 1', 'Ref 2'],
'cve' => ['2011-001'],
'secunia' => ['secunia'],
'osvdb' => ['osvdb'],
'metasploit' => ['exploit/ex1'],
'exploitdb' => ['exploitdb']
} }
let(:expected_vulns) { Vulnerabilities.new(1, Vulnerability.new("I'm the one", 'XSS', expected_refs)) }
end
subject(:wp_item) { WpItem.new(uri, options) }
let(:uri) { URI.parse('http://example.com') }
let(:options) { {} }
describe '#new' do
context 'with no options' do
its(:wp_content_dir) { is_expected.to eq 'wp-content' }
its(:wp_plugins_dir) { is_expected.to eq 'wp-content/plugins' }
its(:uri) { is_expected.to be uri }
end
context 'with :wp_content_dir' do
let(:options) { { wp_content_dir: 'custom' } }
its(:wp_content_dir) { is_expected.to eq 'custom' }
its(:wp_plugins_dir) { is_expected.to eq 'custom/plugins' }
end
context 'with :wp_plugins_dir' do
let(:options) { { wp_plugins_dir: 'c-plugins' } }
its(:wp_content_dir) { is_expected.to eq 'wp-content' }
its(:wp_plugins_dir) { is_expected.to eq 'c-plugins' }
end
end
describe '#set_options' do
context 'no an allowed option' do
it 'ignores the option' do
expect(wp_item).not_to receive(:not_allowed=)
wp_item.send(:set_options, { not_allowed: 'owned' })
end
end
context 'allowed option, w/o setter method' do
it 'raises an error' do
allow(wp_item).to receive(:allowed_options).and_return([:no_setter])
expect {
wp_item.send(:set_options, { no_setter: 'hello' })
}.to raise_error('WpItem does not respond to no_setter=')
end
end
end
describe '#path=' do
after do
wp_item.path = @path
expect(wp_item.path).to eq @expected
end
context 'with default variable value' do
it 'replaces $wp-content$ by wp-content' do
@path = '$wp-content$/hello'
@expected = 'wp-content/hello'
end
it 'replaces $wp-plugins$ by wp-content/plugins' do
@path = '$wp-plugins$/yolo/file.php'
@expected = 'wp-content/plugins/yolo/file.php'
end
end
context 'whith custom variable values' do
before {
allow(wp_item).to receive(:wp_content_dir).and_return('custom-content')
allow(wp_item).to receive(:wp_plugins_dir).and_return('plugins')
}
it 'replaces $wp-content$ by custom-content' do
@path = '$wp-content$/file.php'
@expected = 'custom-content/file.php'
end
it 'replaces $wp-plugins$ by plugins' do
@path = '$wp-plugins$/readme.txt'
@expected = 'plugins/readme.txt'
end
end
end
describe '#uri' do
context 'when the path is present' do
it 'returns it with the uri' do
path = 'somedir/somefile.php'
wp_item.path = path
expect(wp_item.uri).to eq uri.merge(path)
end
end
end
describe '#<=>' do
it 'bases the comparaison on the :name' do
wp_item.name = 'a-name'
other = WpItem.new(uri, name: 'other-name')
expect(wp_item.<=>(other)).to be === 'a-name'.<=>('other-name')
end
end
describe '#==' do
context 'when the :name is the same' do
it 'is ==' do
wp_item.name = 'some-name'
other = WpItem.new(uri, name: 'some-name')
expect(wp_item).to eq other
end
end
context 'otherwise' do
it 'is not ==' do
wp_item.name = 'Test'
other = WpItem.new(uri, name: 'hello')
expect(wp_item).not_to eq other
end
end
end
describe '#===' do
let(:options) { { name: 'a-name', version: '1.2' } }
context 'when the :name and :version are the same' do
it 'is ===' do
expect(WpItem.new(uri, options)).to be === WpItem.new(uri.merge('yo'), options)
end
end
context 'otherwise' do
it 'is not ===' do
expect(WpItem.new(uri, options)).not_to be === WpItem.new(uri, options.merge(version: '1.0'))
end
end
end
end

View File

@@ -1,30 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
describe WpPlugin do
it_behaves_like 'WpPlugin::Vulnerable'
it_behaves_like 'WpItem::Vulnerable' do
let(:options) { { name: 'white-rabbit' } }
let(:db_file) { MODELS_FIXTURES + '/wp_plugin/vulnerable/plugins.json' }
let(:expected_refs) { {
'id' => [2993],
'url' => ['Ref 1', 'Ref 2'],
'cve' => ['2011-001'],
'secunia' => ['secunia'],
'osvdb' => ['osvdb'],
'metasploit' => ['exploit/ex1'],
'exploitdb' => ['exploitdb']
} }
let(:expected_vulns) { Vulnerabilities.new << Vulnerability.new('Follow me!', 'REDIRECT', expected_refs) }
end
subject(:wp_plugin) { WpPlugin.new(uri, options) }
let(:uri) { URI.parse('http://example.com') }
let(:options) { { name: 'plugin-name' } }
describe '#forge_uri' do
its('uri.to_s') { is_expected.to eq 'http://example.com/wp-content/plugins/plugin-name/' }
end
end

View File

@@ -1,164 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
describe 'WpTheme::Findable' do
let(:fixtures_dir) { MODELS_FIXTURES + '/wp_theme/findable' }
let(:uri) { URI.parse('http://example.com/') }
describe '::find_from_css_link' do
before do
stub_request(:get, /.+\/style.css$/).to_return(status: 200)
end
after do
@body ||= File.new(fixtures_dir + '/css_link/' + @file)
stub_request(:get, uri.to_s).to_return(status: 200, body: @body)
wp_theme = WpTheme.send(:find_from_css_link, uri)
expect(wp_theme).to be_a WpTheme if @expected
expect(wp_theme).to eq @expected
expect(wp_theme.wp_content_dir).to eql 'wp-content' if @expected
end
context 'when theme is not present' do
it 'returns nil' do
@body = ''
@expected = nil
end
end
context 'when the theme name has spaces or special chars' do
it 'returns the WpTheme' do
@file = 'theme-name-with-spaces.html'
@expected = WpTheme.new(uri, name: 'Copia di simplefolio')
end
end
context 'when <link> is inline' do
it 'returns the WpTheme' do
@file = 'inline_link_tag.html'
@expected = WpTheme.new(uri, name: 'inline')
end
end
# FIXME: the style_url should be checked in WpTheme for absolute / relative
context 'when relative url is used' do
context 'when leading slash' do
it 'returns the WpTheme' do
@file = 'relative_urls.html'
@expected = WpTheme.new(uri, name: 'theme_name')
end
end
context 'when no leading slash' do
it 'returns the WpTheme' do
@file = 'relative_urls_missing_slash.html'
@expected = WpTheme.new(uri, name: 'theme_name')
end
end
end
context 'when other style.css is referenced' do
it 'returns the WpTheme' do
@file = 'yootheme.html'
@expected = WpTheme.new(uri, name: 'yoo_solar_wp', referenced_url: '/wp-content/themes/yoo_solar_wp/styles/wood/css/style.css')
end
end
# This one might introduce FP btw
context 'when leaked from comments' do
it 'returns the WpTheme' do
@file = 'comments.html'
@expected = WpTheme.new(uri, name: 'debug')
end
end
end
describe '::find_from_wooframework' do
before do
stub_request(:get, /.+\/style.css$/).to_return(status: 200)
end
after do
@body ||= File.new(fixtures_dir + '/wooframework/' + @file)
stub_request(:get, uri.to_s).to_return(status: 200, body: @body)
wp_theme = WpTheme.send(:find_from_wooframework, uri)
if @expected
expect(wp_theme).to be_a WpTheme
end
expect(wp_theme).to eq @expected
end
context 'when theme is not present' do
it 'returns nil' do
@body = ''
@expected = nil
end
end
it 'returns the WpTheme' do
@file = 'merchant-no-version.html'
@expected = WpTheme.new(uri, name: 'Merchant')
end
context 'when the version is present' do
it 'returns the WpTheme with it' do
@file = 'editorial-1.3.5.html'
@expected = WpTheme.new(uri, name: 'Editorial', version: '1.3.5')
end
end
end
describe '::find' do
# Stub all WpTheme::find_from_* to return nil
def stub_all_to_nil
WpTheme.methods.grep(/^find_from_/).each do |method|
allow(WpTheme).to receive(method).and_return(nil)
end
end
context 'when a method is named s_find_from_s' do
it 'does not call it' do
class WpTheme
module Findable
extend self
def s_find_from_s(s); raise 'I should not be called by ::find' end
end
end
stub_all_to_nil
expect { WpTheme.find(uri) }.to_not raise_error
end
end
context 'when the theme is not found' do
it 'returns nil' do
stub_all_to_nil
expect(WpTheme.find(uri)).to be_nil
end
end
context 'when the theme is found' do
it 'returns it, with the :found_from set' do
stub_all_to_nil
stub_request(:get, /.+\/the-oracle\/style.css$/).to_return(status: 200)
expected = WpTheme.new(uri, name: 'the-oracle')
allow(WpTheme).to receive(:find_from_css_link).and_return(expected)
wp_theme = WpTheme.find(uri)
expect(wp_theme).to be_a WpTheme
expect(wp_theme).to eq expected
expect(wp_theme.found_from).to be === 'css link'
end
end
end
end

View File

@@ -1,36 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
describe WpTheme do
it_behaves_like 'WpTheme::Versionable'
it_behaves_like 'WpTheme::Vulnerable'
it_behaves_like 'WpItem::Vulnerable' do
let(:options) { { name: 'the-oracle' } }
let(:db_file) { MODELS_FIXTURES + '/wp_theme/vulnerable/themes_vulns.json' }
let(:expected_refs) { {
'id' => [2993],
'url' => ['Ref 1', 'Ref 2'],
'cve' => ['2011-001'],
'secunia' => ['secunia'],
'osvdb' => ['osvdb'],
'metasploit' => ['exploit/ex1'],
'exploitdb' => ['exploitdb']
} }
let(:expected_vulns) { Vulnerabilities.new << Vulnerability.new('I see you', 'FPD', expected_refs) }
end
subject(:wp_theme) { WpTheme.new(uri, options) }
let(:uri) { URI.parse('http://example.com/') }
let(:options) { { name: 'theme-name' } }
let(:theme_path) { 'wp-content/themes/theme-name/' }
describe '#allowed_options' do
its(:allowed_options) { is_expected.to include :referenced_url }
end
describe '#forge_uri' do
its(:uri) { is_expected.to eq uri.merge(theme_path) }
end
end

View File

@@ -1,33 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
describe WpTimthumb do
it_behaves_like 'WpTimthumb::Existable'
it_behaves_like 'WpTimthumb::Versionable'
subject(:wp_timthumb) { WpTimthumb.new(uri, options) }
let(:uri) { URI.parse('http://example.com/') }
let(:options) { { path: 'path-to/a/timtuhumb.php' } }
describe '#==' do
context 'when both url are equal' do
it 'returns true' do
expect(WpTimthumb.new(uri, path: 'timtuhumb.php')).
to eq(
WpTimthumb.new(uri, path: 'timtuhumb.php')
)
end
end
context 'when urls are different' do
it 'returns false' do
expect(WpTimthumb.new(uri, path: 'hello/timtuhumb.php')).
not_to eq(
WpTimthumb.new(uri, path: 'some-dir/timtuhumb.php')
)
end
end
end
end

View File

@@ -1,88 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
describe WpUser do
it_behaves_like 'WpUser::Existable'
it_behaves_like 'WpUser::BruteForcable'
subject(:wp_user) { WpUser.new(uri, options) }
let(:uri) { URI.parse('http://example.com') }
let(:options) { {} }
describe '#allowed_options' do
[:id, :login, :display_name, :password].each do |sym|
its(:allowed_options) { is_expected.to include sym }
end
its(:allowed_options) { is_expected.not_to include :name }
end
describe '#uri' do
context 'when the id is not set' do
it 'raises an error' do
expect { wp_user.uri }.to raise_error('The id is nil')
end
end
context 'when the id is set' do
it 'returns the uri to the auhor page' do
wp_user.id = 2
expect(wp_user.uri).to eq uri.merge('?author=2')
end
end
end
describe '#to_s' do
after do
subject.id = 1
expect(subject.to_s).to eq @expected
end
it 'returns @id' do
@expected = '1'
end
context 'when @login' do
it 'returns @id | @login' do
subject.login = 'admin'
@expected = '1 | admin'
end
context 'when @display_name' do
it 'returns @id | @login | @display_name' do
subject.login = 'admin'
subject.display_name = 'real name'
@expected = '1 | admin | real name'
end
end
end
end
describe '#<=>' do
it 'bases the comparaison on the :id' do
wp_user.id = 1
other = WpUser.new(uri, id: 3)
expect(wp_user.<=>(other)).to be === 1.<=>(3)
end
end
describe '#===, #==' do
context 'when the :id and :login are the same' do
it 'is ===, and ==' do
expect(WpUser.new(uri, id: 1, name: 'yo')).to eq WpUser.new(uri, id: 1, name: 'yo')
end
end
context 'when :id and :login are different' do
it 'is not === or ==' do
expect(WpUser.new(uri, id: 1, name: 'yo')).not_to eq WpUser.new(uri, id: 2, name:'yo')
end
end
end
end

View File

@@ -1,232 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
describe 'WpVersion::Findable' do
let(:fixtures_dir) { MODELS_FIXTURES + '/wp_version/findable/' }
let(:uri) { URI.parse('http://example.com/') }
let(:generator_urls) {
{
rss_generator: uri.merge('feed/').to_s,
rdf_generator: uri.merge('feed/rdf/').to_s,
atom_generator: uri.merge('feed/atom/').to_s,
comments_rss_generator: uri.merge('comments/feed/').to_s,
sitemap_generator: uri.merge('sitemap.xml').to_s
}
}
# Dynamic creation for all generator methods
WpVersion.methods.grep(/^find_from_.*_generator$/).each do |method|
dir_name = method.to_s[%r{^find_from_(.*)$}, 1]
describe "::#{method}" do
let(:url) { generator_urls[dir_name.to_sym] || uri.to_s }
after do
fixture = fixtures_dir + dir_name + @fixture
stub_request_to_fixture(url: url, fixture: fixture)
expect(WpVersion.send(method, uri)).to eq @expected
end
context 'when generator not found' do
it 'returns nil' do
@fixture = '/no_generator.html'
@expected = nil
end
end
context 'when version not found' do
it 'returns nil' do
@fixture = '/no_version.html'
@expected = nil
end
end
context 'when invalid version' do
it 'returns nil' do
@fixture = '/invalid_version.html'
@expected = nil
end
end
it 'returns 3.3.2' do
@fixture = '/3.3.2.html'
@expected = '3.3.2'
end
it 'returns 3.4-beta4' do
@fixture = '/3.4-beta4.html'
@expected = '3.4-beta4'
end
if method == :find_from_meta_generator
it 'returns 3.5' do
@fixture = '/3.5_minified.html'
@expected = '3.5'
end
it 'returns 3.5.1' do
@fixture = '/3.5.1_mobile.html'
@expected = '3.5.1'
end
end
end
end
describe '::find_from_advanced_fingerprinting' do
let(:fixture_dir) { fixtures_dir + 'advanced_fingerprinting/' }
let(:wp_content_dir) { 'wp-content' }
let(:wp_plugins_dir) { wp_content_dir + '/plugins' }
let(:versions_xml) { fixture_dir + 'wp_versions.xml' }
after do
version = WpVersion.send(
:find_from_advanced_fingerprinting,
uri, wp_content_dir, wp_plugins_dir, versions_xml
)
expect(version).to eq @expected
end
context 'when' do
it 'returns nil' do
stub_request(:get, /.*/).to_return(status: 404, body: '')
@expected = nil
end
end
it 'returns 3.2.1' do
stub_request_to_fixture(
url: uri.merge('wp-admin/js/wp-fullscreen.js').to_s,
fixture: fixture_dir + '3.2.1.js'
)
@expected = '3.2.1'
end
end
describe '::find_from_readme' do
let(:url) { uri.merge('readme.html').to_s }
after do
fixture = fixtures_dir + 'readme' + @fixture
stub_request_to_fixture(url: url, fixture: fixture)
expect(WpVersion.send(:find_from_readme, uri)).to eq @expected
end
context 'when version not found' do
it 'returns nil' do
@fixture = '/empty_version.html'
@expected = nil
end
end
context 'when invalid version' do
it 'returns nil' do
@fixture = '/invalid_version.html'
@expected = nil
end
end
it 'returns 3.3.2' do
@fixture = '/3.3.2.html'
@expected = '3.3.2'
end
context 'when version >= 4.7' do
it 'returns nil' do
@fixture = '/4.7.2.html'
@expected = nil
end
end
end
describe '::find_from_links_opml' do
let(:url) { uri.merge('wp-links-opml.php') }
after do
fixture = fixtures_dir + 'links_opml' + @fixture
stub_request_to_fixture(url: url, fixture: fixture)
expect(WpVersion.send(:find_from_links_opml, uri)).to eq @expected
end
it 'returns 3.4.2' do
@fixture = '/3.4.2.xml'
@expected = '3.4.2'
end
context 'when no generator' do
it 'returns nil' do
@fixture = '/no_generator.xml'
@expected = nil
end
end
end
describe '::find_from_stylesheets_numbers' do
after do
fixture = fixtures_dir + 'stylesheet_numbers' + @fixture
stub_request_to_fixture(url: uri, fixture: fixture)
expect(WpVersion.send(:find_from_stylesheets_numbers, uri)).to eq @expected
end
context 'invalid url' do
it 'returns nil' do
@fixture = '/invalid_url.html'
@expected = nil
end
end
end
describe '::find' do
# Stub all WpVersion::find_from_* to return nil
def stub_all_to_nil
WpVersion.methods.grep(/^find_from_/).each do |method|
allow(WpVersion).to receive(method).and_return(nil)
end
end
let(:wp_content_dir) { 'wp-content' }
let(:wp_plugins_dir) { wp_content_dir + '/plugins' }
let(:version_xml) {}
after do
stub_request(:get, /#{uri.to_s}.*/).to_return(status: 0)
version = WpVersion.find(uri, wp_content_dir, wp_plugins_dir, version_xml)
expect(version).to eq @expected
if @expected
expect(version.found_from).to eq @found_from
end
end
context 'when no version found' do
it 'returns nil' do
stub_all_to_nil
@expected = nil
end
end
WpVersion.methods.grep(/^find_from_/).each do |method|
number = "#{rand(5)}.#{rand(3)}"
found_from = method[/^find_from_(.*)/, 1].sub('_', ' ')
context "when found from #{found_from}" do
it 'returns the correct WpVersion' do
stub_all_to_nil
allow(WpVersion).to receive(method).and_return(number)
@expected = WpVersion.new(uri, number: number)
@found_from = found_from
end
end
end
end
end

View File

@@ -1,26 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
describe WpVersion do
it_behaves_like 'WpVersion::Vulnerable'
subject(:wp_version) { WpVersion.new(uri, options) }
let(:uri) { URI.parse('http://example.com/') }
let(:options) { { number: '1.2' } }
describe '#allowed_options' do
[:number, :found_from].each do |sym|
its(:allowed_options) { is_expected.to include sym }
end
end
describe '#all' do
let(:versions_file) { File.join(MODELS_FIXTURES, 'wp_version', 'findable', 'advanced_fingerprinting', 'wp_versions.xml') }
it 'returns the array containign the two versions' do
expect(WpVersion.all(versions_file)).to eq ['3.2.1', '3.2']
end
end
end

View File

@@ -1,54 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
describe Plugin do
subject(:plugin) { Plugin.new }
describe '#new' do
context 'with some infos' do
subject(:plugin) { Plugin.new(infos) }
let(:infos) { { author: 'John' } }
its(:author) { is_expected.to be === infos[:author] }
end
end
describe '#run' do
it 'should raise a NotImplementedError' do
expect { plugin.run }.to raise_error(NotImplementedError)
end
end
describe '#register_options' do
after :each do
if @exception
expect { plugin.register_options(*@options) }.to raise_error(@exception)
else
plugin.register_options(*@options)
expect(plugin.registered_options.sort).to be === @expected.sort
end
end
context 'when an option is not an Array' do
it 'should raise an error' do
@options = [
['-v', '--verbose', 'It\'s a valid option'],
'Not a valid one'
]
@exception = 'Each option must be an array, String supplied'
end
end
context 'when options are Arrays' do
it 'should register the options' do
@options = [
['-v', '--verbose', 'Verbose mode'],
['-u', '--url TARGET_URL']
]
@expected = *@options
end
end
end
end

View File

@@ -1,97 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
class TestPlugin < Plugin
def initialize
register_options(['-u', '--url'])
end
end
class AnotherPlugin < Plugin
def initialize
super(author: 'John')
# No Options
end
end
describe Plugins do
subject(:plugins) { Plugins.new }
let(:test_plugin) { TestPlugin.new }
let(:another_plugin) { AnotherPlugin.new }
describe '#new' do
context 'without argument' do
its(:option_parser) { is_expected.to be_a CustomOptionParser }
it 'should be an Array' do
expect(plugins).to be_an Array
end
end
context 'with an option_parser argument' do
subject(:plugin) { Plugins.new(CustomOptionParser.new('the banner')) }
its(:option_parser) { is_expected.to be_a CustomOptionParser }
its('option_parser.banner') { is_expected.to be === 'the banner' }
it 'should raise an eror if the parser is not an instance of CustomOptionParser' do
expect { Plugins.new(OptionParser.new) }.to raise_error('The parser must be an instance of CustomOptionParser, OptionParser supplied')
end
end
end
describe '#register_plugin' do
after :each do
if @exception
expect { plugins.register_plugin(@plugin) }.to raise_error(@exception)
else
plugins.register_plugin(@plugin)
expect(plugins).to include(@plugin)
expect(plugins).to be === @expected
end
end
context 'when the argument supplied is not an instance of Plugin' do
it 'should raise an error' do
@plugin = "I'am a String"
@exception = 'The argument must be an instance of Plugin, String supplied'
end
end
it 'should register the plugin' do
@plugin = TestPlugin.new
@expected = [@plugin]
end
it 'should register 2 plugins (the order is important)' do
plugins.register_plugin(test_plugin)
@plugin = another_plugin
@expected = [test_plugin, @plugin]
end
end
describe '#register' do
after :each do
plugins.register(*@plugins_to_register)
@plugins_to_register.each do |plugin|
expect(plugins).to include(plugin)
end
# For the correct order
expect(plugins).to be === @plugins_to_register
end
it 'should register 1 plugin' do
@plugins_to_register = [test_plugin]
end
it 'should register 2 plugins' do
@plugins_to_register = [another_plugin, test_plugin]
end
end
end

View File

@@ -1,3 +0,0 @@
# encoding: UTF-8
# TODO

View File

@@ -1,247 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
describe 'VersionCompare' do
describe '::lesser_or_equal?' do
context 'version checked is newer' do
after { expect(VersionCompare::lesser_or_equal?(@version1, @version2)).to be_truthy }
it 'returns true' do
@version1 = '1.0'
@version2 = '2.0'
end
it 'returns true' do
@version1 = '1.0'
@version2 = '1.1'
end
it 'returns true' do
@version1 = '1.0a'
@version2 = '1.0b'
end
it 'returns true' do
@version1 = '1.0'
@version2 = '5000000'
end
it 'returns true' do
@version1 = '0'
@version2 = '1'
end
it 'returns true' do
@version1 = '0.4.2b'
@version2 = '2.3.3'
end
it 'returns true' do
@version1 = '.47'
@version2 = '.50.3'
end
end
context 'version checked is older' do
after { expect(VersionCompare::lesser_or_equal?(@version1, @version2)).to be_falsey }
it 'returns false' do
@version1 = '1'
@version2 = '0'
end
it 'returns false' do
@version1 = '1.0'
@version2 = '0.5'
end
it 'returns false' do
@version1 = '500000'
@version2 = '1'
end
it 'returns false' do
@version1 = '1.6.3.7.3.4'
@version2 = '1.2.4.567.679.8.e'
end
it 'returns false' do
@version1 = '.47'
@version2 = '.46.3'
end
end
context 'version checked is the same' do
after { expect(VersionCompare::lesser_or_equal?(@version1, @version2)).to be_truthy }
it 'returns true' do
@version1 = '1'
@version2 = '1'
end
it 'returns true' do
@version1 = 'a'
@version2 = 'a'
end
end
context 'version number causes Gem::Version new Exception' do
after { expect(VersionCompare::lesser_or_equal?(@version1, @version2)).to be_falsey }
it 'returns false' do
@version1 = 'a'
@version2 = 'b'
end
end
context 'one version number is not set' do
after { expect(VersionCompare::lesser_or_equal?(@version1, @version2)).to be_falsey }
it 'returns false (version2 nil)' do
@version1 = '1'
@version2 = nil
end
it 'returns false (version1 nil)' do
@version1 = nil
@version2 = '1'
end
it 'returns false (version2 empty)' do
@version1 = '1'
@version2 = ''
end
it 'returns false (version1 empty)' do
@version1 = ''
@version2 = '1'
end
end
end
describe '::lesser?' do
context 'version checked is newer' do
after { expect(VersionCompare::lesser?(@version1, @version2)).to be_truthy }
it 'returns true' do
@version1 = '1.0'
@version2 = '2.0'
end
it 'returns true' do
@version1 = '1.0'
@version2 = '1.1'
end
it 'returns true' do
@version1 = '1.0a'
@version2 = '1.0b'
end
it 'returns true' do
@version1 = '1.0'
@version2 = '5000000'
end
it 'returns true' do
@version1 = '0'
@version2 = '1'
end
it 'returns true' do
@version1 = '0.4.2b'
@version2 = '2.3.3'
end
it 'returns true' do
@version1 = '.47'
@version2 = '.50.3'
end
it 'returns true' do
@version1 = '2.5.9'
@version2 = '2.5.10'
end
end
context 'version checked is older' do
after { expect(VersionCompare::lesser?(@version1, @version2)).to be_falsey }
it 'returns false' do
@version1 = '1'
@version2 = '0'
end
it 'returns false' do
@version1 = '1.0'
@version2 = '0.5'
end
it 'returns false' do
@version1 = '500000'
@version2 = '1'
end
it 'returns false' do
@version1 = '1.6.3.7.3.4'
@version2 = '1.2.4.567.679.8.e'
end
it 'returns false' do
@version1 = '.47'
@version2 = '.46.3'
end
end
context 'version checked is the same' do
after { expect(VersionCompare::lesser?(@version1, @version2)).to be_falsey }
it 'returns true' do
@version1 = '1'
@version2 = '1'
end
it 'returns true' do
@version1 = 'a'
@version2 = 'a'
end
end
context 'version number causes Gem::Version new Exception' do
after { expect(VersionCompare::lesser?(@version1, @version2)).to be_falsey }
it 'returns false' do
@version1 = 'a'
@version2 = 'b'
end
end
context 'one version number is not set' do
after { expect(VersionCompare::lesser?(@version1, @version2)).to be_falsey }
it 'returns false (version2 nil)' do
@version1 = '1'
@version2 = nil
end
it 'returns false (version1 nil)' do
@version1 = nil
@version2 = '1'
end
it 'returns false (version2 empty)' do
@version1 = '1'
@version2 = ''
end
it 'returns false (version1 empty)' do
@version1 = ''
@version2 = '1'
end
end
end
end

View File

@@ -1,240 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
describe 'WebSite' do
let(:fixtures_dir) { SPEC_FIXTURES_WPSCAN_WEB_SITE_DIR }
subject(:web_site) { WebSite.new('http://example.localhost/') }
it_behaves_like 'WebSite::RobotsTxt'
it_behaves_like 'WebSite::InterestingHeaders'
before :all do
Browser::reset
Browser.instance(
config_file: SPEC_FIXTURES_CONF_DIR + '/browser.conf.json',
cache_ttl: 0
)
end
describe '#new' do
its(:url) { is_expected.to be === 'http://example.localhost/' }
end
describe '#url=' do
after :each do
web_site.url = @uri
expect(web_site.url).to be === @expected
end
context 'when protocol or trailing slash is missing' do
it 'should add them' do
@uri = 'example.localhost'
@expected = 'http://example.localhost/'
end
end
context 'when there is a protocol or a trailing slash' do
it 'should not add them' do
@uri = 'http://example.localhost/'
@expected = @uri
end
end
end
describe '#online?' do
it 'should not be considered online if the status code is 0' do
stub_request(:get, web_site.url).to_return(status: 0)
expect(web_site).not_to be_online
end
it 'should be considered online if the status code is != 0' do
stub_request(:get, web_site.url).to_return(status: 200)
expect(web_site).to be_online
end
end
describe '#has_basic_auth?' do
it 'should detect that the wpsite is basic auth protected' do
stub_request(:get, web_site.url).to_return(status: 401)
expect(web_site).to have_basic_auth
end
it 'should not have a basic auth for a 200' do
stub_request(:get, web_site.url).to_return(status: 200)
expect(web_site).not_to have_basic_auth
end
end
describe '#xml_rpc_url' do
it 'returns the xmlrpc url' do
expect(web_site.xml_rpc_url).to be === 'http://example.localhost/xmlrpc.php'
end
end
describe '#has_xml_rpc?' do
it 'returns true' do
stub_request(:get, web_site.xml_rpc_url).
to_return(status: 200, body: 'XML-RPC server accepts POST requests only')
expect(web_site).to have_xml_rpc
end
it 'returns false' do
stub_request(:get, web_site.xml_rpc_url).to_return(status: 200)
expect(web_site).not_to have_xml_rpc
end
end
describe '#redirection' do
it 'returns nil if no redirection detected' do
stub_request(:get, web_site.url).to_return(status: 200, body: '')
expect(web_site.redirection).to be_nil
end
[301, 302].each do |status_code|
it "returns http://new-location.com if the status code is #{status_code}" do
new_location = 'http://new-location.com'
stub_request(:get, web_site.url).
to_return(status: status_code, headers: { location: new_location })
stub_request(:get, new_location).to_return(status: 200)
expect(web_site.redirection).to be === 'http://new-location.com'
end
end
context 'when relative URI in Location' do
it 'returns the absolute URI' do
relative_location = '/blog/'
absolute_location = web_site.uri.merge(relative_location).to_s
stub_request(:get, web_site.url).to_return(status: 301, headers: { location: relative_location })
stub_request(:get, absolute_location)
expect(web_site.redirection).to eql absolute_location
end
context 'when starts with a ?' do
it 'returns the absolute URI' do
relative_location = '?p=blog'
absolute_location = web_site.uri.merge(relative_location).to_s
stub_request(:get, web_site.url).to_return(status: 301, headers: { location: relative_location })
stub_request(:get, absolute_location)
expect(web_site.redirection).to eql absolute_location
end
end
end
context 'when multiple redirections' do
it 'returns the last redirection' do
first_redirection = 'http://www.redirection.com'
last_redirection = 'http://redirection.com'
stub_request(:get, web_site.url).to_return(status: 301, headers: { location: first_redirection })
stub_request(:get, first_redirection).to_return(status: 302, headers: { location: last_redirection })
stub_request(:get, last_redirection).to_return(status: 200)
expect(web_site.redirection).to be === last_redirection
end
end
end
describe '#page_hash' do
after { expect(WebSite.page_hash(page)).to eq Digest::MD5.hexdigest(@expected) }
context 'when the page is an url' do
let(:page) { 'http://e.localhost/somepage.php' }
it 'returns the MD5 hash of the page' do
body = 'Hello World !'
stub_request(:get, page).to_return(body: body)
@expected = body
end
end
context 'when the page is a Typhoeus::Response' do
let(:page) { Typhoeus::Response.new(body: 'Hello Example!') }
it 'returns the correct hash' do
@expected = 'Hello Example!'
end
end
context 'when there are comments' do
let(:page) {
body = "yolo\n\n<!--I should <script>no longer be</script> there -->\nworld!"
Typhoeus::Response.new(body: body)
}
it 'removes them' do
@expected = "yolo\n\n\nworld!"
end
end
context 'when there are scripts' do
let(:page) {
body = "yolo\n\n<script type=\"text/javascript\">alert('Hi');</script>\nworld!"
Typhoeus::Response.new(body: body)
}
it 'removes them' do
@expected = "yolo\n\n\nworld!"
end
end
end
describe '#homepage_hash' do
it 'returns the MD5 hash of the homepage' do
body = 'Hello World'
stub_request(:get, web_site.url).to_return(body: body)
expect(web_site.homepage_hash).to be === Digest::MD5.hexdigest(body)
end
end
describe '#error_404_hash' do
it 'returns the md5sum of the 404 page' do
stub_request(:any, /.*/).
to_return(status: 404, body: '404 page !')
expect(web_site.error_404_hash).to be === Digest::MD5.hexdigest('404 page !')
end
end
describe '::has_log?' do
let(:log_url) { web_site.uri.merge('log.txt').to_s }
let(:pattern) { %r{PHP Fatal error} }
after do
stub_request_to_fixture(url: log_url, fixture: fixtures_dir + "/has_log/#{@file}")
expect(WebSite.has_log?(log_url, pattern)).to eq @expected
end
context 'when the pattern does not match' do
it 'returns false' do
@file = 'no_match.txt'
@expected = false
end
end
context 'when the pattern matches' do
it 'returns true' do
@file = 'matches.txt'
@expected = true
end
end
# This doesn't work in rspec, WebMock or Typhoeus returns the whole file
# See https://github.com/bblimke/webmock/issues/277
#it 'only checks the first 700 bytes' do
# @file = 'matches_after_700_bytes.txt'
# @expected = false
#end
end
end

View File

@@ -1,218 +0,0 @@
# encoding: UTF-8
require File.expand_path(File.join(__dir__, 'wpscan_helper'))
describe WpTarget do
subject(:wp_target) { WpTarget.new(target_url, options) }
subject(:wp_target_custom) { WpTarget.new(target_url, options_custom) }
let(:target_url) { 'http://example.localhost/' }
let(:fixtures_dir) { SPEC_FIXTURES_WPSCAN_WP_TARGET_DIR }
let(:login_url) { wp_target.uri.merge('wp-login.php').to_s }
let(:options) {
{
config_file: SPEC_FIXTURES_CONF_DIR + '/browser.conf.json',
cache_ttl: 0,
wp_content_dir: 'wp-content',
wp_plugins_dir: 'wp-content/plugins'
}
}
let(:options_custom) {
{
config_file: SPEC_FIXTURES_CONF_DIR + '/browser.conf.json',
cache_ttl: 0,
wp_content_dir: 'custom-content',
wp_plugins_dir: 'custom-content/plugins'
}
}
before { Browser::reset }
it_behaves_like 'WpTarget::WpReadme'
it_behaves_like 'WpTarget::WpRegistrable'
it_behaves_like 'WpTarget::WpConfigBackup'
it_behaves_like 'WpTarget::WpLoginProtection'
it_behaves_like 'WpTarget::WpCustomDirectories'
it_behaves_like 'WpTarget::WpFullPathDisclosure'
describe '#initialize' do
it 'should raise an error if the target_url is nil or empty' do
expect { WpTarget.new(nil) }.to raise_error
expect { Wptarget.new('') }.to raise_error
end
end
describe '#login_url' do
it 'returns the login url of the target' do
stub_request(:get, login_url).to_return(status: 200, body: '')
expect(wp_target.login_url).to be === login_url
end
it 'returns the redirection url if there is one (ie: for https)' do
https_login_url = login_url.gsub(/^http:/, 'https:')
stub_request(:get, login_url).to_return(status: 302, headers: { location: https_login_url })
stub_request(:get, https_login_url).to_return(status: 200)
expect(wp_target.login_url).to be === https_login_url
end
end
describe '#wordpress?' do
# each url (wp-login and xmlrpc) pointed to a 404
before :each do
stub_request(:get, wp_target.url).
to_return(status: 200, body: '', headers: { 'X-Pingback' => wp_target.uri.merge('xmlrpc.php')})
# Preventing redirection check from login_url()
allow(wp_target).to receive_messages(redirection: nil)
[wp_target.login_url, wp_target.xml_rpc_url].each do |url|
stub_request(:get, url).to_return(status: 404, body: '')
end
end
it 'returns true if there is a /wp-content/ detected in the index page source' do
stub_request_to_fixture(url: wp_target.url, fixture: fixtures_dir + '/wp_content_dir/wordpress-3.4.1.htm')
expect(wp_target).to be_wordpress
end
it 'returns true if a custom content directory is detected' do
stub_request_to_fixture(url: wp_target_custom.url, fixture: fixtures_dir + '/wp_content_dir/wordpress-3.4.1-custom.htm')
expect(wp_target_custom).to be_wordpress
end
it 'returns true if the xmlrpc is found' do
stub_request(:get, wp_target.xml_rpc_url).
to_return(status: 200, body: File.new(fixtures_dir + '/xmlrpc.php'))
expect(wp_target).to be_wordpress
end
it 'returns true if the wp-login is found and is a valid wordpress one' do
stub_request(:get, wp_target.login_url).
to_return(status: 200, body: File.new(fixtures_dir + '/wp-login.php'))
expect(wp_target).to be_wordpress
end
it 'returns false if both files are not found (404)' do
expect(wp_target).not_to be_wordpress
end
context 'when the url contains "wordpress" and is a 404' do
let(:target_url) { 'http://lamp/wordpress-3.5./' }
it 'returns false' do
stub_request(:get, wp_target.login_url).to_return(status: 404, body: 'The requested URL /wordpress-3.5. was not found on this server.')
expect(wp_target).not_to be_wordpress
end
end
context 'when the response is a 403' do
before { stub_request(:any, /.*/).to_return(status: 403) }
it 'raises an error' do
expect { wp_target.wordpress? }.to raise_error
end
end
end
describe '#wordpress_hosted?' do
it 'returns true if target url is a wordpress.com subdomain' do
target = WpTarget.new('http://test.wordpress.com/')
expect(target.wordpress_hosted?).to be_truthy
end
it 'returns true if target url is a wordpress.com subdomain and has querystring' do
target = WpTarget.new('http://test.wordpress.com/path/file.php?a=b')
expect(target.wordpress_hosted?).to be_truthy
end
it 'returns false if target url is not a wordpress.com subdomain' do
target = WpTarget.new('http://test.example.com/')
expect(target.wordpress_hosted?).to be_falsey
end
end
describe '#debug_log_url' do
it "returns 'http://example.localhost/wp-content/debug.log" do
allow(wp_target).to receive_messages(wp_content_dir: 'wp-content')
expect(wp_target.debug_log_url).to be === 'http://example.localhost/wp-content/debug.log'
end
end
describe '#has_debug_log?' do
let(:fixtures_dir) { SPEC_FIXTURES_WPSCAN_WP_TARGET_DIR + '/debug_log' }
after :each do
allow(wp_target).to receive_messages(wp_content_dir: 'wp-content')
stub_request_to_fixture(url: wp_target.debug_log_url, fixture: @fixture)
expect(wp_target.has_debug_log?).to be === @expected
end
it 'returns false' do
@fixture = SPEC_FIXTURES_DIR + '/empty-file'
@expected = false
end
it 'returns true' do
@fixture = fixtures_dir + '/debug.log'
@expected = true
end
it 'should also detect it if there are PHP notice' do
@fixture = fixtures_dir + '/debug-notice.log'
@expected = true
end
end
describe '#search_replace_db_2_url' do
it 'returns the correct url' do
expect(wp_target.search_replace_db_2_url).to eq 'http://example.localhost/searchreplacedb2.php'
end
end
describe '#search_replace_db_2_exists?' do
it 'returns true' do
stub_request(:any, wp_target.search_replace_db_2_url).to_return(status: 200, body: 'asdf by interconnect asdf')
expect(wp_target.search_replace_db_2_exists?).to be_truthy
end
it 'returns false' do
stub_request(:any, wp_target.search_replace_db_2_url).to_return(status: 500)
expect(wp_target.search_replace_db_2_exists?).to be_falsey
end
it 'returns false' do
stub_request(:any, wp_target.search_replace_db_2_url).to_return(status: 500, body: 'asdf by interconnect asdf')
expect(wp_target.search_replace_db_2_exists?).to be_falsey
end
end
describe '#emergency_url' do
it 'returns the correct url' do
expect(wp_target.emergency_url).to eq 'http://example.localhost/emergency.php'
end
end
describe '#emergency_exists?' do
it 'returns true' do
stub_request(:any, wp_target.emergency_url).to_return(status: 200, body: 'enter your password here')
expect(wp_target.emergency_exists?).to be_truthy
end
it 'returns false' do
stub_request(:any, wp_target.emergency_url).to_return(status: 500)
expect(wp_target.emergency_exists?).to be_falsey
end
it 'returns false' do
stub_request(:any, wp_target.emergency_url).to_return(status: 500, body: 'enter your password here')
expect(wp_target.emergency_exists?).to be_falsey
end
end
end

View File

@@ -1,13 +0,0 @@
# encoding: UTF-8
require 'spec_helper'
require WPSCAN_LIB_DIR + '/wpscan_helper'
SPEC_FIXTURES_WPSCAN_DIR = SPEC_FIXTURES_DIR + '/wpscan'
SPEC_FIXTURES_WPSCAN_WEB_SITE_DIR = SPEC_FIXTURES_WPSCAN_DIR + '/web_site'
SPEC_FIXTURES_WPSCAN_WP_TARGET_DIR = SPEC_FIXTURES_WPSCAN_DIR + '/wp_target'
SPEC_FIXTURES_WPSCAN_WPSCAN_OPTIONS_DIR = SPEC_FIXTURES_WPSCAN_DIR + '/wpscan_options'
SPEC_FIXTURES_WPSCAN_WP_THEME_DIR = SPEC_FIXTURES_WPSCAN_DIR + '/wp_theme'
SPEC_FIXTURES_WPSCAN_WP_PLUGIN_DIR = SPEC_FIXTURES_WPSCAN_DIR + '/wp_plugin'
SPEC_FIXTURES_WPSCAN_WP_VERSION_DIR = SPEC_FIXTURES_WPSCAN_DIR + '/wp_version'

View File

@@ -1,392 +0,0 @@
# encoding: UTF-8
require File.expand_path(File.join(__dir__, 'wpscan_helper'))
describe 'WpscanOptions' do
before :each do
@wpscan_options = WpscanOptions.new
end
describe '#initialize' do
it 'should set all options to nil' do
WpscanOptions::ACCESSOR_OPTIONS.each do |option|
expect(@wpscan_options.send(option)).to be === nil
end
end
end
describe '#url=' do
it 'should raise an error if en empty or nil url is supplied' do
expect { @wpscan_options.url = '' }.to raise_error
expect { @wpscan_options.url = nil }.to raise_error
end
it 'should add the http protocol if not present' do
@wpscan_options.url = 'example.com'
expect(@wpscan_options.url).to be === 'http://example.com'
end
it "should not add the http protocol if it's already present" do
url = 'http://example.com'
@wpscan_options.url = url
expect(@wpscan_options.url).to be === url
end
it 'should encode IDN' do
@wpscan_options.url = 'http://пример.испытание/'
expect(@wpscan_options.url).to be === 'http://xn--e1afmkfd.xn--80akhbyknj4f/'
end
end
describe '#threads=' do
it 'should convert an integer in a string into an integr' do
@wpscan_options.threads = '10'
expect(@wpscan_options.threads).to be_an Integer
expect(@wpscan_options.threads).to be === 10
end
it 'should set to correct number of threads' do
@wpscan_options.threads = 15
expect(@wpscan_options.threads).to be_an Integer
expect(@wpscan_options.threads).to be === 15
end
end
describe '#wordlist=' do
it 'should raise an error if the wordlist file does not exist' do
expect { @wpscan_options.wordlist = '/i/do/not/exist.txt' }.to raise_error
end
it 'should not raise an error' do
wordlist_file = "#{SPEC_FIXTURES_WPSCAN_WPSCAN_OPTIONS_DIR}/wordlist.txt"
@wpscan_options.wordlist = wordlist_file
expect(@wpscan_options.wordlist).to be === wordlist_file
end
end
describe '#proxy=' do
it 'should raise an error' do
expect { @wpscan_options.proxy = 'invalidproxy' }.to raise_error
end
it 'should not raise an error' do
proxy = '127.0.0.1:3038'
@wpscan_options.proxy = proxy
expect(@wpscan_options.proxy).to be === proxy
end
end
describe '#proxy_auth=' do
it 'should raise an error if the format is not correct' do
expect { @wpscan_options.proxy_auth = 'invalidauth' }.to raise_error
end
it 'should not raise en error' do
proxy_auth = 'user:pass'
@wpscan_options.proxy_auth = proxy_auth
expect(@wpscan_options.proxy_auth).to be === proxy_auth
end
end
describe '#enumerate_plugins=' do
it 'should raise an error' do
@wpscan_options.enumerate_only_vulnerable_plugins = true
expect { @wpscan_options.enumerate_plugins = true }.to raise_error(
RuntimeError, 'Please choose only one plugin enumeration option'
)
end
it 'should not raise an error' do
@wpscan_options.enumerate_only_vulnerable_plugins = false
@wpscan_options.enumerate_plugins = true
expect(@wpscan_options.enumerate_plugins).to be_truthy
end
end
describe '#enumerate_themes=' do
it 'should raise an error' do
@wpscan_options.enumerate_only_vulnerable_themes = true
expect { @wpscan_options.enumerate_themes = true }.to raise_error(
RuntimeError, 'Please choose only one theme enumeration option'
)
end
it 'should not raise an error' do
@wpscan_options.enumerate_only_vulnerable_themes = false
@wpscan_options.enumerate_themes = true
expect(@wpscan_options.enumerate_themes).to be_truthy
end
end
describe '#enumerate_only_vulnerable_plugins=' do
it 'should raise an error' do
@wpscan_options.enumerate_plugins = true
expect { @wpscan_options.enumerate_only_vulnerable_plugins = true }.to raise_error(
RuntimeError, 'Please choose only one plugin enumeration option'
)
end
it 'should not raise an error' do
@wpscan_options.enumerate_plugins = false
@wpscan_options.enumerate_only_vulnerable_plugins = true
expect(@wpscan_options.enumerate_only_vulnerable_plugins).to be_truthy
end
end
describe '#enumerate_only_vulnerable_themes=' do
it 'should raise an error' do
@wpscan_options.enumerate_themes = true
expect { @wpscan_options.enumerate_only_vulnerable_themes = true }.to raise_error(
RuntimeError, 'Please choose only one theme enumeration option'
)
end
it 'should not raise an error' do
@wpscan_options.enumerate_themes = false
@wpscan_options.enumerate_only_vulnerable_themes = true
expect(@wpscan_options.enumerate_only_vulnerable_themes).to be_truthy
end
end
describe '#enumerate_all_themes=' do
it 'should raise an error' do
@wpscan_options.enumerate_themes = true
expect { @wpscan_options.enumerate_all_themes = true }.to raise_error(
RuntimeError, 'Please choose only one theme enumeration option'
)
end
it 'should not raise an error' do
@wpscan_options.enumerate_themes = false
@wpscan_options.enumerate_all_themes = true
expect(@wpscan_options.enumerate_all_themes).to be_truthy
end
end
describe '#enumerate_all_plugins=' do
it 'should raise an error' do
@wpscan_options.enumerate_plugins = true
expect { @wpscan_options.enumerate_all_plugins = true }.to raise_error(
RuntimeError, 'Please choose only one plugin enumeration option'
)
end
it 'should not raise an error' do
@wpscan_options.enumerate_plugins = false
@wpscan_options.enumerate_all_plugins = true
expect(@wpscan_options.enumerate_all_plugins).to be_truthy
end
end
describe '#has_options?' do
it 'should return false' do
expect(@wpscan_options.has_options?).to be_falsey
end
it 'should return true' do
@wpscan_options.verbose = false
expect(@wpscan_options.has_options?).to be_truthy
end
end
describe '#to_h' do
it 'should return an empty hash' do
expect(@wpscan_options.to_h).to be_a Hash
expect(@wpscan_options.to_h).to be_empty
end
it 'should return a hash with :verbose = true' do
expected = {verbose: true}
@wpscan_options.verbose = true
expect(@wpscan_options.to_h).to be === expected
end
end
describe '#clean_option' do
after :each do
expect(WpscanOptions.clean_option(@option)).to be === @expected
end
it "should return 'url'" do
@option = '--url'
@expected = 'url'
end
it "should return 'u'" do
@option = '-u'
@expected = 'u'
end
it "should return 'follow_redirection'" do
@option = '--follow-redirection'
@expected = 'follow_redirection'
end
end
describe '#option_to_instance_variable_setter' do
after :each do
expect(WpscanOptions.option_to_instance_variable_setter(@argument)).to be === @expected
end
it 'should return :url=' do
@argument = '--url'
@expected = :url=
end
it 'should return :verbose=' do
@argument = '--verbose'
@expected = :verbose=
end
it 'should return :proxy= for --proxy' do
@argument = '--proxy'
@expected = :proxy=
end
it 'should return nil for --enumerate' do
@argument = '--enumerate'
@expected = nil
end
it 'should return :proxy_auth= for --proxy_auth' do
@argument = '--proxy_auth'
@expected = :proxy_auth=
end
end
describe '#is_long_option?' do
it 'should return true' do
expect(WpscanOptions.is_long_option?('--url')).to be_truthy
end
it 'should return false' do
expect(WpscanOptions.is_long_option?('hello')).to be_falsey
expect(WpscanOptions.is_long_option?('--enumerate')).to be_falsey
end
end
describe '#enumerate_options_from_string' do
after :each do
if @argument
wpscan_options = WpscanOptions.new
wpscan_options.enumerate_options_from_string(@argument)
expect(wpscan_options.to_h).to be === @expected_hash
end
end
it 'should raise an error if p and p! are ' do
expect { @wpscan_options.enumerate_options_from_string('p,vp') }.to raise_error
end
it 'should set enumerate_plugins to true' do
@argument = 'p'
@expected_hash = {enumerate_plugins: true}
end
it 'should set enumerate_only_vulnerable_plugins to tue' do
@argument = 'vp'
@expected_hash = {enumerate_only_vulnerable_plugins: true}
end
it 'should set enumerate_timthumbs to true' do
@argument = 'tt'
@expected_hash = {enumerate_timthumbs: true}
end
it 'should set enumerate_usernames to true' do
@argument = 'u'
@expected_hash = {enumerate_usernames: true}
end
it 'should set enumerate_usernames to true and enumerate_usernames_range to (1..20)' do
@argument = 'u[1-20]'
@expected_hash = {enumerate_usernames: true, enumerate_usernames_range: (1..20)}
end
# Let's try some multiple choices
it 'should set enumerate_timthumbs to true, enumerate_usernames to true, enumerate_usernames_range to (1..2)' do
@argument = 'u[1-2],tt'
@expected_hash = {
enumerate_usernames: true, enumerate_usernames_range: (1..2),
enumerate_timthumbs: true
}
end
end
describe '#set_option_from_cli' do
it 'should raise an error with unknow option' do
expect { @wpscan_options.set_option_from_cli('hello', '') }.to raise_error
end
it 'should set @url to example.com' do
@wpscan_options.set_option_from_cli('--url', 'example.com')
expect(@wpscan_options.url).to be === 'http://example.com'
end
it 'should set @enumerate_plugins to true' do
@wpscan_options.set_option_from_cli('--enumerate', 'p')
expect(@wpscan_options.enumerate_plugins).to be_truthy
expect(@wpscan_options.enumerate_only_vulnerable_plugins).to be_nil
end
it 'should set @enumerate_only_vulnerable_plugins, @enumerate_timthumbs and @enumerate_usernames to true if no argument is given' do
@wpscan_options.set_option_from_cli('--enumerate', '')
expect(@wpscan_options.enumerate_only_vulnerable_plugins).to be_truthy
expect(@wpscan_options.enumerate_timthumbs).to be_truthy
expect(@wpscan_options.enumerate_usernames).to be_truthy
end
end
describe '#load_from_arguments' do
after :each do
set_argv(@argv)
wpscan_options = WpscanOptions.load_from_arguments
expect(wpscan_options.to_h).to be === @expected_hash
end
it 'should return {}' do
@argv = ''
@expected_hash = {}
end
it "should return {:url => 'example.com'}" do
@argv = '--url example.com'
@expected_hash = { url: 'http://example.com' }
end
it "should return {:url => 'example.com'}" do
@argv = '-u example.com'
@expected_hash = { url: 'http://example.com' }
end
it "should return {:username => 'admin'}" do
@argv = '--username admin'
@expected_hash = { username: 'admin' }
end
it "should return {:username => 'Youhou'}" do
@argv = '-U Youhou'
@expected_hash = { username: 'Youhou' }
end
it "should return {:url => 'example.com', :threads => 5, :force => ''}" do
@argv = '-u example.com --force -t 5'
@expected_hash = { url: 'http://example.com', threads: 5, force: '' }
end
it "should return {:url => 'example.com', :enumerate_plugins => true, :enumerate_timthumbs => true}" do
@argv = '-u example.com -e p,tt'
@expected_hash = { url: 'http://example.com', enumerate_plugins: true, enumerate_timthumbs: true }
end
end
end