drop ruby 1.9 support, whitespaces
This commit is contained in:
@@ -2,8 +2,6 @@ language: ruby
|
|||||||
sudo: false
|
sudo: false
|
||||||
cache: bundler
|
cache: bundler
|
||||||
rvm:
|
rvm:
|
||||||
- 1.9.2
|
|
||||||
- 1.9.3
|
|
||||||
- 2.0.0
|
- 2.0.0
|
||||||
- 2.1.0
|
- 2.1.0
|
||||||
- 2.1.1
|
- 2.1.1
|
||||||
@@ -23,9 +21,6 @@ script: bundle exec rspec
|
|||||||
notifications:
|
notifications:
|
||||||
email:
|
email:
|
||||||
- team@wpscan.org
|
- team@wpscan.org
|
||||||
matrix:
|
|
||||||
allow_failures:
|
|
||||||
- rvm: 1.9.2
|
|
||||||
# do not build gh-pages branch
|
# do not build gh-pages branch
|
||||||
branches:
|
branches:
|
||||||
except:
|
except:
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ WPScan comes pre-installed on the following Linux distributions:
|
|||||||
|
|
||||||
Prerequisites:
|
Prerequisites:
|
||||||
|
|
||||||
- Ruby >= 1.9.2 - Recommended: 2.3.0
|
- Ruby >= 2.0.0 - Recommended: 2.3.0
|
||||||
- Curl >= 7.21 - Recommended: latest - FYI the 7.29 has a segfault
|
- Curl >= 7.21 - Recommended: latest - FYI the 7.29 has a segfault
|
||||||
- RubyGems - Recommended: latest
|
- RubyGems - Recommended: latest
|
||||||
- Git
|
- Git
|
||||||
@@ -156,8 +156,8 @@ Apple Xcode, Command Line Tools and the libffi are needed (to be able to install
|
|||||||
curl -sSL https://get.rvm.io | bash -s stable
|
curl -sSL https://get.rvm.io | bash -s stable
|
||||||
source ~/.rvm/scripts/rvm
|
source ~/.rvm/scripts/rvm
|
||||||
echo "source ~/.rvm/scripts/rvm" >> ~/.bashrc
|
echo "source ~/.rvm/scripts/rvm" >> ~/.bashrc
|
||||||
rvm install 2.2.4
|
rvm install 2.3.0
|
||||||
rvm use 2.2.4 --default
|
rvm use 2.3.0 --default
|
||||||
echo "gem: --no-ri --no-rdoc" > ~/.gemrc
|
echo "gem: --no-ri --no-rdoc" > ~/.gemrc
|
||||||
gem install bundler
|
gem install bundler
|
||||||
git clone https://github.com/wpscanteam/wpscan.git
|
git clone https://github.com/wpscanteam/wpscan.git
|
||||||
@@ -192,7 +192,7 @@ Apple Xcode, Command Line Tools and the libffi are needed (to be able to install
|
|||||||
|
|
||||||
Then, open the directory of the readline gem (you have to locate it)
|
Then, open the directory of the readline gem (you have to locate it)
|
||||||
|
|
||||||
cd ~/.rvm/src/ruby-1.9.2-p180/ext/readline
|
cd ~/.rvm/src/ruby-XXXX/ext/readline
|
||||||
ruby extconf.rb
|
ruby extconf.rb
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
|
|||||||
@@ -23,9 +23,7 @@ class CacheFileStore
|
|||||||
@storage_path = File.expand_path(File.join(storage_path, storage_dir))
|
@storage_path = File.expand_path(File.join(storage_path, storage_dir))
|
||||||
@serializer = serializer
|
@serializer = serializer
|
||||||
|
|
||||||
# File.directory? for ruby <= 1.9 otherwise,
|
unless Dir.exist?(@storage_path)
|
||||||
# it makes more sense to do Dir.exist? :/
|
|
||||||
unless File.directory?(@storage_path)
|
|
||||||
FileUtils.mkdir_p(@storage_path)
|
FileUtils.mkdir_p(@storage_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ class WpItems < Array
|
|||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
# @return [ Class ]
|
# @return [ Class ]
|
||||||
def item_class
|
def item_class
|
||||||
Object.const_get(self.class.to_s.gsub(/.$/, ''))
|
Object.const_get(self.class.to_s.gsub(/.$/, ''))
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
require 'common/collections/wp_plugins/detectable'
|
require 'common/collections/wp_plugins/detectable'
|
||||||
|
|
||||||
class WpPlugins < WpItems
|
class WpPlugins < WpItems
|
||||||
extend WpPlugins::Detectable
|
extend WpPlugins::Detectable
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
require 'common/collections/wp_themes/detectable'
|
require 'common/collections/wp_themes/detectable'
|
||||||
|
|
||||||
class WpThemes < WpItems
|
class WpThemes < WpItems
|
||||||
extend WpThemes::Detectable
|
extend WpThemes::Detectable
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
require 'common/collections/wp_timthumbs/detectable'
|
require 'common/collections/wp_timthumbs/detectable'
|
||||||
|
|
||||||
class WpTimthumbs < WpItems
|
class WpTimthumbs < WpItems
|
||||||
extend WpTimthumbs::Detectable
|
extend WpTimthumbs::Detectable
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
require 'common/collections/wp_users/detectable'
|
require 'common/collections/wp_users/detectable'
|
||||||
require 'common/collections/wp_users/output'
|
require 'common/collections/wp_users/output'
|
||||||
require 'common/collections/wp_users/brute_forcable'
|
require 'common/collections/wp_users/brute_forcable'
|
||||||
|
|
||||||
class WpUsers < WpItems
|
class WpUsers < WpItems
|
||||||
extend WpUsers::Detectable
|
extend WpUsers::Detectable
|
||||||
include WpUsers::Output
|
include WpUsers::Output
|
||||||
include WpUsers::BruteForcable
|
include WpUsers::BruteForcable
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,34 +1,34 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
class WpUsers < WpItems
|
class WpUsers < WpItems
|
||||||
module Detectable
|
module Detectable
|
||||||
|
|
||||||
# @return [ Hash ]
|
# @return [ Hash ]
|
||||||
def request_params; {} end
|
def request_params; {} end
|
||||||
|
|
||||||
# No passive detection
|
# No passive detection
|
||||||
#
|
#
|
||||||
# @return [ WpUsers ]
|
# @return [ WpUsers ]
|
||||||
def passive_detection(wp_target, options = {})
|
def passive_detection(wp_target, options = {})
|
||||||
new
|
new
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
# @param [ WpTarget ] wp_target
|
# @param [ WpTarget ] wp_target
|
||||||
# @param [ Hash ] options
|
# @param [ Hash ] options
|
||||||
# @option options [ Range ] :range ((1..10))
|
# @option options [ Range ] :range ((1..10))
|
||||||
#
|
#
|
||||||
# @return [ Array<WpUser> ]
|
# @return [ Array<WpUser> ]
|
||||||
def targets_items(wp_target, options = {})
|
def targets_items(wp_target, options = {})
|
||||||
range = options[:range] || (1..10)
|
range = options[:range] || (1..10)
|
||||||
targets = []
|
targets = []
|
||||||
|
|
||||||
range.each do |user_id|
|
range.each do |user_id|
|
||||||
targets << WpUser.new(wp_target.uri, id: user_id)
|
targets << WpUser.new(wp_target.uri, id: user_id)
|
||||||
end
|
end
|
||||||
targets
|
targets
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -266,3 +266,7 @@ end
|
|||||||
def directory_listing_enabled?(url)
|
def directory_listing_enabled?(url)
|
||||||
Browser.get(url.to_s).body[%r{<title>Index of}] ? true : false
|
Browser.get(url.to_s).body[%r{<title>Index of}] ? true : false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def url_encode(str)
|
||||||
|
CGI.escape(str).gsub("+", "%20")
|
||||||
|
end
|
||||||
|
|||||||
@@ -1,35 +1,5 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
# Since ruby 1.9.2, URI::escape is obsolete
|
|
||||||
# See http://rosettacode.org/wiki/URL_encoding#Ruby and http://www.ruby-forum.com/topic/207489
|
|
||||||
if RUBY_VERSION >= '1.9.2'
|
|
||||||
module URI
|
|
||||||
extend self
|
|
||||||
|
|
||||||
def escape(str)
|
|
||||||
URI::Parser.new.escape(str)
|
|
||||||
end
|
|
||||||
alias :encode :escape
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if RUBY_VERSION < '1.9'
|
|
||||||
class Array
|
|
||||||
# Fix for grep with symbols in ruby <= 1.8.7
|
|
||||||
def _grep_(regexp)
|
|
||||||
matches = []
|
|
||||||
self.each do |value|
|
|
||||||
value = value.to_s
|
|
||||||
matches << value if value.match(regexp)
|
|
||||||
end
|
|
||||||
matches
|
|
||||||
end
|
|
||||||
|
|
||||||
alias_method :grep, :_grep_
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# This is used in WpItem::Existable
|
# This is used in WpItem::Existable
|
||||||
module Typhoeus
|
module Typhoeus
|
||||||
class Response
|
class Response
|
||||||
|
|||||||
@@ -1,62 +1,62 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
require 'vulnerability/output'
|
require 'vulnerability/output'
|
||||||
require 'vulnerability/urls'
|
require 'vulnerability/urls'
|
||||||
|
|
||||||
class Vulnerability
|
class Vulnerability
|
||||||
include Vulnerability::Output
|
include Vulnerability::Output
|
||||||
include Vulnerability::Urls
|
include Vulnerability::Urls
|
||||||
|
|
||||||
attr_accessor :title, :references, :type, :fixed_in
|
attr_accessor :title, :references, :type, :fixed_in
|
||||||
|
|
||||||
#
|
#
|
||||||
# @param [ String ] title The title of the vulnerability
|
# @param [ String ] title The title of the vulnerability
|
||||||
# @param [ String ] type The type of the vulnerability
|
# @param [ String ] type The type of the vulnerability
|
||||||
# @param [ Hash ] references References
|
# @param [ Hash ] references References
|
||||||
# @param [ String ] fixed_in Vuln fixed in Version X
|
# @param [ String ] fixed_in Vuln fixed in Version X
|
||||||
#
|
#
|
||||||
# @return [ Vulnerability ]
|
# @return [ Vulnerability ]
|
||||||
def initialize(title, type, references = {}, fixed_in = '')
|
def initialize(title, type, references = {}, fixed_in = '')
|
||||||
@title = title
|
@title = title
|
||||||
@type = type
|
@type = type
|
||||||
@references = references
|
@references = references
|
||||||
@fixed_in = fixed_in
|
@fixed_in = fixed_in
|
||||||
end
|
end
|
||||||
|
|
||||||
# @param [ Vulnerability ] other
|
# @param [ Vulnerability ] other
|
||||||
#
|
#
|
||||||
# @return [ Boolean ]
|
# @return [ Boolean ]
|
||||||
# :nocov:
|
# :nocov:
|
||||||
def ==(other)
|
def ==(other)
|
||||||
title == other.title &&
|
title == other.title &&
|
||||||
type == other.type &&
|
type == other.type &&
|
||||||
references == other.references &&
|
references == other.references &&
|
||||||
fixed_in == other.fixed_in
|
fixed_in == other.fixed_in
|
||||||
end
|
end
|
||||||
# :nocov:
|
# :nocov:
|
||||||
|
|
||||||
# Create the Vulnerability from the json_item
|
# Create the Vulnerability from the json_item
|
||||||
#
|
#
|
||||||
# @param [ Hash ] json_item
|
# @param [ Hash ] json_item
|
||||||
#
|
#
|
||||||
# @return [ Vulnerability ]
|
# @return [ Vulnerability ]
|
||||||
def self.load_from_json_item(json_item)
|
def self.load_from_json_item(json_item)
|
||||||
references = {}
|
references = {}
|
||||||
references['id'] = [json_item['id']]
|
references['id'] = [json_item['id']]
|
||||||
|
|
||||||
%w(url cve secunia osvdb metasploit exploitdb).each do |key|
|
%w(url cve secunia osvdb metasploit exploitdb).each do |key|
|
||||||
if json_item['references'][key]
|
if json_item['references'][key]
|
||||||
json_item['references'][key] = [json_item['references'][key]] if json_item['references'][key].class != Array
|
json_item['references'][key] = [json_item['references'][key]] if json_item['references'][key].class != Array
|
||||||
references[key] = json_item['references'][key]
|
references[key] = json_item['references'][key]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
new(
|
new(
|
||||||
json_item['title'],
|
json_item['title'],
|
||||||
json_item['type'],
|
json_item['type'],
|
||||||
references,
|
references,
|
||||||
json_item['fixed_in']
|
json_item['fixed_in']
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,123 +1,121 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
require 'wp_item/findable'
|
require 'wp_item/findable'
|
||||||
require 'wp_item/versionable'
|
require 'wp_item/versionable'
|
||||||
require 'wp_item/vulnerable'
|
require 'wp_item/vulnerable'
|
||||||
require 'wp_item/existable'
|
require 'wp_item/existable'
|
||||||
require 'wp_item/infos'
|
require 'wp_item/infos'
|
||||||
require 'wp_item/output'
|
require 'wp_item/output'
|
||||||
|
|
||||||
class WpItem
|
class WpItem
|
||||||
|
|
||||||
extend WpItem::Findable
|
extend WpItem::Findable
|
||||||
include WpItem::Versionable
|
include WpItem::Versionable
|
||||||
include WpItem::Vulnerable
|
include WpItem::Vulnerable
|
||||||
include WpItem::Existable
|
include WpItem::Existable
|
||||||
include WpItem::Infos
|
include WpItem::Infos
|
||||||
include WpItem::Output
|
include WpItem::Output
|
||||||
|
|
||||||
attr_reader :path
|
attr_reader :path
|
||||||
attr_accessor :name, :wp_content_dir, :wp_plugins_dir
|
attr_accessor :name, :wp_content_dir, :wp_plugins_dir
|
||||||
|
|
||||||
# @return [ Array ]
|
# @return [ Array ]
|
||||||
# Make it private ?
|
# Make it private ?
|
||||||
def allowed_options
|
def allowed_options
|
||||||
[:name, :wp_content_dir, :wp_plugins_dir, :path, :version, :db_file]
|
[:name, :wp_content_dir, :wp_plugins_dir, :path, :version, :db_file]
|
||||||
end
|
end
|
||||||
|
|
||||||
# @param [ URI ] target_base_uri
|
# @param [ URI ] target_base_uri
|
||||||
# @param [ Hash ] options See allowed_option
|
# @param [ Hash ] options See allowed_option
|
||||||
#
|
#
|
||||||
# @return [ WpItem ]
|
# @return [ WpItem ]
|
||||||
def initialize(target_base_uri, options = {})
|
def initialize(target_base_uri, options = {})
|
||||||
options[:wp_content_dir] ||= 'wp-content'
|
options[:wp_content_dir] ||= 'wp-content'
|
||||||
options[:wp_plugins_dir] ||= options[:wp_content_dir] + '/plugins'
|
options[:wp_plugins_dir] ||= options[:wp_content_dir] + '/plugins'
|
||||||
|
|
||||||
set_options(options)
|
set_options(options)
|
||||||
forge_uri(target_base_uri)
|
forge_uri(target_base_uri)
|
||||||
end
|
end
|
||||||
|
|
||||||
def identifier
|
def identifier
|
||||||
@identifier ||= name
|
@identifier ||= name
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [ Hash ]
|
# @return [ Hash ]
|
||||||
def db_data
|
def db_data
|
||||||
@db_data ||= json(db_file)[identifier] || {}
|
@db_data ||= json(db_file)[identifier] || {}
|
||||||
end
|
end
|
||||||
|
|
||||||
def latest_version
|
def latest_version
|
||||||
db_data['latest_version']
|
db_data['latest_version']
|
||||||
end
|
end
|
||||||
|
|
||||||
def last_updated
|
def last_updated
|
||||||
db_data['last_ipdated']
|
db_data['last_ipdated']
|
||||||
end
|
end
|
||||||
|
|
||||||
def popular?
|
def popular?
|
||||||
db_data['popular']
|
db_data['popular']
|
||||||
end
|
end
|
||||||
|
|
||||||
# @param [ Hash ] options
|
# @param [ Hash ] options
|
||||||
#
|
#
|
||||||
# @return [ void ]
|
# @return [ void ]
|
||||||
def set_options(options)
|
def set_options(options)
|
||||||
allowed_options.each do |allowed_option|
|
allowed_options.each do |allowed_option|
|
||||||
if options.has_key?(allowed_option)
|
if options.has_key?(allowed_option)
|
||||||
method = :"#{allowed_option}="
|
method = :"#{allowed_option}="
|
||||||
|
|
||||||
if self.respond_to?(method)
|
if self.respond_to?(method)
|
||||||
self.send(method, options[allowed_option])
|
self.send(method, options[allowed_option])
|
||||||
else
|
else
|
||||||
raise "#{self.class} does not respond to #{method}"
|
raise "#{self.class} does not respond to #{method}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
private :set_options
|
private :set_options
|
||||||
|
|
||||||
# @param [ URI ] target_base_uri
|
# @param [ URI ] target_base_uri
|
||||||
#
|
#
|
||||||
# @return [ void ]
|
# @return [ void ]
|
||||||
def forge_uri(target_base_uri)
|
def forge_uri(target_base_uri)
|
||||||
@uri = target_base_uri
|
@uri = target_base_uri
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [ URI ] The uri to the WpItem, with the path if present
|
# @return [ URI ] The uri to the WpItem, with the path if present
|
||||||
def uri
|
def uri
|
||||||
path ? @uri.merge(path) : @uri
|
path ? @uri.merge(path) : @uri
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [ String ] The url to the WpItem
|
# @return [ String ] The url to the WpItem
|
||||||
def url; uri.to_s end
|
def url; uri.to_s end
|
||||||
|
|
||||||
# Sets the path
|
# Sets the path
|
||||||
#
|
#
|
||||||
# Variable, such as $wp-plugins$ and $wp-content$ can be used
|
# Variable, such as $wp-plugins$ and $wp-content$ can be used
|
||||||
# and will be replace by their value
|
# and will be replace by their value
|
||||||
#
|
#
|
||||||
# @param [ String ] path
|
# @param [ String ] path
|
||||||
#
|
#
|
||||||
# @return [ void ]
|
# @return [ void ]
|
||||||
def path=(path)
|
def path=(path)
|
||||||
@path = URI.encode(
|
@path = path.gsub(/\$wp-plugins\$/i, wp_plugins_dir).gsub(/\$wp-content\$/i, wp_content_dir)
|
||||||
path.gsub(/\$wp-plugins\$/i, wp_plugins_dir).gsub(/\$wp-content\$/i, wp_content_dir)
|
end
|
||||||
)
|
|
||||||
end
|
# @param [ WpItem ] other
|
||||||
|
def <=>(other)
|
||||||
# @param [ WpItem ] other
|
name <=> other.name
|
||||||
def <=>(other)
|
end
|
||||||
name <=> other.name
|
|
||||||
end
|
# @param [ WpItem ] other
|
||||||
|
def ==(other)
|
||||||
# @param [ WpItem ] other
|
name === other.name
|
||||||
def ==(other)
|
end
|
||||||
name === other.name
|
|
||||||
end
|
# @param [ WpItem ] other
|
||||||
|
def ===(other)
|
||||||
# @param [ WpItem ] other
|
self == other && version === other.version
|
||||||
def ===(other)
|
end
|
||||||
self == other && version === other.version
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
|
||||||
|
|||||||
@@ -1,50 +1,50 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
class WpItem
|
class WpItem
|
||||||
module Existable
|
module Existable
|
||||||
|
|
||||||
# Check the existence of the WpItem
|
# Check the existence of the WpItem
|
||||||
# If the response is supplied, it's used for the verification
|
# If the response is supplied, it's used for the verification
|
||||||
# Otherwise a new request is done
|
# Otherwise a new request is done
|
||||||
#
|
#
|
||||||
# @param [ Hash ] options See exists_from_response?
|
# @param [ Hash ] options See exists_from_response?
|
||||||
# @param [ Typhoeus::Response ] response
|
# @param [ Typhoeus::Response ] response
|
||||||
#
|
#
|
||||||
# @return [ Boolean ]
|
# @return [ Boolean ]
|
||||||
def exists?(options = {}, response = nil)
|
def exists?(options = {}, response = nil)
|
||||||
unless response
|
unless response
|
||||||
response = Browser.get(url)
|
response = Browser.get(url)
|
||||||
end
|
end
|
||||||
exists_from_response?(response, options)
|
exists_from_response?(response, options)
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
# @param [ Typhoeus::Response ] response
|
# @param [ Typhoeus::Response ] response
|
||||||
# @param [ options ] options
|
# @param [ options ] options
|
||||||
#
|
#
|
||||||
# @option options [ Hash ] :error_404_hash The hash of the error 404 page
|
# @option options [ Hash ] :error_404_hash The hash of the error 404 page
|
||||||
# @option options [ Hash ] :homepage_hash The hash of the homepage
|
# @option options [ Hash ] :homepage_hash The hash of the homepage
|
||||||
# @option options [ Hash ] :exclude_content A regexp with the pattern to exclude from the body of the response
|
# @option options [ Hash ] :exclude_content A regexp with the pattern to exclude from the body of the response
|
||||||
#
|
#
|
||||||
# @return [ Boolean ]
|
# @return [ Boolean ]
|
||||||
def exists_from_response?(response, options = {})
|
def exists_from_response?(response, options = {})
|
||||||
# 301 included as some items do a self-redirect
|
# 301 included as some items do a self-redirect
|
||||||
# Redirects to the 404 and homepage should be ignored (unless dynamic content is used)
|
# Redirects to the 404 and homepage should be ignored (unless dynamic content is used)
|
||||||
# by the page hashes (error_404_hash & homepage_hash)
|
# by the page hashes (error_404_hash & homepage_hash)
|
||||||
if [200, 401, 403, 301].include?(response.code)
|
if [200, 401, 403, 301].include?(response.code)
|
||||||
if response.has_valid_hash?(options[:error_404_hash], options[:homepage_hash])
|
if response.has_valid_hash?(options[:error_404_hash], options[:homepage_hash])
|
||||||
if options[:exclude_content]
|
if options[:exclude_content]
|
||||||
unless response.body.match(options[:exclude_content])
|
unless response.body.match(options[:exclude_content])
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
class WpItem
|
class WpItem
|
||||||
attr_reader :found_from
|
attr_reader :found_from
|
||||||
|
|
||||||
# Sets the found_from attribute
|
# Sets the found_from attribute
|
||||||
#
|
#
|
||||||
# @param [ String ] method The method which found the WpItem
|
# @param [ String ] method The method which found the WpItem
|
||||||
#
|
#
|
||||||
# @return [ void ]
|
# @return [ void ]
|
||||||
def found_from=(method)
|
def found_from=(method)
|
||||||
found = method[%r{find_from_(.*)}, 1]
|
found = method[%r{find_from_(.*)}, 1]
|
||||||
@found_from = found.gsub('_', ' ') if found
|
@found_from = found.gsub('_', ' ') if found
|
||||||
end
|
end
|
||||||
|
|
||||||
module Findable
|
module Findable
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,44 +1,44 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
class WpItem
|
class WpItem
|
||||||
module Vulnerable
|
module Vulnerable
|
||||||
attr_accessor :db_file, :identifier
|
attr_accessor :db_file, :identifier
|
||||||
|
|
||||||
# Get the vulnerabilities associated to the WpItem
|
# Get the vulnerabilities associated to the WpItem
|
||||||
# Filters out already fixed vulnerabilities
|
# Filters out already fixed vulnerabilities
|
||||||
#
|
#
|
||||||
# @return [ Vulnerabilities ]
|
# @return [ Vulnerabilities ]
|
||||||
def vulnerabilities
|
def vulnerabilities
|
||||||
return @vulnerabilities if @vulnerabilities
|
return @vulnerabilities if @vulnerabilities
|
||||||
|
|
||||||
@vulnerabilities = Vulnerabilities.new
|
@vulnerabilities = Vulnerabilities.new
|
||||||
|
|
||||||
[*db_data['vulnerabilities']].each do |vulnerability|
|
[*db_data['vulnerabilities']].each do |vulnerability|
|
||||||
vulnerability = Vulnerability.load_from_json_item(vulnerability)
|
vulnerability = Vulnerability.load_from_json_item(vulnerability)
|
||||||
@vulnerabilities << vulnerability if vulnerable_to?(vulnerability)
|
@vulnerabilities << vulnerability if vulnerable_to?(vulnerability)
|
||||||
end
|
end
|
||||||
|
|
||||||
@vulnerabilities
|
@vulnerabilities
|
||||||
end
|
end
|
||||||
|
|
||||||
def vulnerable?
|
def vulnerable?
|
||||||
vulnerabilities.empty? ? false : true
|
vulnerabilities.empty? ? false : true
|
||||||
end
|
end
|
||||||
|
|
||||||
# Checks if a item is vulnerable to a specific vulnerability
|
# Checks if a item is vulnerable to a specific vulnerability
|
||||||
#
|
#
|
||||||
# @param [ Vulnerability ] vuln Vulnerability to check the item against
|
# @param [ Vulnerability ] vuln Vulnerability to check the item against
|
||||||
#
|
#
|
||||||
# @return [ Boolean ]
|
# @return [ Boolean ]
|
||||||
def vulnerable_to?(vuln)
|
def vulnerable_to?(vuln)
|
||||||
if version && vuln && vuln.fixed_in && !vuln.fixed_in.empty?
|
if version && vuln && vuln.fixed_in && !vuln.fixed_in.empty?
|
||||||
unless VersionCompare::lesser_or_equal?(vuln.fixed_in, version)
|
unless VersionCompare::lesser_or_equal?(vuln.fixed_in, version)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
class WpPlugin < WpItem
|
class WpPlugin < WpItem
|
||||||
# Sets the @uri
|
# Sets the @uri
|
||||||
#
|
#
|
||||||
# @param [ URI ] target_base_uri The URI of the wordpress blog
|
# @param [ URI ] target_base_uri The URI of the wordpress blog
|
||||||
#
|
#
|
||||||
# @return [ void ]
|
# @return [ void ]
|
||||||
def forge_uri(target_base_uri)
|
def forge_uri(target_base_uri)
|
||||||
@uri = target_base_uri.merge(URI.encode(wp_plugins_dir + '/' + name + '/'))
|
@uri = target_base_uri.merge("#{wp_plugins_dir}/#{url_encode(name)}/")
|
||||||
end
|
end
|
||||||
|
|
||||||
def db_file
|
def db_file
|
||||||
@db_file ||= PLUGINS_FILE
|
@db_file ||= PLUGINS_FILE
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,37 +1,37 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
require 'wp_theme/findable'
|
require 'wp_theme/findable'
|
||||||
require 'wp_theme/versionable'
|
require 'wp_theme/versionable'
|
||||||
require 'wp_theme/info'
|
require 'wp_theme/info'
|
||||||
require 'wp_theme/output'
|
require 'wp_theme/output'
|
||||||
require 'wp_theme/childtheme'
|
require 'wp_theme/childtheme'
|
||||||
|
|
||||||
class WpTheme < WpItem
|
class WpTheme < WpItem
|
||||||
extend WpTheme::Findable
|
extend WpTheme::Findable
|
||||||
include WpTheme::Versionable
|
include WpTheme::Versionable
|
||||||
include WpTheme::Info
|
include WpTheme::Info
|
||||||
include WpTheme::Output
|
include WpTheme::Output
|
||||||
include WpTheme::Childtheme
|
include WpTheme::Childtheme
|
||||||
|
|
||||||
attr_accessor :referenced_url
|
attr_accessor :referenced_url
|
||||||
|
|
||||||
def allowed_options; super << :referenced_url end
|
def allowed_options; super << :referenced_url end
|
||||||
|
|
||||||
# Sets the @uri
|
# Sets the @uri
|
||||||
#
|
#
|
||||||
# @param [ URI ] target_base_uri The URI of the wordpress blog
|
# @param [ URI ] target_base_uri The URI of the wordpress blog
|
||||||
#
|
#
|
||||||
# @return [ void ]
|
# @return [ void ]
|
||||||
def forge_uri(target_base_uri)
|
def forge_uri(target_base_uri)
|
||||||
@uri = target_base_uri.merge(URI.encode(wp_content_dir + '/themes/' + name + '/'))
|
@uri = target_base_uri.merge("#{wp_content_dir}/themes/#{url_encode(name)}/")
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [ String ] The url to the theme stylesheet
|
# @return [ String ] The url to the theme stylesheet
|
||||||
def style_url
|
def style_url
|
||||||
@uri.merge('style.css').to_s
|
@uri.merge('style.css').to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
def db_file
|
def db_file
|
||||||
@db_file ||= THEMES_FILE
|
@db_file ||= THEMES_FILE
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,64 +1,64 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
class WpTheme < WpItem
|
class WpTheme < WpItem
|
||||||
module Findable
|
module Findable
|
||||||
|
|
||||||
# Find the main theme of the blog
|
# Find the main theme of the blog
|
||||||
#
|
#
|
||||||
# @param [ URI ] target_uri
|
# @param [ URI ] target_uri
|
||||||
#
|
#
|
||||||
# @return [ WpTheme ]
|
# @return [ WpTheme ]
|
||||||
def find(target_uri)
|
def find(target_uri)
|
||||||
methods.grep(/^find_from_/).each do |method|
|
methods.grep(/^find_from_/).each do |method|
|
||||||
if wp_theme = self.send(method, target_uri)
|
if wp_theme = self.send(method, target_uri)
|
||||||
wp_theme.found_from = method
|
wp_theme.found_from = method
|
||||||
|
|
||||||
return wp_theme
|
return wp_theme
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
# Discover the wordpress theme by parsing the css link rel
|
# Discover the wordpress theme by parsing the css link rel
|
||||||
#
|
#
|
||||||
# @param [ URI ] target_uri
|
# @param [ URI ] target_uri
|
||||||
#
|
#
|
||||||
# @return [ WpTheme ]
|
# @return [ WpTheme ]
|
||||||
def find_from_css_link(target_uri)
|
def find_from_css_link(target_uri)
|
||||||
response = Browser.get_and_follow_location(target_uri.to_s)
|
response = Browser.get_and_follow_location(target_uri.to_s)
|
||||||
|
|
||||||
# https + domain is optional because of relative links
|
# https + domain is optional because of relative links
|
||||||
return unless response.body =~ %r{(?:https?://[^"']+/)?([^/\s]+)/themes/([^"'/]+)[^"']*/style.css}i
|
return unless response.body =~ %r{(?:https?://[^"']+/)?([^/\s]+)/themes/([^"'/]+)[^"']*/style.css}i
|
||||||
|
|
||||||
new(
|
new(
|
||||||
target_uri,
|
target_uri,
|
||||||
name: Regexp.last_match[2],
|
name: Regexp.last_match[2],
|
||||||
referenced_url: Regexp.last_match[0],
|
referenced_url: Regexp.last_match[0],
|
||||||
wp_content_dir: Regexp.last_match[1]
|
wp_content_dir: Regexp.last_match[1]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
# @param [ URI ] target_uri
|
# @param [ URI ] target_uri
|
||||||
#
|
#
|
||||||
# @return [ WpTheme ]
|
# @return [ WpTheme ]
|
||||||
def find_from_wooframework(target_uri)
|
def find_from_wooframework(target_uri)
|
||||||
body = Browser.get(target_uri.to_s).body
|
body = Browser.get(target_uri.to_s).body
|
||||||
regexp = %r{<meta name="generator" content="([^\s"]+)\s?([^"]+)?" />\s+<meta name="generator" content="WooFramework\s?([^"]+)?" />}
|
regexp = %r{<meta name="generator" content="([^\s"]+)\s?([^"]+)?" />\s+<meta name="generator" content="WooFramework\s?([^"]+)?" />}
|
||||||
|
|
||||||
if matches = regexp.match(body)
|
if matches = regexp.match(body)
|
||||||
woo_theme_name = matches[1]
|
woo_theme_name = matches[1]
|
||||||
woo_theme_version = matches[2]
|
woo_theme_version = matches[2]
|
||||||
#woo_framework_version = matches[3] # Not used at this time
|
#woo_framework_version = matches[3] # Not used at this time
|
||||||
|
|
||||||
return new(
|
return new(
|
||||||
target_uri,
|
target_uri,
|
||||||
name: woo_theme_name,
|
name: woo_theme_name,
|
||||||
version: woo_theme_version
|
version: woo_theme_version
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
class WpTheme < WpItem
|
class WpTheme < WpItem
|
||||||
module Versionable
|
module Versionable
|
||||||
def version
|
def version
|
||||||
@version ||= Browser.get(style_url).body[%r{Version:\s*(?!trunk)([0-9a-z\.-]+)}i, 1]
|
@version ||= Browser.get(style_url).body[%r{Version:\s*(?!trunk)([0-9a-z\.-]+)}i, 1]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
require 'wp_timthumb/versionable'
|
require 'wp_timthumb/versionable'
|
||||||
require 'wp_timthumb/existable'
|
require 'wp_timthumb/existable'
|
||||||
require 'wp_timthumb/output'
|
require 'wp_timthumb/output'
|
||||||
require 'wp_timthumb/vulnerable'
|
require 'wp_timthumb/vulnerable'
|
||||||
|
|
||||||
class WpTimthumb < WpItem
|
class WpTimthumb < WpItem
|
||||||
include WpTimthumb::Versionable
|
include WpTimthumb::Versionable
|
||||||
include WpTimthumb::Existable
|
include WpTimthumb::Existable
|
||||||
include WpTimthumb::Output
|
include WpTimthumb::Output
|
||||||
include WpTimthumb::Vulnerable
|
include WpTimthumb::Vulnerable
|
||||||
|
|
||||||
# @param [ WpTimthumb ] other
|
# @param [ WpTimthumb ] other
|
||||||
#
|
#
|
||||||
# @return [ Boolean ]
|
# @return [ Boolean ]
|
||||||
def ==(other)
|
def ==(other)
|
||||||
url == other.url
|
url == other.url
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
class WpTimthumb < WpItem
|
class WpTimthumb < WpItem
|
||||||
module Versionable
|
module Versionable
|
||||||
|
|
||||||
# Get the version from the body of an invalid request
|
# Get the version from the body of an invalid request
|
||||||
# See https://code.google.com/p/timthumb/source/browse/trunk/timthumb.php#426
|
# See https://code.google.com/p/timthumb/source/browse/trunk/timthumb.php#426
|
||||||
#
|
#
|
||||||
# @return [ String ] The version
|
# @return [ String ] The version
|
||||||
def version
|
def version
|
||||||
unless @version
|
unless @version
|
||||||
response = Browser.get(url)
|
response = Browser.get(url)
|
||||||
@version = response.body[%r{TimThumb version\s*: ([^<]+)} , 1]
|
@version = response.body[%r{TimThumb version\s*: ([^<]+)} , 1]
|
||||||
end
|
end
|
||||||
@version
|
@version
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [ String ]
|
# @return [ String ]
|
||||||
def to_s
|
def to_s
|
||||||
"#{url}#{ ' v' + version if version}"
|
"#{url}#{ ' v' + version if version}"
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,86 +1,86 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
class WpUser < WpItem
|
class WpUser < WpItem
|
||||||
module Existable
|
module Existable
|
||||||
|
|
||||||
# @param [ Typhoeus::Response ] response
|
# @param [ Typhoeus::Response ] response
|
||||||
# @param [ Hash ] options
|
# @param [ Hash ] options
|
||||||
#
|
#
|
||||||
# @return [ Boolean ]
|
# @return [ Boolean ]
|
||||||
def exists_from_response?(response, options = {})
|
def exists_from_response?(response, options = {})
|
||||||
load_from_response(response)
|
load_from_response(response)
|
||||||
|
|
||||||
@login ? true : false
|
@login ? true : false
|
||||||
end
|
end
|
||||||
|
|
||||||
# Load the login and display_name from the response
|
# Load the login and display_name from the response
|
||||||
#
|
#
|
||||||
# @param [ Typhoeus::Response ] response
|
# @param [ Typhoeus::Response ] response
|
||||||
#
|
#
|
||||||
# @return [ void ]
|
# @return [ void ]
|
||||||
def load_from_response(response)
|
def load_from_response(response)
|
||||||
if response.code == 301 # login in location?
|
if response.code == 301 # login in location?
|
||||||
location = response.headers_hash['Location']
|
location = response.headers_hash['Location']
|
||||||
|
|
||||||
return if location.nil? || location.empty?
|
return if location.nil? || location.empty?
|
||||||
|
|
||||||
@login = Existable.login_from_author_pattern(location)
|
@login = Existable.login_from_author_pattern(location)
|
||||||
@display_name = Existable.display_name_from_body(
|
@display_name = Existable.display_name_from_body(
|
||||||
Browser.get(location).body
|
Browser.get(location).body
|
||||||
)
|
)
|
||||||
elsif response.code == 200 # login in body?
|
elsif response.code == 200 # login in body?
|
||||||
@login = Existable.login_from_body(response.body)
|
@login = Existable.login_from_body(response.body)
|
||||||
@display_name = Existable.display_name_from_body(response.body)
|
@display_name = Existable.display_name_from_body(response.body)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
private :load_from_response
|
private :load_from_response
|
||||||
|
|
||||||
# @param [ String ] text
|
# @param [ String ] text
|
||||||
#
|
#
|
||||||
# @return [ String ] The login
|
# @return [ String ] The login
|
||||||
def self.login_from_author_pattern(text)
|
def self.login_from_author_pattern(text)
|
||||||
return unless text =~ %r{/author/([^/\b"']+)/?}i
|
return unless text =~ %r{/author/([^/\b"']+)/?}i
|
||||||
|
|
||||||
Regexp.last_match[1].force_encoding('UTF-8')
|
Regexp.last_match[1].force_encoding('UTF-8')
|
||||||
end
|
end
|
||||||
|
|
||||||
# @param [ String ] body
|
# @param [ String ] body
|
||||||
#
|
#
|
||||||
# @return [ String ] The login
|
# @return [ String ] The login
|
||||||
def self.login_from_body(body)
|
def self.login_from_body(body)
|
||||||
# Feed URL with Permalinks
|
# Feed URL with Permalinks
|
||||||
login = WpUser::Existable.login_from_author_pattern(body)
|
login = WpUser::Existable.login_from_author_pattern(body)
|
||||||
|
|
||||||
unless login
|
unless login
|
||||||
# No Permalinks
|
# No Permalinks
|
||||||
login = body[%r{<body class="archive author author-([^\s]+)[ "]}i, 1]
|
login = body[%r{<body class="archive author author-([^\s]+)[ "]}i, 1]
|
||||||
login ? login.force_encoding('UTF-8') : nil
|
login ? login.force_encoding('UTF-8') : nil
|
||||||
end
|
end
|
||||||
|
|
||||||
login
|
login
|
||||||
end
|
end
|
||||||
|
|
||||||
# @note Some bodies are encoded in ASCII-8BIT, and Nokogiri doesn't support it
|
# @note Some bodies are encoded in ASCII-8BIT, and Nokogiri doesn't support it
|
||||||
# So it's forced to UTF-8 when this encoding is detected
|
# So it's forced to UTF-8 when this encoding is detected
|
||||||
#
|
#
|
||||||
# @param [ String ] body
|
# @param [ String ] body
|
||||||
#
|
#
|
||||||
# @return [ String ] The display_name
|
# @return [ String ] The display_name
|
||||||
def self.display_name_from_body(body)
|
def self.display_name_from_body(body)
|
||||||
if title_tag = body[%r{<title>([^<]+)</title>}i, 1]
|
if title_tag = body[%r{<title>([^<]+)</title>}i, 1]
|
||||||
title_tag.force_encoding('UTF-8') if title_tag.encoding == Encoding::ASCII_8BIT
|
title_tag.force_encoding('UTF-8') if title_tag.encoding == Encoding::ASCII_8BIT
|
||||||
title_tag = Nokogiri::HTML::DocumentFragment.parse(title_tag).to_s
|
title_tag = Nokogiri::HTML::DocumentFragment.parse(title_tag).to_s
|
||||||
# & are not decoded with Nokogiri
|
# & are not decoded with Nokogiri
|
||||||
title_tag.gsub!('&', '&')
|
title_tag.gsub!('&', '&')
|
||||||
|
|
||||||
# replace UTF chars like » with dummy character
|
# replace UTF chars like » with dummy character
|
||||||
title_tag.gsub!(/&#(\d+);/, '|')
|
title_tag.gsub!(/&#(\d+);/, '|')
|
||||||
|
|
||||||
name = title_tag[%r{([^|«»]+) }, 1]
|
name = title_tag[%r{([^|«»]+) }, 1]
|
||||||
|
|
||||||
return name.strip if name
|
return name.strip if name
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,38 +1,38 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
require 'wp_version/findable'
|
require 'wp_version/findable'
|
||||||
require 'wp_version/output'
|
require 'wp_version/output'
|
||||||
|
|
||||||
class WpVersion < WpItem
|
class WpVersion < WpItem
|
||||||
extend WpVersion::Findable
|
extend WpVersion::Findable
|
||||||
include WpVersion::Output
|
include WpVersion::Output
|
||||||
|
|
||||||
# The version number
|
# The version number
|
||||||
attr_accessor :number
|
attr_accessor :number
|
||||||
alias_method :version, :number # Needed to have the right behaviour in Vulnerable#vulnerable_to?
|
alias_method :version, :number # Needed to have the right behaviour in Vulnerable#vulnerable_to?
|
||||||
|
|
||||||
# @return [ Array ]
|
# @return [ Array ]
|
||||||
def allowed_options; super << :number << :found_from end
|
def allowed_options; super << :number << :found_from end
|
||||||
|
|
||||||
def identifier
|
def identifier
|
||||||
@identifier ||= number
|
@identifier ||= number
|
||||||
end
|
end
|
||||||
|
|
||||||
def db_file
|
def db_file
|
||||||
@db_file ||= WORDPRESSES_FILE
|
@db_file ||= WORDPRESSES_FILE
|
||||||
end
|
end
|
||||||
|
|
||||||
# @param [ WpVersion ] other
|
# @param [ WpVersion ] other
|
||||||
#
|
#
|
||||||
# @return [ Boolean ]
|
# @return [ Boolean ]
|
||||||
def ==(other)
|
def ==(other)
|
||||||
number == other.number
|
number == other.number
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [ Array<String> ] All the stable versions from version_file
|
# @return [ Array<String> ] All the stable versions from version_file
|
||||||
def self.all(versions_file = WP_VERSIONS_FILE)
|
def self.all(versions_file = WP_VERSIONS_FILE)
|
||||||
Nokogiri.XML(File.open(versions_file)).css('version').reduce([]) do |a, node|
|
Nokogiri.XML(File.open(versions_file)).css('version').reduce([]) do |a, node|
|
||||||
a << node.text.to_s
|
a << node.text.to_s
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -130,8 +130,6 @@ class WpVersion < WpItem
|
|||||||
def find_from_advanced_fingerprinting(target_uri, wp_content_dir, wp_plugins_dir, versions_xml)
|
def find_from_advanced_fingerprinting(target_uri, wp_content_dir, wp_plugins_dir, versions_xml)
|
||||||
xml = xml(versions_xml)
|
xml = xml(versions_xml)
|
||||||
|
|
||||||
# This wp_item will take care of encoding the path
|
|
||||||
# and replace variables like $wp-content$ & $wp-plugins$
|
|
||||||
wp_item = WpItem.new(target_uri,
|
wp_item = WpItem.new(target_uri,
|
||||||
wp_content_dir: wp_content_dir,
|
wp_content_dir: wp_content_dir,
|
||||||
wp_plugins_dir: wp_plugins_dir)
|
wp_plugins_dir: wp_plugins_dir)
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
require 'rubygems'
|
require 'rubygems'
|
||||||
|
|
||||||
version = RUBY_VERSION.dup
|
version = RUBY_VERSION.dup
|
||||||
if Gem::Version.create(version) < Gem::Version.create(1.9)
|
if Gem::Version.create(version) < Gem::Version.create(2.0)
|
||||||
puts "Ruby >= 1.9 required to run wpscan (You have #{version})"
|
puts "Ruby >= 2.0.0 required to run wpscan (You have #{version})"
|
||||||
exit(1)
|
exit(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class WpTarget < WebSite
|
|||||||
queue_count = 0
|
queue_count = 0
|
||||||
|
|
||||||
backups.each do |file|
|
backups.each do |file|
|
||||||
file_url = @uri.merge(URI.escape(file)).to_s
|
file_url = @uri.merge(url_encode(file)).to_s
|
||||||
request = browser.forge_request(file_url)
|
request = browser.forge_request(file_url)
|
||||||
|
|
||||||
request.on_complete do |response|
|
request.on_complete do |response|
|
||||||
|
|||||||
@@ -105,11 +105,6 @@ describe WpItem do
|
|||||||
@expected = 'plugins/readme.txt'
|
@expected = 'plugins/readme.txt'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'also encodes chars' do
|
|
||||||
@path = 'some dir with spaces'
|
|
||||||
@expected = 'some%20dir%20with%20spaces'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#uri' do
|
describe '#uri' do
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ shared_examples 'WpTarget::WpConfigBackup' do
|
|||||||
# set all @config_backup_files to point to a 404
|
# set all @config_backup_files to point to a 404
|
||||||
before :each do
|
before :each do
|
||||||
config_backup_files.each do |backup_file|
|
config_backup_files.each do |backup_file|
|
||||||
file_url = wp_target.uri.merge(URI.escape(backup_file)).to_s
|
file_url = wp_target.uri.merge(url_encode(backup_file)).to_s
|
||||||
|
|
||||||
stub_request(:get, file_url).to_return(status: 404)
|
stub_request(:get, file_url).to_return(status: 404)
|
||||||
end
|
end
|
||||||
@@ -24,7 +24,7 @@ shared_examples 'WpTarget::WpConfigBackup' do
|
|||||||
expected = []
|
expected = []
|
||||||
|
|
||||||
config_backup_files.sample(1).each do |backup_file|
|
config_backup_files.sample(1).each do |backup_file|
|
||||||
file_url = wp_target.uri.merge(URI.escape(backup_file)).to_s
|
file_url = wp_target.uri.merge(url_encode(backup_file)).to_s
|
||||||
expected << file_url
|
expected << file_url
|
||||||
|
|
||||||
stub_request_to_fixture(url: file_url, fixture: fixtures_dir + '/wp-config.php')
|
stub_request_to_fixture(url: file_url, fixture: fixtures_dir + '/wp-config.php')
|
||||||
@@ -40,7 +40,7 @@ shared_examples 'WpTarget::WpConfigBackup' do
|
|||||||
expected = []
|
expected = []
|
||||||
|
|
||||||
config_backup_files.sample(2).each do |backup_file|
|
config_backup_files.sample(2).each do |backup_file|
|
||||||
file_url = wp_target.uri.merge(URI.escape(backup_file)).to_s
|
file_url = wp_target.uri.merge(url_encode(backup_file)).to_s
|
||||||
expected << file_url
|
expected << file_url
|
||||||
|
|
||||||
stub_request_to_fixture(url: file_url, fixture: fixtures_dir + '/wp-config.php')
|
stub_request_to_fixture(url: file_url, fixture: fixtures_dir + '/wp-config.php')
|
||||||
|
|||||||
Reference in New Issue
Block a user