Merge branch 'new-enumeration-system'

This commit is contained in:
erwanlr
2013-04-05 14:07:06 +02:00
292 changed files with 6555 additions and 26491 deletions

View File

@@ -1,21 +1,4 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
require 'spec_helper'

View File

@@ -1,21 +1,4 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
require 'spec_helper'

View File

@@ -0,0 +1,29 @@
#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: WpItems.new << WpItem.new(uri, name: 'js-source') <<
WpItem.new(uri, name: 'escaped-url') <<
WpItem.new(uri, name: 'link-tag') <<
WpItem.new(uri, name: 'script-tag') <<
WpItem.new(uri, name: 'style-tag')
}
end
end
end

View File

@@ -0,0 +1,30 @@
#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_VULNS_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: 'js-source') <<
WpPlugin.new(uri, name: 'escaped-url') <<
WpPlugin.new(uri, name: 'link-tag') <<
WpPlugin.new(uri, name: 'script-tag') <<
WpPlugin.new(uri, name: 'style-tag')
}
end
end
end

View File

@@ -0,0 +1,28 @@
#encoding: UTF-8
require 'spec_helper'
describe WpThemes do
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_VULNS_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')
}
end
end
end

View File

@@ -0,0 +1,123 @@
# 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
}.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
subject.passive_detection(wp_target).should == subject.new
end
end
describe '::targets_items_from_file' do
after do
targets = subject.send(:targets_items_from_file, file, wp_target)
targets.map { |t| t.url }.should == @expected.map { |t| t.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)
targets.map { |t| t.url }.should == expected_targets_from_theme(theme).map { |t| t.url }
end
end
describe '::targets_items' do
let(:options) { {} }
after do
targets = subject.send(:targets_items, wp_target, options)
targets.map { |t| t.url }.should == @expected.sort.map { |t| t.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

@@ -0,0 +1,59 @@
# 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
subject.request_params.should === {}
end
end
describe '::passive_detection' do
it 'return an empty WpUsers' do
subject.passive_detection(wp_target).should == subject.new
end
end
describe '::targets_items' do
after do
targets = subject.send(:targets_items, wp_target, options)
targets.should == @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,76 +0,0 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
require File.expand_path(File.dirname(__FILE__) + '../../../lib/wpscan/wpscan_helper')
describe 'common_helper' do
describe '#get_equal_string' do
after :each do
output = get_equal_string_end(@input)
output.should == @expected
end
it 'sould return an empty string' do
@input = ['']
@expected = ''
end
it 'sould return an empty string' do
@input = []
@expected = ''
end
it 'sould return asdf' do
@input = ['kjh asdf', 'oijr asdf']
@expected = ' asdf'
end
it 'sould return &laquo; BlogName' do
@input = ['user1 &laquo; BlogName',
'user2 &laquo; BlogName',
'user3 &laquo; BlogName',
'user4 &laquo; BlogName']
@expected = ' &laquo; BlogName'
end
it 'sould return an empty string' do
@input = %w{user1 user2 user3 user4}
@expected = ''
end
it 'sould return an empty string' do
@input = ['user1 &laquo; BlogName',
'user2 &laquo; BlogName',
'user3 &laquo; BlogName',
'user4 &laquo; BlogNamea']
@expected = ''
end
it 'sould return an empty string' do
@input = %w{ user1 }
@expected = ''
end
it 'sould return | test' do
@input = ['admin | test', 'test | test']
@expected = ' | test'
end
end
end

View File

@@ -0,0 +1,28 @@
# encoding: UTF-8
require 'spec_helper'
describe Vulnerability::Output do
let(:modules_url) { 'http://www.metasploit.com/modules/' }
describe '::metasploit_module_url' do
after :each do
Vulnerability::Output.metasploit_module_url(@module).should == @expected
end
it 'removes the leading slash' do
@module = '/exploit/testing'
@expected = modules_url + 'exploit/testing'
end
it 'returns the correct url' do
@module = 'gathering/yolo'
@expected = modules_url + @module
end
end
describe '#output' do
# How to test it ? oO
end
end

View File

@@ -0,0 +1,41 @@
# encoding: UTF-8
require 'spec_helper'
describe Vulnerability do
describe '#new' do
subject(:vulnerability) { Vulnerability.new(title, type, references, modules) }
let(:title) { 'A vulnerability title' }
let(:type) { 'XSS' }
let(:references) { %w{http://ref1.com http://ref2.com} }
context 'w/o metasploit 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(:metasploit_modules) { should be_empty }
end
context 'with metasploit modules argument' do
let(:modules) { %w{exploit/some_exploit exploit/unix/anotherone } }
its(:metasploit_modules) { should be modules }
end
end
describe '::load_from_xml_node' do
subject(:vulnerability) { Vulnerability.load_from_xml_node(node) }
let(:node) {
xml(MODELS_FIXTURES + '/vulnerability/xml_node.xml').xpath('//vulnerability')
}
its(:title) { should == 'Vuln Title' }
its(:type) { should == 'CSRF' }
its(:references) { should == ['Ref 1', 'Ref 2'] }
its(:metasploit_modules) { should == %w{exploit/ex1} }
end
end

View File

@@ -0,0 +1,163 @@
# 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(:readme_url) { uri.merge('readme.txt').to_s }
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(:vulns_file) { MODELS_FIXTURES + '/wp_item/vulnerable/items_vulns.xml' }
let(:vulns_xpath) { "//item[@name='neo']/vulnerability" }
let(:expected_vulns) { Vulnerabilities.new << Vulnerability.new("I'm the one", 'XSS', ['http://ref1.com']) }
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) { should == 'wp-content' }
its(:wp_plugins_dir) { should == 'wp-content/plugins' }
its(:uri) { should be uri }
end
context 'with :wp_content_dir' do
let(:options) { { wp_content_dir: 'custom' } }
its(:wp_content_dir) { should == 'custom' }
its(:wp_plugins_dir) { should == 'custom/plugins' }
end
context 'with :wp_plugins_dir' do
let(:options) { { wp_plugins_dir: 'c-plugins' } }
its(:wp_content_dir) { should == 'wp-content' }
its(:wp_plugins_dir) { should == 'c-plugins' }
end
end
describe '#set_options' do
context 'no an allowed option' do
it 'ignores the option' do
wp_item.should_not_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
wp_item.stub(: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
wp_item.path.should == @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 {
wp_item.stub(:wp_content_dir).and_return('custom-content')
wp_item.stub(: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
it 'also encodes chars' do
@path = 'some dir with spaces'
@expected = 'some%20dir%20with%20spaces'
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
wp_item.uri.should == 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')
wp_item.<=>(other).should === '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')
wp_item.should == other
end
end
context 'otherwise' do
it 'is not ==' do
wp_item.name = 'Test'
other = WpItem.new(uri, name: 'hello')
wp_item.should_not == 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
WpItem.new(uri, options).should === WpItem.new(uri.merge('yo'), options)
end
end
context 'otherwise' do
it 'is not ===' do
WpItem.new(uri, options).should_not === WpItem.new(uri, options.merge(version: '1.0'))
end
end
end
end

View File

@@ -0,0 +1,21 @@
# 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(:vulns_file) { MODELS_FIXTURES + '/wp_plugin/vulnerable/plugins_vulns.xml' }
let(:expected_vulns) { Vulnerabilities.new << Vulnerability.new('Follow me!', 'REDIRECT', ['http://ref2.com']) }
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') { should == 'http://example.com/wp-content/plugins/plugin-name/' }
end
end

View File

@@ -0,0 +1,135 @@
# 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
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)
if @expected
wp_theme.should be_a WpTheme
end
wp_theme.should == @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
it 'returns the WpTheme' do
@file = 'relative_urls.html'
@expected = WpTheme.new(uri, name: 'theme_name')
end
end
end
describe '::find_from_wooframework' do
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
wp_theme.should be_a WpTheme
end
wp_theme.should == @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|
WpTheme.stub(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()
WpTheme.find(uri).should be_nil
end
end
context 'when the theme is found' do
it 'returns it, with the :found_from set' do
stub_all_to_nil()
expected = WpTheme.new(uri, name: 'the-oracle')
WpTheme.stub(:find_from_css_link).and_return(expected)
wp_theme = WpTheme.find(uri)
wp_theme.should be_a WpTheme
wp_theme.should == expected
wp_theme.found_from.should === 'css link'
end
end
end
end

View File

@@ -0,0 +1,40 @@
# 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(:vulns_file) { MODELS_FIXTURES + '/wp_theme/vulnerable/themes_vulns.xml' }
let(:expected_vulns) { Vulnerabilities.new << Vulnerability.new('I see you', 'FPD', ['http://ref.com']) }
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) { should include :style_url }
end
describe '#forge_uri' do
its(:uri) { should == uri.merge(theme_path) }
end
describe '#style_url' do
its(:style_url) { should == uri.merge(theme_path + '/style.css').to_s }
context 'when its already set' do
it 'returns it instead of the default one' do
url = uri.merge(theme_path + '/custom.css').to_s
wp_theme.style_url = url
wp_theme.style_url.should == url
end
end
end
end

View File

@@ -0,0 +1,31 @@
# 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
WpTimthumb.new(uri, path: 'timtuhumb.php').
should ==
WpTimthumb.new(uri, path: 'timtuhumb.php')
end
end
context 'when urls are different' do
it 'returns false' do
WpTimthumb.new(uri, path: 'hello/timtuhumb.php').
should_not ==
WpTimthumb.new(uri, path: 'some-dir/timtuhumb.php')
end
end
end
end

View File

@@ -0,0 +1,87 @@
# encoding: UTF-8
require 'spec_helper'
describe WpUser do
it_behaves_like 'WpUser::Existable'
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) { should include sym }
end
its(:allowed_options) { should_not 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
wp_user.uri.should == uri.merge('?author=2')
end
end
end
describe '#to_s' do
after do
subject.id = 1
subject.to_s.should == @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)
wp_user.<=>(other).should === 1.<=>(3)
end
end
describe '#===, #==' do
context 'when the :id and :login are the same' do
it 'is ===, and ==' do
WpUser.new(uri, id: 1, name: 'yo').should == WpUser.new(uri, id: 1, name: 'yo')
end
end
context 'when :id and :login are different' do
it 'is not === or ==' do
WpUser.new(uri, id: 1, name: 'yo').should_not == WpUser.new(uri, id: 2, name:'yo')
end
end
end
end

View File

@@ -0,0 +1,202 @@
# 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)
WpVersion.send(method, uri).should == @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
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
)
version.should == @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)
WpVersion.send(:find_from_readme, uri).should == @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
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)
WpVersion.send(:find_from_links_opml, uri).should == @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' do
# Stub all WpVersion::find_from_* to return nil
def stub_all_to_nil
WpVersion.methods.grep(/^find_from_/).each do |method|
WpVersion.stub(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
version = WpVersion.find(uri, wp_content_dir, wp_plugins_dir, version_xml)
version.should == @expected
if @expected
version.found_from.should == @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()
WpVersion.stub(method).and_return(number)
@expected = WpVersion.new(uri, number: number)
@found_from = found_from
end
end
end
end
end

View File

@@ -0,0 +1,23 @@
# encoding: UTF-8
require 'spec_helper'
describe WpVersion do
it_behaves_like 'WpVersion::Vulnerable'
it_behaves_like 'WpItem::Vulnerable' do
let(:options) { { number: '3.2' } }
let(:vulns_file) { MODELS_FIXTURES + '/wp_version/vulnerable/versions_vulns.xml' }
let(:expected_vulns) { Vulnerabilities.new << Vulnerability.new('Here I Am', 'SQLI', ['http://ref1.com']) }
end
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) { should include sym }
end
end
end

View File

@@ -1,21 +1,4 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
shared_examples_for 'BruteForce' do
before :each do
@@ -59,7 +42,7 @@ shared_examples_for 'BruteForce' do
)
end
user = WpUser.new('admin', 1, nil)
user = WpUser.new(@module.uri, login: 'admin')
result = @module.brute_force([user], @wordlist)
result.length.should == 1
@@ -69,7 +52,7 @@ shared_examples_for 'BruteForce' do
it 'should cover the timeout branch and return an empty array' do
stub_request(:post, @module.login_url).to_timeout
user = WpUser.new('admin', 1, nil)
user = WpUser.new(@module.uri, login: 'admin')
result = @module.brute_force([user], @wordlist)
result.should == []
end

View File

@@ -1,21 +1,4 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
shared_examples_for 'Malwares' do

View File

@@ -1,21 +1,4 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
shared_examples_for 'WpConfigBackup' do

View File

@@ -1,21 +1,4 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
shared_examples_for 'WpFullPathDisclosure' do

View File

