Merge branch 'new-enumeration-system'
This commit is contained in:
@@ -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'
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
29
spec/lib/common/collections/wp_items_spec.rb
Normal file
29
spec/lib/common/collections/wp_items_spec.rb
Normal 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
|
||||
30
spec/lib/common/collections/wp_plugins_spec.rb
Normal file
30
spec/lib/common/collections/wp_plugins_spec.rb
Normal 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
|
||||
28
spec/lib/common/collections/wp_themes_spec.rb
Normal file
28
spec/lib/common/collections/wp_themes_spec.rb
Normal 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
|
||||
123
spec/lib/common/collections/wp_timthumbs/detectable_spec.rb
Normal file
123
spec/lib/common/collections/wp_timthumbs/detectable_spec.rb
Normal 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
|
||||
59
spec/lib/common/collections/wp_users/detectable_spec.rb
Normal file
59
spec/lib/common/collections/wp_users/detectable_spec.rb
Normal 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
|
||||
@@ -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 « BlogName' do
|
||||
@input = ['user1 « BlogName',
|
||||
'user2 « BlogName',
|
||||
'user3 « BlogName',
|
||||
'user4 « BlogName']
|
||||
@expected = ' « 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 « BlogName',
|
||||
'user2 « BlogName',
|
||||
'user3 « BlogName',
|
||||
'user4 « 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
|
||||
28
spec/lib/common/models/vulnerability/output_spec.rb
Normal file
28
spec/lib/common/models/vulnerability/output_spec.rb
Normal 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
|
||||
41
spec/lib/common/models/vulnerability_spec.rb
Normal file
41
spec/lib/common/models/vulnerability_spec.rb
Normal 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
|
||||
163
spec/lib/common/models/wp_item_spec.rb
Normal file
163
spec/lib/common/models/wp_item_spec.rb
Normal 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
|
||||
21
spec/lib/common/models/wp_plugin_spec.rb
Normal file
21
spec/lib/common/models/wp_plugin_spec.rb
Normal 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
|
||||
135
spec/lib/common/models/wp_theme/findable_spec.rb
Normal file
135
spec/lib/common/models/wp_theme/findable_spec.rb
Normal 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
|
||||
40
spec/lib/common/models/wp_theme_spec.rb
Normal file
40
spec/lib/common/models/wp_theme_spec.rb
Normal 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
|
||||
31
spec/lib/common/models/wp_timthumb_spec.rb
Normal file
31
spec/lib/common/models/wp_timthumb_spec.rb
Normal 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
|
||||
87
spec/lib/common/models/wp_user_spec.rb
Normal file
87
spec/lib/common/models/wp_user_spec.rb
Normal 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
|
||||
202
spec/lib/common/models/wp_version/findable_spec.rb
Normal file
202
spec/lib/common/models/wp_version/findable_spec.rb
Normal 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
|
||||
23
spec/lib/common/models/wp_version_spec.rb
Normal file
23
spec/lib/common/models/wp_version_spec.rb
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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'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'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
|
||||
@@ -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 }
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -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')
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -0,0 +1,3 @@
|
||||
item1
|
||||
item-2
|
||||
mr-smith
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -0,0 +1,3 @@
|
||||
plugin1
|
||||
plugin-2
|
||||
mr-smith
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -0,0 +1,3 @@
|
||||
3colours
|
||||
42k
|
||||
a-ri
|
||||
@@ -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>
|
||||
@@ -0,0 +1,4 @@
|
||||
timthumb.php
|
||||
$wp-content$/timthumb.php
|
||||
$wp-plugins$/a-gallery/timthumb.php
|
||||
$wp-content$/themes/theme-name/timthumb.php
|
||||
7
spec/samples/common/models/vulnerability/xml_node.xml
Normal file
7
spec/samples/common/models/vulnerability/xml_node.xml
Normal 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>
|
||||
30
spec/samples/common/models/wp_item/versionable/simple-login-lockdown-0.4.txt
Executable file
30
spec/samples/common/models/wp_item/versionable/simple-login-lockdown-0.4.txt
Executable 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!
|
||||
5
spec/samples/common/models/wp_item/vulnerable/empty.xml
Normal file
5
spec/samples/common/models/wp_item/vulnerable/empty.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<vulnerabilities>
|
||||
|
||||
</vulnerabilities>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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 » 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 » 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>
|
||||
16
spec/samples/common/models/wp_theme/versionable/bueno-1.5.1.css
Executable file
16
spec/samples/common/models/wp_theme/versionable/bueno-1.5.1.css
Executable 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 */ /*-------------------------------------------------------------------------------------------*/
|
||||
@@ -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>
|
||||
36
spec/samples/common/models/wp_user/existable/admin.html
Normal file
36
spec/samples/common/models/wp_user/existable/admin.html
Normal 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 » Feed" href="http://lamp/wordpress-3.3.2/?feed=rss2" />
|
||||
<link rel="alternate" type="application/rss+xml" title="Wordpress 3.3.2 » Comments Feed" href="http://lamp/wordpress-3.3.2/?feed=comments-rss2" />
|
||||
<link rel="alternate" type="application/rss+xml" title="Wordpress 3.3.2 » Posts by admin Feed" href="http://lamp/wordpress-3.3.2/?feed=rss2&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>
|
||||
38
spec/samples/common/models/wp_version/findable/meta_generator/3.3.2.html
Executable file
38
spec/samples/common/models/wp_version/findable/meta_generator/3.3.2.html
Executable 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 » Feed" href="http://lamp/wordpress-3.3.2/?feed=rss2" />
|
||||
<link rel="alternate" type="application/rss+xml" title="Wordpress 3.3.2 » 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>
|
||||
32
spec/samples/common/models/wp_version/findable/meta_generator/3.4-beta4.html
Executable file
32
spec/samples/common/models/wp_version/findable/meta_generator/3.4-beta4.html
Executable 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 » Feed" href="http://lamp/wordpress-3.4-beta-4/?feed=rss2" />
|
||||
<link rel="alternate" type="application/rss+xml" title="Wordpress 3.4 beta 4 » 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>
|
||||
@@ -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 » Feed" href="http://lamp/wordpress-3.3.2/?feed=rss2" />
|
||||
<link rel="alternate" type="application/rss+xml" title="Wordpress 3.3.2 » 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>
|
||||
@@ -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 » Feed" href="http://lamp/wordpress-3.3.2/?feed=rss2" />
|
||||
<link rel="alternate" type="application/rss+xml" title="Wordpress 3.3.2 » 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>
|
||||
@@ -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" -->
|
||||
@@ -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
Reference in New Issue
Block a user