Compare commits
54 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
361c96d746 | ||
|
|
e7dbf9278d | ||
|
|
6564fddb27 | ||
|
|
d382874e86 | ||
|
|
91b30bee9f | ||
|
|
7804aad776 | ||
|
|
b7552ac8aa | ||
|
|
a76c94cccf | ||
|
|
c0ae5c7cad | ||
|
|
cc55b39b83 | ||
|
|
d8a6884ab6 | ||
|
|
5ce3581386 | ||
|
|
2208f2a8c0 | ||
|
|
a4a14c7e63 | ||
|
|
aa464b476c | ||
|
|
3c92712a6e | ||
|
|
fd0c47f5d7 | ||
|
|
c03a44d225 | ||
|
|
d31d45ba71 | ||
|
|
db528b27f4 | ||
|
|
e6d29f6f18 | ||
|
|
e4d6b988ef | ||
|
|
ec68291bf0 | ||
|
|
3a6a451db1 | ||
|
|
7ec095d708 | ||
|
|
57f6206aee | ||
|
|
390f10e83f | ||
|
|
8727935cb2 | ||
|
|
d0e868f556 | ||
|
|
01c357e146 | ||
|
|
a0fed4a9d0 | ||
|
|
c4aed0ec89 | ||
|
|
cc737090a2 | ||
|
|
1652c09e95 | ||
|
|
2538b88579 | ||
|
|
8c2eb63840 | ||
|
|
36df5ee6e4 | ||
|
|
9720b4edf1 | ||
|
|
13d35b7607 | ||
|
|
13c2c51cfd | ||
|
|
f43175b0c3 | ||
|
|
1508aba8b2 | ||
|
|
5414ab05e5 | ||
|
|
bd5d2db634 | ||
|
|
3259dd29d8 | ||
|
|
6e56013a95 | ||
|
|
252f762209 | ||
|
|
15c0448cf1 | ||
|
|
4c800bacaa | ||
|
|
86a73229c0 | ||
|
|
cc41b96e88 | ||
|
|
e16c5584d1 | ||
|
|
94bab3f550 | ||
|
|
9d04b23fb2 |
@@ -1 +1 @@
|
||||
2.2.2
|
||||
2.2.3
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
language: ruby
|
||||
sudo: false
|
||||
cache: bundler
|
||||
rvm:
|
||||
- 1.9.2
|
||||
- 1.9.3
|
||||
@@ -12,12 +14,13 @@ rvm:
|
||||
- 2.2.0
|
||||
- 2.2.1
|
||||
- 2.2.2
|
||||
- 2.2.3
|
||||
before_install:
|
||||
- "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
|
||||
script: bundle exec rspec
|
||||
notifications:
|
||||
email:
|
||||
- wpscanteam@gmail.com
|
||||
- team@wpscan.org
|
||||
matrix:
|
||||
allow_failures:
|
||||
- rvm: 1.9.2
|
||||
|
||||
39
CHANGELOG.md
39
CHANGELOG.md
@@ -1,6 +1,43 @@
|
||||
# Changelog
|
||||
## Master
|
||||
[Work in progress](https://github.com/wpscanteam/wpscan/compare/2.8...master)
|
||||
[Work in progress](https://github.com/wpscanteam/wpscan/compare/2.9...master)
|
||||
|
||||
## Version 2.9
|
||||
Released: 2015-10-15
|
||||
|
||||
New
|
||||
* GZIP Encoding in updater
|
||||
* Adds --throttle option to throttle requests
|
||||
* Uses new API and local database file structure
|
||||
* Adds last updated and latest version to plugins and themes
|
||||
|
||||
Removed
|
||||
* ArchAssault from README
|
||||
* APIv1 local databases
|
||||
|
||||
General core
|
||||
* Update to Ruby 2.2.3
|
||||
* Use yajl-ruby as JSON parser
|
||||
* New dependancy for Ubuntu 14.04 (libgmp-dev)
|
||||
* Use Travis container based infra and caching
|
||||
|
||||
Fixed issues
|
||||
* Fix #835 - Readme requests to wp root dir
|
||||
* Fix #836 - Critical icon output twice when the site is not running WP
|
||||
* Fix #839 - Terminal-table dependency is broken
|
||||
* Fix #841 - error: undefined method `cells' for #<Array:0x000000029cc2f8>
|
||||
* Fix #852 - GZIP Encoding in updater
|
||||
* Fix #853 - APIv2 integration
|
||||
* Fix #858 - Detection FP
|
||||
* Fix #873 - false positive "site has Must Use Plugins"
|
||||
|
||||
WPScan Database Statistics:
|
||||
* Total vulnerable versions: 132
|
||||
* Total vulnerable plugins: 1170
|
||||
* Total vulnerable themes: 368
|
||||
* Total version vulnerabilities: 1476
|
||||
* Total plugin vulnerabilities: 1913
|
||||
* Total theme vulnerabilities: 450
|
||||
|
||||
## Version 2.8
|
||||
Released: 2015-06-22
|
||||
|
||||
2
CREDITS
2
CREDITS
@@ -1,6 +1,6 @@
|
||||
**CREDITS**
|
||||
|
||||
This file is used to state the individual WPScan Team members (core developers) and give credit to WPScan's other contributors. If you feel your name should be in here email wpscanteam@gmail.com.
|
||||
This file is used to state the individual WPScan Team members (core developers) and give credit to WPScan's other contributors. If you feel your name should be in here email team@wpscan.org.
|
||||
|
||||
*WPScan Team*
|
||||
|
||||
|
||||
8
Gemfile
8
Gemfile
@@ -1,10 +1,12 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
gem 'typhoeus', '~>0.7.0'
|
||||
gem 'typhoeus', '~>0.8.0'
|
||||
gem 'nokogiri'
|
||||
gem 'addressable'
|
||||
gem 'json'
|
||||
gem 'terminal-table'
|
||||
gem 'yajl-ruby' # Better JSON parser regarding memory usage
|
||||
# TODO: update the below when terminal-table 1.5.3+ is released.
|
||||
# (and delete the Terminal module in lib/common/hacks.rb)
|
||||
gem 'terminal-table', '~>1.4.5'
|
||||
gem 'ruby-progressbar', '>=1.6.0'
|
||||
|
||||
group :test do
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -27,7 +27,7 @@ Example cases which do not require a commercial license, and thus fall under the
|
||||
- Using WPScan to test your own systems.
|
||||
- Any non-commercial use of WPScan.
|
||||
|
||||
If you need to purchase a commercial license or are unsure whether you need to purchase a commercial license contact us - wpscanteam@gmail.com.
|
||||
If you need to purchase a commercial license or are unsure whether you need to purchase a commercial license contact us - team@wpscan.org.
|
||||
|
||||
We may grant commercial licenses at no monetary cost at our own discretion if the commercial usage is deemed by the WPScan Team to significantly benefit WPScan.
|
||||
|
||||
|
||||
11
README.md
11
README.md
@@ -38,7 +38,7 @@ Example cases which do not require a commercial license, and thus fall under the
|
||||
- Using WPScan to test your own systems.
|
||||
- Any non-commercial use of WPScan.
|
||||
|
||||
If you need to purchase a commercial license or are unsure whether you need to purchase a commercial license contact us - wpscanteam@gmail.com.
|
||||
If you need to purchase a commercial license or are unsure whether you need to purchase a commercial license contact us - team@wpscan.org.
|
||||
|
||||
We may grant commercial licenses at no monetary cost at our own discretion if the commercial usage is deemed by the WPScan Team to significantly benefit WPScan.
|
||||
|
||||
@@ -88,12 +88,11 @@ WPScan comes pre-installed on the following Linux distributions:
|
||||
- [Kali Linux](http://www.kali.org/)
|
||||
- [Pentoo](http://www.pentoo.ch/)
|
||||
- [SamuraiWTF](http://samurai.inguardians.com/)
|
||||
- [ArchAssault](https://archassault.org/)
|
||||
- [BlackArch](http://blackarch.org/)
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- Ruby >= 1.9.2 - Recommended: 2.2.2
|
||||
- Ruby >= 1.9.2 - Recommended: 2.2.3
|
||||
- Curl >= 7.21 - Recommended: latest - FYI the 7.29 has a segfault
|
||||
- RubyGems - Recommended: latest
|
||||
- Git
|
||||
@@ -112,7 +111,7 @@ Before Ubuntu 14.04:
|
||||
|
||||
From Ubuntu 14.04:
|
||||
|
||||
sudo apt-get install libcurl4-openssl-dev libxml2 libxml2-dev libxslt1-dev ruby-dev build-essential
|
||||
sudo apt-get install libcurl4-openssl-dev libxml2 libxml2-dev libxslt1-dev ruby-dev build-essential libgmp-dev
|
||||
git clone https://github.com/wpscanteam/wpscan.git
|
||||
cd wpscan
|
||||
sudo gem install bundler && bundle install --without test
|
||||
@@ -156,8 +155,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
|
||||
source ~/.rvm/scripts/rvm
|
||||
echo "source ~/.rvm/scripts/rvm" >> ~/.bashrc
|
||||
rvm install 2.2.2
|
||||
rvm use 2.2.2 --default
|
||||
rvm install 2.2.3
|
||||
rvm use 2.2.3 --default
|
||||
echo "gem: --no-ri --no-rdoc" > ~/.gemrc
|
||||
gem install bundler
|
||||
git clone https://github.com/wpscanteam/wpscan.git
|
||||
|
||||
@@ -17,14 +17,15 @@ class Browser
|
||||
:proxy_auth,
|
||||
:request_timeout,
|
||||
:connect_timeout,
|
||||
:cookie
|
||||
:cookie,
|
||||
:throttle
|
||||
]
|
||||
|
||||
@@instance = nil
|
||||
|
||||
attr_reader :hydra, :cache_dir
|
||||
|
||||
attr_accessor :referer, :cookie
|
||||
attr_accessor :referer, :cookie, :vhost
|
||||
|
||||
# @param [ Hash ] options
|
||||
#
|
||||
@@ -71,11 +72,13 @@ class Browser
|
||||
#
|
||||
def browser_defaults
|
||||
@max_threads = 20
|
||||
# 10 minutes, at this time the cache is cleaned before each scan. If this value is set to 0, the cache will be disabled
|
||||
# 10 minutes, at this time the cache is cleaned before each scan.
|
||||
# If this value is set to 0, the cache will be disabled
|
||||
@cache_ttl = 600
|
||||
@request_timeout = 60 # 60s
|
||||
@connect_timeout = 10 # 10s
|
||||
@user_agent = "WPScan v#{WPSCAN_VERSION} (http://wpscan.org)"
|
||||
@throttle = 0
|
||||
end
|
||||
|
||||
#
|
||||
@@ -86,7 +89,6 @@ class Browser
|
||||
#
|
||||
# @return [ void ]
|
||||
def load_config(config_file = nil)
|
||||
|
||||
if File.symlink?(config_file)
|
||||
raise '[ERROR] Config file is a symlink.'
|
||||
else
|
||||
@@ -99,7 +101,6 @@ class Browser
|
||||
self.send(:"#{option_name}=", data[option_name])
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# @param [ String ] url
|
||||
@@ -121,11 +122,8 @@ class Browser
|
||||
)
|
||||
|
||||
if @proxy
|
||||
params = params.merge(proxy: @proxy)
|
||||
|
||||
if @proxy_auth
|
||||
params = params.merge(proxyauth: @proxy_auth)
|
||||
end
|
||||
params.merge!(proxy: @proxy)
|
||||
params.merge!(proxyauth: @proxy_auth) if @proxy_auth
|
||||
end
|
||||
|
||||
if @basic_auth
|
||||
@@ -136,15 +134,23 @@ class Browser
|
||||
)
|
||||
end
|
||||
|
||||
if vhost
|
||||
params = Browser.append_params_header_field(
|
||||
params,
|
||||
'Host',
|
||||
vhost
|
||||
)
|
||||
end
|
||||
|
||||
params.merge!(referer: referer)
|
||||
params.merge!(timeout: @request_timeout) if @request_timeout
|
||||
params.merge!(connecttimeout: @connect_timeout) if @connect_timeout
|
||||
|
||||
# Used to enable the cache system if :cache_ttl > 0
|
||||
params.merge!(cache_ttl: @cache_ttl) unless params.has_key?(:cache_ttl)
|
||||
params.merge!(cache_ttl: @cache_ttl) unless params.key?(:cache_ttl)
|
||||
|
||||
# Prevent infinite self redirection
|
||||
params.merge!(maxredirs: 3) unless params.has_key?(:maxredirs)
|
||||
params.merge!(maxredirs: 3) unless params.key?(:maxredirs)
|
||||
|
||||
# Disable SSL-Certificate checks
|
||||
params.merge!(ssl_verifypeer: false)
|
||||
@@ -172,5 +178,4 @@ class Browser
|
||||
end
|
||||
params
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -4,7 +4,7 @@ class Browser
|
||||
module Options
|
||||
|
||||
attr_accessor :cache_ttl, :request_timeout, :connect_timeout
|
||||
attr_reader :basic_auth, :proxy, :proxy_auth
|
||||
attr_reader :basic_auth, :proxy, :proxy_auth, :throttle
|
||||
attr_writer :user_agent
|
||||
|
||||
# Sets the Basic Authentification credentials
|
||||
@@ -93,6 +93,11 @@ class Browser
|
||||
@connect_timeout = timeout.to_i
|
||||
end
|
||||
|
||||
# @param [ String, Integer ] throttle
|
||||
def throttle=(throttle)
|
||||
@throttle = throttle.to_i.abs / 1000.0
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def invalid_proxy_auth_format
|
||||
@@ -110,6 +115,5 @@ class Browser
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -67,6 +67,7 @@ class WpItems < Array
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# @return [ Class ]
|
||||
def item_class
|
||||
Object.const_get(self.class.to_s.gsub(/.$/, ''))
|
||||
|
||||
@@ -32,11 +32,7 @@ class WpItems < Array
|
||||
progress_bar.progress += 1 if options[:show_progression]
|
||||
|
||||
if target_item.exists?(exist_options, response)
|
||||
unless results.include?(target_item)
|
||||
if !options[:only_vulnerable] || options[:only_vulnerable] && target_item.vulnerable?
|
||||
results << target_item
|
||||
end
|
||||
end
|
||||
results << target_item unless results.include?(target_item)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -53,7 +49,7 @@ class WpItems < Array
|
||||
# run the remaining requests
|
||||
hydra.run
|
||||
|
||||
results.select!(&:vulnerable?) if options[:only_vulnerable]
|
||||
results.select!(&:vulnerable?) if options[:type] == :vulnerable
|
||||
results.sort!
|
||||
|
||||
results # can't just return results.sort as it would return an array, and we want a WpItems
|
||||
@@ -155,15 +151,7 @@ class WpItems < Array
|
||||
item_class = self.item_class
|
||||
vulns_file = self.vulns_file
|
||||
|
||||
targets = vulnerable_targets_items(wp_target, item_class, vulns_file)
|
||||
|
||||
unless options[:only_vulnerable]
|
||||
unless options[:file]
|
||||
raise 'A file must be supplied'
|
||||
end
|
||||
|
||||
targets += targets_items_from_file(options[:file], wp_target, item_class, vulns_file)
|
||||
end
|
||||
targets = target_items_from_type(wp_target, item_class, vulns_file, options[:type])
|
||||
|
||||
targets.uniq! { |t| t.name }
|
||||
targets.sort_by { rand }
|
||||
@@ -174,14 +162,25 @@ class WpItems < Array
|
||||
# @param [ String ] vulns_file
|
||||
#
|
||||
# @return [ Array<WpItem> ]
|
||||
def vulnerable_targets_items(wp_target, item_class, vulns_file)
|
||||
def target_items_from_type(wp_target, item_class, vulns_file, type)
|
||||
targets = []
|
||||
json = json(vulns_file)
|
||||
|
||||
[*json].each do |item|
|
||||
case type
|
||||
when :vulnerable
|
||||
items = json.select { |item| !json[item]['vulnerabilities'].empty? }.keys
|
||||
when :popular
|
||||
items = json.select { |item| json[item]['popular'] == true }.keys
|
||||
when :all
|
||||
items = json.keys
|
||||
else
|
||||
raise "Unknown type #{type}"
|
||||
end
|
||||
|
||||
items.each do |item|
|
||||
targets << create_item(
|
||||
item_class,
|
||||
item.keys.inject,
|
||||
item,
|
||||
wp_target,
|
||||
vulns_file
|
||||
)
|
||||
@@ -233,6 +232,5 @@ class WpItems < Array
|
||||
def item_class
|
||||
Object.const_get(self.to_s.gsub(/.$/, ''))
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,17 +2,11 @@
|
||||
|
||||
class WpPlugins < WpItems
|
||||
module Detectable
|
||||
|
||||
# @return [ String ]
|
||||
def vulns_file
|
||||
PLUGINS_VULNS_FILE
|
||||
PLUGINS_FILE
|
||||
end
|
||||
|
||||
# @return [ String ]
|
||||
# def item_xpath
|
||||
# '//plugin'
|
||||
# end
|
||||
|
||||
# @param [ WpTarget ] wp_target
|
||||
# @param [ Hash ] options
|
||||
#
|
||||
|
||||
@@ -5,13 +5,7 @@ class WpThemes < WpItems
|
||||
|
||||
# @return [ String ]
|
||||
def vulns_file
|
||||
THEMES_VULNS_FILE
|
||||
end
|
||||
|
||||
# @return [ String ]
|
||||
# def item_xpath
|
||||
# '//theme'
|
||||
# end
|
||||
|
||||
THEMES_FILE
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -18,22 +18,17 @@ COMMON_PLUGINS_DIR = File.join(COMMON_LIB_DIR, 'plugins')
|
||||
WPSCAN_PLUGINS_DIR = File.join(WPSCAN_LIB_DIR, 'plugins') # Not used ATM
|
||||
|
||||
# Data files
|
||||
PLUGINS_FILE = File.join(DATA_DIR, 'plugins.txt')
|
||||
PLUGINS_FULL_FILE = File.join(DATA_DIR, 'plugins_full.txt')
|
||||
PLUGINS_VULNS_FILE = File.join(DATA_DIR, 'plugin_vulns.json')
|
||||
THEMES_FILE = File.join(DATA_DIR, 'themes.txt')
|
||||
THEMES_FULL_FILE = File.join(DATA_DIR, 'themes_full.txt')
|
||||
THEMES_VULNS_FILE = File.join(DATA_DIR, 'theme_vulns.json')
|
||||
WP_VULNS_FILE = File.join(DATA_DIR, 'wp_vulns.json')
|
||||
WORDPRESSES_FILE = File.join(DATA_DIR, 'wordpresses.json')
|
||||
PLUGINS_FILE = File.join(DATA_DIR, 'plugins.json')
|
||||
THEMES_FILE = File.join(DATA_DIR, 'themes.json')
|
||||
WP_VERSIONS_FILE = File.join(DATA_DIR, 'wp_versions.xml')
|
||||
LOCAL_FILES_FILE = File.join(DATA_DIR, 'local_vulnerable_files.xml')
|
||||
# VULNS_XSD = File.join(DATA_DIR, 'vuln.xsd')
|
||||
WP_VERSIONS_XSD = File.join(DATA_DIR, 'wp_versions.xsd')
|
||||
LOCAL_FILES_XSD = File.join(DATA_DIR, 'local_vulnerable_files.xsd')
|
||||
USER_AGENTS_FILE = File.join(DATA_DIR, 'user-agents.txt')
|
||||
LAST_UPDATE_FILE = File.join(DATA_DIR, '.last_update')
|
||||
|
||||
WPSCAN_VERSION = '2.8'
|
||||
WPSCAN_VERSION = '2.9'
|
||||
|
||||
$LOAD_PATH.unshift(LIB_DIR)
|
||||
$LOAD_PATH.unshift(WPSCAN_LIB_DIR)
|
||||
@@ -49,9 +44,13 @@ end
|
||||
|
||||
require 'environment'
|
||||
|
||||
def escape_glob(s)
|
||||
s.gsub(/[\\\{\}\[\]\*\?]/) { |x| '\\' + x }
|
||||
end
|
||||
|
||||
# TODO : add an exclude pattern ?
|
||||
def require_files_from_directory(absolute_dir_path, files_pattern = '*.rb')
|
||||
files = Dir[File.join(absolute_dir_path, files_pattern)]
|
||||
files = Dir[File.join(escape_glob(absolute_dir_path), files_pattern)]
|
||||
|
||||
# Files in the root dir are loaded first, then those in the subdirectories
|
||||
files.sort_by { |file| [file.count('/'), file] }.each do |f|
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
class DbUpdater
|
||||
FILES = %w(
|
||||
local_vulnerable_files.xml local_vulnerable_files.xsd
|
||||
plugins_full.txt plugins.txt themes_full.txt themes.txt
|
||||
timthumbs.txt user-agents.txt wp_versions.xml wp_versions.xsd
|
||||
plugin_vulns.json theme_vulns.json wp_vulns.json LICENSE
|
||||
wordpresses.json plugins.json themes.json LICENSE
|
||||
)
|
||||
|
||||
attr_reader :repo_directory
|
||||
@@ -22,7 +21,8 @@ class DbUpdater
|
||||
def request_params
|
||||
{
|
||||
ssl_verifyhost: 2,
|
||||
ssl_verifypeer: true
|
||||
ssl_verifypeer: true,
|
||||
accept_encoding: 'gzip, deflate'
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
@@ -42,11 +42,12 @@ class Vulnerability
|
||||
# @return [ Vulnerability ]
|
||||
def self.load_from_json_item(json_item)
|
||||
references = {}
|
||||
references['id'] = [json_item['id']]
|
||||
|
||||
%w(id url cve secunia osvdb metasploit exploitdb).each do |key|
|
||||
if json_item[key]
|
||||
json_item[key] = [json_item[key]] if json_item[key].class != Array
|
||||
references[key] = json_item[key]
|
||||
%w(url cve secunia osvdb metasploit exploitdb).each do |key|
|
||||
if json_item['references'][key]
|
||||
json_item['references'][key] = [json_item['references'][key]] if json_item['references'][key].class != Array
|
||||
references[key] = json_item['references'][key]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -54,7 +55,7 @@ class Vulnerability
|
||||
json_item['title'],
|
||||
json_item['type'],
|
||||
references,
|
||||
json_item['fixed_in'],
|
||||
json_item['fixed_in']
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -2,22 +2,22 @@
|
||||
|
||||
class Vulnerability
|
||||
module Output
|
||||
|
||||
# output the vulnerability
|
||||
def output(verbose = false)
|
||||
puts
|
||||
puts critical("Title: #{title}")
|
||||
|
||||
references.each do |key, urls|
|
||||
methodname = "url_#{key}"
|
||||
|
||||
urls.each do |u|
|
||||
next unless respond_to?(methodname)
|
||||
url = send(methodname, u)
|
||||
puts " Reference: #{url}" if url
|
||||
end
|
||||
end
|
||||
unless fixed_in.nil?
|
||||
puts notice("Fixed in: #{fixed_in}")
|
||||
end
|
||||
|
||||
puts notice("Fixed in: #{fixed_in}") if fixed_in
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -22,7 +22,7 @@ class WpItem
|
||||
# @return [ Array ]
|
||||
# Make it private ?
|
||||
def allowed_options
|
||||
[:name, :wp_content_dir, :wp_plugins_dir, :path, :version, :vulns_file]
|
||||
[:name, :wp_content_dir, :wp_plugins_dir, :path, :version, :db_file]
|
||||
end
|
||||
|
||||
# @param [ URI ] target_base_uri
|
||||
@@ -30,7 +30,6 @@ class WpItem
|
||||
#
|
||||
# @return [ WpItem ]
|
||||
def initialize(target_base_uri, options = {})
|
||||
|
||||
options[:wp_content_dir] ||= 'wp-content'
|
||||
options[:wp_plugins_dir] ||= options[:wp_content_dir] + '/plugins'
|
||||
|
||||
@@ -38,6 +37,27 @@ class WpItem
|
||||
forge_uri(target_base_uri)
|
||||
end
|
||||
|
||||
def identifier
|
||||
@identifier ||= name
|
||||
end
|
||||
|
||||
# @return [ Hash ]
|
||||
def db_data
|
||||
@db_data ||= json(db_file)[identifier] || {}
|
||||
end
|
||||
|
||||
def latest_version
|
||||
db_data['latest_version']
|
||||
end
|
||||
|
||||
def last_updated
|
||||
db_data['last_ipdated']
|
||||
end
|
||||
|
||||
def popular?
|
||||
db_data['popular']
|
||||
end
|
||||
|
||||
# @param [ Hash ] options
|
||||
#
|
||||
# @return [ void ]
|
||||
|
||||
@@ -5,12 +5,17 @@ class WpItem
|
||||
|
||||
# @return [ Void ]
|
||||
def output(verbose = false)
|
||||
outdated = VersionCompare.lesser?(version, latest_version) if latest_version
|
||||
|
||||
puts
|
||||
puts info("Name: #{self}") #this will also output the version number if detected
|
||||
puts " | Latest version: #{latest_version} #{'(up to date)' if version}" if latest_version && !outdated
|
||||
puts " | Last updated: #{last_updated}" if last_updated
|
||||
puts " | Location: #{url}"
|
||||
#puts " | WordPress: #{wordpress_url}" if wordpress_org_item?
|
||||
puts " | Readme: #{readme_url}" if has_readme?
|
||||
puts " | Changelog: #{changelog_url}" if has_changelog?
|
||||
puts warning("The version is out of date, the latest version is #{latest_version}") if latest_version && outdated
|
||||
|
||||
puts warning("Directory listing is enabled: #{url}") if has_directory_listing?
|
||||
puts warning("An error_log file has been found: #{error_log_url}") if has_error_log?
|
||||
|
||||
|
||||
@@ -2,30 +2,23 @@
|
||||
|
||||
class WpItem
|
||||
module Vulnerable
|
||||
attr_accessor :vulns_file, :identifier
|
||||
attr_accessor :db_file, :identifier
|
||||
|
||||
# Get the vulnerabilities associated to the WpItem
|
||||
# Filters out already fixed vulnerabilities
|
||||
#
|
||||
# @return [ Vulnerabilities ]
|
||||
def vulnerabilities
|
||||
json = json(vulns_file)
|
||||
vulnerabilities = Vulnerabilities.new
|
||||
return @vulnerabilities if @vulnerabilities
|
||||
|
||||
json.each do |item|
|
||||
asset = item[identifier]
|
||||
@vulnerabilities = Vulnerabilities.new
|
||||
|
||||
next unless asset
|
||||
|
||||
asset['vulnerabilities'].each do |vulnerability|
|
||||
[*db_data['vulnerabilities']].each do |vulnerability|
|
||||
vulnerability = Vulnerability.load_from_json_item(vulnerability)
|
||||
vulnerabilities << vulnerability if vulnerable_to?(vulnerability)
|
||||
@vulnerabilities << vulnerability if vulnerable_to?(vulnerability)
|
||||
end
|
||||
|
||||
break # No need to iterate any further
|
||||
end
|
||||
|
||||
vulnerabilities
|
||||
@vulnerabilities
|
||||
end
|
||||
|
||||
def vulnerable?
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
require 'wp_plugin/vulnerable'
|
||||
|
||||
class WpPlugin < WpItem
|
||||
include WpPlugin::Vulnerable
|
||||
|
||||
# Sets the @uri
|
||||
#
|
||||
# @param [ URI ] target_base_uri The URI of the wordpress blog
|
||||
@@ -14,4 +10,7 @@ class WpPlugin < WpItem
|
||||
@uri = target_base_uri.merge(URI.encode(wp_plugins_dir + '/' + name + '/'))
|
||||
end
|
||||
|
||||
def db_file
|
||||
@db_file ||= PLUGINS_FILE
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
class WpPlugin < WpItem
|
||||
module Vulnerable
|
||||
|
||||
# @return [ String ] The path to the file containing vulnerabilities
|
||||
def vulns_file
|
||||
unless @vulns_file
|
||||
@vulns_file = PLUGINS_VULNS_FILE
|
||||
end
|
||||
@vulns_file
|
||||
end
|
||||
|
||||
# @return [ String ]
|
||||
def identifier
|
||||
@name
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
require 'wp_theme/findable'
|
||||
require 'wp_theme/versionable'
|
||||
require 'wp_theme/vulnerable'
|
||||
require 'wp_theme/info'
|
||||
require 'wp_theme/output'
|
||||
require 'wp_theme/childtheme'
|
||||
@@ -10,7 +9,6 @@ require 'wp_theme/childtheme'
|
||||
class WpTheme < WpItem
|
||||
extend WpTheme::Findable
|
||||
include WpTheme::Versionable
|
||||
include WpTheme::Vulnerable
|
||||
include WpTheme::Info
|
||||
include WpTheme::Output
|
||||
include WpTheme::Childtheme
|
||||
@@ -33,4 +31,7 @@ class WpTheme < WpItem
|
||||
@uri.merge('style.css').to_s
|
||||
end
|
||||
|
||||
def db_file
|
||||
@db_file ||= THEMES_FILE
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
class WpTheme < WpItem
|
||||
module Vulnerable
|
||||
|
||||
# @return [ String ] The path to the file containing vulnerabilities
|
||||
def vulns_file
|
||||
unless @vulns_file
|
||||
@vulns_file = THEMES_VULNS_FILE
|
||||
end
|
||||
@vulns_file
|
||||
end
|
||||
|
||||
# @return [ String ]
|
||||
def identifier
|
||||
@name
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -39,7 +39,7 @@ class WpUser < WpItem
|
||||
#
|
||||
# @return [ String ] The login
|
||||
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')
|
||||
end
|
||||
|
||||
@@ -1,21 +1,27 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
require 'wp_version/findable'
|
||||
require 'wp_version/vulnerable'
|
||||
require 'wp_version/output'
|
||||
|
||||
class WpVersion < WpItem
|
||||
|
||||
extend WpVersion::Findable
|
||||
include WpVersion::Vulnerable
|
||||
include WpVersion::Output
|
||||
|
||||
# The version number
|
||||
attr_accessor :number
|
||||
alias_method :version, :number # Needed to have the right behaviour in Vulnerable#vulnerable_to?
|
||||
|
||||
# @return [ Array ]
|
||||
def allowed_options; super << :number << :found_from end
|
||||
|
||||
def identifier
|
||||
@identifier ||= number
|
||||
end
|
||||
|
||||
def db_file
|
||||
@db_file ||= WORDPRESSES_FILE
|
||||
end
|
||||
|
||||
# @param [ WpVersion ] other
|
||||
#
|
||||
# @return [ Boolean ]
|
||||
@@ -29,5 +35,4 @@ class WpVersion < WpItem
|
||||
a << node.text.to_s
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -31,7 +31,7 @@ class WpVersion < WpItem
|
||||
#
|
||||
# @return [ String ]
|
||||
def version_pattern
|
||||
'([^\r\n"\']+\.[^\r\n"\']+)'
|
||||
'([^\r\n"\',]+\.[^\r\n"\',]+)'
|
||||
end
|
||||
|
||||
protected
|
||||
@@ -68,7 +68,7 @@ class WpVersion < WpItem
|
||||
def find_from_meta_generator(target_uri)
|
||||
scan_url(
|
||||
target_uri,
|
||||
%r{name="generator" content="wordpress #{version_pattern}"}i
|
||||
%r{name="generator" content="wordpress #{version_pattern}.*"}i
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
class WpVersion < WpItem
|
||||
module Vulnerable
|
||||
|
||||
# @return [ String ] The path to the file containing vulnerabilities
|
||||
def vulns_file
|
||||
unless @vulns_file
|
||||
@vulns_file = WP_VULNS_FILE
|
||||
end
|
||||
@vulns_file
|
||||
end
|
||||
|
||||
# @return [ String ]
|
||||
def identifier
|
||||
@number
|
||||
end
|
||||
|
||||
# @return [ String ]
|
||||
# def vulns_xpath
|
||||
# "//wordpress[@version='#{@number}']/vulnerability"
|
||||
# end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -11,8 +11,8 @@ class VersionCompare
|
||||
# @return [ Boolean ]
|
||||
def self.lesser_or_equal?(version1, version2)
|
||||
# Prepend a '0' if the version starts with a '.'
|
||||
version1 = "0#{version1}" if version1 && version1[0,1] == '.'
|
||||
version2 = "0#{version2}" if version2 && version2[0,1] == '.'
|
||||
version1 = prepend_zero(version1)
|
||||
version2 = prepend_zero(version2)
|
||||
|
||||
return true if (version1 == version2)
|
||||
# Both versions must be set
|
||||
@@ -27,4 +27,36 @@ class VersionCompare
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
# Compares two version strings. Returns true if version1 < version2
|
||||
# and false otherwise
|
||||
#
|
||||
# @param [ String ] version1
|
||||
# @param [ String ] version2
|
||||
#
|
||||
# @return [ Boolean ]
|
||||
def self.lesser?(version1, version2)
|
||||
# Prepend a '0' if the version starts with a '.'
|
||||
version1 = prepend_zero(version1)
|
||||
version2 = prepend_zero(version2)
|
||||
|
||||
return false if (version1 == version2)
|
||||
# Both versions must be set
|
||||
return false unless (version1 and version2)
|
||||
return false if (version1.empty? or version2.empty?)
|
||||
begin
|
||||
return true if (Gem::Version.new(version1) < Gem::Version.new(version2))
|
||||
rescue ArgumentError => e
|
||||
# Example: ArgumentError: Malformed version number string a
|
||||
return false if e.message =~ /Malformed version number string/
|
||||
raise
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
# @return [ String ]
|
||||
def self.prepend_zero(version)
|
||||
return nil if version.nil?
|
||||
version[0,1] == '.' ? "0#{version}" : version
|
||||
end
|
||||
end
|
||||
|
||||
@@ -31,7 +31,7 @@ begin
|
||||
require 'pathname'
|
||||
# Third party libs
|
||||
require 'typhoeus'
|
||||
require 'json'
|
||||
require 'yajl/json_gem'
|
||||
require 'nokogiri'
|
||||
require 'terminal-table'
|
||||
require 'ruby-progressbar'
|
||||
|
||||
@@ -28,6 +28,7 @@ class WebSite
|
||||
if entries
|
||||
entries.flatten!
|
||||
entries.compact.sort!
|
||||
entries.uniq!
|
||||
wordpress_path = @uri.path
|
||||
RobotsTxt.known_dirs.each do |d|
|
||||
entries.delete(d)
|
||||
|
||||
@@ -28,8 +28,13 @@ class WpTarget < WebSite
|
||||
@wp_content_dir = options[:wp_content_dir]
|
||||
@wp_plugins_dir = options[:wp_plugins_dir]
|
||||
@multisite = nil
|
||||
@vhost = options[:vhost]
|
||||
|
||||
Browser.instance.referer = url
|
||||
if @vhost
|
||||
Browser.instance.vhost = @vhost
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# check if the target website is
|
||||
@@ -44,11 +49,7 @@ class WpTarget < WebSite
|
||||
fail "The target is responding with a 403, this might be due to a WAF or a plugin.\n" \
|
||||
'You should try to supply a valid user-agent via the --user-agent option or use the --random-agent option' if response.code == 403
|
||||
|
||||
if wp_content_dir
|
||||
dir = wp_content_dir
|
||||
else
|
||||
dir = 'wp-content'
|
||||
end
|
||||
dir = wp_content_dir ? wp_content_dir : 'wp-content'
|
||||
|
||||
if response.body =~ /["'][^"']*\/#{Regexp.escape(dir)}\/[^"']*["']/i
|
||||
wordpress = true
|
||||
|
||||
@@ -2,24 +2,21 @@
|
||||
|
||||
class WpTarget < WebSite
|
||||
module WpFullPathDisclosure
|
||||
|
||||
# Check for Full Path Disclosure (FPD)
|
||||
#
|
||||
# @return [ Boolean ]
|
||||
def has_full_path_disclosure?
|
||||
response = Browser.get(full_path_disclosure_url)
|
||||
response.body[%r{Fatal error}i] ? true : false
|
||||
Browser.get(full_path_disclosure_url).body[%r/Fatal error/i] ? true : false
|
||||
end
|
||||
|
||||
def full_path_disclosure_data
|
||||
return nil unless has_full_path_disclosure?
|
||||
Browser.get(full_path_disclosure_url).body[%r{<b>([^<]+\.php)</b>}, 1]
|
||||
Browser.get(full_path_disclosure_url).body[/Fatal error:.+? in (.+?) on/i, 1]
|
||||
end
|
||||
|
||||
# @return [ String ]
|
||||
def full_path_disclosure_url
|
||||
@uri.merge('wp-includes/rss-functions.php').to_s
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,14 +2,13 @@
|
||||
|
||||
class WpTarget < WebSite
|
||||
module WpMustUsePlugins
|
||||
|
||||
# Checks to see if the must use plugin folder exists
|
||||
#
|
||||
# @return [ Boolean ]
|
||||
def has_must_use_plugins?
|
||||
response = Browser.get(must_use_url)
|
||||
|
||||
if response && WpTarget.valid_response_codes.include?(response.code)
|
||||
if response && [200, 401, 403].include?(response.code)
|
||||
hash = WebSite.page_hash(response)
|
||||
return true if hash != error_404_hash && hash != homepage_hash
|
||||
end
|
||||
@@ -21,6 +20,5 @@ class WpTarget < WebSite
|
||||
def must_use_url
|
||||
@uri.merge("#{wp_content_dir}/mu-plugins/").to_s
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -105,6 +105,7 @@ def help
|
||||
puts '--request-timeout <request-timeout> Request Timeout.'
|
||||
puts '--connect-timeout <connect-timeout> Connect Timeout.'
|
||||
puts '--max-threads <max-threads> Maximum Threads.'
|
||||
puts '--throttle <milliseconds> Milliseconds to wait before doing another web request. If used, the --threads should be set to 1.'
|
||||
puts '--help | -h This help screen.'
|
||||
puts '--verbose | -v Verbose output.'
|
||||
puts '--version Output the current version and exit.'
|
||||
@@ -118,8 +119,14 @@ down = 0
|
||||
@total_requests_done = 0
|
||||
|
||||
Typhoeus.on_complete do |response|
|
||||
next if response.cached?
|
||||
|
||||
down += 1 if response.code == 0
|
||||
@total_requests_done += 1
|
||||
|
||||
fail 'The target seems to be down' if down >= 30
|
||||
|
||||
next unless Browser.instance.throttle > 0
|
||||
|
||||
sleep(Browser.instance.throttle)
|
||||
end
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
class WpscanOptions
|
||||
|
||||
ACCESSOR_OPTIONS = [
|
||||
:batch,
|
||||
:enumerate_plugins,
|
||||
@@ -19,6 +18,7 @@ class WpscanOptions
|
||||
:proxy_auth,
|
||||
:threads,
|
||||
:url,
|
||||
:vhost,
|
||||
:wordlist,
|
||||
:force,
|
||||
:update,
|
||||
@@ -42,7 +42,8 @@ class WpscanOptions
|
||||
:request_timeout,
|
||||
:connect_timeout,
|
||||
:max_threads,
|
||||
:no_banner
|
||||
:no_banner,
|
||||
:throttle
|
||||
]
|
||||
|
||||
attr_accessor *ACCESSOR_OPTIONS
|
||||
@@ -61,6 +62,10 @@ class WpscanOptions
|
||||
@url = URI.parse(add_http_protocol(url)).to_s
|
||||
end
|
||||
|
||||
def vhost=(vhost)
|
||||
@vhost = vhost
|
||||
end
|
||||
|
||||
def threads=(threads)
|
||||
@threads = threads.is_a?(Integer) ? threads : threads.to_i
|
||||
end
|
||||
@@ -246,6 +251,7 @@ class WpscanOptions
|
||||
def self.get_opt_long
|
||||
GetoptLong.new(
|
||||
['--url', '-u', GetoptLong::REQUIRED_ARGUMENT],
|
||||
['--vhost',GetoptLong::OPTIONAL_ARGUMENT],
|
||||
['--enumerate', '-e', GetoptLong::OPTIONAL_ARGUMENT],
|
||||
['--username', '-U', GetoptLong::REQUIRED_ARGUMENT],
|
||||
['--usernames', GetoptLong::REQUIRED_ARGUMENT],
|
||||
@@ -275,7 +281,8 @@ class WpscanOptions
|
||||
['--no-color', GetoptLong::NO_ARGUMENT],
|
||||
['--cookie', GetoptLong::REQUIRED_ARGUMENT],
|
||||
['--log', GetoptLong::NO_ARGUMENT],
|
||||
['--no-banner', GetoptLong::NO_ARGUMENT]
|
||||
['--no-banner', GetoptLong::NO_ARGUMENT],
|
||||
['--throttle', GetoptLong::REQUIRED_ARGUMENT]
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ describe WpPlugins do
|
||||
let(:expected) do
|
||||
{
|
||||
request_params: { cache_ttl: 0, followlocation: true },
|
||||
vulns_file: PLUGINS_VULNS_FILE,
|
||||
vulns_file: PLUGINS_FILE,
|
||||
targets_items_from_file: [ WpPlugin.new(uri, name: 'plugin1'),
|
||||
WpPlugin.new(uri, name:'plugin-2'),
|
||||
WpPlugin.new(uri, name: 'mr-smith')],
|
||||
|
||||
@@ -13,7 +13,7 @@ describe WpThemes do
|
||||
let(:expected) do
|
||||
{
|
||||
request_params: { cache_ttl: 0, followlocation: true },
|
||||
vulns_file: THEMES_VULNS_FILE,
|
||||
vulns_file: THEMES_FILE,
|
||||
targets_items_from_file: [ WpTheme.new(uri, name: '3colours'),
|
||||
WpTheme.new(uri, name:'42k'),
|
||||
WpTheme.new(uri, name: 'a-ri')],
|
||||
|
||||
@@ -11,11 +11,11 @@ describe WpItem do
|
||||
end
|
||||
it_behaves_like 'WpItem::Versionable'
|
||||
it_behaves_like 'WpItem::Vulnerable' do
|
||||
let(:vulns_file) { MODELS_FIXTURES + '/wp_item/vulnerable/items_vulns.json' }
|
||||
let(:db_file) { MODELS_FIXTURES + '/wp_item/vulnerable/items_vulns.json' }
|
||||
let(:identifier) { 'neo' }
|
||||
let(:expected_refs) { {
|
||||
'id' => [2993],
|
||||
'url' => ['Ref 1,Ref 2'],
|
||||
'url' => ['Ref 1', 'Ref 2'],
|
||||
'cve' => ['2011-001'],
|
||||
'secunia' => ['secunia'],
|
||||
'osvdb' => ['osvdb'],
|
||||
|
||||
@@ -6,10 +6,10 @@ 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.json' }
|
||||
let(:db_file) { MODELS_FIXTURES + '/wp_plugin/vulnerable/plugins.json' }
|
||||
let(:expected_refs) { {
|
||||
'id' => [2993],
|
||||
'url' => ['Ref 1,Ref 2'],
|
||||
'url' => ['Ref 1', 'Ref 2'],
|
||||
'cve' => ['2011-001'],
|
||||
'secunia' => ['secunia'],
|
||||
'osvdb' => ['osvdb'],
|
||||
|
||||
@@ -7,10 +7,10 @@ describe WpTheme do
|
||||
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.json' }
|
||||
let(:db_file) { MODELS_FIXTURES + '/wp_theme/vulnerable/themes_vulns.json' }
|
||||
let(:expected_refs) { {
|
||||
'id' => [2993],
|
||||
'url' => ['Ref 1,Ref 2'],
|
||||
'url' => ['Ref 1', 'Ref 2'],
|
||||
'cve' => ['2011-001'],
|
||||
'secunia' => ['secunia'],
|
||||
'osvdb' => ['osvdb'],
|
||||
|
||||
@@ -65,6 +65,11 @@ describe 'WpVersion::Findable' do
|
||||
@fixture = '/3.5_minified.html'
|
||||
@expected = '3.5'
|
||||
end
|
||||
|
||||
it 'returns 3.5.1' do
|
||||
@fixture = '/3.5.1_mobile.html'
|
||||
@expected = '3.5.1'
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -4,20 +4,6 @@ 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.json' }
|
||||
let(:expected_refs) { {
|
||||
'id' => [2993],
|
||||
'url' => ['Ref 1,Ref 2'],
|
||||
'cve' => ['2011-001'],
|
||||
'secunia' => ['secunia'],
|
||||
'osvdb' => ['osvdb'],
|
||||
'metasploit' => ['exploit/ex1'],
|
||||
'exploitdb' => ['exploitdb']
|
||||
} }
|
||||
let(:expected_vulns) { Vulnerabilities.new << Vulnerability.new('Here I Am', 'SQLI', expected_refs) }
|
||||
end
|
||||
|
||||
subject(:wp_version) { WpVersion.new(uri, options) }
|
||||
let(:uri) { URI.parse('http://example.com/') }
|
||||
|
||||
@@ -121,4 +121,122 @@ describe 'VersionCompare' do
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe '::lesser?' do
|
||||
context 'version checked is newer' do
|
||||
after { expect(VersionCompare::lesser?(@version1, @version2)).to be_truthy }
|
||||
|
||||
it 'returns true' do
|
||||
@version1 = '1.0'
|
||||
@version2 = '2.0'
|
||||
end
|
||||
|
||||
it 'returns true' do
|
||||
@version1 = '1.0'
|
||||
@version2 = '1.1'
|
||||
end
|
||||
|
||||
it 'returns true' do
|
||||
@version1 = '1.0a'
|
||||
@version2 = '1.0b'
|
||||
end
|
||||
|
||||
it 'returns true' do
|
||||
@version1 = '1.0'
|
||||
@version2 = '5000000'
|
||||
end
|
||||
|
||||
it 'returns true' do
|
||||
@version1 = '0'
|
||||
@version2 = '1'
|
||||
end
|
||||
|
||||
it 'returns true' do
|
||||
@version1 = '0.4.2b'
|
||||
@version2 = '2.3.3'
|
||||
end
|
||||
|
||||
it 'returns true' do
|
||||
@version1 = '.47'
|
||||
@version2 = '.50.3'
|
||||
end
|
||||
end
|
||||
|
||||
context 'version checked is older' do
|
||||
after { expect(VersionCompare::lesser?(@version1, @version2)).to be_falsey }
|
||||
|
||||
it 'returns false' do
|
||||
@version1 = '1'
|
||||
@version2 = '0'
|
||||
end
|
||||
|
||||
it 'returns false' do
|
||||
@version1 = '1.0'
|
||||
@version2 = '0.5'
|
||||
end
|
||||
|
||||
it 'returns false' do
|
||||
@version1 = '500000'
|
||||
@version2 = '1'
|
||||
end
|
||||
|
||||
it 'returns false' do
|
||||
@version1 = '1.6.3.7.3.4'
|
||||
@version2 = '1.2.4.567.679.8.e'
|
||||
end
|
||||
|
||||
it 'returns false' do
|
||||
@version1 = '.47'
|
||||
@version2 = '.46.3'
|
||||
end
|
||||
end
|
||||
|
||||
context 'version checked is the same' do
|
||||
after { expect(VersionCompare::lesser?(@version1, @version2)).to be_falsey }
|
||||
|
||||
it 'returns true' do
|
||||
@version1 = '1'
|
||||
@version2 = '1'
|
||||
end
|
||||
|
||||
it 'returns true' do
|
||||
@version1 = 'a'
|
||||
@version2 = 'a'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'version number causes Gem::Version new Exception' do
|
||||
after { expect(VersionCompare::lesser?(@version1, @version2)).to be_falsey }
|
||||
|
||||
it 'returns false' do
|
||||
@version1 = 'a'
|
||||
@version2 = 'b'
|
||||
end
|
||||
end
|
||||
|
||||
context 'one version number is not set' do
|
||||
after { expect(VersionCompare::lesser?(@version1, @version2)).to be_falsey }
|
||||
|
||||
it 'returns false (version2 nil)' do
|
||||
@version1 = '1'
|
||||
@version2 = nil
|
||||
end
|
||||
|
||||
it 'returns false (version1 nil)' do
|
||||
@version1 = nil
|
||||
@version2 = '1'
|
||||
end
|
||||
|
||||
it 'returns false (version2 empty)' do
|
||||
@version1 = '1'
|
||||
@version2 = ''
|
||||
end
|
||||
|
||||
it 'returns false (version1 empty)' do
|
||||
@version1 = ''
|
||||
@version2 = '1'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
[
|
||||
{
|
||||
"mr-smith": {
|
||||
"vulnerabilities":[
|
||||
{
|
||||
"id":2989,
|
||||
"title":"Administrator-exploitable blind SQLi in WordPress 1.0 - 3.8.1",
|
||||
"references":"https://security.dxw.com/advisories/sqli-in-wordpress-3-6-1/,http://www.example.com",
|
||||
"references": {
|
||||
"url": "https://security.dxw.com/advisories/sqli-in-wordpress-3-6-1/,http://www.example.com"
|
||||
},
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
"updated_at":"2014-07-28T12:43:41.000Z"
|
||||
},
|
||||
{
|
||||
"id":2990,
|
||||
"title":"Potential Authentication Cookie Forgery",
|
||||
"references":"https://labs.mwrinfosecurity.com/blog/2014/04/11/wordpress-auth-cookie-forgery/,https://github.com/WordPress/WordPress/commit/78a915e0e5927cf413aa6c2cef2fca3dc587f8be",
|
||||
"references": {
|
||||
"url": "https://labs.mwrinfosecurity.com/blog/2014/04/11/wordpress-auth-cookie-forgery/,https://github.com/WordPress/WordPress/commit/78a915e0e5927cf413aa6c2cef2fca3dc587f8be",
|
||||
"osvdb":"105620",
|
||||
"cve":"2014-0166",
|
||||
"cve":"2014-0166"
|
||||
},
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
"updated_at":"2014-07-28T12:10:07.000Z",
|
||||
"fixed_in":"3.8.2"
|
||||
@@ -22,9 +25,11 @@
|
||||
{
|
||||
"id":2991,
|
||||
"title":"Privilege escalation: contributors publishing posts",
|
||||
"references":"https://github.com/wpscanteam/wpscan/wiki/CVE-2014-0165",
|
||||
"references": {
|
||||
"url": "https://github.com/wpscanteam/wpscan/wiki/CVE-2014-0165",
|
||||
"osvdb":"105630",
|
||||
"cve":"2014-0165",
|
||||
"cve":"2014-0165"
|
||||
},
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
"updated_at":"2014-07-28T12:10:07.000Z",
|
||||
"fixed_in":"3.8.2"
|
||||
@@ -32,27 +37,28 @@
|
||||
{
|
||||
"id":2992,
|
||||
"title":"Plupload Unspecified XSS",
|
||||
"references": {
|
||||
"osvdb":"105622",
|
||||
"secunia":"57769",
|
||||
"secunia":"57769"
|
||||
},
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
"updated_at":"2014-07-28T12:10:07.000Z",
|
||||
"fixed_in":"3.8.2"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"neo": {
|
||||
"vulnerabilities":[
|
||||
{
|
||||
"id":2993,
|
||||
"title":"wp-admin/options-writing.php Cleartext Admin Credentials Disclosure",
|
||||
"references":"http://seclists.org/fulldisclosure/2013/Dec/135",
|
||||
"osvdb":"101101",
|
||||
"references": {
|
||||
"url": "http://seclists.org/fulldisclosure/2013/Dec/135",
|
||||
"osvdb":"101101"
|
||||
},
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
"updated_at":"2014-07-28T12:10:07.000Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -1,18 +1,21 @@
|
||||
[
|
||||
{
|
||||
"mr-smith": {
|
||||
"vulnerabilities":[
|
||||
{
|
||||
"id":2989,
|
||||
"title":"Administrator-exploitable blind SQLi in WordPress 1.0 - 3.8.1",
|
||||
"references":"https://security.dxw.com/advisories/sqli-in-wordpress-3-6-1/,http://www.example.com",
|
||||
"references": {
|
||||
"url": "https://security.dxw.com/advisories/sqli-in-wordpress-3-6-1/,http://www.example.com"
|
||||
},
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
"updated_at":"2014-07-28T12:43:41.000Z"
|
||||
},
|
||||
{
|
||||
"id":2990,
|
||||
"title":"Potential Authentication Cookie Forgery",
|
||||
"references":"https://labs.mwrinfosecurity.com/blog/2014/04/11/wordpress-auth-cookie-forgery/,https://github.com/WordPress/WordPress/commit/78a915e0e5927cf413aa6c2cef2fca3dc587f8be",
|
||||
"references": {
|
||||
"url": "https://labs.mwrinfosecurity.com/blog/2014/04/11/wordpress-auth-cookie-forgery/,https://github.com/WordPress/WordPress/commit/78a915e0e5927cf413aa6c2cef2fca3dc587f8be"
|
||||
},
|
||||
"osvdb":"105620",
|
||||
"cve":"2014-0166",
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
@@ -22,9 +25,11 @@
|
||||
{
|
||||
"id":2991,
|
||||
"title":"Privilege escalation: contributors publishing posts",
|
||||
"references":"https://github.com/wpscanteam/wpscan/wiki/CVE-2014-0165",
|
||||
"references": {
|
||||
"url": "https://github.com/wpscanteam/wpscan/wiki/CVE-2014-0165",
|
||||
"osvdb":"105630",
|
||||
"cve":"2014-0165",
|
||||
"cve":"2014-0165"
|
||||
},
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
"updated_at":"2014-07-28T12:10:07.000Z",
|
||||
"fixed_in":"3.8.2"
|
||||
@@ -32,27 +37,28 @@
|
||||
{
|
||||
"id":2992,
|
||||
"title":"Plupload Unspecified XSS",
|
||||
"references": {
|
||||
"osvdb":"105622",
|
||||
"secunia":"57769",
|
||||
"secunia":"57769"
|
||||
},
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
"updated_at":"2014-07-28T12:10:07.000Z",
|
||||
"fixed_in":"3.8.2"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"neo": {
|
||||
"vulnerabilities":[
|
||||
{
|
||||
"id":2993,
|
||||
"title":"wp-admin/options-writing.php Cleartext Admin Credentials Disclosure",
|
||||
"references":"http://seclists.org/fulldisclosure/2013/Dec/135",
|
||||
"osvdb":"101101",
|
||||
"references": {
|
||||
"url": "http://seclists.org/fulldisclosure/2013/Dec/135",
|
||||
"osvdb":"101101"
|
||||
},
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
"updated_at":"2014-07-28T12:10:07.000Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -1,20 +1,23 @@
|
||||
[
|
||||
{
|
||||
"shopperpress": {
|
||||
"vulnerabilities":[
|
||||
{
|
||||
"id":2989,
|
||||
"title":"Administrator-exploitable blind SQLi in WordPress 1.0 - 3.8.1",
|
||||
"references":"https://security.dxw.com/advisories/sqli-in-wordpress-3-6-1/,http://www.example.com",
|
||||
"references": {
|
||||
"url": "https://security.dxw.com/advisories/sqli-in-wordpress-3-6-1/,http://www.example.com"
|
||||
},
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
"updated_at":"2014-07-28T12:43:41.000Z"
|
||||
},
|
||||
{
|
||||
"id":2990,
|
||||
"title":"Potential Authentication Cookie Forgery",
|
||||
"references":"https://labs.mwrinfosecurity.com/blog/2014/04/11/wordpress-auth-cookie-forgery/,https://github.com/WordPress/WordPress/commit/78a915e0e5927cf413aa6c2cef2fca3dc587f8be",
|
||||
"references": {
|
||||
"url": "https://labs.mwrinfosecurity.com/blog/2014/04/11/wordpress-auth-cookie-forgery/,https://github.com/WordPress/WordPress/commit/78a915e0e5927cf413aa6c2cef2fca3dc587f8be",
|
||||
"osvdb":"105620",
|
||||
"cve":"2014-0166",
|
||||
"cve":"2014-0166"
|
||||
},
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
"updated_at":"2014-07-28T12:10:07.000Z",
|
||||
"fixed_in":"3.8.2"
|
||||
@@ -22,9 +25,11 @@
|
||||
{
|
||||
"id":2991,
|
||||
"title":"Privilege escalation: contributors publishing posts",
|
||||
"references":"https://github.com/wpscanteam/wpscan/wiki/CVE-2014-0165",
|
||||
"references": {
|
||||
"url": "https://github.com/wpscanteam/wpscan/wiki/CVE-2014-0165",
|
||||
"osvdb":"105630",
|
||||
"cve":"2014-0165",
|
||||
"cve":"2014-0165"
|
||||
},
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
"updated_at":"2014-07-28T12:10:07.000Z",
|
||||
"fixed_in":"3.8.2"
|
||||
@@ -32,27 +37,29 @@
|
||||
{
|
||||
"id":2992,
|
||||
"title":"Plupload Unspecified XSS",
|
||||
"references": {
|
||||
"osvdb":"105622",
|
||||
"secunia":"57769",
|
||||
"secunia":"57769"
|
||||
},
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
"updated_at":"2014-07-28T12:10:07.000Z",
|
||||
"fixed_in":"3.8.2"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"webfolio": {
|
||||
"vulnerabilities":[
|
||||
{
|
||||
"id":2993,
|
||||
"title":"wp-admin/options-writing.php Cleartext Admin Credentials Disclosure",
|
||||
"references":"http://seclists.org/fulldisclosure/2013/Dec/135",
|
||||
"osvdb":"101101",
|
||||
"references": {
|
||||
"url": "http://seclists.org/fulldisclosure/2013/Dec/135",
|
||||
"osvdb":"101101"
|
||||
},
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
"updated_at":"2014-07-28T12:10:07.000Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
{
|
||||
"id": "3911",
|
||||
"title": "Vuln Title",
|
||||
"references":{
|
||||
"url": "Ref 1,Ref 2",
|
||||
"secunia": "secunia",
|
||||
"osvdb": "osvdb",
|
||||
"cve": "2011-001",
|
||||
"metasploit": "exploit/ex1",
|
||||
"exploitdb": "exploitdb",
|
||||
"exploitdb": "exploitdb"
|
||||
},
|
||||
"created_at": "2014-07-28T12:10:45.000Z",
|
||||
"updated_at": "2014-07-28T12:10:45.000Z",
|
||||
"type": "CSRF",
|
||||
|
||||
@@ -1,29 +1,30 @@
|
||||
[
|
||||
{
|
||||
"not-this-one": {
|
||||
"vulnerabilities":[
|
||||
{
|
||||
"id":2989,
|
||||
"title":"Administrator-exploitable blind SQLi in WordPress 1.0 - 3.8.1",
|
||||
"url":"https://security.dxw.com/advisories/sqli-in-wordpress-3-6-1/,http://www.example.com",
|
||||
"references": {
|
||||
"url": ["https://security.dxw.com/advisories/sqli-in-wordpress-3-6-1/" ,"http://www.example.com"]
|
||||
},
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
"updated_at":"2014-07-28T12:43:41.000Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"neo": {
|
||||
"vulnerabilities":[
|
||||
{
|
||||
"id":2993,
|
||||
"title":"I'm the one",
|
||||
"url":"Ref 1,Ref 2",
|
||||
"osvdb":"osvdb",
|
||||
"cve":"2011-001",
|
||||
"secunia":"secunia",
|
||||
"metasploit":"exploit/ex1",
|
||||
"exploitdb":"exploitdb",
|
||||
"references": {
|
||||
"url": ["Ref 1", "Ref 2"],
|
||||
"osvdb": ["osvdb"],
|
||||
"cve": ["2011-001"],
|
||||
"secunia": ["secunia"],
|
||||
"metasploit": ["exploit/ex1"],
|
||||
"exploitdb": ["exploitdb"]
|
||||
},
|
||||
"type":"XSS",
|
||||
"fixed_in":"",
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
@@ -32,4 +33,3 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
58
spec/samples/common/models/wp_plugin/vulnerable/plugins.json
Normal file
58
spec/samples/common/models/wp_plugin/vulnerable/plugins.json
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"mr-smith": {
|
||||
"vulnerabilities":[
|
||||
{
|
||||
"id":2993,
|
||||
"title":"I should not appear in the results",
|
||||
"references": {
|
||||
"url": ["Ref 1","Ref 2"],
|
||||
"osvdb": ["osvdb"],
|
||||
"cve": ["2011-001"],
|
||||
"secunia": ["secunia"],
|
||||
"metasploit": ["exploit/ex1"],
|
||||
"exploitdb": ["exploitdb"]
|
||||
},
|
||||
"type":"XSS",
|
||||
"fixed_in":"",
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
"updated_at":"2014-07-28T12:10:07.000Z"
|
||||
},
|
||||
{
|
||||
"id":2989,
|
||||
"title":"Neither do I",
|
||||
"references": {
|
||||
"url": ["Ref 1" ,"Ref 2"],
|
||||
"osvdb": ["osvdb"],
|
||||
"cve": ["2011-001"],
|
||||
"secunia": ["secunia"],
|
||||
"metasploit": ["exploit/ex1"],
|
||||
"exploitdb": ["exploitdb"]
|
||||
},
|
||||
"type":"XSS",
|
||||
"fixed_in":"",
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
"updated_at":"2014-07-28T12:10:07.000Z"
|
||||
}
|
||||
]
|
||||
},
|
||||
"white-rabbit": {
|
||||
"vulnerabilities": [
|
||||
{
|
||||
"id":2993,
|
||||
"title":"Follow me!",
|
||||
"references": {
|
||||
"url": ["Ref 1", "Ref 2"],
|
||||
"osvdb": ["osvdb"],
|
||||
"cve": ["2011-001"],
|
||||
"secunia": ["secunia"],
|
||||
"metasploit": ["exploit/ex1"],
|
||||
"exploitdb": ["exploitdb"]
|
||||
},
|
||||
"type":"REDIRECT",
|
||||
"fixed_in":"",
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
"updated_at":"2014-07-28T12:10:07.000Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
[
|
||||
{
|
||||
"mr-smith":{
|
||||
"vulnerabilities":[
|
||||
{
|
||||
"id":2989,
|
||||
"title":"I should not appear in the results",
|
||||
"url":"Ref 1,Ref 2",
|
||||
"osvdb":"osvdb",
|
||||
"cve":"2011-001",
|
||||
"secunia":"secunia",
|
||||
"metasploit":"exploit/ex1",
|
||||
"exploitdb":"exploitdb",
|
||||
"type":"XSS",
|
||||
"fixed_in":"",
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
"updated_at":"2014-07-28T12:10:07.000Z"
|
||||
},
|
||||
{
|
||||
"id":2989,
|
||||
"title":"Neither do I",
|
||||
"url":"Ref 1,Ref 2",
|
||||
"osvdb":"osvdb",
|
||||
"cve":"2011-001",
|
||||
"secunia":"secunia",
|
||||
"metasploit":"exploit/ex1",
|
||||
"exploitdb":"exploitdb",
|
||||
"type":"XSS",
|
||||
"fixed_in":"",
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
"updated_at":"2014-07-28T12:10:07.000Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"white-rabbit":{
|
||||
"vulnerabilities":[
|
||||
{
|
||||
"id":2993,
|
||||
"title":"Follow me!",
|
||||
"url":"Ref 1,Ref 2",
|
||||
"osvdb":"osvdb",
|
||||
"cve":"2011-001",
|
||||
"secunia":"secunia",
|
||||
"metasploit":"exploit/ex1",
|
||||
"exploitdb":"exploitdb",
|
||||
"type":"REDIRECT",
|
||||
"fixed_in":"",
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
"updated_at":"2014-07-28T12:10:07.000Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -1,16 +1,17 @@
|
||||
[
|
||||
{
|
||||
"mr-smith": {
|
||||
"vulnerabilities":[
|
||||
{
|
||||
"id":2989,
|
||||
"title":"I should not appear in the results",
|
||||
"url":"Ref 1,Ref 2",
|
||||
"osvdb":"osvdb",
|
||||
"cve":"2011-001",
|
||||
"secunia":"secunia",
|
||||
"metasploit":"exploit/ex1",
|
||||
"exploitdb":"exploitdb",
|
||||
"references": {
|
||||
"url": ["Ref 1", "Ref 2"],
|
||||
"osvdb": ["osvdb"],
|
||||
"cve": ["2011-001"],
|
||||
"secunia": ["secunia"],
|
||||
"metasploit": ["exploit/ex1"],
|
||||
"exploitdb": ["exploitdb"]
|
||||
},
|
||||
"type":"XSS",
|
||||
"fixed_in":"",
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
@@ -19,32 +20,34 @@
|
||||
{
|
||||
"id":2989,
|
||||
"title":"Neither do I",
|
||||
"url":"Ref 1,Ref 2",
|
||||
"osvdb":"osvdb",
|
||||
"cve":"2011-001",
|
||||
"secunia":"secunia",
|
||||
"metasploit":"exploit/ex1",
|
||||
"exploitdb":"exploitdb",
|
||||
"references": {
|
||||
"url": ["Ref 1", "Ref 2"],
|
||||
"osvdb": ["osvdb"],
|
||||
"cve": ["2011-001"],
|
||||
"secunia": ["secunia"],
|
||||
"metasploit": ["exploit/ex1"],
|
||||
"exploitdb": ["exploitdb"]
|
||||
},
|
||||
"type":"XSS",
|
||||
"fixed_in":"",
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
"updated_at":"2014-07-28T12:10:07.000Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"the-oracle": {
|
||||
"vulnerabilities":[
|
||||
{
|
||||
"id":2993,
|
||||
"title":"I see you",
|
||||
"url":"Ref 1,Ref 2",
|
||||
"osvdb":"osvdb",
|
||||
"cve":"2011-001",
|
||||
"secunia":"secunia",
|
||||
"metasploit":"exploit/ex1",
|
||||
"exploitdb":"exploitdb",
|
||||
"references": {
|
||||
"url": ["Ref 1", "Ref 2"],
|
||||
"osvdb": ["osvdb"],
|
||||
"cve": ["2011-001"],
|
||||
"secunia": ["secunia"],
|
||||
"metasploit": ["exploit/ex1"],
|
||||
"exploitdb": ["exploitdb"]
|
||||
},
|
||||
"type":"FPD",
|
||||
"fixed_in":"",
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
@@ -53,4 +56,4 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US" prefix="og: http://ogp.me/ns#">
|
||||
<head>
|
||||
|
||||
<meta charset="UTF-8" />
|
||||
|
||||
<title>Test</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<link rel="stylesheet" type="text/css" href="http://example.com/wp-content/themes/scrollider child/style.css" media="screen" />
|
||||
<link rel="stylesheet" type="text/css" media="print"
|
||||
href="http://example.com/wp-content/themes/scrollider child/print.css" />
|
||||
<link rel="pingback" href="http://example.com/xmlrpc.php" />
|
||||
|
||||
<!-- This site is optimized with the Yoast WordPress SEO plugin v1.6.1 - https://yoast.com/wordpress/plugins/seo/ -->
|
||||
<link rel="canonical" href="http://example.com" />
|
||||
<link rel="next" href="http://example.com/page/2/" />
|
||||
<meta property="og:locale" content="en_US" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content="Test" />
|
||||
<meta property="og:url" content="http://example.com" />
|
||||
<meta property="og:site_name" content="Test" />
|
||||
<script type="application/ld+json">{ "@context": "http://schema.org", "@type": "WebSite", "url": "http://example.com/", "potentialAction": { "@type": "SearchAction", "target": "http://example.com/?s={search_term}", "query-input": "required name=search_term" } }</script>
|
||||
<!-- / Yoast WordPress SEO plugin. -->
|
||||
|
||||
<link rel="alternate" type="application/rss+xml" title="Test" href="http://www.example.com/feed" />
|
||||
<link rel="alternate" type="application/rss+xml" title="Test" href="http://example.com/comments/feed/" />
|
||||
<link rel='stylesheet' id='colorbox-theme3-css' href='http://example.com/wp-content/plugins/ewsel-lightbox-for-galleries/colorbox/theme3/colorbox.css?ver=1.3.14' type='text/css' media='screen' />
|
||||
<link rel='stylesheet' id='woo-layout-css' href='http://example.com/wp-content/themes/scrollider/css/layout.css?ver=3.5.1' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='woocommerce-css' href='http://example.com/wp-content/themes/scrollider/css/woocommerce.css?ver=3.5.1' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='contact-form-7-css' href='http://example.com/wp-content/plugins/contact-form-7/includes/css/styles.css?ver=3.4.2' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='videogallery_css-css' href='http://example.com/wp-content/plugins/contus-video-gallery/css/style.min.css?ver=3.5.1' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='SFSImainCss-css' href='http://example.com/wp-content/plugins/ultimate-social-media-icons/css/sfsi-style.css?ver=3.5.1' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='SFSIJqueryCSS-css' href='http://example.com/wp-content/plugins/ultimate-social-media-icons/css/jquery-ui-1.10.4/jquery-ui-min.css?ver=3.5.1' type='text/css' media='all' />
|
||||
<link rel='stylesheet' id='prettyPhoto-css' href='http://example.com/wp-content/themes/scrollider/includes/css/prettyPhoto.css?ver=3.5.1' type='text/css' media='all' />
|
||||
<script type='text/javascript' src='http://example.com/wp-includes/js/jquery/jquery.js?ver=1.8.3'></script>
|
||||
<script type='text/javascript' src='http://example.com/wp-content/plugins/ewsel-lightbox-for-galleries/colorbox/jquery.colorbox-min.js?ver=1.3.14'></script>
|
||||
<script type='text/javascript' src='http://example.com/wp-content/plugins/contus-video-gallery/js/script.min.js?ver=3.5.1'></script>
|
||||
<script type='text/javascript'>
|
||||
/* <![CDATA[ */
|
||||
var ajax_object = {"ajax_url":"http:\/\/example.com\/wp-admin\/admin-ajax.php"};
|
||||
/* ]]> */
|
||||
</script>
|
||||
<script type='text/javascript' src='http://example.com/wp-content/plugins/ultimate-social-media-icons/js/custom.js?ver=3.5.1'></script>
|
||||
<script type='text/javascript' src='http://example.com/wp-content/themes/scrollider/includes/js/third-party.js?ver=3.5.1'></script>
|
||||
<script type='text/javascript' src='http://example.com/wp-content/themes/scrollider/includes/js/general.js?ver=3.5.1'></script>
|
||||
<script type='text/javascript'>
|
||||
/* <![CDATA[ */
|
||||
var woo_masonry_data = {"numberOfColumns":"3"};
|
||||
/* ]]> */
|
||||
</script>
|
||||
<script type='text/javascript' src='http://example.com/wp-content/themes/scrollider/includes/js/jquery.masonry.min.js?ver=3.5.1'></script>
|
||||
<script type='text/javascript' src='http://example.com/wp-content/themes/scrollider/includes/js/jquery.flexslider-min.js?ver=3.5.1'></script>
|
||||
<script type='text/javascript'>
|
||||
/* <![CDATA[ */
|
||||
var woo_localized_data = {"animation":"fade","controlsContainer":".controls-container","smoothHeight":"true","useCSS":"true","directionNav":"true","controlNav":"true","manualControls":".manual ol li","slideshow":"true","pauseOnHover":"false","slideshowSpeed":"3000","animationDuration":"0","touch":"false"};
|
||||
/* ]]> */
|
||||
</script>
|
||||
<script type='text/javascript' src='http://example.com/wp-content/themes/scrollider/includes/js/featured-slider.js?ver=1.2.5'></script>
|
||||
<script type='text/javascript' src='http://example.com/wp-content/plugins/vslider/js/vslider.js?ver=3.5.1'></script>
|
||||
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://example.com/xmlrpc.php?rsd" />
|
||||
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://example.com/wp-includes/wlwmanifest.xml" />
|
||||
<meta name="generator" content="WordPress 3.5.1, fitted with the WordPress Mobile Pack 1.2.5" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"><meta property="og:image" content="http://example.com/wp-content/uploads/2015/07/test.jpg"><meta property="og:image:type" content=""><meta property="og:image:width" content="1000"><meta property="og:image:height" content="752">
|
||||
<!-- Theme version -->
|
||||
<meta name="generator" content="Scrollider Child 1.0.0" />
|
||||
<meta name="generator" content="Scrollider 1.2.13" />
|
||||
<meta name="generator" content="WooFramework 5.5.5" />
|
||||
@@ -1,36 +1,37 @@
|
||||
[
|
||||
{
|
||||
"3.5": {
|
||||
"vulnerabilities":[
|
||||
{
|
||||
"id":2989,
|
||||
"title":"I should not appear in the results",
|
||||
"url":"Ref 1,Ref 2",
|
||||
"osvdb":"osvdb",
|
||||
"cve":"2011-001",
|
||||
"secunia":"secunia",
|
||||
"metasploit":"exploit/ex1",
|
||||
"exploitdb":"exploitdb",
|
||||
"references": {
|
||||
"url": ["Ref 1", "Ref 2"],
|
||||
"osvdb": ["osvdb"],
|
||||
"cve": ["2011-001"],
|
||||
"secunia": ["secunia"],
|
||||
"metasploit": ["exploit/ex1"],
|
||||
"exploitdb": ["exploitdb"]
|
||||
},
|
||||
"type":"XSS",
|
||||
"fixed_in":"",
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
"updated_at":"2014-07-28T12:10:07.000Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"3.2": {
|
||||
"vulnerabilities":[
|
||||
{
|
||||
"id":2993,
|
||||
"title":"Here I Am",
|
||||
"url":"Ref 1,Ref 2",
|
||||
"osvdb":"osvdb",
|
||||
"cve":"2011-001",
|
||||
"secunia":"secunia",
|
||||
"metasploit":"exploit/ex1",
|
||||
"exploitdb":"exploitdb",
|
||||
"references": {
|
||||
"url": ["Ref 1", "Ref 2"],
|
||||
"osvdb": ["osvdb"],
|
||||
"cve": ["2011-001"],
|
||||
"secunia": ["secunia"],
|
||||
"metasploit": ["exploit/ex1"],
|
||||
"exploitdb": ["exploitdb"]
|
||||
},
|
||||
"type":"SQLI",
|
||||
"fixed_in":"",
|
||||
"created_at":"2014-07-28T12:10:07.000Z",
|
||||
@@ -39,4 +40,3 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
User-agent: *
|
||||
Disallow: /wp-admin/
|
||||
Disallow: /wp-admin/
|
||||
Disallow: /wp-admin/
|
||||
Disallow: /wp-admin/
|
||||
Disallow: /wp-includes/
|
||||
Disallow: /wordpress/admin/
|
||||
Disallow: /wordpress/wp-admin/
|
||||
Disallow: /wordpress/secret/
|
||||
Disallow: /wordpress/secret/
|
||||
Disallow: /wordpress/
|
||||
Disallow: /wordpress/secret/
|
||||
Disallow: /Wordpress/wp-admin/
|
||||
Disallow: /wp-admin/tralling-space/
|
||||
Allow: /asdf/
|
||||
|
||||
Sitemap: http://10.0.0.0/sitemap.xml.gz
|
||||
@@ -0,0 +1,9 @@
|
||||
User-agent: *
|
||||
Disallow: /wp-admin/
|
||||
Disallow: /wp-admin/
|
||||
Disallow: /wp-admin/
|
||||
Disallow: /wp-admin/
|
||||
Disallow: /wp-admin/
|
||||
Disallow: /wp-admin/
|
||||
|
||||
Sitemap: http://10.0.0.0/sitemap.xml.gz
|
||||
@@ -61,6 +61,24 @@ shared_examples 'WebSite::RobotsTxt' do
|
||||
http://example.localhost/asdf/
|
||||
)
|
||||
end
|
||||
|
||||
it 'removes duplicate entries from robots.txt test 1' do
|
||||
@fixture = fixtures_dir + '/robots_txt/robots_duplicate_1.txt'
|
||||
@expected = %w(
|
||||
http://example.localhost/wordpress/
|
||||
http://example.localhost/wordpress/admin/
|
||||
http://example.localhost/wordpress/wp-admin/
|
||||
http://example.localhost/wordpress/secret/
|
||||
http://example.localhost/Wordpress/wp-admin/
|
||||
http://example.localhost/wp-admin/tralling-space/
|
||||
http://example.localhost/asdf/
|
||||
)
|
||||
end
|
||||
|
||||
it 'removes duplicate entries from robots.txt test 2' do
|
||||
@fixture = fixtures_dir + '/robots_txt/robots_duplicate_2.txt'
|
||||
@expected = nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'installed in sub directory' do
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
shared_examples 'WpItem::Vulnerable' do
|
||||
|
||||
# 2 variables have to be set in the described class or subject:
|
||||
# let(:vulns_file) { }
|
||||
# let(:expected_vulns) { } The expected Vulnerabilities when using vulns_file and vulns_xpath
|
||||
# let(:db_file) { }
|
||||
# let(:expected_vulns) { } The expected Vulnerabilities when using db_file and vulns_xpath
|
||||
#
|
||||
# 1 variable is optional, used if supplied, otherwise subject.vulns_xpath is used
|
||||
# let(:vulns_xpath) { }
|
||||
@@ -18,7 +18,7 @@ shared_examples 'WpItem::Vulnerable' do
|
||||
end
|
||||
|
||||
after do
|
||||
subject.vulns_file = @vulns_file
|
||||
subject.db_file = @db_file
|
||||
subject.identifier = identifier if defined?(identifier)
|
||||
|
||||
result = subject.vulnerabilities
|
||||
@@ -26,15 +26,15 @@ shared_examples 'WpItem::Vulnerable' do
|
||||
expect(result).to eq @expected
|
||||
end
|
||||
|
||||
context 'when the vulns_file is empty' do
|
||||
context 'when the db_file is empty' do
|
||||
it 'returns an empty Vulnerabilities' do
|
||||
@vulns_file = empty_file
|
||||
@db_file = empty_file
|
||||
@expected = Vulnerabilities.new
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns the expected vulnerabilities' do
|
||||
@vulns_file = vulns_file
|
||||
@db_file = db_file
|
||||
@expected = expected_vulns
|
||||
end
|
||||
end
|
||||
|
||||
@@ -39,68 +39,8 @@ shared_examples 'WpItems::Detectable' do
|
||||
end
|
||||
end
|
||||
|
||||
describe '::targets_items_from_file' do
|
||||
after do
|
||||
results = subject.send(:targets_items_from_file, file, wp_target, item_class, vulns_file)
|
||||
|
||||
expect(results.map { |i| i.name }).to eq @expected.map { |i| i.name }
|
||||
|
||||
unless results.empty?
|
||||
results.each do |item|
|
||||
expect(item).to be_a item_class
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# should raise error.
|
||||
# context 'when an empty file' do
|
||||
# let(:file) { empty_file }
|
||||
|
||||
# it 'returns an empty Array' do
|
||||
# @expected = []
|
||||
# end
|
||||
# end
|
||||
|
||||
context 'when a file' do
|
||||
let(:file) { targets_items_file }
|
||||
|
||||
it 'returns the expected Array of WpItem' do
|
||||
@expected = expected[:targets_items_from_file]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '::vulnerable_targets_items' do
|
||||
after do
|
||||
results = subject.send(:vulnerable_targets_items, wp_target, item_class, vulns_file)
|
||||
|
||||
expect(results.map { |i| i.name }).to eq @expected.map { |i| i.name }
|
||||
|
||||
unless results.empty?
|
||||
results.each do |item|
|
||||
expect(item).to be_a item_class
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# should raise error.
|
||||
# context 'when an empty file' do
|
||||
# let(:file) { empty_file }
|
||||
|
||||
# it 'returns an empty Array' do
|
||||
# @expected = []
|
||||
# end
|
||||
# end
|
||||
|
||||
context 'when a file' do
|
||||
it 'returns the expected Array of WpItem' do
|
||||
@expected = expected[:vulnerable_targets_items]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '::targets_items' do
|
||||
let(:options) { {} }
|
||||
let(:options) { { type: :all } }
|
||||
|
||||
after do
|
||||
if @expected
|
||||
@@ -110,29 +50,13 @@ shared_examples 'WpItems::Detectable' do
|
||||
end
|
||||
end
|
||||
|
||||
context 'when :only_vulnerable' do
|
||||
let(:options) { { only_vulnerable: true } }
|
||||
context 'when :type = :vulnerable' do
|
||||
let(:options) { { type: :vulnerable } }
|
||||
|
||||
it 'returns the expected Array of WpItem' do
|
||||
@expected = expected[:vulnerable_targets_items]
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not :only_vulnerable' do
|
||||
context 'when no :file' do
|
||||
it 'raises an error' do
|
||||
expect { subject.send(:targets_items, wp_target, options) }.to raise_error('A file must be supplied')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when :file' do
|
||||
let(:options) { { file: targets_items_file } }
|
||||
|
||||
it 'returns the expected Array of WpItem' do
|
||||
@expected = (expected[:targets_items_from_file] + expected[:vulnerable_targets_items]).uniq {|t| t.name }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '::passive_detection' do
|
||||
@@ -176,8 +100,8 @@ shared_examples 'WpItems::Detectable' do
|
||||
expect(result.sort.map { |i| i.name }).to eq @expected.sort.map { |i| i.name }
|
||||
end
|
||||
|
||||
context 'when :only_vulnerable' do
|
||||
let(:options) { { only_vulnerable: true } }
|
||||
context 'when :type = :vulnerable' do
|
||||
let(:options) { { type: :vulnerable } }
|
||||
let(:targets) { expected[:vulnerable_targets_items] }
|
||||
|
||||
it 'only checks and return vulnerable targets' do
|
||||
@@ -207,7 +131,7 @@ shared_examples 'WpItems::Detectable' do
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no :only_vulnerable' do
|
||||
context 'when no :type = :vulnerable' do
|
||||
let(:targets) { (expected[:vulnerable_targets_items] + expected[:targets_items_from_file]).uniq { |t| t.name } }
|
||||
|
||||
it 'checks all targets, and merge the results with passive_detection' do
|
||||
|
||||
@@ -2,25 +2,25 @@
|
||||
|
||||
shared_examples 'WpPlugin::Vulnerable' do
|
||||
|
||||
describe '#vulns_file' do
|
||||
after { expect(subject.vulns_file).to eq @expected }
|
||||
describe '#db_file' do
|
||||
after { expect(subject.db_file).to eq @expected }
|
||||
|
||||
context 'when :vulns_file is no set' do
|
||||
context 'when :db_file is no set' do
|
||||
it 'returns the default one' do
|
||||
@expected = PLUGINS_VULNS_FILE
|
||||
@expected = PLUGINS_FILE
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the :vulns_file is already set' do
|
||||
context 'when the :db_file is already set' do
|
||||
it 'returns it' do
|
||||
@expected = 'test.json'
|
||||
subject.vulns_file = @expected
|
||||
subject.db_file = @expected
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#identifier' do
|
||||
its(:identifier) { is_expected.to eq 'plugin-name' }
|
||||
its(:identifier) { should eq 'plugin-name' }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -2,25 +2,25 @@
|
||||
|
||||
shared_examples 'WpTheme::Vulnerable' do
|
||||
|
||||
describe '#vulns_file' do
|
||||
after { expect(subject.vulns_file).to eq @expected }
|
||||
describe '#db_file' do
|
||||
after { expect(subject.db_file).to eq @expected }
|
||||
|
||||
context 'when :vulns_file is not set' do
|
||||
context 'when :db_file is not set' do
|
||||
it 'returns the default one' do
|
||||
@expected = THEMES_VULNS_FILE
|
||||
@expected = THEMES_FILE
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the :vulns_file is already set' do
|
||||
context 'when the :db_file is already set' do
|
||||
it 'returns it' do
|
||||
@expected = 'test.json'
|
||||
subject.vulns_file = @expected
|
||||
subject.db_file = @expected
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#identifier' do
|
||||
its(:identifier) { is_expected.to eq 'theme-name' }
|
||||
its(:identifier) { should eq 'theme-name' }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -29,6 +29,13 @@ shared_examples 'WpUser::Existable' do
|
||||
@expected = nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no author given' do
|
||||
it 'returns nil' do
|
||||
@text = '<a href="http://wp.lab/author/" class="btn btn-default">See Posts</a>'
|
||||
@expected = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '::login_from_body' do
|
||||
|
||||
@@ -2,25 +2,25 @@
|
||||
|
||||
shared_examples 'WpVersion::Vulnerable' do
|
||||
|
||||
describe '#vulns_file' do
|
||||
after { expect(subject.vulns_file).to eq @expected }
|
||||
describe '#db_file' do
|
||||
after { expect(subject.db_file).to eq @expected }
|
||||
|
||||
context 'when :vulns_file is no set' do
|
||||
context 'when :db_file is no set' do
|
||||
it 'returns the default one' do
|
||||
@expected = WP_VULNS_FILE
|
||||
@expected = WORDPRESSES_FILE
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the :vulns_file is already set' do
|
||||
context 'when the :db_file is already set' do
|
||||
it 'returns it' do
|
||||
@expected = 'test.json'
|
||||
subject.vulns_file = @expected
|
||||
subject.db_file = @expected
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#identifier' do
|
||||
its(:identifier) { is_expected.to eq '1.2' }
|
||||
its(:identifier) { should eq '1.2' }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
41
wpscan.rb
41
wpscan.rb
@@ -133,7 +133,7 @@ def main
|
||||
# Remote website is wordpress?
|
||||
unless wpscan_options.force
|
||||
unless wp_target.wordpress?
|
||||
raise critical('The remote website is up, but does not seem to be running WordPress.')
|
||||
raise 'The remote website is up, but does not seem to be running WordPress.'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -273,15 +273,29 @@ def main
|
||||
# Enumerate the installed plugins
|
||||
if wpscan_options.enumerate_plugins or wpscan_options.enumerate_only_vulnerable_plugins or wpscan_options.enumerate_all_plugins
|
||||
puts
|
||||
puts info("Enumerating installed plugins #{'(only vulnerable ones)' if wpscan_options.enumerate_only_vulnerable_plugins} ...")
|
||||
if wpscan_options.enumerate_only_vulnerable_plugins
|
||||
puts info('Enumerating installed plugins (only ones with known vulnerabilities) ...')
|
||||
plugin_enumeration_type = :vulnerable
|
||||
end
|
||||
|
||||
if wpscan_options.enumerate_plugins
|
||||
puts info('Enumerating installed plugins (only ones marked as popular) ...')
|
||||
plugin_enumeration_type = :popular
|
||||
end
|
||||
|
||||
if wpscan_options.enumerate_all_plugins
|
||||
puts info('Enumerating all plugins (may take a while and use a lot of system resources) ...')
|
||||
plugin_enumeration_type = :all
|
||||
end
|
||||
puts
|
||||
|
||||
wp_plugins = WpPlugins.aggressive_detection(wp_target,
|
||||
enum_options.merge(
|
||||
file: wpscan_options.enumerate_all_plugins ? PLUGINS_FULL_FILE : PLUGINS_FILE,
|
||||
only_vulnerable: wpscan_options.enumerate_only_vulnerable_plugins || false
|
||||
file: PLUGINS_FILE,
|
||||
type: plugin_enumeration_type
|
||||
)
|
||||
)
|
||||
|
||||
puts
|
||||
if !wp_plugins.empty?
|
||||
puts info("We found #{wp_plugins.size} plugins:")
|
||||
@@ -295,13 +309,26 @@ def main
|
||||
# Enumerate installed themes
|
||||
if wpscan_options.enumerate_themes or wpscan_options.enumerate_only_vulnerable_themes or wpscan_options.enumerate_all_themes
|
||||
puts
|
||||
puts info("Enumerating installed themes #{'(only vulnerable ones)' if wpscan_options.enumerate_only_vulnerable_themes} ...")
|
||||
if wpscan_options.enumerate_only_vulnerable_themes
|
||||
puts info('Enumerating installed themes (only ones with known vulnerabilities) ...')
|
||||
theme_enumeration_type = :vulnerable
|
||||
end
|
||||
|
||||
if wpscan_options.enumerate_themes
|
||||
puts info('Enumerating installed themes (only ones marked as popular) ...')
|
||||
theme_enumeration_type = :popular
|
||||
end
|
||||
|
||||
if wpscan_options.enumerate_all_themes
|
||||
puts info('Enumerating all themes (may take a while and use a lot of system resources) ...')
|
||||
theme_enumeration_type = :all
|
||||
end
|
||||
puts
|
||||
|
||||
wp_themes = WpThemes.aggressive_detection(wp_target,
|
||||
enum_options.merge(
|
||||
file: wpscan_options.enumerate_all_themes ? THEMES_FULL_FILE : THEMES_FILE,
|
||||
only_vulnerable: wpscan_options.enumerate_only_vulnerable_themes || false
|
||||
file: THEMES_FILE,
|
||||
type: theme_enumeration_type
|
||||
)
|
||||
)
|
||||
puts
|
||||
|
||||
Reference in New Issue
Block a user