@@ -1,27 +1,11 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
shared_examples_for 'WpLoginProtection' do
before :each do
@module = WpScanModuleSpec.new('http://example.localhost')
@module.extend(WpLoginProtection)
@module.stub(:wp_plugins_dir).and_return('wp-content/plugins')
@fixtures_dir = SPEC_FIXTURES_WPSCAN_MODULES_DIR + '/wp_login_protection'
end
@@ -70,10 +54,10 @@ shared_examples_for 'WpLoginProtection' do
expected = plugin_name_from_fixture === plugin_name_from_symbol ? true : false
it "#{symbol_to_call} with #{fixture} should return #{expected}" do
@plugin_name = plugin_name_from_fixture
@fixture = @fixtures_dir + '/' + fixture
@plugin_name = plugin_name_from_fixture
@fixture = @fixtures_dir + '/' + fixture
@symbol_to_call = symbol_to_call
@expected = expected
@expected = expected
end
end
end
@@ -89,33 +73,25 @@ shared_examples_for 'WpLoginProtection' do
stub_request(:get, @module.send(:limit_login_attempts_url).to_s).to_return(status: 404)
stub_request(:get, @module.send(:bluetrait_event_viewer_url).to_s).to_return(status: 404)
@module.login_protection_plugin().should === @plugin_expected
@module.login_protection_plugin().should == @plugin_expected
@module.has_login_protection?.should === @has_protection_expected
end
it 'should return nil if no protection is present' do
@fixture = @fixtures_dir + '/wp-login-clean.php'
@plugin_expected = nil
@fixture = @fixtures_dir + '/wp-login-clean.php'
@plugin_expected = nil
@has_protection_expected = false
end
it 'should return a login-lockdown WpPlugin object' do
@fixture = @fixtures_dir + '/wp-login-login_lockdown.php'
@plugin_expected = WpPlugin.new(
base_url: @module.url,
path: '/plugins/login-lockdown/',
name: 'login-lockdown'
)
@fixture = @fixtures_dir + '/wp-login-login_lockdown.php'
@plugin_expected = WpPlugin.new(@module.uri, name: 'login-lockdown')
@has_protection_expected = true
end
it 'should return a login-lock WpPlugin object' do
@fixture = @fixtures_dir + '/wp-login-login_lock.php'
@plugin_expected = WpPlugin.new(
base_url: @module.url,
path: '/plugins/login-lock/',
name: 'login-lock'
)
@fixture = @fixtures_dir + '/wp-login-login_lock.php'
@plugin_expected = WpPlugin.new(@module.uri, name: 'login-lock')
@has_protection_expected = true
end
end

View File

@@ -1,197 +0,0 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
shared_examples_for 'WpPlugins' do
before :all do
@fixtures_dir = SPEC_FIXTURES_WPSCAN_MODULES_DIR + '/wp_plugins'
@plugins_file = @fixtures_dir + '/plugins.txt'
@plugin_vulns_file = @fixtures_dir + '/plugin_vulns.xml'
@wp_url = 'http://example.localhost/'
end
before :each do
@module = WpScanModuleSpec.new(@wp_url)
@module.error_404_hash = Digest::MD5.hexdigest('Error 404!')
@module.homepage_hash = Digest::MD5.hexdigest('Homepage!')
@module.extend(WpPlugins)
@options = {
base_url: @wp_url,
only_vulnerable_ones: false,
show_progression: false,
error_404_hash: @module.error_404_hash,
homepage_hash: @module.homepage_hash,
vulns_file: @plugin_vulns_file,
file: @plugins_file,
type: 'plugins',
wp_content_dir: 'wp-content',
vulns_xpath_2: '//plugin'
}
File.exist?(@plugin_vulns_file).should == true
File.exist?(@plugins_file).should == true
# These targets are listed in @fixtures_dir + '/plugins.txt'
# TODO : load them directly from the fixture file
@targets = [
WpPlugin.new(
{
base_url: 'http://example.localhost/',
path: 'exclude-pages/exclude_pages.php',
wp_content_dir: 'wp-content',
name: 'exclude-pages'
}),
WpPlugin.new(
{
base_url: 'http://example.localhost/',
path: 'display-widgets/display-widgets.php',
wp_content_dir: 'wp-content',
name: 'display-widgets'
}),
WpPlugin.new(
{
base_url: 'http://example.localhost/',
path: 'media-library',
wp_content_dir: 'wp-content',
name: 'media-library'
}),
WpPlugin.new(
{
base_url: 'http://example.localhost/',
path: 'deans',
wp_content_dir: 'wp-content',
name: 'deans'
}),
WpPlugin.new(
{
base_url: 'http://example.localhost/',
path: 'formidable/formidable.php',
wp_content_dir: 'wp-content',
name: 'formidable'
}),
WpPlugin.new(
{
base_url: 'http://example.localhost/',
path: 'regenerate-thumbnails/readme.txt',
wp_content_dir: 'wp-content',
name: 'regenerate-thumbnails'
})
]
end
describe '#plugins_from_passive_detection' do
let(:passive_detection_fixtures) { @fixtures_dir + '/passive_detection' }
it 'should return an empty array' do
stub_request_to_fixture(url: @module.url, fixture: File.new(passive_detection_fixtures + '/no_plugins.htm'))
plugins = @module.plugins_from_passive_detection(base_url: @module.url, wp_content_dir: 'wp-content')
plugins.should be_empty
end
it 'should return the expected plugins' do
stub_request_to_fixture(url: @module.url, fixture: File.new(passive_detection_fixtures + '/various_plugins.htm'))
expected_plugin_names = %w{
wp-minify
comment-info-tip
tweet-blender
optinpop
s2member
wp-polls
commentluv
}
expected_plugins = []
expected_plugin_names.each do |plugin_name|
expected_plugins << WpPlugin.new(
base_url: @module.url,
path: "/plugins/#{plugin_name}/",
name: plugin_name
)
end
plugins = @module.plugins_from_passive_detection(base_url: @module.url, wp_content_dir: 'wp-content')
plugins.should_not be_empty
plugins.length.should == expected_plugins.length
plugins.sort.should == expected_plugins.sort
end
end
describe '#plugins_from_aggressive_detection' do
before :each do
stub_request(:get, @module.uri.to_s).to_return(status: 200)
# Point all targets to a 404
@targets.each do |target|
stub_request(:get, target.get_full_url.to_s).to_return(status: 404)
# to_s calls readme_url
stub_request(:get, target.readme_url.to_s).to_return(status: 404)
end
end
after :each do
@passive_detection_fixture = SPEC_FIXTURES_DIR + '/empty-file' unless @passive_detection_fixture
stub_request_to_fixture(url: "#{@module.uri}/".sub(/\/\/$/, '/'), fixture: @passive_detection_fixture)
detected = @module.plugins_from_aggressive_detection(@options)
detected.length.should == @expected_plugins.length
detected.sort.should == @expected_plugins.sort
end
it 'should return an empty array' do
@expected_plugins = []
end
it 'should return an array with 3 WpPlugin (1 detected from passive method)' do
@passive_detection_fixture = @fixtures_dir + '/passive_detection/one_plugin.htm'
@expected_plugins = @targets.sample(2)
@expected_plugins.each do |p|
stub_request(:get, p.get_full_url.to_s).to_return(status: 200)
end
new_plugin = WpPlugin.new(
base_url: 'http://example.localhost/',
path: '/plugins/comment-info-tip/',
name: 'comment-info-tip'
)
stub_request(:get, new_plugin.readme_url.to_s).to_return(status: 200)
@expected_plugins << new_plugin
end
# testing response codes
WpTarget.valid_response_codes.each do |valid_response_code|
it "should detect the plugin if the reponse.code is #{valid_response_code}" do
@expected_plugins = []
plugin_url = [@targets.sample(1)[0]]
plugin_url.should_not be_nil
plugin_url.length.should == 1
@expected_plugins = plugin_url
stub_request(:get, plugin_url[0].get_full_url.to_s).to_return(status: valid_response_code)
end
end
it 'should not detect the plugin if there is a redirection to the homepage' do
# Let's pick up 2 plugins (The first one will redirect to the homepage)
plugins = @targets.sample(2)
stub_request(:get, plugins[0].get_full_url.to_s).to_return(status: 200, body: 'Homepage!')
stub_request(:get, plugins[1].get_full_url.to_s).to_return(status: 200)
@expected_plugins = [plugins[1]]
end
end
end

View File

@@ -1,21 +1,4 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
shared_examples_for 'WpReadme' do

View File

@@ -1,211 +0,0 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
shared_examples_for 'WpThemes' do
before :all do
@fixtures_dir = SPEC_FIXTURES_WPSCAN_MODULES_DIR + '/wp_themes'
@themes_file = @fixtures_dir + '/themes.txt'
@theme_vulns_file = @fixtures_dir + '/theme_vulns.xml'
@wp_url = 'http://example.localhost/'
end
before :each do
@module = WpScanModuleSpec.new(@wp_url)
@module.error_404_hash = Digest::MD5.hexdigest('Error 404!')
@module.extend(WpThemes)
@options = {
base_url: @wp_url,
only_vulnerable_ones: false,
show_progression: false,
error_404_hash: Digest::MD5.hexdigest('Error 404!'),
vulns_file: @theme_vulns_file,
file: @themes_file,
type: 'themes',
wp_content_dir: 'wp-content',
vulns_xpath_2: '//theme'
}
File.exist?(@theme_vulns_file).should == true
File.exist?(@themes_file).should == true
@targets = [
WpTheme.new({
base_url: 'http://example.localhost/',
path: 'zenpro/404.php',
wp_content_dir: 'wp-content',
name: 'zenpro'
}),
WpTheme.new({
base_url: 'http://example.localhost/',
path: 'zeta-zip/404.php',
wp_content_dir: 'wp-content',
name: 'zeta-zip'
}),
WpTheme.new({
base_url: 'http://example.localhost/',
path: 'zfirst/404.php',
wp_content_dir: 'wp-content',
name: 'zfirst'
}),
WpTheme.new({
base_url: 'http://example.localhost/',
path: 'zgrey/404.php',
wp_content_dir: 'wp-content',
name: 'zgrey'
}),
WpTheme.new({
base_url: 'http://example.localhost/',
path: 'zindi-ii/404.php',
wp_content_dir: 'wp-content',
name: 'zindi-ii'
}),
WpTheme.new({
base_url: 'http://example.localhost/',
path: 'zindi/404.php',
wp_content_dir: 'wp-content',
name: 'zindi'
}),
WpTheme.new({
base_url: 'http://example.localhost/',
path: 'zombie-apocalypse/404.php',
wp_content_dir: 'wp-content',
name: 'zombie-apocalypse'
}),
WpTheme.new({
base_url: 'http://example.localhost/',
path: 'zsofa/404.php',
wp_content_dir: 'wp-content',
name: 'zsofa'
}),
WpTheme.new({
base_url: 'http://example.localhost/',
path: 'zwei-seiten/404.php',
wp_content_dir: 'wp-content',
name: 'zwei-seiten'
}),
WpTheme.new({
base_url: 'http://example.localhost/',
path: 'twentyten/404.php',
wp_content_dir: 'wp-content',
name: 'twentyten'
}),
WpTheme.new({
base_url: 'http://example.localhost/',
path: 'shopperpress',
wp_content_dir: 'wp-content',
name: 'shopperpress'
}),
WpTheme.new({
base_url: 'http://example.localhost/',
path: 'wise',
wp_content_dir: 'wp-content',
name: 'wise'
}),
WpTheme.new({
base_url: 'http://example.localhost/',
path: 'webfolio',
wp_content_dir: 'wp-content',
name: 'webfolio'
})
]
end
describe '#themes_from_passive_detection' do
let(:passive_detection_fixtures) { @fixtures_dir + '/passive_detection' }
it 'should return an empty array' do
stub_request_to_fixture(url: @module.url, fixture: File.new(passive_detection_fixtures + '/no_theme.htm'))
themes = @module.themes_from_passive_detection(base_url: @module.url, wp_content_dir: 'wp-content')
themes.should be_empty
end
it 'should return the expected themes' do
stub_request_to_fixture(url: @module.url, fixture: File.new(passive_detection_fixtures + '/various_themes.htm'))
expected_theme_names = %w{ theme1 theme2 theme3 }
expected_themes = []
expected_theme_names.each do |theme_name|
expected_themes << WpTheme.new(
base_url: @module.url,
path: "/themes/#{theme_name}/",
name: theme_name
)
end
themes = @module.themes_from_passive_detection(base_url: @module.url, wp_content_dir: 'wp-content')
themes.should_not be_empty
themes.length.should == expected_themes.length
themes.sort.should == expected_themes.sort
end
end
describe '#themes_from_aggressive_detection' do
before :each do
stub_request(:get, @module.uri.to_s).to_return(status: 200)
# Point all targets to a 404
@targets.each do |target|
stub_request(:get, target.get_full_url.to_s).to_return(status: 404)
# to_s calls readme_url
stub_request(:get, target.readme_url.to_s).to_return(status: 404)
end
end
after :each do
@passive_detection_fixture = SPEC_FIXTURES_DIR + '/empty-file' unless @passive_detection_fixture
stub_request_to_fixture(url: "#{@module.uri}/".sub(/\/\/$/, '/'), fixture: @passive_detection_fixture)
detected = @module.themes_from_aggressive_detection(@options)
detected.length.should == @expected_themes.length
detected.sort.should == @expected_themes.sort
end
it 'should return an empty array' do
@expected_themes = []
end
it 'should return an array with 3 WpTheme (1 detected from passive method)' do
@passive_detection_fixture = @fixtures_dir + '/passive_detection/one_theme.htm'
@expected_themes = @targets.sample(2)
@expected_themes.each do |p|
stub_request(:get, p.get_full_url.to_s).to_return(status: 200)
end
new_theme = WpTheme.new(
base_url: 'http://example.localhost/',
path: '/themes/custom-twentyten/',
name: 'custom-twentyten'
)
stub_request(:get, new_theme.readme_url.to_s).to_return(status: 200)
@expected_themes << new_theme
end
# testing response codes
WpTarget.valid_response_codes.each do |valid_response_code|
it "should detect the theme if the reponse.code is #{valid_response_code}" do
@expected_themes = []
theme_url = [@targets.sample(1)[0]]
theme_url.should_not be_nil
theme_url.length.should == 1
@expected_themes = theme_url
stub_request(:get, theme_url[0].get_full_url.to_s).to_return(status: valid_response_code)
end
end
end
end

View File

@@ -1,115 +0,0 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
shared_examples_for 'WpTimthumbs' do
before :each do
@options = {}
@url = 'http://example.localhost/'
@theme_name = 'bueno'
@options[:base_url] = @url
@options[:wp_content_dir] = 'wp-content'
@options[:name] = @theme_name
@options[:error_404_hash] = 'xx'
@options[:show_progression] = false
@options[:only_vulnerable_ones] = false
@options[:vulns_file] = 'xx'
@options[:type] = 'timthumbs'
@module = WpScanModuleSpec.new(@url)
@fixtures_dir = SPEC_FIXTURES_WPSCAN_MODULES_DIR + '/wp_timthumbs'
@timthumbs_file = @fixtures_dir + '/timthumbs.txt'
@targets_from_file = %w{
http://example.localhost/wp-content/plugins/fotoslide/timthumb.php
http://example.localhost/wp-content/plugins/feature-slideshow/timthumb.php
}
@targets_from_theme =
[
'http://example.localhost/wp-content/themes/' + @theme_name + '/timthumb.php',
'http://example.localhost/wp-content/themes/' + @theme_name + '/lib/timthumb.php',
'http://example.localhost/wp-content/themes/' + @theme_name + '/inc/timthumb.php',
'http://example.localhost/wp-content/themes/' + @theme_name + '/includes/timthumb.php',
'http://example.localhost/wp-content/themes/' + @theme_name + '/scripts/timthumb.php',
'http://example.localhost/wp-content/themes/' + @theme_name + '/tools/timthumb.php',
'http://example.localhost/wp-content/themes/' + @theme_name + '/functions/timthumb.php'
]
@module.extend(WpTimthumbs)
end
describe '#targets_url_from_theme' do
it 'should return the targets for the theme' do
targets = @module.send(:targets_url_from_theme, @theme_name, @options)
targets.should_not be_empty
targets.length.should > 0
temp = []
targets.each do |t|
temp << t.get_full_url.to_s
end
temp.sort.should === @targets_from_theme.sort
end
end
describe '#timthumbs and #has_timthumbs?' do
before :each do
@options[:file] = @timthumbs_file
@targets_from_file.each do |url|
stub_request(:get, url).to_return(status: 404)
end
end
it 'should return an empty array' do
timthumbs = @module.timthumbs(nil, @options)
timthumbs.should be_empty
@module.has_timthumbs?(nil, @options).should be_false
end
it 'should return an array with 7 elements (from passive detection)' do
stub_request(:get, %r{http://example\.localhost/wp-content/themes/my-theme/.*}).to_return(status: 200)
timthumbs = @module.timthumbs('my-theme', @options)
timthumbs.length.should == 7
end
it 'should return an array with 2 timthumbs url' do
expected = []
urls = []
urls_hash = WpEnumerator.generate_items(@options)
urls_hash.each do |u|
url = u.get_full_url.to_s
urls << url
stub_request(:get, url).to_return(status: 404)
end
urls.sample(2).each do |target_url|
expected << target_url
stub_request(:get, target_url).
to_return(status: 200, body: File.new(@fixtures_dir + '/timthumb.php'))
end
timthumbs = @module.timthumbs(nil, @options)
timthumbs.should_not be_empty
temp = []
timthumbs.each do |t|
temp << t.get_full_url.to_s
end
temp.sort.should === expected.sort
@module.has_timthumbs?(nil).should be_true
end
end
end

View File

@@ -1,279 +0,0 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
shared_examples_for 'WpUsernames' do
before :each do
@target_url = 'http://example.localhost/'
@module = WpScanModuleSpec.new(@target_url)
@fixtures_dir = SPEC_FIXTURES_WPSCAN_MODULES_DIR + '/wp_usernames'
@module.extend(WpUsernames)
end
describe '#author_url' do
it 'should return the auhor url according to his id' do
@module.author_url(1).should === "#@target_url?author=1"
end
end
describe '#usernames' do
before :each do
(1..10).each do |index|
stub_request(:get, @module.author_url(index)).to_return(status: 404)
end
end
it 'should return an empty array' do
@module.usernames.should be_empty
end
it 'should return an array with 1 username (from header location)' do
stub_request(:get, @module.author_url(3)).
to_return(status: 301, headers: {'location' => '/author/Youhou'})
usernames = @module.usernames
usernames.should_not be_empty
usernames.length.should == 1
usernames[0].id.should == 3
usernames[0].name.should == 'Youhou'
usernames[0].nickname.should == 'empty'
end
it 'should return an array with 1 username (from in the body response)' do
stub_request(:get, @module.author_url(2)).
to_return(status: 200, body: File.new(@fixtures_dir + '/test.html'))
usernames = @module.usernames(range: (1..2))
usernames.should_not be_empty
usernames.should === ([WpUser.new('test', 2, 'first last | user&#039;s Blog!')])
end
it 'should return an array with 2 usernames (one is a duplicate and should not be present twice)' do
stub_request(:get, @module.author_url(4)).
to_return(status: 301, headers: {'location' => '/author/Youhou/'})
stub_request(:get, @module.author_url(2)).
to_return(status: 200, body: File.new(@fixtures_dir + '/test.html'))
usernames = @module.usernames(range: (1..5))
usernames.should_not be_empty
expected = [
WpUser.new('test', 2, 'first last | user&#039;s Blog!'),
WpUser.new('Youhou', 4, 'empty')
]
usernames.sort_by { |u| u.name }.should === expected.sort_by { |u| u.name }
end
end
describe '#get_nickname_from_url' do
after :each do
url = 'http://example.localhost/'
stub_request(:get, url).to_return(status: @status, body: @content)
username = @module.get_nickname_from_url(url)
username.should === @expected
end
it 'should return nil' do
@status = 200
@content = ''
@expected = nil
end
it 'should return nil' do
@status = 400
@content = ''
@expected = nil
end
it 'should return admin' do
@status = 200
@content = '<title>admin</title>'
@expected = 'admin'
end
it 'should return nil' do
@status = 201
@content = '<title>admin</title>'
@expected = nil
end
end
describe '#get_nickname_from_response' do
after :each do
url = 'http://example.localhost/'
stub_request(:get, url).to_return(status: @status, body: @content)
resp = Browser.instance.get(url)
nickname = @module.get_nickname_from_response(resp)
nickname.should === @expected
end
it 'should return nil' do
@status = 200
@content = ''
@expected = nil
end
it 'should return nil' do
@status = 400
@content = ''
@expected = nil
end
it 'should return admin' do
@status = 200
@content = '<title>admin</title>'
@expected = 'admin'
end
it 'should return nil' do
@status = 201
@content = '<title>admin</title>'
@expected = nil
end
end
describe '#get_username_from_response' do
after :each do
url = @module.url
stub_request_to_fixture(url: url, fixture: File.new(@fixtures_dir + @file))
resp = Browser.instance.get(url)
username = @module.get_username_from_response(resp)
username.should === @expected
end
# No Permalinks
it 'should return admin' do
@file = '/admin.html'
@expected = 'admin'
end
# With Permalinks
it 'should return test' do
@file = '/test.html'
@expected = 'test'
end
end
describe '#extract_nickname_from_body' do
after :each do
result = @module.extract_nickname_from_body(@body)
result.should === @expected
end
it 'should return admin' do
@body = '<title>admin</title>'
@expected = 'admin'
end
it 'should return nil' do
@body = '<title>adm<in</title>'
@expected = nil
end
it 'should return nil' do
@body = '<titler>admin</titler>'
@expected = nil
end
it 'should return admin | ' do
@body = '<title>admin | </title>'
@expected = 'admin | '
end
it 'should return an empty string' do
@body = '<title></title>'
@expected = ''
end
end
describe '#remove_junk_from_nickname' do
it 'should throw an exception' do
@input = nil
expect { @module.remove_junk_from_nickname(@input) }.to raise_error(RuntimeError, 'Need an array as input')
end
it 'should not throw an exception' do
@input = []
expect { @module.remove_junk_from_nickname(@input) }.to_not raise_error
end
it 'should throw an exception' do
@input = [WpOptions.new]
expect { @module.remove_junk_from_nickname(@input) }.to raise_error(RuntimeError, 'Items must be of type WpUser')
end
end
describe '#remove_junk_from_nickname' do
after :each do
result = @module.remove_junk_from_nickname(@input)
result.should === @expected
end
it 'should return an empty array' do
@input = []
@expected = @input
end
it 'should return input object' do
@input = [WpUser.new(nil, nil, nil)]
@expected = @input
end
it 'should return input object' do
@input = [WpUser.new('', '', '')]
@expected = @input
end
it 'should remove asdf' do
@input = [WpUser.new(nil, nil, 'lkjh asdf'), WpUser.new(nil, nil, 'ijrjd asdf')]
@expected = [WpUser.new(nil, nil, 'lkjh'), WpUser.new(nil, nil, 'ijrjd')]
end
it 'should return unmodified input object' do
@input = [WpUser.new(nil, nil, 'lkjh asdfa'), WpUser.new(nil, nil, 'ijrjd asdf')]
@expected = @input
end
it 'should return input object' do
@input = [WpUser.new(nil, nil, 'lkjh asdf')]
@expected = @input
end
it 'should return lkhj asdf' do
@input = [WpUser.new(nil, nil, 'lkhj asdf'), WpUser.new(nil, nil, 'lkhj asdf')]
@expected = [WpUser.new(nil, nil, ''), WpUser.new(nil, nil, '')]
end
end
# Issue 66
describe '#remove_junk_from_nickname' do
it 'should contain the string empty' do
input = [WpUser.new('admin', 1, 'admin | Wordpress 3.4.2'), WpUser.new('', 2, 'Wordpress 3.4.2')]
result = @module.remove_junk_from_nickname(input)
result[0].nickname.should === 'admin | '
result[0].name.should === 'admin'
result[0].id.should === 1
result[1].nickname.should === 'empty'
result[1].name.should === 'empty'
result[1].id.should === 2
end
end
end

View File

@@ -1,21 +1,4 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
describe 'WebSite' do
let(:fixtures_dir) { SPEC_FIXTURES_WPSCAN_WEB_SITE_DIR }

View File

@@ -1,24 +0,0 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
require File.expand_path(File.dirname(__FILE__) + '/wpscan_helper')
describe WpDetector do
# TODO
end

View File

@@ -1,24 +0,0 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
require File.expand_path(File.dirname(__FILE__) + '/wpscan_helper')
describe WpEnumerator do
# TODO
end

View File

@@ -1,587 +0,0 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
require File.expand_path(File.dirname(__FILE__) + '/wpscan_helper')
describe WpPlugin do
describe '#initialize' do
it 'should create a correct instance' do
instance = WpItem.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'test/asdf.php',
vulns_file: 'XXX.xml',
name: 'test',
vulns_xpath: 'XX',
type: 'plugins'
)
instance.wp_content_dir.should == 'wp-content'
instance.base_url.should == 'http://sub.example.com/path/to/wordpress/'
instance.path.should == 'test/asdf.php'
end
end
describe '#get_full_url' do
after :each do
arguments = {
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'test/asdf.php',
vulns_file: 'XXX.xml',
name: 'test',
vulns_xpath: 'XX',
type: 'plugins',
wp_content_dir: @wp_content_dir
}
instance = WpItem.new(arguments)
instance.get_full_url.to_s.should === @expected
end
it 'should return the correct url' do
@expected = 'http://sub.example.com/path/to/wordpress/wp-content/plugins/test/asdf.php'
end
it 'should return the correct url (custom wp_content_dir)' do
@wp_content_dir = 'custom'
@expected = 'http://sub.example.com/path/to/wordpress/custom/plugins/test/asdf.php'
end
it 'should trim / and add missing / before concatenating url' do
@wp_content_dir = '/custom/'
@expected = 'http://sub.example.com/path/to/wordpress/custom/plugins/test/asdf.php'
end
end
describe '#get_url_without_filename' do
after :each do
arguments = {
base_url: @base_url || 'http://sub.example.com/path/to/wordpress/',
path: @path || 'test/asdf.php',
vulns_file: 'XXX.xml',
name: 'test',
vulns_xpath: 'XX',
type: 'plugins',
wp_content_dir: @wp_content_dir
}
instance = WpItem.new(arguments)
instance.get_url_without_filename.to_s.should === @expected
end
it 'should return the correct url' do
@expected = 'http://sub.example.com/path/to/wordpress/wp-content/plugins/test/'
end
it 'should return the correct url (custom wp_content_dir)' do
@wp_content_dir = 'custom'
@expected = 'http://sub.example.com/path/to/wordpress/custom/plugins/test/'
end
it 'should trim / and add missing / before concatenating url' do
@wp_content_dir = '/custom/'
@expected = 'http://sub.example.com/path/to/wordpress/custom/plugins/test/'
end
it 'should not remove the last foldername' do
@path = 'test/'
@expected = 'http://sub.example.com/path/to/wordpress/wp-content/plugins/test/'
end
it 'should return the correct url (https)' do
@base_url = 'https://sub.example.com/path/to/wordpress/'
@expected = 'https://sub.example.com/path/to/wordpress/wp-content/plugins/test/'
end
it "should add the last slash if it's not present" do
@path = 'test-one'
@expected = 'http://sub.example.com/path/to/wordpress/wp-content/plugins/test-one/'
end
end
describe '#version' do
let(:fixtures_dir) { SPEC_FIXTURES_WPSCAN_WP_PLUGIN_DIR + '/version' }
before :each do
@instance = WpItem.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'test/asdf.php',
vulns_file: 'XXX.xml',
name: 'test',
vulns_xpath: 'XX',
type: 'plugins'
)
end
it 'should return a version number' do
stub_request(:get, @instance.readme_url.to_s).to_return(status: 200, body: 'Stable tag: 1.2.4.3.2.1')
@instance.version.should == '1.2.4.3.2.1'
end
it 'should not return a version number' do
stub_request(:get, @instance.readme_url.to_s).to_return(status: 200, body: 'Stable tag: trunk')
@instance.version.should be nil
end
it 'should return nil if the version is invalid (IE : trunk etc)' do
stub_request_to_fixture(url: @instance.readme_url.to_s, fixture: fixtures_dir + '/trunk-version.txt')
@instance.version.should be_nil
end
it 'should return the version 0.4' do
stub_request_to_fixture(url: @instance.readme_url.to_s, fixture: fixtures_dir + '/simple-login-lockdown-0.4.txt')
@instance.version.should === '0.4'
end
end
describe '#directory_listing?' do
before :each do
@instance = WpItem.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'test/asdf.php',
vulns_file: 'XXX.xml',
name: 'test',
vulns_xpath: 'XX',
type: 'plugins'
)
end
it 'should return true' do
stub_request(:get, @instance.get_url_without_filename.to_s)
.to_return(status: 200, body: '<html><head><title>Index of asdf</title></head></html>')
@instance.directory_listing?.should == true
end
it 'should return false' do
stub_request(:get, @instance.get_url_without_filename.to_s)
.to_return(status: 200, body: '<html><head><title>My Wordpress Site</title></head></html>')
@instance.directory_listing?.should == false
end
it 'should return false on a 404' do
stub_request(:get, @instance.get_url_without_filename.to_s.to_s).to_return(status: 404)
@instance.directory_listing?.should be_false
end
end
describe '#extract_name_from_url' do
after :each do
arguments = {
base_url: 'http://sub.example.com/path/to/wordpress/',
path: @path || 'test/asdf.php',
vulns_file: 'XXX.xml',
name: 'test',
vulns_xpath: 'XX',
type: @type || 'plugins',
wp_content_dir: @wp_content_dir
}
instance = WpItem.new(arguments)
instance.extract_name_from_url.should === @expected
end
it 'should extract the correct name' do
@expected = 'test'
end
it 'should extract the correct name (custom wp_content_dir)' do
@wp_content_dir = 'custom'
@expected = 'test'
end
it 'should extract the correct name' do
@path = 'test2/asdf.php'
@wp_content_dir = '/custom/'
@expected = 'test2'
end
it 'should extract the correct plugin name' do
@path = 'testplugin/'
@expected = 'testplugin'
end
it 'should extract the correct theme name' do
@path = 'testtheme/'
@type = 'themes'
@expected = 'testtheme'
end
end
describe '#to_s' do
before :each do
@instance = WpItem.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'test/asdf.php',
vulns_file: 'XXX.xml',
name: 'test',
vulns_xpath: 'XX',
type: 'plugins'
)
end
it 'should return the name including a version number' do
stub_request(:get, @instance.readme_url.to_s).to_return(status: 200, body: 'Stable tag: 1.2.4.3.2.1')
@instance.to_s.should == 'test v1.2.4.3.2.1'
end
it 'should not return the name without a version number' do
stub_request(:get, @instance.readme_url.to_s).to_return(status: 200, body: 'Stable tag: trunk')
@instance.to_s.should == 'test'
end
end
describe '#==' do
before :each do
@instance = WpItem.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'test/asdf.php',
vulns_file: 'XXX.xml',
name: 'test',
vulns_xpath: 'XX',
type: 'plugins'
)
end
it 'should return false' do
instance2 = WpItem.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'newname/asdf.php',
type: 'plugins',
vulns_file: 'XXX.xml',
vulns_xpath: 'XX'
)
(@instance == instance2).should == false
end
it 'should return true' do
instance2 = WpItem.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'test/asdf.php',
type: 'plugins',
vulns_file: 'XXX.xml',
vulns_xpath: 'XX'
)
(@instance == instance2).should == true
end
end
describe '#get_sub_folder' do
after :each do
arguments = {
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'test/asdf.php',
vulns_file: 'XXX.xml',
wp_content_dir: 'wp-content',
wp_plugins_dir: 'wp-content/plugins',
name: 'test',
vulns_xpath: 'XX',
type: @type || 'themes'
}
instance = WpItem.new(arguments)
if @raise_error
expect { instance.get_sub_folder }.to @raise_error
else
instance.get_sub_folder.should === @expected
end
end
it 'should return themes' do
@expected = 'themes'
end
it 'should return nil' do
@type = 'timthumbs'
@expected = nil
end
it 'should raise an exception' do
@type = 'type'
@raise_error = raise_error(RuntimeError, 'unknown type type')
end
end
describe '#readme_url' do
after :each do
arguments = {
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'test/asdf.php',
vulns_file: 'XXX.xml',
name: 'test',
vulns_xpath: 'XX',
type: @type || 'plugins',
wp_content_dir: @wp_content_dir
}
instance = WpItem.new(arguments)
instance.readme_url.to_s.should === @expected
end
it 'should return the corrent plugin readme url' do
@expected = 'http://sub.example.com/path/to/wordpress/wp-content/plugins/test/readme.txt'
end
it 'should return the corrent plugin readme url (custom wp_content)' do
@wp_content_dir = 'custom'
@expected = 'http://sub.example.com/path/to/wordpress/custom/plugins/test/readme.txt'
end
it 'should return the corrent theme readme url' do
@type = 'themes'
@expected = 'http://sub.example.com/path/to/wordpress/wp-content/themes/test/readme.txt'
end
it 'should return the corrent theme readme url (custom wp_content)' do
@type = 'themes'
@wp_content_dir = 'custom'
@expected = 'http://sub.example.com/path/to/wordpress/custom/themes/test/readme.txt'
end
end
describe '#changelog_url' do
after :each do
arguments = {
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'test/asdf.php',
vulns_file: 'XXX.xml',
name: 'test',
vulns_xpath: 'XX',
type: @type || 'plugins',
wp_content_dir: @wp_content_dir
}
instance = WpItem.new(arguments)
instance.changelog_url.to_s.should === @expected
end
it 'should return the corrent plugin changelog url' do
@expected = 'http://sub.example.com/path/to/wordpress/wp-content/plugins/test/changelog.txt'
end
it 'should return the corrent plugin changelog url (custom wp_content)' do
@wp_content_dir = 'custom'
@expected = 'http://sub.example.com/path/to/wordpress/custom/plugins/test/changelog.txt'
end
it 'should return the corrent theme changelog url' do
@type = 'themes'
@expected = 'http://sub.example.com/path/to/wordpress/wp-content/themes/test/changelog.txt'
end
it 'should return the corrent theme changelog url (custom wp_content)' do
@type = 'themes'
@wp_content_dir = 'custom'
@expected = 'http://sub.example.com/path/to/wordpress/custom/themes/test/changelog.txt'
end
end
describe '#has_readme?' do
before :each do
@instance = WpItem.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'test/asdf.php',
vulns_file: 'XXX.xml',
name: 'test',
vulns_xpath: 'XX',
type: 'plugins'
)
end
it 'should return true' do
stub_request(:get, @instance.readme_url.to_s).to_return(status: 200)
@instance.has_readme?.should == true
end
it 'should return false' do
stub_request(:get, @instance.readme_url.to_s).to_return(status: 403)
@instance.has_readme?.should == false
end
end
describe '#has_changelog?' do
before :each do
@instance = WpItem.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'test/asdf.php',
vulns_file: 'XXX.xml',
name: 'test',
vulns_xpath: 'XX',
type: 'plugins'
)
end
it 'should return true' do
stub_request(:get, @instance.changelog_url.to_s).to_return(status: 200)
@instance.has_changelog?.should == true
end
it 'should return false' do
stub_request(:get, @instance.changelog_url.to_s).to_return(status: 403)
@instance.has_changelog?.should == false
end
end
describe '#wp_org_url' do
it 'sould return a themes url' do
instance = WpItem.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'test/asdf.php',
vulns_file: 'XXX.xml',
name: 'test',
vulns_xpath: 'XX',
type: 'themes'
)
instance.wp_org_url.to_s.should == 'http://wordpress.org/extend/themes/test/'
end
it 'sould return a plugins url' do
instance = WpItem.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'test/asdf.php',
vulns_file: 'XXX.xml',
name: 'test',
vulns_xpath: 'XX',
type: 'plugins'
)
instance.wp_org_url.to_s.should == 'http://wordpress.org/extend/plugins/test/'
end
it 'sould raise an exception' do
instance = WpItem.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'test/asdf.php',
vulns_file: 'XXX.xml',
name: 'test',
vulns_xpath: 'XX',
type: 'invalid'
)
expect { instance.wp_org_url }.to raise_error(RuntimeError, 'No Wordpress URL for invalid')
end
end
describe '#wp_org_item?' do
it 'sould return true' do
instance = WpItem.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'test/asdf.php',
vulns_file: 'XXX.xml',
name: 'w3-total-cache',
vulns_xpath: 'XX',
type: 'plugins'
)
instance.wp_org_item?.should be_true
end
it 'sould return true' do
instance = WpItem.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'test/asdf.php',
vulns_file: 'XXX.xml',
name: 'twentyten',
vulns_xpath: 'XX',
type: 'themes'
)
instance.wp_org_item?.should be_true
end
it 'sould return false' do
instance = WpItem.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'test/asdf.php',
vulns_file: 'XXX.xml',
name: 'can_not_be_in_repository',
vulns_xpath: 'XX',
type: 'plugins'
)
instance.wp_org_item?.should be_false
end
it 'sould return false' do
instance = WpItem.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'test/asdf.php',
vulns_file: 'XXX.xml',
name: 'can_not_be_in_repository',
vulns_xpath: 'XX',
type: 'themes'
)
instance.wp_org_item?.should be_false
end
it 'sould raise an exception' do
instance = WpItem.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'test/asdf.php',
vulns_file: 'XXX.xml',
name: 'test',
vulns_xpath: 'XX',
type: 'invalid'
)
expect { instance.wp_org_item? }.to raise_error(RuntimeError, 'Unknown type invalid')
end
end
describe '#error_log_url' do
it 'should return a correct url' do
temp = WpItem.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'name/asdf.php',
vulns_file: 'XXX.xml',
name: 'name',
vulns_xpath: 'XX',
type: 'plugins')
temp.error_log_url.to_s.should == 'http://sub.example.com/path/to/wordpress/wp-content/plugins/name/error_log'
end
end
describe '#error_log?' do
before :each do
@temp = WpItem.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'test/asdf.php',
vulns_file: 'XXX.xml',
name: 'name',
vulns_xpath: 'XX',
type: 'plugins')
end
it 'should return true' do
stub_request(:get, @temp.error_log_url.to_s).to_return(status: 200, body: 'PHP Fatal error')
@temp.error_log?.should be true
end
it 'should return false' do
stub_request(:get, @temp.error_log_url.to_s).to_return(status: 500, body: 'Access denied')
@temp.error_log?.should be false
end
it 'should return true' do
fixtures_dir = SPEC_FIXTURES_WPSCAN_WP_PLUGIN_DIR + '/error_log'
stub_request(:get, @temp.error_log_url.to_s).to_return(
status: 200,
body: File.new(fixtures_dir + '/error_log')
)
@temp.error_log?.should be true
end
end
end

View File

@@ -1,139 +0,0 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
require File.expand_path(File.dirname(__FILE__) + '/wpscan_helper')
describe WpOptions do
describe '#check_options' do
before :each do
@options = {}
@options[:base_url] = 'url'
@options[:only_vulnerable_ones] = false
@options[:file] = 'file'
@options[:vulns_file] = 'vulns_file'
@options[:vulns_xpath] = 'vulns_xpath'
@options[:vulns_xpath_2] = 'vulns_xpath_2'
@options[:wp_content_dir] = 'wp_content_dir'
@options[:show_progression] = true
@options[:error_404_hash] = 'error_404_hash'
@options[:type] = 'type'
@message = ''
end
after :each do
expect { WpOptions.check_options(@options) }.to raise_error(RuntimeError, @message)
end
it 'should raise an exception (base_url empty)' do
@options[:base_url] = ''
@message = 'base_url must be set'
end
it 'should raise an exception (base_url nil)' do
@options[:base_url] = nil
@message = 'base_url must be set'
end
it 'should raise an exception (only_vulnerable_ones nil)' do
@options[:only_vulnerable_ones] = nil
@message = 'only_vulnerable_ones must be set'
end
it 'should raise an exception (file empty)' do
@options[:file] = ''
@message = 'file must be set'
end
it 'should raise an exception (file nil)' do
@options[:file] = nil
@message = 'file must be set'
end
it 'should raise an exception (vulns_file empty)' do
@options[:vulns_file] = ''
@message = 'vulns_file must be set'
end
it 'should raise an exception (vulns_file nil)' do
@options[:vulns_file] = nil
@message = 'vulns_file must be set'
end
it 'should raise an exception (vulns_xpath empty)' do
@options[:vulns_xpath] = ''
@message = 'vulns_xpath must be set'
end
it 'should raise an exception (vulns_xpath nil)' do
@options[:vulns_xpath] = nil
@message = 'vulns_xpath must be set'
end
it 'should raise an exception (vulns_xpath_2 empty)' do
@options[:vulns_xpath_2] = ''
@message = 'vulns_xpath_2 must be set'
end
it 'should raise an exception (vulns_xpath_2 nil)' do
@options[:vulns_xpath_2] = nil
@message = 'vulns_xpath_2 must be set'
end
it 'should raise an exception (wp_content_dir empty)' do
@options[:wp_content_dir] = ''
@message = 'wp_content_dir must be set'
end
it 'should raise an exception (wp_content_dir nil)' do
@options[:wp_content_dir] = nil
@message = 'wp_content_dir must be set'
end
it 'should raise an exception (show_progression nil)' do
@options[:show_progression] = nil
@message = 'show_progression must be set'
end
it 'should raise an exception (error_404_hash empty)' do
@options[:error_404_hash] = ''
@message = 'error_404_hash must be set'
end
it 'should raise an exception (error_404_hash nil)' do
@options[:error_404_hash] = nil
@message = 'error_404_hash must be set'
end
it 'should raise an exception (type empty)' do
@options[:type] = ''
@message = 'type must be set'
end
it 'should raise an exception (type nil)' do
@options[:type] = nil
@message = 'type must be set'
end
it 'should raise an exception (type unknown)' do
@options[:type] = 'unknown'
@message = 'Unknown type unknown'
end
end
end

View File

@@ -1,44 +0,0 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
require File.expand_path(File.dirname(__FILE__) + '/wpscan_helper')
describe WpPlugin do
describe '#initialize' do
it 'should not raise an exception' do
expect { WpPlugin.new(base_url: 'url', path: 'path', wp_content_dir: 'dir', name: 'name') }.to_not raise_error
end
it 'should not raise an exception (wp_content_dir not set)' do
expect { WpPlugin.new(base_url: 'url', path: 'path', name: 'name') }.to_not raise_error
end
it 'should raise an exception (base_url not set)' do
expect { WpPlugin.new(path: 'path', wp_content_dir: 'dir', name: 'name') }.to raise_error
end
it 'should raise an exception (path not set)' do
expect { WpPlugin.new(base_url: 'url', wp_content_dir: 'dir', name: 'name') }.to raise_error
end
it 'should raise an exception (name not set)' do
expect { WpPlugin.new(base_url: 'url', path: 'path', wp_content_dir: 'dir') }.to raise_error
end
end
end

View File

@@ -1,21 +1,4 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
require File.expand_path(File.dirname(__FILE__) + '/wpscan_helper')
@@ -41,10 +24,6 @@ describe WpTarget do
it_should_behave_like 'WpLoginProtection'
it_should_behave_like 'Malwares'
it_should_behave_like 'BruteForce'
it_should_behave_like 'WpUsernames'
it_should_behave_like 'WpTimthumbs'
it_should_behave_like 'WpPlugins'
it_should_behave_like 'WpThemes'
describe '#initialize' do
it 'should raise an error if the target_url is nil or empty' do

View File

@@ -1,289 +0,0 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
require File.expand_path(File.dirname(__FILE__) + '/wpscan_helper')
describe WpTheme do
before :all do
@target_uri = URI.parse('http://example.localhost/')
Browser.instance(
config_file: SPEC_FIXTURES_CONF_DIR + '/browser/browser.conf.json',
cache_timeout: 0
)
end
describe '#initialize' do
it 'should not raise an exception' do
expect { WpTheme.new(base_url: 'url', path: 'path', wp_content_dir: 'dir', name: 'name') }.to_not raise_error
end
it 'should not raise an exception (wp_content_dir not set)' do
expect { WpTheme.new(base_url: 'url', path: 'path', name: 'name') }.to_not raise_error
end
it 'should raise an exception (base_url not set)' do
expect { WpTheme.new(path: 'path', wp_content_dir: 'dir', name: 'name') }.to raise_error
end
it 'should raise an exception (path not set)' do
expect { WpTheme.new(base_url: 'url', wp_content_dir: 'dir', name: 'name') }.to raise_error
end
it 'should raise an exception (name not set)' do
expect { WpTheme.new(base_url: 'url', path: 'path', wp_content_dir: 'dir') }.to raise_error
end
end
describe '#find_from_css_link' do
let(:fixtures_dir) { SPEC_FIXTURES_WPSCAN_WP_THEME_DIR + '/find/css_link' }
after :each do
if @expected_name
stub_request_to_fixture(url: @target_uri.to_s, fixture: @fixture)
wp_theme = WpTheme.find_from_css_link(@target_uri)
wp_theme.should be_a WpTheme
wp_theme.name.should === @expected_name
end
end
it 'should return nil if no theme is present' do
stub_request(:get, @target_uri.to_s).to_return(status: 200, body: '')
WpTheme.find_from_css_link(@target_uri).should be_nil
end
it 'should return a WpTheme object with .name = twentyeleven' do
@fixture = fixtures_dir + '/wordpress-twentyeleven.htm'
@expected_name = 'twentyeleven'
end
# http://code.google.com/p/wpscan/issues/detail?id=131
# Theme name with spaces raises bad URI(is not URI?)
it 'should not raise an error if the theme name has spaces or special chars' do
@fixture = fixtures_dir + '/theme-name-with-spaces.html'
@expected_name = 'Copia di simplefolio'
end
# https://github.com/wpscanteam/wpscan/issues/18
it 'should get the theme if the <link> is inline with some other tags' do
@fixture = fixtures_dir + '/inline_link_tag.html'
@expected_name = 'inline'
end
it 'should get the theme name even if relative URLs are used' do
@fixture = fixtures_dir + '/relative_urls.html'
@expected_name = 'theme_name'
end
end
describe '#find_from_wooframework' do
let(:fixtures_dir) { SPEC_FIXTURES_WPSCAN_WP_THEME_DIR + '/find/wooframework' }
after :each do
stub_request_to_fixture(url: @target_uri.to_s, fixture: @fixture)
wp_theme = WpTheme.find_from_wooframework(@target_uri)
stub_request(:get, wp_theme.default_style_url.to_s).to_return(status: 200)
stub_request(:get, wp_theme.readme_url.to_s).to_return(status: 200)
wp_theme.should be_a WpTheme unless wp_theme.nil?
wp_theme.should === @expected_theme
end
it "should return a WpTheme object with .name 'Editorial' and .version '1.3.5'" do
@fixture = fixtures_dir + '/editorial-1.3.5.html'
@expected_theme = WpTheme.new(name: 'Editorial', version: '1.3.5', base_url: 'http://example.localhost/', path: 'Editorial')
end
it "should return a WpTheme object with .name 'Merchant'" do
@fixture = fixtures_dir + '/merchant-no-version.html'
@expected_theme = WpTheme.new(name: 'Merchant', base_url: 'http://example.localhost/', path: 'Merchant')
end
end
describe '#find' do
let(:fixtures_dir) { SPEC_FIXTURES_WPSCAN_WP_THEME_DIR + '/find' }
after :each do
stub_request_to_fixture(url: @target_uri.to_s, fixture: @fixture)
wp_theme = WpTheme.find(@target_uri)
if @expected_name
wp_theme.should be_a WpTheme
wp_theme.name.should === @expected_name
else
wp_theme.should be_nil
end
end
it 'should return nil if no theme is found' do
@fixture = SPEC_FIXTURES_DIR + '/empty-file'
@expected_name = nil
end
it "should return a WpTheme object with .name 'twentyeleven'" do
@fixture = fixtures_dir + '/css_link/wordpress-twentyeleven.htm'
@expected_name = 'twentyeleven'
end
it "should a WpTheme object with .name 'Merchant'" do
@fixture = fixtures_dir + '/wooframework/merchant-no-version.html'
@expected_name = 'Merchant'
end
end
describe '#version' do
let(:fixtures_dir) { SPEC_FIXTURES_WPSCAN_WP_THEME_DIR + '/version' }
let(:theme_style_url) { @target_uri.merge('wp-content/themes/spec-theme/style.css').to_s }
after :each do
if @fixture
stub_request_to_fixture(url: theme_style_url, fixture: @fixture)
wp_theme = WpTheme.new(name: 'spec-theme', style_url: theme_style_url, base_url: 'http://example.localhost/', path: 'spec-theme')
stub_request(:get, wp_theme.readme_url.to_s).to_return(status: 200)
wp_theme.version.should === @expected
end
end
it 'should return nil if the version is not found' do
@fixture = fixtures_dir + '/twentyeleven-unknow.css'
@expected = nil
end
it 'should return nil if the style_url is nil' do
wp_theme = WpTheme.new(name: 'hello-world', base_url: 'http://example.localhost/', path: 'hello-world')
stub_request(:get, wp_theme.default_style_url.to_s).to_return(status: 200)
stub_request(:get, wp_theme.readme_url.to_s).to_return(status: 200)
wp_theme.version.should be_nil
end
it 'should return 1.3' do
@fixture = fixtures_dir + '/twentyeleven-1.3.css'
@expected = '1.3'
end
it 'should return 1.5.1' do
@fixture = fixtures_dir + '/bueno-1.5.1.css'
@expected = '1.5.1'
end
it 'should get the version from default style.css url' do
wp_theme = WpTheme.new(name: 'hello-world', base_url: 'http://example.localhost/', path: 'hello-world')
stub_request(:get, wp_theme.default_style_url.to_s).to_return(status: 200, body: 'Version: 1.3.4.5')
stub_request(:get, wp_theme.readme_url.to_s).to_return(status: 404)
wp_theme.version.should === '1.3.4.5'
end
it 'should get the version from custom style.css url' do
style_url = 'http://example.localhost/custom_style.css'
wp_theme = WpTheme.new(name: 'hello-world', base_url: 'http://example.localhost/', path: 'hello-world', style_url: style_url)
stub_request(:get, style_url).to_return(status: 200, body: 'Version: 1.3.4.5')
stub_request(:get, wp_theme.readme_url.to_s).to_return(status: 404)
wp_theme.version.should === '1.3.4.5'
end
it 'should get the version from readme.txt' do
wp_theme = WpTheme.new(name: 'hello-world', base_url: 'http://example.localhost/', path: 'hello-world')
stub_request(:get, wp_theme.default_style_url.to_s).to_return(status: 404)
stub_request(:get, wp_theme.readme_url.to_s).to_return(status: 200, body: 'Stable Tag: 1.2.3.4')
wp_theme.version.should === '1.2.3.4'
end
it 'should get the version from readme.txt' do
wp_theme = WpTheme.new(name: 'hello-world', base_url: 'http://example.localhost/', path: 'hello-world')
stub_request(:get, wp_theme.default_style_url.to_s).to_return(status: 200)
stub_request(:get, wp_theme.readme_url.to_s).to_return(status: 200, body: 'Stable Tag: 1.2.3.4')
wp_theme.version.should === '1.2.3.4'
end
end
describe '#===' do
it 'should return false (name not equal)' do
instance = WpTheme.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'themes/name/asdf.php',
vulns_file: 'XXX.xml',
version: '1.0'
)
instance2 = WpTheme.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'themes/newname/asdf.php',
vulns_file: 'XXX.xml',
version: '1.0'
)
(instance === instance2).should == false
end
it 'should return false (version not equal)' do
instance = WpTheme.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'themes/name/asdf.php',
vulns_file: 'XXX.xml',
version: '1.0'
)
instance2 = WpTheme.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'themes/name/asdf.php',
vulns_file: 'XXX.xml',
version: '2.0'
)
(instance === instance2).should == false
end
it 'should return false (version and name not equal)' do
instance = WpTheme.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'themes/name/asdf.php',
vulns_file: 'XXX.xml',
version: '1.0'
)
instance2 = WpTheme.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'themes/newname/asdf.php',
vulns_file: 'XXX.xml',
version: '2.0'
)
(instance === instance2).should == false
end
it 'should return true' do
instance = WpTheme.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'themes/test/asdf.php',
vulns_file: 'XXX.xml',
version: '1.0'
)
instance2 = WpTheme.new(
base_url: 'http://sub.example.com/path/to/wordpress/',
path: 'themes/test/asdf.php',
vulns_file: 'XXX.xml',
version: '1.0'
)
(instance === instance2).should == true
end
end
end

View File

@@ -1,86 +0,0 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
require File.expand_path(File.dirname(__FILE__) + '/wpscan_helper')
describe WpUser do
describe '#initialize' do
it 'should replace nil with empty' do
user = WpUser.new(nil, nil, nil)
user.name.should == 'empty'
user.id.should == 'empty'
user.nickname == 'empty'
end
it 'should initialize a user object' do
user = WpUser.new('name', 'id', 'nickname')
user.name.should == 'name'
user.id.should == 'id'
user.nickname == 'nickname'
end
end
describe '#<=>' do
it 'should return -1' do
user1 = WpUser.new('b', nil, nil)
user2 = WpUser.new('a', nil, nil)
(user1 <=> user2).should === -1
end
it 'should return 0' do
user1 = WpUser.new('a', nil, nil)
user2 = WpUser.new('a', nil, nil)
(user1 <=> user2).should === 0
end
it 'should return 1' do
user1 = WpUser.new('a', nil, nil)
user2 = WpUser.new('b', nil, nil)
(user1 <=> user2).should === 1
end
end
describe '#===' do
it 'should return true' do
user1 = WpUser.new('a', 'id', 'nick')
user2 = WpUser.new('a', 'id', 'nick')
(user1 === user2).should be_true
end
it 'should return false' do
user1 = WpUser.new('a', 'id', 'nick')
user2 = WpUser.new('b', 'id', 'nick')
(user1 === user2).should be_false
end
end
describe '#eql?' do
it 'should return true' do
user1 = WpUser.new('a', 'id', 'nick')
user2 = WpUser.new('a', 'id', 'nick')
(user1.eql? user2).should be_true
end
it 'should return false' do
user1 = WpUser.new('a', 'id', 'nick')
user2 = WpUser.new('b', 'id', 'nick')
(user1.eql? user2).should be_false
end
end
end

View File

@@ -1,306 +0,0 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
require File.expand_path(File.dirname(__FILE__) + '/wpscan_helper')
describe WpVersion do
before :all do
@target_uri = URI.parse('http://example.localhost/')
@browser = Browser.instance(config_file: SPEC_FIXTURES_CONF_DIR + '/browser/browser.conf.json')
end
describe '#find_from_meta_generator' do
let(:fixtures_dir) { SPEC_FIXTURES_WPSCAN_WP_VERSION_DIR + '/meta-generator' }
after :each do
stub_request_to_fixture(url: @target_uri.to_s, fixture: @fixture)
WpVersion.find_from_meta_generator(base_uri: @target_uri.to_s).should === @expected
end
it 'should return nil if the meta-generator is not found' do
@fixture = fixtures_dir + '/no-meta-generator.htm'
@expected = nil
end
it 'should return 3.3.2' do
@fixture = fixtures_dir + '/3.3.2.htm'
@expected = '3.3.2'
end
it 'should return 3.4-beta4' do
@fixture = fixtures_dir + '/3.4-beta4.htm'
@expected = '3.4-beta4'
end
it "should return nil if it's not a valid version, must contains at least one '.'" do
@fixture = fixtures_dir + '/invalid_version.htm'
@expected = nil
end
it 'should return 3.5' do
@fixture = fixtures_dir + '/3.5_minified.htm'
@expected = '3.5'
end
end
describe '#find_from_rss_generator' do
let(:fixtures_dir) { SPEC_FIXTURES_WPSCAN_WP_VERSION_DIR + '/rss-generator' }
after :each do
@status_code ||= 200
stub_request_to_fixture(url: @target_uri.merge('feed/').to_s, status: @status_code, fixture: @fixture)
WpVersion.find_from_rss_generator(base_uri: @target_uri).should === @expected
end
it 'should return nil on a 404' do
@status_code = 404
@fixture = SPEC_FIXTURES_WPSCAN_WP_VERSION_DIR + '/404.htm'
@expected = nil
end
it 'should return nil if the rss-generator is not found' do
@fixture = fixtures_dir + '/no-rss-generator.htm'
@expected = nil
end
it 'should return nil if the version is not found (but the rss-generator is present)' do
@fixture = fixtures_dir + '/no-version.htm'
@expected = nil
end
it 'shuld return 3.3.2' do
@fixture = fixtures_dir + '/3.3.2.htm'
@expected = '3.3.2'
end
it 'should return 3.4-beta4' do
@fixture = fixtures_dir + '/3.4-beta4.htm'
@expected = '3.4-beta4'
end
it "should return nil if it's not a valid version, must contains at least one '.'" do
@fixture = fixtures_dir + '/invalid_version.htm'
@expected = nil
end
end
describe '#find_from_rdf_generator' do
let(:fixtures_dir) { SPEC_FIXTURES_WPSCAN_WP_VERSION_DIR + '/rdf-generator' }
after :each do
@status_code ||= 200
stub_request_to_fixture(url: @target_uri.merge('feed/rdf/').to_s, status: @status_code, fixture: @fixture)
WpVersion.find_from_rdf_generator(base_uri: @target_uri).should === @expected
end
it 'should return nil on a 404' do
@status_code = 404
@fixture = SPEC_FIXTURES_WPSCAN_WP_VERSION_DIR + '/404.htm'
@expected = nil
end
it 'should return nil if the rdf-generator is not found' do
@fixture = fixtures_dir + '/no-rdf-generator.htm'
@expected = nil
end
it 'should return nil if the version is not found (but the rdf-generator is present)' do
@fixture = fixtures_dir + '/no-version.htm'
@expected = nil
end
it 'shuld return 3.3.2' do
@fixture = fixtures_dir + '/3.3.2.htm'
@expected = '3.3.2'
end
it 'should return 3.4-beta4' do
@fixture = fixtures_dir + '/3.4-beta4.htm'
@expected = '3.4-beta4'
end
it "should return nil if it's not a valid version, must contains at least one '.'" do
@fixture = fixtures_dir + '/invalid_version.htm'
@expected = nil
end
end
describe '#find_from_atom_generator' do
let(:fixtures_dir) { SPEC_FIXTURES_WPSCAN_WP_VERSION_DIR + '/atom-generator' }
after :each do
@status_code ||= 200
stub_request_to_fixture(url: @target_uri.merge('feed/atom/').to_s, status: @status_code, fixture: @fixture)
WpVersion.find_from_atom_generator(base_uri: @target_uri).should === @expected
end
it 'should return nil on a 404' do
@status_code = 404
@fixture = SPEC_FIXTURES_WPSCAN_WP_VERSION_DIR + '/404.htm'
@expected = nil
end
it 'should return nil if the atom-generator is not found' do
@fixture = fixtures_dir + '/no-atom-generator.htm'
@expected = nil
end
it 'should return nil if the version is not found (but the atom-generator is present)' do
@fixture = fixtures_dir + '/no-version.htm'
@expected = nil
end
it 'shuld return 3.3.2' do
@fixture = fixtures_dir + '/3.3.2.htm'
@expected = '3.3.2'
end
it 'should return 3.4-beta4' do
@fixture = fixtures_dir + '/3.4-beta4.htm'
@expected = '3.4-beta4'
end
it "should return nil if it's not a valid version, must contains at least one '.'" do
@fixture = fixtures_dir + '/invalid_version.htm'
@expected = nil
end
end
describe '#find_from_sitemap_generator' do
after :each do
stub_request(:get, @target_uri.merge('sitemap.xml').to_s).
to_return(status: 200, body: @body)
WpVersion.find_from_sitemap_generator(base_uri: @target_uri).should === @expected
end
it 'should return nil if the generator is not found' do
@body = ''
@expected = nil
end
it 'should return the version : 3.3.2' do
@body = '<!-- generator="wordpress/3.3.2" -->'
@expected = '3.3.2'
end
it "should return nil if it's not a valid version, must contains at least one '.'" do
@body = '<!-- generator="wordpress/5065" -->'
@expected = nil
end
end
describe '#find_from_readme' do
let(:fixtures_dir) { SPEC_FIXTURES_WPSCAN_WP_VERSION_DIR + '/readme' }
after :each do
@status_code ||= 200
stub_request_to_fixture(url: @target_uri.merge('readme.html').to_s, status: @status_code, fixture: @fixture)
WpVersion.find_from_readme(base_uri: @target_uri).should === @expected
end
it 'should return nil on a 404' do
@status_code = 404
@fixture = SPEC_FIXTURES_WPSCAN_WP_VERSION_DIR + '/404.htm'
@expected = nil
end
it 'should return nil if the version number is not present' do
@fixture = fixtures_dir + '/empty-version.html'
@expected = nil
end
it 'should return 3.3.2' do
@fixture = fixtures_dir + '/readme-3.3.2.html'
@expected = '3.3.2'
end
it "should return nil if it's not a valid version, must contains at least one '.'" do
@fixture = fixtures_dir + '/invalid_version.html'
@expected = nil
end
end
describe '#find_from_advanced_fingerprinting' do
let(:fixtures_dir) { SPEC_FIXTURES_WPSCAN_WP_VERSION_DIR + '/advanced' }
it 'should return 3.2.1' do
stub_request_to_fixture(
url: @target_uri.merge('wp-admin/js/wp-fullscreen.js').to_s,
fixture: "#{fixtures_dir}/3.2.1.js"
)
version = WpVersion.find_from_advanced_fingerprinting(
base_uri: @target_uri,
wp_content_dir: 'wp-content',
version_xml: "#{fixtures_dir}/wp_versions.xml"
)
version.should == '3.2.1'
end
end
describe '#find_from_links_opml' do
let(:fixtures_dir) { SPEC_FIXTURES_WPSCAN_WP_VERSION_DIR + '/opml' }
it 'should return 3.4.2' do
stub_request_to_fixture(
url: @target_uri.merge('wp-links-opml.php').to_s,
fixture: "#{fixtures_dir}/wp-links-opml.xml"
)
version = WpVersion.find_from_links_opml(base_uri: @target_uri)
version.should == '3.4.2'
end
it 'should return nil' do
stub_request_to_fixture(
url: @target_uri.merge('wp-links-opml.php').to_s,
fixture: "#{fixtures_dir}/wp-links-opml-nogenerator.xml"
)
version = WpVersion.find_from_links_opml(base_uri: @target_uri)
version.should be_nil
end
end
describe '#initialize' do
it 'should initialize a WpVersion object' do
v = WpVersion.new(1, {discovery_method: 'method', vulns_file: 'asdf.xml'})
v.number.should == 1
v.discovery_method.should == 'method'
end
end
describe '#find' do
let(:fixtures_dir) { SPEC_FIXTURES_WPSCAN_WP_VERSION_DIR + '/advanced' }
it 'should find all versions' do
# All requests get a HTTP 404
stub_request(:any, /.*/).to_return(status: 404)
# Wordpress Version 3.2.1
stub_request_to_fixture(
url: @target_uri.merge('wp-admin/js/wp-fullscreen.js').to_s,
fixture: "#{fixtures_dir}/3.2.1.js"
)
version = WpVersion.find(@target_uri, 'wp-content')
version.number.should == '3.2.1'
version.discovery_method.should == 'advanced fingerprinting'
end
end
end

View File

@@ -1,37 +0,0 @@
# encoding: UTF-8
# TODO
describe '#vulnerabilities' do
let(:location_url) { 'http://example.localhost/' }
let(:fixtures_dir) { SPEC_FIXTURES_WPSCAN_WP_PLUGIN_DIR + '/vulnerabilities' }
let(:vulns_file) { fixtures_dir + '/plugin_vulns.xml' }
let(:wp_plugin) do
WpPlugin.new(
base_url: location_url,
name: 'spec-plugin',
path: 'plugins/spec-plugin/',
vulns_file: vulns_file
)
end
it 'should return an empty array when no vulnerabilities are found' do
WpPlugin.new(
base_url: 'http://example.localhost/',
name: 'no-vulns',
path: 'plugins/no-vulns/',
vulns_file: vulns_file
).vulnerabilities.should be_empty
end
it 'should return an arry with 2 vulnerabilities' do
vulnerabilities = wp_plugin.vulnerabilities
vulnerabilities.should_not be_empty
vulnerabilities.length.should == 2
vulnerabilities.each { |vulnerability| vulnerability.should be_a WpVulnerability }
vulnerabilities[0].title.should === 'WPScan Spec'
vulnerabilities[1].title.should === 'Spec SQL Injection'
end
end

View File

@@ -1,21 +1,4 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
require 'spec_helper'

View File

@@ -1,21 +1,4 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
require File.expand_path(File.dirname(__FILE__) + '/wpscan_helper')

View File

@@ -1,70 +1,47 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
require File.expand_path(File.dirname(__FILE__) + '/../../wpstools_helper')
describe 'StatsPlugin' do
before :each do
@stats = StatsPlugin.new()
end
subject(:stats) { StatsPlugin.new }
let(:plugins_vulns) { MODELS_FIXTURES + '/wp_plugin/vulnerable/plugins_vulns.xml' }
let(:themes_vulns) { MODELS_FIXTURES + '/wp_theme/vulnerable/themes_vulns.xml' }
let(:plugins_file) { COLLECTIONS_FIXTURES + '/wp_plugins/detectable/targets.txt' }
let(:themes_file) { COLLECTIONS_FIXTURES + '/wp_themes/detectable/targets.txt'}
describe '#vuln_plugin_count' do
it 'should return the correct number' do
xml = "#{SPEC_FIXTURES_WPSCAN_WP_PLUGIN_DIR}/vulnerabilities/plugin_vulns.xml"
@stats.vuln_plugin_count(xml).should == 2
it 'returns the correct number' do
stats.vuln_plugin_count(plugins_vulns).should == 2
end
end
describe '#vuln_theme_count' do
it 'should return the correct number' do
xml = "#{SPEC_FIXTURES_WPSCAN_WP_THEME_DIR}/vulnerabilities/theme_vulns.xml"
@stats.vuln_theme_count(xml).should == 2
it 'returns the correct number' do
stats.vuln_theme_count(themes_vulns).should == 2
end
end
describe '#plugin_vulns_count' do
it 'should return the correct number' do
xml = "#{SPEC_FIXTURES_WPSCAN_WP_PLUGIN_DIR}/vulnerabilities/plugin_vulns.xml"
@stats.plugin_vulns_count(xml).should == 3
it 'returns the correct number' do
stats.plugin_vulns_count(plugins_vulns).should == 3
end
end
describe '#theme_vulns_count' do
it 'should return the correct number' do
xml = "#{SPEC_FIXTURES_WPSCAN_WP_THEME_DIR}/vulnerabilities/theme_vulns.xml"
@stats.theme_vulns_count(xml).should == 3
it 'returns the correct number' do
stats.theme_vulns_count(themes_vulns).should == 3
end
end
describe '#total_plugins' do
it 'should return the correct numer' do
xml = "#{SPEC_FIXTURES_WPSCAN_WP_PLUGIN_DIR}/vulnerabilities/plugin_vulns.xml"
file = "#{SPEC_FIXTURES_WPSCAN_WP_PLUGIN_DIR}/plugins.txt"
@stats.total_plugins(file, xml).should == 4
it 'returns the correct numer' do
stats.total_plugins(plugins_file).should == 3
end
end
describe '#total_themes' do
it 'should return the correct numer' do
xml = "#{SPEC_FIXTURES_WPSCAN_WP_THEME_DIR}/vulnerabilities/theme_vulns.xml"
file = "#{SPEC_FIXTURES_WPSCAN_WP_THEME_DIR}/themes.txt"
@stats.total_themes(file, xml).should == 5
it 'returns the correct numer' do
stats.total_themes(themes_file).should == 3
end
end
end
end

View File

@@ -1,21 +1,4 @@
# encoding: UTF-8
#--
# WPScan - WordPress Security Scanner
# Copyright (C) 2012-2013
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++
require 'spec_helper'

View File

@@ -0,0 +1,51 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="fr-FR">
<head profile="http://gmpg.org/xfn/11">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta property="fb:page_id" content="18968879441564"/>
<title>Example.com</title>
<link rel="alternate" type="application/rss+xml" title="Example RSS Feed" href="http://example.com/feed"/>
<link rel="alternate" type="application/atom+xml" title="Example Atom Feed" href="http://example.com/feed/atom"/>
<link rel="pingback" href="http://example.com/xmlrpc.php"/>
<link rel='stylesheet' href='http://example.com/wp-content/items/link-tag/cache/7f8155a5485bc445ed0adb136722b.css?m=1224763007' type='text/css' media='screen'/>
<script type="text/javascript">
var TB_pluginPath = 'http://www.welovebug.com/wp-content/items/js-source';
var TB_config = {
'widget_show_photos':true,
'widget_show_source':true,
'widget_show_header':true,
'general_link_screen_names':true,
'general_link_hash_tags':true,
'general_link_urls':true,
'widget_check_sources':true,
'widget_show_user':true
}
</script>
<style type="text/css">
#fancybox-loading.fancybox-ie div { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://example.com/wp-content/items/style-tag/fancybox/fancy_loading.png', sizingMethod='scale'); }
</style>
<script type='text/javascript' src='http://example.com/wp-content/items/script-tag/s2member-o.php?ws_plugin__s2member_js_w_globals=1'></script>
</head>
<body>
<div class="top">
<div class="header">
<h1 class="logo">
Blablabla the following plugin should not match : /wp-content/items/this-plugin-should-not-match/sub.css
</h1>
</div>
</div>
</body>
<script type='text/javascript'>
/* <![CDATA[ */
var pollsL10n = {"ajax_url":"http:\/\/example.com\/wp-content\/items\/escaped-url\/wp-polls.php","text_wait":"Your last request is still being processed. Please wait a while ...","text_valid":"Please choose a valid poll answer.","text_multiple":"Maximum number of choices allowed: ","show_loading":"1","show_fading":"1"};
/* ]]> */
</script>
<script type='text/javascript' src='http://platform.twitter.com/widgets.js?ver=1.0.0'></script>
<!-- a duplicate one -->
<script type='text/javascript' src='http://example.com/wp-content/items/script-tag/s2member-o.php?ws_plugin__s2member_js_w_globals=1'></script>
</html>

View File

@@ -0,0 +1,3 @@
item1
item-2
mr-smith

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- the vulnerability node is not needed -->
<vulnerabilities>
<item name="mr-smith"/>
<not-valid name='I should not appear in the results'/>
<item name="neo"/>
</vulnerabilities>

View File

@@ -7,15 +7,10 @@
<link rel="alternate" type="application/rss+xml" title="Example RSS Feed" href="http://example.com/feed"/>
<link rel="alternate" type="application/atom+xml" title="Example Atom Feed" href="http://example.com/feed/atom"/>
<link rel="pingback" href="http://example.com/xmlrpc.php"/>
<link rel='stylesheet' href='http://example.com/wp-content/plugins/wp-minify/cache/7f8155a5485bc445ed0adb136722b.css?m=1224763007' type='text/css' media='screen'/>
<link rel='stylesheet' href='http://example.com/wp-content/plugins/link-tag/cache/7f8155a5485bc445ed0adb136722b.css?m=1224763007' type='text/css' media='screen'/>
<!-- Start Comment Info Tip Plugin -->
<link type="text/css" rel="stylesheet" href="http://example.com/wp-content/plugins/comment-info-tip/comment-info-tip.css" />
<!-- End Comment Info Tip Plugin -->
<!-- #121 : http://code.google.com/p/wpscan/issues/detail?id=121 -->
<script type="text/javascript">
var TB_pluginPath = 'http://www.welovebug.com/wp-content/plugins/tweet-blender';
var TB_pluginPath = 'http://www.welovebug.com/wp-content/plugins/js-source';
var TB_config = {
'widget_show_photos':true,
'widget_show_source':true,
@@ -27,13 +22,12 @@
'widget_show_user':true
}
</script>
<!-- /#121 -->
<style type="text/css">
#fancybox-loading.fancybox-ie div { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://example.com/wp-content/plugins/optinpop/fancybox/fancy_loading.png', sizingMethod='scale'); }
#fancybox-loading.fancybox-ie div { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://example.com/wp-content/plugins/style-tag/fancybox/fancy_loading.png', sizingMethod='scale'); }
</style>
<script type='text/javascript' src='http://example.com/wp-content/plugins/s2member/s2member-o.php?ws_plugin__s2member_js_w_globals=1'></script>
<script type='text/javascript' src='http://example.com/wp-content/plugins/script-tag/s2member-o.php?ws_plugin__s2member_js_w_globals=1'></script>
</head>
<body>
<div class="top">
@@ -47,12 +41,11 @@
<script type='text/javascript'>
/* <![CDATA[ */
var pollsL10n = {"ajax_url":"http:\/\/example.com\/wp-content\/plugins\/wp-polls\/wp-polls.php","text_wait":"Your last request is still being processed. Please wait a while ...","text_valid":"Please choose a valid poll answer.","text_multiple":"Maximum number of choices allowed: ","show_loading":"1","show_fading":"1"};
var pollsL10n = {"ajax_url":"http:\/\/example.com\/wp-content\/plugins\/escaped-url\/wp-polls.php","text_wait":"Your last request is still being processed. Please wait a while ...","text_valid":"Please choose a valid poll answer.","text_multiple":"Maximum number of choices allowed: ","show_loading":"1","show_fading":"1"};
/* ]]> */
</script>
<script type='text/javascript' src='http://platform.twitter.com/widgets.js?ver=1.0.0'></script>
<script type="text/javascript" src="http://example.com/wp-content/plugins/commentluv/js/commentluv.js?ver=3.3.1"></script>
<!-- a duplicate one -->
<script type='text/javascript' src='http://example.com/wp-content/plugins/s2member/s2member-o.php?ws_plugin__s2member_js_w_globals=1'></script>
<script type='text/javascript' src='http://example.com/wp-content/plugins/script-tag/s2member-o.php?ws_plugin__s2member_js_w_globals=1'></script>
</html>

View File

@@ -0,0 +1,3 @@
plugin1
plugin-2
mr-smith

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- the vulnerability node is not needed -->
<vulnerabilities>
<plugin name="mr-smith"/>
<not-valid name='I should not appear in the results'/>
<plugin name="neo"/>
</vulnerabilities>

View File

@@ -9,8 +9,8 @@
<link rel="pingback" href="http://example.com/xmlrpc.php"/>
<link type="text/css" rel="stylesheet" href="http://example.localhost/wp-content/themes/theme1/style.css" />
<link type="text/css" rel="stylesheet" href="http://example.localhost/wp-content/themes/theme2/javascript.js" />
<link type="text/css" rel="stylesheet" href="http://example.localhost/wp-content/themes/theme3/test.png" />
<link type="text/css" rel="stylesheet" href="http://example.localhost/wp-content/themes/theme 2/javascript.js" />
<link type="text/css" rel="stylesheet" href="http://example.localhost/wp-content/themes/theme-3/test.png" />
</head>
<body>

View File

@@ -0,0 +1,3 @@
3colours
42k
a-ri

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- the vulnerability node is not needed -->
<themes>
<theme name="shopperpress"/>
<not-valid name="wise"/>
<theme name="webfolio"/>
</themes>

View File

@@ -0,0 +1,4 @@
timthumb.php
$wp-content$/timthumb.php
$wp-plugins$/a-gallery/timthumb.php
$wp-content$/themes/theme-name/timthumb.php

View File

@@ -0,0 +1,7 @@
<vulnerability>
<title>Vuln Title</title>
<reference>Ref 1</reference>
<reference>Ref 2</reference>
<type>CSRF</type>
<metasploit>exploit/ex1</metasploit>
</vulnerability>

View File

@@ -0,0 +1,30 @@
=== Simple Login Lockdown ===
Contributors: chrisguitarguy
Donate link: http://www.pwsausa.org/
Tags: security, login
Requires at least: 3.2.0
Tested up to: 3.3
Stable tag: 0.4
Simple Login Lockdown prevents brute force login attacks/attempts on your WordPress installation.
== Changelog ==
= 0.1 =
* Proof of concept
* no options page
= 0.2 =
* New function to get the IP address.
* Added filter to IP for flexibility with proxies, etc.
= 0.3 =
* small bug fix
= 0.4 =
* Added plugin options page
== Upgrade Notice ==
= 04 =
* Dont get attacked!

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<vulnerabilities>
</vulnerabilities>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<vulnerabilities>
<item name="not-this-one">
<vulnerability>
<title>I should not appear in the results</title>
<reference>http://ref1.com</reference>
<type>RFI</type>
</vulnerability>
</item>
<item name="neo">
<vulnerability>
<title>I'm the one</title>
<reference>http://ref1.com</reference>
<type>XSS</type>
</vulnerability>
</item>
</vulnerabilities>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<vulnerabilities>
<plugin name="mr-smith">
<vulnerability>
<title>I should not appear in the results</title>
<reference>http://ref1.com</reference>
<type>RCE</type>
</vulnerability>
<vulnerability>
<title>Neither do I</title>
<reference>http://ref3.com</reference>
<type>FPD</type>
</vulnerability>
</plugin>
<plugin name="white-rabbit">
<vulnerability>
<title>Follow me!</title>
<reference>http://ref2.com</reference>
<type>REDIRECT</type>
</vulnerability>
</plugin>
</vulnerabilities>

View File

@@ -0,0 +1,32 @@
<!DOCTYPE html>
<!--[if IE 6]>
<html id="ie6" dir="ltr" lang="en-US">
<![endif]-->
<!--[if IE 7]>
<html id="ie7" dir="ltr" lang="en-US">
<![endif]-->
<!--[if IE 8]>
<html id="ie8" dir="ltr" lang="en-US">
<![endif]-->
<!--[if !(IE 6) | !(IE 7) | !(IE 8) ]><!-->
<html dir="ltr" lang="en-US">
<!--<![endif]-->
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>wordpress-3.2.1 | Just another WordPress site</title>
<link rel="profile" href="http://gmpg.org/xfn/11" />
<link rel="stylesheet" type="text/css" media="all" href="http://lamp/wordpress-3.2.1/wp-content/themes/Copia di simplefolio/style.css" />
<link rel="pingback" href="http://lamp/wordpress-3.2.1/xmlrpc.php" />
<!--[if lt IE 9]>
<script src="http://lamp/wordpress-3.2.1/wp-content/themes/twentyeleven/js/html5.js" type="text/javascript"></script>
<![endif]-->
<link rel="alternate" type="application/rss+xml" title="wordpress-3.2.1 &raquo; Feed" href="http://192.168.1.103/wordpress-3.2.1/?feed=rss2" />
<link rel="alternate" type="application/rss+xml" title="wordpress-3.2.1 &raquo; Comments Feed" href="http://192.168.1.103/wordpress-3.2.1/?feed=comments-rss2" />
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://lamp/wordpress-3.2.1/xmlrpc.php?rsd" />
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://lamp/wordpress-3.2.1/wp-includes/wlwmanifest.xml" />
<link rel='index' title='wordpress-3.2.1' href='http://192.168.1.103/wordpress-3.2.1' />
<meta name="generator" content="WordPress 3.2.1" />
<style type="text/css">.recentcomments a{display:inline !important;padding:0 !important;margin:0 !important;}</style>
</head>
</html>

View File

@@ -0,0 +1,16 @@
/* Theme Name: Bueno Version: 1.5.1 Description: Designed by <a href='http://www.woothemes.com'>WooThemes</a>
Author: WooThemes Author URI: http://www.woothemes.com Copyright: (c) 2009 WooThemes.
License: GNU/GPL Version 2 or later. http://www.gnu.org/licenses/gpl.html */ /*
WARNING! DO NOT EDIT THIS FILE! To make it easy to update your theme, you should
not edit the styles in this file. Instead use the custom.css file to add your
styles. You can copy a style from this file and paste it in custom.css and it
will override the style in this file. You have been warned! :) */ /* Default styles
*/ @import "css/reset.css"; /*-------------------------------------------------------------------------------------------
INDEX: 1. SETUP -1.1 Defaults -1.2 Hyperlinks 2. SITE STRUCTURE & APPEARANCE -2.1
Containers & Columns -2.2 Navigation -2.2.1 Drop-down menus -2.3 Header -2.4 Content
-2.5 Sidebar -2.6 Extended Footer -2.7 Footer 3. POSTS -3.1 Typographic Elements
-3.2 Images -3.3 Pagination / WP-Pagenavi 4. WIDGETS -4.1 Generic Widgets -4.2
Specific Widgets -4.3 Extended Footer Widgets 5. COMMENTS -5.1 Comments -5.2 Pingbacks
/ Trackbacks -5.3 Comments Form -5.4 Gravity forms -------------------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------------------*/
/* 1. SETUP */ /*-------------------------------------------------------------------------------------------*/

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<vulnerabilities>
<theme name="not-this-one">
<vulnerability>
<title>I should not appear in the results</title>
<reference>http://some-ref.com</reference>
<type>SQLI</type>
</vulnerability>
<vulnerability>
<title>Neither do I</title>
<reference>http://some-other-ref.com</reference>
<type>XSS</type>
</vulnerability>
</theme>
<theme name="the-oracle">
<vulnerability>
<title>I see you</title>
<reference>http://ref.com</reference>
<type>FPD</type>
</vulnerability>
</theme>
</vulnerabilities>

View File

@@ -0,0 +1,36 @@
<!DOCTYPE html>
<!--[if IE 6]>
<html id="ie6" dir="ltr" lang="en-US">
<![endif]-->
<!--[if IE 7]>
<html id="ie7" dir="ltr" lang="en-US">
<![endif]-->
<!--[if IE 8]>
<html id="ie8" dir="ltr" lang="en-US">
<![endif]-->
<!--[if !(IE 6) | !(IE 7) | !(IE 8) ]><!-->
<html dir="ltr" lang="en-US">
<!--<![endif]-->
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>admin d-name | Wordpress 3.3.2</title>
<link rel="profile" href="http://gmpg.org/xfn/11" />
<link rel="stylesheet" type="text/css" media="all" href="http://lamp/wordpress-3.3.2/wp-content/themes/twentyeleven/style.css" />
<link rel="pingback" href="http://lamp/wordpress-3.3.2/xmlrpc.php" />
<!--[if lt IE 9]>
<script src="http://lamp/wordpress-3.3.2/wp-content/themes/twentyeleven/js/html5.js" type="text/javascript"></script>
<![endif]-->
<meta name='robots' content='noindex,nofollow' />
<link rel="alternate" type="application/rss+xml" title="Wordpress 3.3.2 &raquo; Feed" href="http://lamp/wordpress-3.3.2/?feed=rss2" />
<link rel="alternate" type="application/rss+xml" title="Wordpress 3.3.2 &raquo; Comments Feed" href="http://lamp/wordpress-3.3.2/?feed=comments-rss2" />
<link rel="alternate" type="application/rss+xml" title="Wordpress 3.3.2 &raquo; Posts by admin Feed" href="http://lamp/wordpress-3.3.2/?feed=rss2&#038;author=1" />
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://lamp/wordpress-3.3.2/xmlrpc.php?rsd" />
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://lamp/wordpress-3.3.2/wp-includes/wlwmanifest.xml" />
<meta name="generator" content="WordPress 3.3.2" />
<style type="text/css">.recentcomments a{display:inline !important;padding:0 !important;margin:0 !important;}</style>
</head>
<body class="archive author author-admin author-1 single-author two-column right-sidebar">
</body>
</html>

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<!--[if IE 6]>
<html id="ie6" dir="ltr" lang="en-US">
<![endif]-->
<!--[if IE 7]>
<html id="ie7" dir="ltr" lang="en-US">
<![endif]-->
<!--[if IE 8]>
<html id="ie8" dir="ltr" lang="en-US">
<![endif]-->
<!--[if !(IE 6) | !(IE 7) | !(IE 8) ]><!-->
<html dir="ltr" lang="en-US">
<!--<![endif]-->
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>Wordpress 3.3.2 | Just another WordPress site</title>
<link rel="profile" href="http://gmpg.org/xfn/11" />
<link rel="stylesheet" type="text/css" media="all" href="http://lamp/wordpress-3.3.2/wp-content/themes/twentyeleven/style.css" />
<link rel="pingback" href="http://lamp/wordpress-3.3.2/xmlrpc.php" />
<!--[if lt IE 9]>
<script src="http://lamp/wordpress-3.3.2/wp-content/themes/twentyeleven/js/html5.js" type="text/javascript"></script>
<![endif]-->
<meta name='robots' content='noindex,nofollow' />
<link rel="alternate" type="application/rss+xml" title="Wordpress 3.3.2 &raquo; Feed" href="http://lamp/wordpress-3.3.2/?feed=rss2" />
<link rel="alternate" type="application/rss+xml" title="Wordpress 3.3.2 &raquo; Comments Feed" href="http://lamp/wordpress-3.3.2/?feed=comments-rss2" />
<link rel='stylesheet' id='admin-bar-css' href='http://lamp/wordpress-3.3.2/wp-includes/css/admin-bar.css?ver=20111209' type='text/css' media='all' />
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://lamp/wordpress-3.3.2/xmlrpc.php?rsd" />
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://lamp/wordpress-3.3.2/wp-includes/wlwmanifest.xml" />
<meta name="generator" content="WordPress 3.3.2" />
<style type="text/css">.recentcomments a{display:inline !important;padding:0 !important;margin:0 !important;}</style>
<style type="text/css" media="print">#wpadminbar { display:none; }</style>
<style type="text/css" media="screen">
html { margin-top: 28px !important; }
* html body { margin-top: 28px !important; }
</style>
</head>
</html>

View File

@@ -0,0 +1,32 @@
<!DOCTYPE html>
<!--[if IE 6]>
<html id="ie6" dir="ltr" lang="en-US">
<![endif]-->
<!--[if IE 7]>
<html id="ie7" dir="ltr" lang="en-US">
<![endif]-->
<!--[if IE 8]>
<html id="ie8" dir="ltr" lang="en-US">
<![endif]-->
<!--[if !(IE 6) | !(IE 7) | !(IE 8) ]><!-->
<html dir="ltr" lang="en-US">
<!--<![endif]-->
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>Wordpress 3.4 beta 4 | Just another WordPress site</title>
<link rel="profile" href="http://gmpg.org/xfn/11" />
<link rel="stylesheet" type="text/css" media="all" href="http://lamp/wordpress-3.4-beta-4/wp-content/themes/twentyeleven/style.css" />
<link rel="pingback" href="http://lamp/wordpress-3.4-beta-4/xmlrpc.php" />
<!--[if lt IE 9]>
<script src="http://lamp/wordpress-3.4-beta-4/wp-content/themes/twentyeleven/js/html5.js" type="text/javascript"></script>
<![endif]-->
<meta name='robots' content='noindex,nofollow' />
<link rel="alternate" type="application/rss+xml" title="Wordpress 3.4 beta 4 &raquo; Feed" href="http://lamp/wordpress-3.4-beta-4/?feed=rss2" />
<link rel="alternate" type="application/rss+xml" title="Wordpress 3.4 beta 4 &raquo; Comments Feed" href="http://lamp/wordpress-3.4-beta-4/?feed=comments-rss2" />
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://lamp/wordpress-3.4-beta-4/xmlrpc.php?rsd" />
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://lamp/wordpress-3.4-beta-4/wp-includes/wlwmanifest.xml" />
<meta name="generator" content="WordPress 3.4-beta4" />
<style type="text/css">.recentcomments a{display:inline !important;padding:0 !important;margin:0 !important;}</style>
</head>
</html>

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<!--[if IE 6]>
<html id="ie6" dir="ltr" lang="en-US">
<![endif]-->
<!--[if IE 7]>
<html id="ie7" dir="ltr" lang="en-US">
<![endif]-->
<!--[if IE 8]>
<html id="ie8" dir="ltr" lang="en-US">
<![endif]-->
<!--[if !(IE 6) | !(IE 7) | !(IE 8) ]><!-->
<html dir="ltr" lang="en-US">
<!--<![endif]-->
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>Wordpress 3.3.2 | Just another WordPress site</title>
<link rel="profile" href="http://gmpg.org/xfn/11" />
<link rel="stylesheet" type="text/css" media="all" href="http://lamp/wordpress-3.3.2/wp-content/themes/twentyeleven/style.css" />
<link rel="pingback" href="http://lamp/wordpress-3.3.2/xmlrpc.php" />
<!--[if lt IE 9]>
<script src="http://lamp/wordpress-3.3.2/wp-content/themes/twentyeleven/js/html5.js" type="text/javascript"></script>
<![endif]-->
<meta name='robots' content='noindex,nofollow' />
<link rel="alternate" type="application/rss+xml" title="Wordpress 3.3.2 &raquo; Feed" href="http://lamp/wordpress-3.3.2/?feed=rss2" />
<link rel="alternate" type="application/rss+xml" title="Wordpress 3.3.2 &raquo; Comments Feed" href="http://lamp/wordpress-3.3.2/?feed=comments-rss2" />
<link rel='stylesheet' id='admin-bar-css' href='http://lamp/wordpress-3.3.2/wp-includes/css/admin-bar.css?ver=20111209' type='text/css' media='all' />
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://lamp/wordpress-3.3.2/xmlrpc.php?rsd" />
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://lamp/wordpress-3.3.2/wp-includes/wlwmanifest.xml" />
<meta name="generator" content="WordPress 5506" />
<style type="text/css">.recentcomments a{display:inline !important;padding:0 !important;margin:0 !important;}</style>
<style type="text/css" media="print">#wpadminbar { display:none; }</style>
<style type="text/css" media="screen">
html { margin-top: 28px !important; }
* html body { margin-top: 28px !important; }
</style>
</head>
</html>

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<!--[if IE 6]>
<html id="ie6" dir="ltr" lang="en-US">
<![endif]-->
<!--[if IE 7]>
<html id="ie7" dir="ltr" lang="en-US">
<![endif]-->
<!--[if IE 8]>
<html id="ie8" dir="ltr" lang="en-US">
<![endif]-->
<!--[if !(IE 6) | !(IE 7) | !(IE 8) ]><!-->
<html dir="ltr" lang="en-US">
<!--<![endif]-->
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>Wordpress 3.3.2 | Just another WordPress site</title>
<link rel="profile" href="http://gmpg.org/xfn/11" />
<link rel="stylesheet" type="text/css" media="all" href="http://lamp/wordpress-3.3.2/wp-content/themes/twentyeleven/style.css" />
<link rel="pingback" href="http://lamp/wordpress-3.3.2/xmlrpc.php" />
<!--[if lt IE 9]>
<script src="http://lamp/wordpress-3.3.2/wp-content/themes/twentyeleven/js/html5.js" type="text/javascript"></script>
<![endif]-->
<meta name='robots' content='noindex,nofollow' />
<link rel="alternate" type="application/rss+xml" title="Wordpress 3.3.2 &raquo; Feed" href="http://lamp/wordpress-3.3.2/?feed=rss2" />
<link rel="alternate" type="application/rss+xml" title="Wordpress 3.3.2 &raquo; Comments Feed" href="http://lamp/wordpress-3.3.2/?feed=comments-rss2" />
<link rel='stylesheet' id='admin-bar-css' href='http://lamp/wordpress-3.3.2/wp-includes/css/admin-bar.css?ver=20111209' type='text/css' media='all' />
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://lamp/wordpress-3.3.2/xmlrpc.php?rsd" />
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://lamp/wordpress-3.3.2/wp-includes/wlwmanifest.xml" />
<meta name="generator" content="WordPress" />
<style type="text/css">.recentcomments a{display:inline !important;padding:0 !important;margin:0 !important;}</style>
<style type="text/css" media="print">#wpadminbar { display:none; }</style>
<style type="text/css" media="screen">
html { margin-top: 28px !important; }
* html body { margin-top: 28px !important; }
</style>
</head>
</html>

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="http://lamp/wp-content/plugins/google-sitemap-generator/sitemap.xsl"?><!-- generator="wordpress/3.3.2" -->
<!-- sitemap-generator-url="http://www.arnebrachhold.de" sitemap-generator-version="3.2.8" -->
<!-- generated-on="21 January, 2013 12:14 pm" -->

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="http://lamp/wp-content/plugins/google-sitemap-generator/sitemap.xsl"?><!-- generator="wordpress/3.4-beta4" -->
<!-- sitemap-generator-url="http://www.arnebrachhold.de" sitemap-generator-version="3.2.8" -->
<!-- generated-on="21 January, 2013 12:14 pm" -->

Some files were not shown because too many files have changed in this diff Show More