WPSTools updated to respect ruby standards according to rubocop
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
#--
|
#--
|
||||||
# WPScan - WordPress Security Scanner
|
# WPScan - WordPress Security Scanner
|
||||||
# Copyright (C) 2012-2013
|
# Copyright (C) 2012-2013
|
||||||
@@ -45,7 +46,11 @@ class Browser
|
|||||||
override_config_with_options(options)
|
override_config_with_options(options)
|
||||||
end
|
end
|
||||||
|
|
||||||
@hydra = Typhoeus::Hydra.new(:max_concurrency => @max_threads, :timeout => @request_timeout)
|
@hydra = Typhoeus::Hydra.new(
|
||||||
|
max_concurrency: @max_threads,
|
||||||
|
timeout: @request_timeout
|
||||||
|
)
|
||||||
|
|
||||||
# TODO : add an option for the cache dir instead of using a constant
|
# TODO : add an option for the cache dir instead of using a constant
|
||||||
@cache = CacheFileStore.new(CACHE_DIR + '/browser')
|
@cache = CacheFileStore.new(CACHE_DIR + '/browser')
|
||||||
|
|
||||||
@@ -69,12 +74,13 @@ class Browser
|
|||||||
end
|
end
|
||||||
|
|
||||||
def user_agent_mode=(ua_mode)
|
def user_agent_mode=(ua_mode)
|
||||||
ua_mode ||= "static"
|
ua_mode ||= 'static'
|
||||||
|
|
||||||
if USER_AGENT_MODES.include?(ua_mode)
|
if USER_AGENT_MODES.include?(ua_mode)
|
||||||
@user_agent_mode = ua_mode
|
@user_agent_mode = ua_mode
|
||||||
# For semi-static user agent mode, the user agent has to be nil the first time (it will be set with the getter)
|
# For semi-static user agent mode, the user agent has to
|
||||||
@user_agent = nil if ua_mode === "semi-static"
|
# be nil the first time (it will be set with the getter)
|
||||||
|
@user_agent = nil if ua_mode === 'semi-static'
|
||||||
else
|
else
|
||||||
raise "Unknow user agent mode : '#{ua_mode}'"
|
raise "Unknow user agent mode : '#{ua_mode}'"
|
||||||
end
|
end
|
||||||
@@ -83,12 +89,12 @@ class Browser
|
|||||||
# return the user agent, according to the user_agent_mode
|
# return the user agent, according to the user_agent_mode
|
||||||
def user_agent
|
def user_agent
|
||||||
case @user_agent_mode
|
case @user_agent_mode
|
||||||
when "semi-static"
|
when 'semi-static'
|
||||||
unless @user_agent
|
unless @user_agent
|
||||||
@user_agent = @available_user_agents.sample
|
|
||||||
end
|
|
||||||
when "random"
|
|
||||||
@user_agent = @available_user_agents.sample
|
@user_agent = @available_user_agents.sample
|
||||||
|
end
|
||||||
|
when 'random'
|
||||||
|
@user_agent = @available_user_agents.sample
|
||||||
end
|
end
|
||||||
@user_agent
|
@user_agent
|
||||||
end
|
end
|
||||||
@@ -109,21 +115,25 @@ class Browser
|
|||||||
@proxy_auth = auth
|
@proxy_auth = auth
|
||||||
elsif auth.is_a?(String)
|
elsif auth.is_a?(String)
|
||||||
if matches = %r{([^:]+):(.*)}.match(auth)
|
if matches = %r{([^:]+):(.*)}.match(auth)
|
||||||
@proxy_auth = {:proxy_username => matches[1], :proxy_password => matches[2]}
|
@proxy_auth = {
|
||||||
|
proxy_username: matches[1],
|
||||||
|
proxy_password: matches[2]
|
||||||
|
}
|
||||||
else
|
else
|
||||||
raise_invalid_proxy_format()
|
raise_invalid_proxy_auth_format()
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
raise_invalid_proxy_format()
|
raise_invalid_proxy_auth_format()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def raise_invalid_proxy_format
|
def raise_invalid_proxy_auth_format
|
||||||
raise "Invalid proxy auth format, expected username:password or {:proxy_username => username, :proxy_password => password}"
|
raise 'Invalid proxy auth format, expected username:password or {proxy_username: username, proxy_password: password}'
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO reload hydra (if the .load_config is called on a browser object, hydra will not have the new @max_threads and @request_timeout)
|
# TODO reload hydra (if the .load_config is called on a browser object,
|
||||||
|
# hydra will not have the new @max_threads and @request_timeout)
|
||||||
def load_config(config_file = nil)
|
def load_config(config_file = nil)
|
||||||
@config_file = config_file || @config_file
|
@config_file = config_file || @config_file
|
||||||
|
|
||||||
@@ -146,7 +156,9 @@ class Browser
|
|||||||
end
|
end
|
||||||
|
|
||||||
@hydra.cache_getter do |request|
|
@hydra.cache_getter do |request|
|
||||||
@cache.read_entry(Browser.generate_cache_key_from_request(request)) rescue nil
|
@cache.read_entry(
|
||||||
|
Browser.generate_cache_key_from_request(request)
|
||||||
|
) rescue nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
#--
|
#--
|
||||||
# WPScan - WordPress Security Scanner
|
# WPScan - WordPress Security Scanner
|
||||||
# Copyright (C) 2012-2013
|
# Copyright (C) 2012-2013
|
||||||
@@ -18,7 +19,8 @@
|
|||||||
|
|
||||||
#
|
#
|
||||||
# => @todo take consideration of the cache_timeout :
|
# => @todo take consideration of the cache_timeout :
|
||||||
# -> create 2 files per key : one for the data storage (key.store ?) and the other for the cache timeout (key.expiration, key.timeout ?)
|
# -> create 2 files per key : one for the data storage (key.store ?)
|
||||||
|
# and the other for the cache timeout (key.expiration, key.timeout ?)
|
||||||
# or 1 file for all timeouts ?
|
# or 1 file for all timeouts ?
|
||||||
# -> 2 dirs : 1 for storage, the other for cache_timeout ?
|
# -> 2 dirs : 1 for storage, the other for cache_timeout ?
|
||||||
#
|
#
|
||||||
@@ -28,14 +30,16 @@ require 'yaml'
|
|||||||
class CacheFileStore
|
class CacheFileStore
|
||||||
attr_reader :storage_path, :serializer
|
attr_reader :storage_path, :serializer
|
||||||
|
|
||||||
# The serializer must have the 2 methods .load and .dump (Marshal and YAML have them)
|
# The serializer must have the 2 methods .load and .dump
|
||||||
|
# (Marshal and YAML have them)
|
||||||
# YAML is Human Readable, contrary to Marshal which store in a binary format
|
# YAML is Human Readable, contrary to Marshal which store in a binary format
|
||||||
# Marshal does not need any "require"
|
# Marshal does not need any "require"
|
||||||
def initialize(storage_path, serializer = Marshal)
|
def initialize(storage_path, serializer = Marshal)
|
||||||
@storage_path = File.expand_path(storage_path)
|
@storage_path = File.expand_path(storage_path)
|
||||||
@serializer = serializer
|
@serializer = serializer
|
||||||
|
|
||||||
# File.directory? for ruby <= 1.9 otherwise, it makes more sense to do Dir.exist? :/
|
# File.directory? for ruby <= 1.9 otherwise,
|
||||||
|
# it makes more sense to do Dir.exist? :/
|
||||||
unless File.directory?(@storage_path)
|
unless File.directory?(@storage_path)
|
||||||
Dir.mkdir(@storage_path)
|
Dir.mkdir(@storage_path)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
|
#
|
||||||
# WPScan - WordPress Security Scanner
|
# WPScan - WordPress Security Scanner
|
||||||
# Copyright (C) 2012-2013
|
# Copyright (C) 2012-2013
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
|
#
|
||||||
# WPScan - WordPress Security Scanner
|
# WPScan - WordPress Security Scanner
|
||||||
# Copyright (C) 2012-2013
|
# Copyright (C) 2012-2013
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
|
#
|
||||||
# WPScan - WordPress Security Scanner
|
# WPScan - WordPress Security Scanner
|
||||||
# Copyright (C) 2012-2013
|
# Copyright (C) 2012-2013
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
#--
|
#--
|
||||||
# WPScan - WordPress Security Scanner
|
# WPScan - WordPress Security Scanner
|
||||||
# Copyright (C) 2012-2013
|
# Copyright (C) 2012-2013
|
||||||
@@ -18,39 +19,39 @@
|
|||||||
|
|
||||||
LIB_DIR = File.dirname(__FILE__)
|
LIB_DIR = File.dirname(__FILE__)
|
||||||
ROOT_DIR = File.expand_path(LIB_DIR + '/..') # expand_path is used to get "wpscan/" instead of "wpscan/lib/../"
|
ROOT_DIR = File.expand_path(LIB_DIR + '/..') # expand_path is used to get "wpscan/" instead of "wpscan/lib/../"
|
||||||
DATA_DIR = ROOT_DIR + "/data"
|
DATA_DIR = ROOT_DIR + '/data'
|
||||||
CONF_DIR = ROOT_DIR + "/conf"
|
CONF_DIR = ROOT_DIR + '/conf'
|
||||||
CACHE_DIR = ROOT_DIR + "/cache"
|
CACHE_DIR = ROOT_DIR + '/cache'
|
||||||
WPSCAN_LIB_DIR = LIB_DIR + "/wpscan"
|
WPSCAN_LIB_DIR = LIB_DIR + '/wpscan'
|
||||||
WPSTOOLS_LIB_DIR = LIB_DIR + "/wpstools"
|
WPSTOOLS_LIB_DIR = LIB_DIR + '/wpstools'
|
||||||
UPDATER_LIB_DIR = LIB_DIR + "/updater"
|
UPDATER_LIB_DIR = LIB_DIR + '/updater'
|
||||||
COMMON_LIB_DIR = LIB_DIR + "/common"
|
COMMON_LIB_DIR = LIB_DIR + '/common'
|
||||||
LOG_FILE = ROOT_DIR + "/log.txt"
|
LOG_FILE = ROOT_DIR + '/log.txt'
|
||||||
# Plugins directories
|
# Plugins directories
|
||||||
COMON_PLUGINS_DIR = COMMON_LIB_DIR + "/plugins"
|
COMON_PLUGINS_DIR = COMMON_LIB_DIR + '/plugins'
|
||||||
WPSCAN_PLUGINS_DIR = WPSCAN_LIB_DIR + "/plugins"
|
WPSCAN_PLUGINS_DIR = WPSCAN_LIB_DIR + '/plugins'
|
||||||
WPSTOOLS_PLUGINS_DIR = WPSTOOLS_LIB_DIR + "/plugins"
|
WPSTOOLS_PLUGINS_DIR = WPSTOOLS_LIB_DIR + '/plugins'
|
||||||
|
|
||||||
# Data files
|
# Data files
|
||||||
PLUGINS_FILE = DATA_DIR + "/plugins.txt"
|
PLUGINS_FILE = DATA_DIR + '/plugins.txt'
|
||||||
PLUGINS_FULL_FILE = DATA_DIR + "/plugins_full.txt"
|
PLUGINS_FULL_FILE = DATA_DIR + '/plugins_full.txt'
|
||||||
PLUGINS_VULNS_FILE = DATA_DIR + "/plugin_vulns.xml"
|
PLUGINS_VULNS_FILE = DATA_DIR + '/plugin_vulns.xml'
|
||||||
THEMES_FILE = DATA_DIR + "/themes.txt"
|
THEMES_FILE = DATA_DIR + '/themes.txt'
|
||||||
THEMES_FULL_FILE = DATA_DIR + "/themes_full.txt"
|
THEMES_FULL_FILE = DATA_DIR + '/themes_full.txt'
|
||||||
THEMES_VULNS_FILE = DATA_DIR + "/theme_vulns.xml"
|
THEMES_VULNS_FILE = DATA_DIR + '/theme_vulns.xml'
|
||||||
WP_VULNS_FILE = DATA_DIR + "/wp_vulns.xml"
|
WP_VULNS_FILE = DATA_DIR + '/wp_vulns.xml'
|
||||||
WP_VERSIONS_FILE = DATA_DIR + "/wp_versions.xml"
|
WP_VERSIONS_FILE = DATA_DIR + '/wp_versions.xml'
|
||||||
LOCAL_FILES_FILE = DATA_DIR + "/local_vulnerable_files.xml"
|
LOCAL_FILES_FILE = DATA_DIR + '/local_vulnerable_files.xml'
|
||||||
VULNS_XSD = DATA_DIR + "/vuln.xsd"
|
VULNS_XSD = DATA_DIR + '/vuln.xsd'
|
||||||
WP_VERSIONS_XSD = DATA_DIR + "/wp_versions.xsd"
|
WP_VERSIONS_XSD = DATA_DIR + '/wp_versions.xsd'
|
||||||
LOCAL_FILES_XSD = DATA_DIR + "/local_vulnerable_files.xsd"
|
LOCAL_FILES_XSD = DATA_DIR + '/local_vulnerable_files.xsd'
|
||||||
|
|
||||||
WPSCAN_VERSION = "2.0"
|
WPSCAN_VERSION = '2.0'
|
||||||
|
|
||||||
require "#{LIB_DIR}/environment"
|
require "#{LIB_DIR}/environment"
|
||||||
|
|
||||||
# TODO : add an exclude pattern ?
|
# TODO : add an exclude pattern ?
|
||||||
def require_files_from_directory(absolute_dir_path, files_pattern = "*.rb")
|
def require_files_from_directory(absolute_dir_path, files_pattern = '*.rb')
|
||||||
Dir[File.join(absolute_dir_path, files_pattern)].sort.each do |f|
|
Dir[File.join(absolute_dir_path, files_pattern)].sort.each do |f|
|
||||||
f = File.expand_path(f)
|
f = File.expand_path(f)
|
||||||
require f
|
require f
|
||||||
@@ -59,7 +60,7 @@ def require_files_from_directory(absolute_dir_path, files_pattern = "*.rb")
|
|||||||
end
|
end
|
||||||
|
|
||||||
#require_files_from_directory(COMMON_LIB_DIR)
|
#require_files_from_directory(COMMON_LIB_DIR)
|
||||||
require_files_from_directory(COMMON_LIB_DIR, "**/*.rb")
|
require_files_from_directory(COMMON_LIB_DIR, '**/*.rb')
|
||||||
|
|
||||||
# Add protocol
|
# Add protocol
|
||||||
def add_http_protocol(url)
|
def add_http_protocol(url)
|
||||||
@@ -71,8 +72,8 @@ def add_trailing_slash(url)
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Gets the string all elements in stringarray ends with
|
# Gets the string all elements in stringarray ends with
|
||||||
def get_equal_string_end(stringarray = [""])
|
def get_equal_string_end(stringarray = [''])
|
||||||
already_found = ""
|
already_found = ''
|
||||||
looping = true
|
looping = true
|
||||||
counter = -1
|
counter = -1
|
||||||
if stringarray.kind_of? Array and stringarray.length > 1
|
if stringarray.kind_of? Array and stringarray.length > 1
|
||||||
@@ -97,15 +98,15 @@ end
|
|||||||
|
|
||||||
# Since ruby 1.9.2, URI::escape is obsolete
|
# 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
|
# See http://rosettacode.org/wiki/URL_encoding#Ruby and http://www.ruby-forum.com/topic/207489
|
||||||
if RUBY_VERSION >= "1.9.2"
|
if RUBY_VERSION >= '1.9.2'
|
||||||
module URI
|
module URI
|
||||||
def self.escape(str)
|
def self.escape(str)
|
||||||
URI.encode_www_form_component(str).gsub("+", "%20")
|
URI.encode_www_form_component(str).gsub('+', '%20')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if RUBY_VERSION < "1.9"
|
if RUBY_VERSION < '1.9'
|
||||||
class Array
|
class Array
|
||||||
# Fix for grep with symbols in ruby <= 1.8.7
|
# Fix for grep with symbols in ruby <= 1.8.7
|
||||||
def _grep_(regexp)
|
def _grep_(regexp)
|
||||||
@@ -128,25 +129,25 @@ require_files_from_directory(UPDATER_LIB_DIR)
|
|||||||
if @updater
|
if @updater
|
||||||
REVISION = @updater.local_revision_number()
|
REVISION = @updater.local_revision_number()
|
||||||
else
|
else
|
||||||
REVISION = "NA"
|
REVISION = 'NA'
|
||||||
end
|
end
|
||||||
|
|
||||||
# our 1337 banner
|
# our 1337 banner
|
||||||
def banner()
|
def banner
|
||||||
puts '____________________________________________________'
|
puts '____________________________________________________'
|
||||||
puts " __ _______ _____ "
|
puts ' __ _______ _____ '
|
||||||
puts " \\ \\ / / __ \\ / ____| "
|
puts ' \\ \\ / / __ \\ / ____| '
|
||||||
puts " \\ \\ /\\ / /| |__) | (___ ___ __ _ _ __ "
|
puts ' \\ \\ /\\ / /| |__) | (___ ___ __ _ _ __ '
|
||||||
puts " \\ \\/ \\/ / | ___/ \\___ \\ / __|/ _` | '_ \\ "
|
puts ' \\ \\/ \\/ / | ___/ \\___ \\ / __|/ _` | \'_ \\ '
|
||||||
puts " \\ /\\ / | | ____) | (__| (_| | | | |"
|
puts ' \\ /\\ / | | ____) | (__| (_| | | | |'
|
||||||
puts " \\/ \\/ |_| |_____/ \\___|\\__,_|_| |_| v#{WPSCAN_VERSION}r#{REVISION}"
|
puts " \\/ \\/ |_| |_____/ \\___|\\__,_|_| |_| v#{WPSCAN_VERSION}r#{REVISION}"
|
||||||
puts
|
puts
|
||||||
puts " WordPress Security Scanner by the WPScan Team"
|
puts ' WordPress Security Scanner by the WPScan Team'
|
||||||
puts " Sponsored by the RandomStorm Open Source Initiative"
|
puts ' Sponsored by the RandomStorm Open Source Initiative'
|
||||||
puts '_____________________________________________________'
|
puts '_____________________________________________________'
|
||||||
puts
|
puts
|
||||||
if RUBY_VERSION < "1.9"
|
if RUBY_VERSION < '1.9'
|
||||||
puts "[WARNING] Ruby < 1.9 not officially supported, please upgrade."
|
puts '[WARNING] Ruby < 1.9 not officially supported, please upgrade.'
|
||||||
puts
|
puts
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -165,16 +166,16 @@ end
|
|||||||
|
|
||||||
def get_metasploit_url(module_path)
|
def get_metasploit_url(module_path)
|
||||||
# remove leading slash
|
# remove leading slash
|
||||||
module_path = module_path.sub(/^\//, "")
|
module_path = module_path.sub(/^\//, '')
|
||||||
"http://www.metasploit.com/modules/#{module_path}"
|
"http://www.metasploit.com/modules/#{module_path}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Override for puts to enable logging
|
# Override for puts to enable logging
|
||||||
def puts(o = "")
|
def puts(o = '')
|
||||||
# remove color for logging
|
# remove color for logging
|
||||||
if o.respond_to?("gsub")
|
if o.respond_to?('gsub')
|
||||||
temp = o.gsub(/\e\[\d+m(.*)?\e\[0m/, '\1')
|
temp = o.gsub(/\e\[\d+m(.*)?\e\[0m/, '\1')
|
||||||
File.open(LOG_FILE, "a+") { |f| f.puts(temp) }
|
File.open(LOG_FILE, 'a+') { |f| f.puts(temp) }
|
||||||
end
|
end
|
||||||
super(o)
|
super(o)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
#--
|
#--
|
||||||
# WPScan - WordPress Security Scanner
|
# WPScan - WordPress Security Scanner
|
||||||
# Copyright (C) 2012-2013
|
# Copyright (C) 2012-2013
|
||||||
@@ -47,7 +48,7 @@ rescue LoadError => e
|
|||||||
if missing_gem
|
if missing_gem
|
||||||
if missing_gem =~ /nokogiri/i
|
if missing_gem =~ /nokogiri/i
|
||||||
puts
|
puts
|
||||||
puts "Nokogiri needs some packets, please run 'sudo apt-get install libxml2 libxml2-dev libxslt1-dev' to install them. Then run the command below"
|
puts 'Nokogiri needs some packets, please run \'sudo apt-get install libxml2 libxml2-dev libxslt1-dev\' to install them. Then run the command below'
|
||||||
puts
|
puts
|
||||||
end
|
end
|
||||||
puts "[TIP] Try to run 'gem install #{missing_gem}' or 'gem install --user-install #{missing_gem}'. If you still get an error, Please see README file or https://github.com/wpscanteam/wpscan"
|
puts "[TIP] Try to run 'gem install #{missing_gem}' or 'gem install --user-install #{missing_gem}'. If you still get an error, Please see README file or https://github.com/wpscanteam/wpscan"
|
||||||
@@ -55,7 +56,7 @@ rescue LoadError => e
|
|||||||
exit(1)
|
exit(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
if Typhoeus::VERSION == "0.4.0"
|
if Typhoeus::VERSION == '0.4.0'
|
||||||
puts "Typhoeus 0.4.0 detected, please update the gem otherwise wpscan will not work correctly"
|
puts 'Typhoeus 0.4.0 detected, please update the gem otherwise wpscan will not work correctly'
|
||||||
exit(1)
|
exit(1)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
#--
|
#--
|
||||||
# WPScan - WordPress Security Scanner
|
# WPScan - WordPress Security Scanner
|
||||||
# Copyright (C) 2012-2013
|
# Copyright (C) 2012-2013
|
||||||
@@ -24,7 +25,8 @@ class GitUpdater < Updater
|
|||||||
%x[git #{repo_directory_arguments()} status 2>&1] =~ /On branch/ ? true : false
|
%x[git #{repo_directory_arguments()} status 2>&1] =~ /On branch/ ? true : false
|
||||||
end
|
end
|
||||||
|
|
||||||
# Git has not a revsion number like SVN, so we will take the 7 first chars of the last commit hash
|
# Git has not a revsion number like SVN,
|
||||||
|
# so we will take the 7 first chars of the last commit hash
|
||||||
def local_revision_number
|
def local_revision_number
|
||||||
git_log = %x[git #{repo_directory_arguments()} log -1 2>&1]
|
git_log = %x[git #{repo_directory_arguments()} log -1 2>&1]
|
||||||
git_log[/commit ([0-9a-z]{7})/i, 1].to_s
|
git_log[/commit ([0-9a-z]{7})/i, 1].to_s
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
#--
|
#--
|
||||||
# WPScan - WordPress Security Scanner
|
# WPScan - WordPress Security Scanner
|
||||||
# Copyright (C) 2012-2013
|
# Copyright (C) 2012-2013
|
||||||
@@ -21,7 +22,7 @@ require File.expand_path(File.dirname(__FILE__) + '/updater')
|
|||||||
class SvnUpdater < Updater
|
class SvnUpdater < Updater
|
||||||
|
|
||||||
REVISION_PATTERN = /revision="(\d+)"/i
|
REVISION_PATTERN = /revision="(\d+)"/i
|
||||||
TRUNK_URL = "https://github.com/wpscanteam/wpscan"
|
TRUNK_URL = 'https://github.com/wpscanteam/wpscan'
|
||||||
|
|
||||||
def is_installed?
|
def is_installed?
|
||||||
%x[svn info "#@repo_directory" --xml 2>&1] =~ /revision=/ ? true : false
|
%x[svn info "#@repo_directory" --xml 2>&1] =~ /revision=/ ? true : false
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
#--
|
#--
|
||||||
# WPScan - WordPress Security Scanner
|
# WPScan - WordPress Security Scanner
|
||||||
# Copyright (C) 2012-2013
|
# Copyright (C) 2012-2013
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
#--
|
#--
|
||||||
# WPScan - WordPress Security Scanner
|
# WPScan - WordPress Security Scanner
|
||||||
# Copyright (C) 2012-2013
|
# Copyright (C) 2012-2013
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
|
#
|
||||||
# WPScan - WordPress Security Scanner
|
# WPScan - WordPress Security Scanner
|
||||||
# Copyright (C) 2012-2013
|
# Copyright (C) 2012-2013
|
||||||
#
|
#
|
||||||
@@ -18,13 +20,11 @@
|
|||||||
class CheckerPlugin < Plugin
|
class CheckerPlugin < Plugin
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
super(
|
super(author: 'WPScanTeam - @erwanlr')
|
||||||
:author => "@wpscanteam - @erwanlr"
|
|
||||||
)
|
|
||||||
|
|
||||||
register_options(
|
register_options(
|
||||||
["--check-vuln-ref-urls", "--cvru", "Check all the vulnerabilities reference urls for 404"],
|
['--check-vuln-ref-urls', '--cvru', 'Check all the vulnerabilities reference urls for 404'],
|
||||||
["--check-local-vulnerable-files LOCAL_DIRECTORY", "--clvf", "Perform a recursive scan in the LOCAL_DIRECTORY to find vulnerable files or shells"]
|
['--check-local-vulnerable-files LOCAL_DIRECTORY', '--clvf', 'Perform a recursive scan in the LOCAL_DIRECTORY to find vulnerable files or shells']
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -39,11 +39,11 @@ class CheckerPlugin < Plugin
|
|||||||
end
|
end
|
||||||
|
|
||||||
def check_vuln_ref_urls
|
def check_vuln_ref_urls
|
||||||
vuln_ref_files = [ PLUGINS_VULNS_FILE , THEMES_VULNS_FILE, WP_VULNS_FILE ]
|
vuln_ref_files = [PLUGINS_VULNS_FILE, THEMES_VULNS_FILE, WP_VULNS_FILE]
|
||||||
error_codes = [404, 500, 403]
|
error_codes = [404, 500, 403]
|
||||||
not_found_regexp = %r{No Results Found|error 404|ID Invalid or Not Found}i
|
not_found_regexp = %r{No Results Found|error 404|ID Invalid or Not Found}i
|
||||||
|
|
||||||
puts "[+] Checking vulnerabilities reference urls"
|
puts '[+] Checking vulnerabilities reference urls'
|
||||||
|
|
||||||
vuln_ref_files.each do |vuln_ref_file|
|
vuln_ref_files.each do |vuln_ref_file|
|
||||||
xml = Nokogiri::XML(File.open(vuln_ref_file)) do |config|
|
xml = Nokogiri::XML(File.open(vuln_ref_file)) do |config|
|
||||||
@@ -51,7 +51,7 @@ class CheckerPlugin < Plugin
|
|||||||
end
|
end
|
||||||
|
|
||||||
urls = []
|
urls = []
|
||||||
xml.xpath("//reference").each { |node| urls << node.text }
|
xml.xpath('//reference').each { |node| urls << node.text }
|
||||||
|
|
||||||
urls.uniq!
|
urls.uniq!
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ class CheckerPlugin < Plugin
|
|||||||
number_of_urls = urls.size
|
number_of_urls = urls.size
|
||||||
|
|
||||||
urls.each do |url|
|
urls.each do |url|
|
||||||
request = browser.forge_request(url, { :cache_timeout => 0, :follow_location => true })
|
request = browser.forge_request(url, { cache_timeout: 0, follow_location: true })
|
||||||
request_count += 1
|
request_count += 1
|
||||||
|
|
||||||
request.on_complete do |response|
|
request.on_complete do |response|
|
||||||
@@ -95,11 +95,11 @@ class CheckerPlugin < Plugin
|
|||||||
if Dir::exist?(dir_to_scan)
|
if Dir::exist?(dir_to_scan)
|
||||||
xml_file = LOCAL_FILES_FILE
|
xml_file = LOCAL_FILES_FILE
|
||||||
local_hashes = {}
|
local_hashes = {}
|
||||||
file_extension_to_scan = "*.{js,php,swf,html,htm}"
|
file_extension_to_scan = '*.{js,php,swf,html,htm}'
|
||||||
|
|
||||||
print "[+] Generating local hashes ... "
|
print '[+] Generating local hashes ... '
|
||||||
|
|
||||||
Dir[File::join(dir_to_scan, "**", file_extension_to_scan)].each do |filename|
|
Dir[File::join(dir_to_scan, '**', file_extension_to_scan)].each do |filename|
|
||||||
sha1sum = Digest::SHA1.file(filename).hexdigest
|
sha1sum = Digest::SHA1.file(filename).hexdigest
|
||||||
|
|
||||||
if local_hashes.has_key?(sha1sum)
|
if local_hashes.has_key?(sha1sum)
|
||||||
@@ -109,36 +109,36 @@ class CheckerPlugin < Plugin
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
puts "done."
|
puts 'done.'
|
||||||
|
|
||||||
puts "[+] Checking for vulnerable files ..."
|
puts '[+] Checking for vulnerable files ...'
|
||||||
|
|
||||||
xml = Nokogiri::XML(File.open(xml_file)) do |config|
|
xml = Nokogiri::XML(File.open(xml_file)) do |config|
|
||||||
config.noblanks
|
config.noblanks
|
||||||
end
|
end
|
||||||
|
|
||||||
xml.xpath("//hash").each do |node|
|
xml.xpath('//hash').each do |node|
|
||||||
sha1sum = node.attribute("sha1").text
|
sha1sum = node.attribute('sha1').text
|
||||||
|
|
||||||
if local_hashes.has_key?(sha1sum)
|
if local_hashes.has_key?(sha1sum)
|
||||||
local_filenames = local_hashes[sha1sum]
|
local_filenames = local_hashes[sha1sum]
|
||||||
vuln_title = node.search("title").text
|
vuln_title = node.search('title').text
|
||||||
vuln_filename = node.search("file").text
|
vuln_filename = node.search('file').text
|
||||||
vuln_refrence = node.search("reference").text
|
vuln_refrence = node.search('reference').text
|
||||||
|
|
||||||
puts " #{vuln_filename} found :"
|
puts " #{vuln_filename} found :"
|
||||||
puts " | Location(s):"
|
puts ' | Location(s):'
|
||||||
local_filenames.each do |file|
|
local_filenames.each do |file|
|
||||||
puts " | - #{file}"
|
puts " | - #{file}"
|
||||||
end
|
end
|
||||||
puts " |"
|
puts ' |'
|
||||||
puts " | Title: #{vuln_title}"
|
puts " | Title: #{vuln_title}"
|
||||||
puts " | Refrence: #{vuln_refrence}" if !vuln_refrence.empty?
|
puts " | Refrence: #{vuln_refrence}" if !vuln_refrence.empty?
|
||||||
puts
|
puts
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
puts "done."
|
puts 'done.'
|
||||||
|
|
||||||
else
|
else
|
||||||
puts "The supplied directory '#{dir_to_scan}' does not exist"
|
puts "The supplied directory '#{dir_to_scan}' does not exist"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#!/usr/bin/env ruby
|
# encoding: UTF-8
|
||||||
|
|
||||||
#--
|
#--
|
||||||
# WPScan - WordPress Security Scanner
|
# WPScan - WordPress Security Scanner
|
||||||
# Copyright (C) 2012-2013
|
# Copyright (C) 2012-2013
|
||||||
@@ -26,14 +25,14 @@ class GenerateList
|
|||||||
# type = themes | plugins
|
# type = themes | plugins
|
||||||
def initialize(type, verbose)
|
def initialize(type, verbose)
|
||||||
if type =~ /plugins/i
|
if type =~ /plugins/i
|
||||||
@type = "plugin"
|
@type = 'plugin'
|
||||||
@svn_url = "http://plugins.svn.wordpress.org/"
|
@svn_url = 'http://plugins.svn.wordpress.org/'
|
||||||
@popular_url = "http://wordpress.org/extend/plugins/browse/popular/"
|
@popular_url = 'http://wordpress.org/extend/plugins/browse/popular/'
|
||||||
@popular_regex = %r{<h3><a href="http://wordpress.org/extend/plugins/(.+)/">.+</a></h3>}i
|
@popular_regex = %r{<h3><a href="http://wordpress.org/extend/plugins/(.+)/">.+</a></h3>}i
|
||||||
elsif type =~ /themes/i
|
elsif type =~ /themes/i
|
||||||
@type = "theme"
|
@type = 'theme'
|
||||||
@svn_url = "http://themes.svn.wordpress.org/"
|
@svn_url = 'http://themes.svn.wordpress.org/'
|
||||||
@popular_url = "http://wordpress.org/extend/themes/browse/popular/"
|
@popular_url = 'http://wordpress.org/extend/themes/browse/popular/'
|
||||||
@popular_regex = %r{<h3><a href="http://wordpress.org/extend/themes/(.+)">.+</a></h3>}i
|
@popular_regex = %r{<h3><a href="http://wordpress.org/extend/themes/(.+)">.+</a></h3>}i
|
||||||
else
|
else
|
||||||
raise "Type #{type} not defined"
|
raise "Type #{type} not defined"
|
||||||
@@ -45,24 +44,24 @@ class GenerateList
|
|||||||
|
|
||||||
def set_file_name(type)
|
def set_file_name(type)
|
||||||
case @type
|
case @type
|
||||||
when "plugin"
|
when 'plugin'
|
||||||
case type
|
case type
|
||||||
when :full
|
when :full
|
||||||
@file_name = PLUGINS_FULL_FILE
|
@file_name = PLUGINS_FULL_FILE
|
||||||
when :popular
|
when :popular
|
||||||
@file_name = PLUGINS_FILE
|
@file_name = PLUGINS_FILE
|
||||||
else
|
else
|
||||||
raise "Unknown type"
|
raise 'Unknown type'
|
||||||
end
|
end
|
||||||
when "theme"
|
when 'theme'
|
||||||
case type
|
case type
|
||||||
when :full
|
when :full
|
||||||
@file_name = THEMES_FULL_FILE
|
@file_name = THEMES_FULL_FILE
|
||||||
when :popular
|
when :popular
|
||||||
@file_name = THEMES_FILE
|
@file_name = THEMES_FILE
|
||||||
else
|
else
|
||||||
raise "Unknown type"
|
raise 'Unknown type'
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
raise "Unknown type #@type"
|
raise "Unknown type #@type"
|
||||||
end
|
end
|
||||||
@@ -87,7 +86,7 @@ class GenerateList
|
|||||||
page_count = 1
|
page_count = 1
|
||||||
queue_count = 0
|
queue_count = 0
|
||||||
|
|
||||||
(1...(pages.to_i+1)).each do |page|
|
(1...(pages.to_i + 1)).each do |page|
|
||||||
# First page has another URL
|
# First page has another URL
|
||||||
url = (page == 1) ? @popular_url : @popular_url + 'page/' + page.to_s + '/'
|
url = (page == 1) ? @popular_url : @popular_url + 'page/' + page.to_s + '/'
|
||||||
request = @browser.forge_request(url)
|
request = @browser.forge_request(url)
|
||||||
@@ -95,7 +94,7 @@ class GenerateList
|
|||||||
queue_count += 1
|
queue_count += 1
|
||||||
|
|
||||||
request.on_complete do |response|
|
request.on_complete do |response|
|
||||||
puts "[+] Parsing page " + page_count.to_s if @verbose
|
puts "[+] Parsing page #{page_count}" if @verbose
|
||||||
page_count += 1
|
page_count += 1
|
||||||
response.body.scan(@popular_regex).each do |item|
|
response.body.scan(@popular_regex).each do |item|
|
||||||
puts "[+] Found popular #@type: #{item}" if @verbose
|
puts "[+] Found popular #@type: #{item}" if @verbose
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
|
#
|
||||||
# WPScan - WordPress Security Scanner
|
# WPScan - WordPress Security Scanner
|
||||||
# Copyright (C) 2012-2013
|
# Copyright (C) 2012-2013
|
||||||
#
|
#
|
||||||
@@ -18,18 +20,16 @@
|
|||||||
class ListGeneratorPlugin < Plugin
|
class ListGeneratorPlugin < Plugin
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
super(
|
super(author: 'WPScanTeam - @FireFart')
|
||||||
:author => "WPScanTeam - @FireFart"
|
|
||||||
)
|
|
||||||
|
|
||||||
register_options(
|
register_options(
|
||||||
["--generate-plugin-list [NUMBER_OF_PAGES]", "--gpl", Integer, "Generate a new data/plugins.txt file. (supply number of *pages* to parse, default : 150)"],
|
['--generate-plugin-list [NUMBER_OF_PAGES]', '--gpl', Integer, 'Generate a new data/plugins.txt file. (supply number of *pages* to parse, default : 150)'],
|
||||||
["--generate-full-plugin-list", "--gfpl", "Generate a new full data/plugins.txt file"],
|
['--generate-full-plugin-list', '--gfpl', 'Generate a new full data/plugins.txt file'],
|
||||||
|
|
||||||
["--generate-theme-list [NUMBER_OF_PAGES]", "--gtl", Integer, "Generate a new data/themes.txt file. (supply number of *pages* to parse, default : 150)"],
|
['--generate-theme-list [NUMBER_OF_PAGES]', '--gtl', Integer, 'Generate a new data/themes.txt file. (supply number of *pages* to parse, default : 150)'],
|
||||||
["--generate-full-theme-list", "--gftl", "Generate a new full data/themes.txt file"],
|
['--generate-full-theme-list', '--gftl', 'Generate a new full data/themes.txt file'],
|
||||||
|
|
||||||
["--generate-all", "--ga", "Generate a new full plugins, full themes, popular plugins and popular themes list"],
|
['--generate-all', '--ga', 'Generate a new full plugins, full themes, popular plugins and popular themes list']
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -40,13 +40,13 @@ class ListGeneratorPlugin < Plugin
|
|||||||
if options.has_key?(:generate_plugin_list) || generate_all
|
if options.has_key?(:generate_plugin_list) || generate_all
|
||||||
number_of_pages = options[:generate_plugin_list] || 150
|
number_of_pages = options[:generate_plugin_list] || 150
|
||||||
|
|
||||||
puts "[+] Generating new most popular plugin list"
|
puts '[+] Generating new most popular plugin list'
|
||||||
puts
|
puts
|
||||||
GenerateList.new('plugins', verbose).generate_popular_list(number_of_pages)
|
GenerateList.new('plugins', verbose).generate_popular_list(number_of_pages)
|
||||||
end
|
end
|
||||||
|
|
||||||
if options[:generate_full_plugin_list] || generate_all
|
if options[:generate_full_plugin_list] || generate_all
|
||||||
puts "[+] Generating new full plugin list"
|
puts '[+] Generating new full plugin list'
|
||||||
puts
|
puts
|
||||||
GenerateList.new('plugins', verbose).generate_full_list
|
GenerateList.new('plugins', verbose).generate_full_list
|
||||||
end
|
end
|
||||||
@@ -54,13 +54,13 @@ class ListGeneratorPlugin < Plugin
|
|||||||
if options.has_key?(:generate_theme_list) || generate_all
|
if options.has_key?(:generate_theme_list) || generate_all
|
||||||
number_of_pages = options[:generate_theme_list] || 150
|
number_of_pages = options[:generate_theme_list] || 150
|
||||||
|
|
||||||
puts "[+] Generating new most popular theme list"
|
puts '[+] Generating new most popular theme list'
|
||||||
puts
|
puts
|
||||||
GenerateList.new('themes', verbose).generate_popular_list(number_of_pages)
|
GenerateList.new('themes', verbose).generate_popular_list(number_of_pages)
|
||||||
end
|
end
|
||||||
|
|
||||||
if options[:generate_full_theme_list] || generate_all
|
if options[:generate_full_theme_list] || generate_all
|
||||||
puts "[+] Generating new full theme list"
|
puts '[+] Generating new full theme list'
|
||||||
puts
|
puts
|
||||||
GenerateList.new('themes', verbose).generate_full_list
|
GenerateList.new('themes', verbose).generate_full_list
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#!/usr/bin/env ruby
|
# encoding: UTF-8
|
||||||
|
|
||||||
#--
|
#--
|
||||||
# WPScan - WordPress Security Scanner
|
# WPScan - WordPress Security Scanner
|
||||||
# Copyright (C) 2012-2013
|
# Copyright (C) 2012-2013
|
||||||
@@ -24,12 +23,12 @@ class SvnParser
|
|||||||
attr_accessor :verbose, :svn_root, :keep_empty_dirs
|
attr_accessor :verbose, :svn_root, :keep_empty_dirs
|
||||||
|
|
||||||
def initialize(svn_root)
|
def initialize(svn_root)
|
||||||
@svn_root = svn_root
|
@svn_root = svn_root
|
||||||
@svn_browser = Browser.instance
|
@svn_browser = Browser.instance
|
||||||
@svn_hydra = @svn_browser.hydra
|
@svn_hydra = @svn_browser.hydra
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse()
|
def parse
|
||||||
get_root_directories
|
get_root_directories
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -38,11 +37,13 @@ class SvnParser
|
|||||||
|
|
||||||
# Gets all directories in the SVN root
|
# Gets all directories in the SVN root
|
||||||
def get_root_directories
|
def get_root_directories
|
||||||
dirs = []
|
dirs = []
|
||||||
rootindex = @svn_browser.get(@svn_root).body
|
rootindex = @svn_browser.get(@svn_root).body
|
||||||
|
|
||||||
rootindex.scan(%r{<li><a href=".+">(.+)/</a></li>}i).each do |dir|
|
rootindex.scan(%r{<li><a href=".+">(.+)/</a></li>}i).each do |dir|
|
||||||
dirs << dir[0]
|
dirs << dir[0]
|
||||||
end
|
end
|
||||||
|
|
||||||
dirs.sort!
|
dirs.sort!
|
||||||
dirs.uniq
|
dirs.uniq
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
#--
|
#--
|
||||||
# WPScan - WordPress Security Scanner
|
# WPScan - WordPress Security Scanner
|
||||||
# Copyright (C) 2012-2013
|
# Copyright (C) 2012-2013
|
||||||
@@ -19,33 +20,33 @@
|
|||||||
require File.expand_path(File.dirname(__FILE__) + '/../common_helper')
|
require File.expand_path(File.dirname(__FILE__) + '/../common_helper')
|
||||||
|
|
||||||
require_files_from_directory(WPSTOOLS_LIB_DIR)
|
require_files_from_directory(WPSTOOLS_LIB_DIR)
|
||||||
require_files_from_directory(WPSTOOLS_PLUGINS_DIR, "**/*.rb")
|
require_files_from_directory(WPSTOOLS_PLUGINS_DIR, '**/*.rb')
|
||||||
|
|
||||||
def usage()
|
def usage
|
||||||
script_name = $0
|
script_name = $0
|
||||||
puts
|
puts
|
||||||
puts "-h for further help."
|
puts '-h for further help.'
|
||||||
puts
|
puts
|
||||||
puts "Examples:"
|
puts 'Examples:'
|
||||||
puts
|
puts
|
||||||
puts "- Generate a new 'most popular' plugin list, up to 150 pages ..."
|
puts "- Generate a new 'most popular' plugin list, up to 150 pages ..."
|
||||||
puts "ruby #{script_name} --generate-plugin-list 150"
|
puts "ruby #{script_name} --generate-plugin-list 150"
|
||||||
puts
|
puts
|
||||||
puts "- Generate a new full plugin list"
|
puts '- Generate a new full plugin list'
|
||||||
puts "ruby #{script_name} --generate-full-plugin-list"
|
puts "ruby #{script_name} --generate-full-plugin-list"
|
||||||
puts
|
puts
|
||||||
puts "- Generate a new 'most popular' theme list, up to 150 pages ..."
|
puts "- Generate a new 'most popular' theme list, up to 150 pages ..."
|
||||||
puts "ruby #{script_name} --generate-theme-list 150"
|
puts "ruby #{script_name} --generate-theme-list 150"
|
||||||
puts
|
puts
|
||||||
puts "- Generate a new full theme list"
|
puts '- Generate a new full theme list'
|
||||||
puts "ruby #{script_name} --generate-full-theme-list"
|
puts "ruby #{script_name} --generate-full-theme-list"
|
||||||
puts
|
puts
|
||||||
puts "- Generate all list"
|
puts '- Generate all list'
|
||||||
puts "ruby #{script_name} --generate-all"
|
puts "ruby #{script_name} --generate-all"
|
||||||
puts
|
puts
|
||||||
puts "Locally scan a wordpress installation for vulnerable files or shells"
|
puts 'Locally scan a wordpress installation for vulnerable files or shells'
|
||||||
puts "ruby #{script_name} --check-local-vulnerable-files /var/www/wordpress/"
|
puts "ruby #{script_name} --check-local-vulnerable-files /var/www/wordpress/"
|
||||||
puts
|
puts
|
||||||
puts "See README for further information."
|
puts 'See README for further information.'
|
||||||
puts
|
puts
|
||||||
end
|
end
|
||||||
|
|||||||
156
wpscan.rb
156
wpscan.rb
@@ -19,17 +19,17 @@
|
|||||||
#++
|
#++
|
||||||
|
|
||||||
$: << '.'
|
$: << '.'
|
||||||
require File.dirname(__FILE__) +'/lib/wpscan/wpscan_helper'
|
require File.dirname(__FILE__) + '/lib/wpscan/wpscan_helper'
|
||||||
|
|
||||||
def output_vulnerabilities(vulns)
|
def output_vulnerabilities(vulns)
|
||||||
vulns.each do |vulnerability|
|
vulns.each do |vulnerability|
|
||||||
puts
|
puts
|
||||||
puts " | " + red("* Title: #{vulnerability.title}")
|
puts ' | ' + red("* Title: #{vulnerability.title}")
|
||||||
vulnerability.references.each do |r|
|
vulnerability.references.each do |r|
|
||||||
puts " | " + red("* Reference: #{r}")
|
puts ' | ' + red("* Reference: #{r}")
|
||||||
end
|
end
|
||||||
vulnerability.metasploit_modules.each do |m|
|
vulnerability.metasploit_modules.each do |m|
|
||||||
puts " | " + red("* Metasploit module: #{get_metasploit_url(m)}")
|
puts ' | ' + red("* Metasploit module: #{get_metasploit_url(m)}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -61,8 +61,8 @@ begin
|
|||||||
end
|
end
|
||||||
puts @updater.update()
|
puts @updater.update()
|
||||||
else
|
else
|
||||||
puts "Svn / Git not installed, or wpscan has not been installed with one of them."
|
puts 'Svn / Git not installed, or wpscan has not been installed with one of them.'
|
||||||
puts "Update aborted"
|
puts 'Update aborted'
|
||||||
end
|
end
|
||||||
exit(1)
|
exit(1)
|
||||||
end
|
end
|
||||||
@@ -89,37 +89,37 @@ begin
|
|||||||
puts
|
puts
|
||||||
else
|
else
|
||||||
puts "The remote host tried to redirect us to #{redirection}"
|
puts "The remote host tried to redirect us to #{redirection}"
|
||||||
puts "Do you want follow the redirection ? [y/n]"
|
puts 'Do you want follow the redirection ? [y/n]'
|
||||||
end
|
end
|
||||||
|
|
||||||
if wpscan_options.follow_redirection or Readline.readline =~ /^y/i
|
if wpscan_options.follow_redirection or Readline.readline =~ /^y/i
|
||||||
wpscan_options.url = redirection
|
wpscan_options.url = redirection
|
||||||
wp_target = WpTarget.new(redirection, wpscan_options.to_h)
|
wp_target = WpTarget.new(redirection, wpscan_options.to_h)
|
||||||
else
|
else
|
||||||
puts "Scan aborted"
|
puts 'Scan aborted'
|
||||||
exit
|
exit
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if wp_target.has_basic_auth? && wpscan_options.basic_auth.nil?
|
if wp_target.has_basic_auth? && wpscan_options.basic_auth.nil?
|
||||||
raise "A basic authentification is required, please provide it with --basic-auth <login:password>"
|
raise 'A basic authentification is required, please provide it with --basic-auth <login:password>'
|
||||||
end
|
end
|
||||||
|
|
||||||
# Remote website is wordpress?
|
# Remote website is wordpress?
|
||||||
unless wpscan_options.force
|
unless wpscan_options.force
|
||||||
unless wp_target.wordpress?
|
unless wp_target.wordpress?
|
||||||
raise "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
|
||||||
end
|
end
|
||||||
|
|
||||||
unless wp_target.wp_content_dir
|
unless wp_target.wp_content_dir
|
||||||
raise "The wp_content_dir has not been found, please supply it with --wp-content-dir"
|
raise 'The wp_content_dir has not been found, please supply it with --wp-content-dir'
|
||||||
end
|
end
|
||||||
|
|
||||||
unless wp_target.wp_plugins_dir_exists?
|
unless wp_target.wp_plugins_dir_exists?
|
||||||
puts "The plugins directory '#{wp_target.wp_plugins_dir}' does not exist."
|
puts "The plugins directory '#{wp_target.wp_plugins_dir}' does not exist."
|
||||||
puts "You can specify one per command line option (don't forget to include the wp-content directory if needed)"
|
puts 'You can specify one per command line option (don\'t forget to include the wp-content directory if needed)'
|
||||||
puts "Continue? [y/n]"
|
puts 'Continue? [y/n]'
|
||||||
unless Readline.readline =~ /^y/i
|
unless Readline.readline =~ /^y/i
|
||||||
exit
|
exit
|
||||||
end
|
end
|
||||||
@@ -134,33 +134,33 @@ begin
|
|||||||
wp_theme = wp_target.theme
|
wp_theme = wp_target.theme
|
||||||
if wp_theme
|
if wp_theme
|
||||||
# Theme version is handled in wp_item.to_s
|
# Theme version is handled in wp_item.to_s
|
||||||
puts green("[+]") + " The WordPress theme in use is #{wp_theme}"
|
puts green('[+]') + " The WordPress theme in use is #{wp_theme}"
|
||||||
puts
|
puts
|
||||||
puts " | Name: #{wp_theme}" #this will also output the version number if detected
|
puts " | Name: #{wp_theme}" #this will also output the version number if detected
|
||||||
puts " | Location: #{wp_theme.get_url_without_filename}"
|
puts " | Location: #{wp_theme.get_url_without_filename}"
|
||||||
puts " | WordPress: #{wp_theme.wp_org_url}" if wp_theme.wp_org_item?
|
puts " | WordPress: #{wp_theme.wp_org_url}" if wp_theme.wp_org_item?
|
||||||
puts " | Directory listing enabled: Yes" if wp_theme.directory_listing?
|
puts ' | Directory listing enabled: Yes' if wp_theme.directory_listing?
|
||||||
puts " | Readme: #{wp_theme.readme_url}" if wp_theme.has_readme?
|
puts " | Readme: #{wp_theme.readme_url}" if wp_theme.has_readme?
|
||||||
puts " | Changelog: #{wp_theme.changelog_url}" if wp_theme.has_changelog?
|
puts " | Changelog: #{wp_theme.changelog_url}" if wp_theme.has_changelog?
|
||||||
|
|
||||||
theme_vulnerabilities = wp_theme.vulnerabilities
|
theme_vulnerabilities = wp_theme.vulnerabilities
|
||||||
unless theme_vulnerabilities.empty?
|
unless theme_vulnerabilities.empty?
|
||||||
puts red("[!]") + " We have identified #{theme_vulnerabilities.size} vulnerabilities for this theme :"
|
puts red('[!]') + " We have identified #{theme_vulnerabilities.size} vulnerabilities for this theme :"
|
||||||
output_vulnerabilities(theme_vulnerabilities)
|
output_vulnerabilities(theme_vulnerabilities)
|
||||||
end
|
end
|
||||||
puts
|
puts
|
||||||
end
|
end
|
||||||
|
|
||||||
if wp_target.has_readme?
|
if wp_target.has_readme?
|
||||||
puts red("[!]") + " The WordPress '#{wp_target.readme_url}' file exists"
|
puts red('[!]') + " The WordPress '#{wp_target.readme_url}' file exists"
|
||||||
end
|
end
|
||||||
|
|
||||||
if wp_target.has_full_path_disclosure?
|
if wp_target.has_full_path_disclosure?
|
||||||
puts red("[!]") + " Full Path Disclosure (FPD) in '#{wp_target.full_path_disclosure_url}'"
|
puts red('[!]') + " Full Path Disclosure (FPD) in '#{wp_target.full_path_disclosure_url}'"
|
||||||
end
|
end
|
||||||
|
|
||||||
if wp_target.has_debug_log?
|
if wp_target.has_debug_log?
|
||||||
puts red("[!]") + " Debug log file found : #{wp_target.debug_log_url}"
|
puts red('[!]') + " Debug log file found : #{wp_target.debug_log_url}"
|
||||||
end
|
end
|
||||||
|
|
||||||
wp_target.config_backup.each do |file_url|
|
wp_target.config_backup.each do |file_url|
|
||||||
@@ -172,46 +172,46 @@ begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
if wp_target.is_multisite?
|
if wp_target.is_multisite?
|
||||||
puts green("[+]") + " This site seems to be a multisite (http://codex.wordpress.org/Glossary#Multisite)"
|
puts green('[+]') + ' This site seems to be a multisite (http://codex.wordpress.org/Glossary#Multisite)'
|
||||||
end
|
end
|
||||||
|
|
||||||
if wp_target.registration_enabled?
|
if wp_target.registration_enabled?
|
||||||
puts green("[+]") + " User registration is enabled"
|
puts green('[+]') + ' User registration is enabled'
|
||||||
end
|
end
|
||||||
|
|
||||||
if wp_target.has_xml_rpc?
|
if wp_target.has_xml_rpc?
|
||||||
puts green("[+]") + " XML-RPC Interface available under #{wp_target.xml_rpc_url}"
|
puts green('[+]') + " XML-RPC Interface available under #{wp_target.xml_rpc_url}"
|
||||||
end
|
end
|
||||||
|
|
||||||
if wp_target.has_malwares?
|
if wp_target.has_malwares?
|
||||||
malwares = wp_target.malwares
|
malwares = wp_target.malwares
|
||||||
puts red("[!]") + " #{malwares.size} malware(s) found :"
|
puts red('[!]') + " #{malwares.size} malware(s) found :"
|
||||||
|
|
||||||
malwares.each do |malware_url|
|
malwares.each do |malware_url|
|
||||||
puts
|
puts
|
||||||
puts " | " + red("#{malware_url}")
|
puts ' | ' + red("#{malware_url}")
|
||||||
end
|
end
|
||||||
puts
|
puts
|
||||||
end
|
end
|
||||||
|
|
||||||
wp_version = wp_target.version
|
wp_version = wp_target.version
|
||||||
if wp_version
|
if wp_version
|
||||||
puts green("[+]") + " WordPress version #{wp_version.number} identified from #{wp_version.discovery_method}"
|
puts green('[+]') + " WordPress version #{wp_version.number} identified from #{wp_version.discovery_method}"
|
||||||
|
|
||||||
version_vulnerabilities = wp_version.vulnerabilities
|
version_vulnerabilities = wp_version.vulnerabilities
|
||||||
|
|
||||||
unless version_vulnerabilities.empty?
|
unless version_vulnerabilities.empty?
|
||||||
puts
|
puts
|
||||||
puts red("[!]") + " We have identified #{version_vulnerabilities.size} vulnerabilities from the version number :"
|
puts red('[!]') + " We have identified #{version_vulnerabilities.size} vulnerabilities from the version number :"
|
||||||
output_vulnerabilities(version_vulnerabilities)
|
output_vulnerabilities(version_vulnerabilities)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if wpscan_options.enumerate_plugins == nil and wpscan_options.enumerate_only_vulnerable_plugins == nil
|
if wpscan_options.enumerate_plugins == nil and wpscan_options.enumerate_only_vulnerable_plugins == nil
|
||||||
puts
|
puts
|
||||||
puts green("[+]") + " Enumerating plugins from passive detection ... "
|
puts green('[+]') + ' Enumerating plugins from passive detection ... '
|
||||||
|
|
||||||
plugins = wp_target.plugins_from_passive_detection(:base_url => wp_target.uri, :wp_content_dir => wp_target.wp_content_dir)
|
plugins = wp_target.plugins_from_passive_detection(base_url: wp_target.uri, wp_content_dir: wp_target.wp_content_dir)
|
||||||
unless plugins.empty?
|
unless plugins.empty?
|
||||||
puts "#{plugins.size} found :"
|
puts "#{plugins.size} found :"
|
||||||
|
|
||||||
@@ -224,84 +224,84 @@ begin
|
|||||||
output_vulnerabilities(plugin.vulnerabilities)
|
output_vulnerabilities(plugin.vulnerabilities)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
puts "No plugins found :("
|
puts 'No plugins found :('
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Enumerate the installed plugins
|
# Enumerate the installed plugins
|
||||||
if wpscan_options.enumerate_plugins or wpscan_options.enumerate_only_vulnerable_plugins or wpscan_options.enumerate_all_plugins
|
if wpscan_options.enumerate_plugins or wpscan_options.enumerate_only_vulnerable_plugins or wpscan_options.enumerate_all_plugins
|
||||||
puts
|
puts
|
||||||
puts green("[+]") + " Enumerating installed plugins #{'(only vulnerable ones)' if wpscan_options.enumerate_only_vulnerable_plugins} ..."
|
puts green('[+]') + " Enumerating installed plugins #{'(only vulnerable ones)' if wpscan_options.enumerate_only_vulnerable_plugins} ..."
|
||||||
puts
|
puts
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
:base_url => wp_target.uri,
|
base_url: wp_target.uri,
|
||||||
:only_vulnerable_ones => wpscan_options.enumerate_only_vulnerable_plugins || false,
|
only_vulnerable_ones: wpscan_options.enumerate_only_vulnerable_plugins || false,
|
||||||
:show_progression => true,
|
show_progression: true,
|
||||||
:wp_content_dir => wp_target.wp_content_dir,
|
wp_content_dir: wp_target.wp_content_dir,
|
||||||
:error_404_hash => wp_target.error_404_hash,
|
error_404_hash: wp_target.error_404_hash,
|
||||||
:homepage_hash => wp_target.homepage_hash,
|
homepage_hash: wp_target.homepage_hash,
|
||||||
:wp_plugins_dir => wp_target.wp_plugins_dir,
|
wp_plugins_dir: wp_target.wp_plugins_dir,
|
||||||
:full => wpscan_options.enumerate_all_plugins,
|
full: wpscan_options.enumerate_all_plugins,
|
||||||
:exclude_content_based => wpscan_options.exclude_content_based
|
exclude_content_based: wpscan_options.exclude_content_based
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins = wp_target.plugins_from_aggressive_detection(options)
|
plugins = wp_target.plugins_from_aggressive_detection(options)
|
||||||
unless plugins.empty?
|
unless plugins.empty?
|
||||||
puts
|
puts
|
||||||
puts
|
puts
|
||||||
puts green("[+]") + " We found #{plugins.size.to_s} plugins:"
|
puts green('[+]') + " We found #{plugins.size.to_s} plugins:"
|
||||||
|
|
||||||
plugins.each do |plugin|
|
plugins.each do |plugin|
|
||||||
puts
|
puts
|
||||||
puts " | Name: #{plugin}" #this will also output the version number if detected
|
puts " | Name: #{plugin}" #this will also output the version number if detected
|
||||||
puts " | Location: #{plugin.get_url_without_filename}"
|
puts " | Location: #{plugin.get_url_without_filename}"
|
||||||
puts " | WordPress: #{plugin.wp_org_url}" if plugin.wp_org_item?
|
puts " | WordPress: #{plugin.wp_org_url}" if plugin.wp_org_item?
|
||||||
puts " | Directory listing enabled: Yes" if plugin.directory_listing?
|
puts ' | Directory listing enabled: Yes' if plugin.directory_listing?
|
||||||
puts " | Readme: #{plugin.readme_url}" if plugin.has_readme?
|
puts " | Readme: #{plugin.readme_url}" if plugin.has_readme?
|
||||||
puts " | Changelog: #{plugin.changelog_url}" if plugin.has_changelog?
|
puts " | Changelog: #{plugin.changelog_url}" if plugin.has_changelog?
|
||||||
|
|
||||||
output_vulnerabilities(plugin.vulnerabilities)
|
output_vulnerabilities(plugin.vulnerabilities)
|
||||||
|
|
||||||
if plugin.error_log?
|
if plugin.error_log?
|
||||||
puts " | " + red("[!]") + " A WordPress error_log file has been found : #{plugin.error_log_url}"
|
puts ' | ' + red('[!]') + " A WordPress error_log file has been found : #{plugin.error_log_url}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
puts
|
puts
|
||||||
puts "No plugins found :("
|
puts 'No plugins found :('
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Enumerate installed themes
|
# Enumerate installed themes
|
||||||
if wpscan_options.enumerate_themes or wpscan_options.enumerate_only_vulnerable_themes or wpscan_options.enumerate_all_themes
|
if wpscan_options.enumerate_themes or wpscan_options.enumerate_only_vulnerable_themes or wpscan_options.enumerate_all_themes
|
||||||
puts
|
puts
|
||||||
puts green("[+]") + " Enumerating installed themes #{'(only vulnerable ones)' if wpscan_options.enumerate_only_vulnerable_themes} ..."
|
puts green('[+]') + " Enumerating installed themes #{'(only vulnerable ones)' if wpscan_options.enumerate_only_vulnerable_themes} ..."
|
||||||
puts
|
puts
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
:base_url => wp_target.uri,
|
base_url: wp_target.uri,
|
||||||
:only_vulnerable_ones => wpscan_options.enumerate_only_vulnerable_themes || false,
|
only_vulnerable_ones: wpscan_options.enumerate_only_vulnerable_themes || false,
|
||||||
:show_progression => true,
|
show_progression: true,
|
||||||
:wp_content_dir => wp_target.wp_content_dir,
|
wp_content_dir: wp_target.wp_content_dir,
|
||||||
:error_404_hash => wp_target.error_404_hash,
|
error_404_hash: wp_target.error_404_hash,
|
||||||
:homepage_hash => wp_target.homepage_hash,
|
homepage_hash: wp_target.homepage_hash,
|
||||||
:full => wpscan_options.enumerate_all_themes,
|
full: wpscan_options.enumerate_all_themes,
|
||||||
:exclude_content_based => wpscan_options.exclude_content_based
|
exclude_content_based: wpscan_options.exclude_content_based
|
||||||
}
|
}
|
||||||
|
|
||||||
themes = wp_target.themes_from_aggressive_detection(options)
|
themes = wp_target.themes_from_aggressive_detection(options)
|
||||||
unless themes.empty?
|
unless themes.empty?
|
||||||
puts
|
puts
|
||||||
puts
|
puts
|
||||||
puts green("[+]") + " We found #{themes.size.to_s} themes:"
|
puts green('[+]') + " We found #{themes.size.to_s} themes:"
|
||||||
|
|
||||||
themes.each do |theme|
|
themes.each do |theme|
|
||||||
puts
|
puts
|
||||||
puts " | Name: #{theme}" #this will also output the version number if detected
|
puts " | Name: #{theme}" #this will also output the version number if detected
|
||||||
puts " | Location: #{theme.get_url_without_filename}"
|
puts " | Location: #{theme.get_url_without_filename}"
|
||||||
puts " | WordPress: #{theme.wp_org_url}" if theme.wp_org_item?
|
puts " | WordPress: #{theme.wp_org_url}" if theme.wp_org_item?
|
||||||
puts " | Directory listing enabled: Yes" if theme.directory_listing?
|
puts ' | Directory listing enabled: Yes' if theme.directory_listing?
|
||||||
puts " | Readme: #{theme.readme_url}" if theme.has_readme?
|
puts " | Readme: #{theme.readme_url}" if theme.has_readme?
|
||||||
puts " | Changelog: #{theme.changelog_url}" if theme.has_changelog?
|
puts " | Changelog: #{theme.changelog_url}" if theme.has_changelog?
|
||||||
|
|
||||||
@@ -309,22 +309,22 @@ begin
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
puts
|
puts
|
||||||
puts "No themes found :("
|
puts 'No themes found :('
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if wpscan_options.enumerate_timthumbs
|
if wpscan_options.enumerate_timthumbs
|
||||||
puts
|
puts
|
||||||
puts green("[+]") + " Enumerating timthumb files ..."
|
puts green('[+]') + ' Enumerating timthumb files ...'
|
||||||
puts
|
puts
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
:base_url => wp_target.uri,
|
base_url: wp_target.uri,
|
||||||
:show_progression => true,
|
show_progression: true,
|
||||||
:wp_content_dir => wp_target.wp_content_dir,
|
wp_content_dir: wp_target.wp_content_dir,
|
||||||
:error_404_hash => wp_target.error_404_hash,
|
error_404_hash: wp_target.error_404_hash,
|
||||||
:homepage_hash => wp_target.homepage_hash,
|
homepage_hash: wp_target.homepage_hash,
|
||||||
:exclude_content_based => wpscan_options.exclude_content_based
|
exclude_content_based: wpscan_options.exclude_content_based
|
||||||
}
|
}
|
||||||
|
|
||||||
theme_name = wp_theme ? wp_theme.name : nil
|
theme_name = wp_theme ? wp_theme.name : nil
|
||||||
@@ -332,36 +332,36 @@ begin
|
|||||||
timthumbs = wp_target.timthumbs
|
timthumbs = wp_target.timthumbs
|
||||||
|
|
||||||
puts
|
puts
|
||||||
puts green("[+]") + " We found #{timthumbs.size.to_s} timthumb file/s :"
|
puts green('[+]') + " We found #{timthumbs.size.to_s} timthumb file/s :"
|
||||||
puts
|
puts
|
||||||
|
|
||||||
timthumbs.each do |t|
|
timthumbs.each do |t|
|
||||||
puts " | " + red("[!]") + " #{t.get_full_url.to_s}"
|
puts ' | ' + red('[!]') + " #{t.get_full_url.to_s}"
|
||||||
end
|
end
|
||||||
puts
|
puts
|
||||||
puts red(" * Reference: http://www.exploit-db.com/exploits/17602/")
|
puts red(' * Reference: http://www.exploit-db.com/exploits/17602/')
|
||||||
else
|
else
|
||||||
puts
|
puts
|
||||||
puts "No timthumb files found :("
|
puts 'No timthumb files found :('
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# If we haven't been supplied a username, enumerate them...
|
# If we haven't been supplied a username, enumerate them...
|
||||||
if !wpscan_options.username and wpscan_options.wordlist or wpscan_options.enumerate_usernames
|
if !wpscan_options.username and wpscan_options.wordlist or wpscan_options.enumerate_usernames
|
||||||
puts
|
puts
|
||||||
puts green("[+]") + " Enumerating usernames ..."
|
puts green('[+]') + ' Enumerating usernames ...'
|
||||||
|
|
||||||
usernames = wp_target.usernames(:range => wpscan_options.enumerate_usernames_range)
|
usernames = wp_target.usernames(range: wpscan_options.enumerate_usernames_range)
|
||||||
|
|
||||||
if usernames.empty?
|
if usernames.empty?
|
||||||
puts
|
puts
|
||||||
puts "We did not enumerate any usernames :("
|
puts 'We did not enumerate any usernames :('
|
||||||
puts "Try supplying your own username with the --username option"
|
puts 'Try supplying your own username with the --username option'
|
||||||
puts
|
puts
|
||||||
exit(1)
|
exit(1)
|
||||||
else
|
else
|
||||||
puts
|
puts
|
||||||
puts green("[+]") + " We found the following #{usernames.length.to_s} username/s :"
|
puts green('[+]') + " We found the following #{usernames.length.to_s} username/s :"
|
||||||
puts
|
puts
|
||||||
|
|
||||||
max_id_length = usernames.sort { |a, b| a.id.to_s.length <=> b.id.to_s.length }.last.id.to_s.length
|
max_id_length = usernames.sort { |a, b| a.id.to_s.length <=> b.id.to_s.length }.last.id.to_s.length
|
||||||
@@ -378,7 +378,7 @@ begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
usernames = [WpUser.new(wpscan_options.username, -1, "empty")]
|
usernames = [WpUser.new(wpscan_options.username, -1, 'empty')]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Start the brute forcer
|
# Start the brute forcer
|
||||||
@@ -390,19 +390,19 @@ begin
|
|||||||
|
|
||||||
puts
|
puts
|
||||||
puts "The plugin #{protection_plugin.name} has been detected. It might record the IP and timestamp of every failed login. Not a good idea for brute forcing !"
|
puts "The plugin #{protection_plugin.name} has been detected. It might record the IP and timestamp of every failed login. Not a good idea for brute forcing !"
|
||||||
puts "[?] Do you want to start the brute force anyway ? [y/n]"
|
puts '[?] Do you want to start the brute force anyway ? [y/n]'
|
||||||
|
|
||||||
bruteforce = false if Readline.readline !~ /^y/i
|
bruteforce = false if Readline.readline !~ /^y/i
|
||||||
end
|
end
|
||||||
|
|
||||||
if bruteforce
|
if bruteforce
|
||||||
puts
|
puts
|
||||||
puts green("[+]") + " Starting the password brute forcer"
|
puts green('[+]') + ' Starting the password brute forcer'
|
||||||
puts
|
puts
|
||||||
wp_target.brute_force(usernames, wpscan_options.wordlist, {:show_progression => true})
|
wp_target.brute_force(usernames, wpscan_options.wordlist, {show_progression: true})
|
||||||
else
|
else
|
||||||
puts
|
puts
|
||||||
puts "Brute forcing aborted"
|
puts 'Brute forcing aborted'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -410,10 +410,10 @@ begin
|
|||||||
puts
|
puts
|
||||||
puts green("[+] Finished at #{stop_time.asctime}")
|
puts green("[+] Finished at #{stop_time.asctime}")
|
||||||
elapsed = stop_time - start_time
|
elapsed = stop_time - start_time
|
||||||
puts green("[+] Elapsed time: #{Time.at(elapsed).utc.strftime("%H:%M:%S")}")
|
puts green("[+] Elapsed time: #{Time.at(elapsed).utc.strftime('%H:%M:%S')}")
|
||||||
exit() # must exit!
|
exit() # must exit!
|
||||||
rescue => e
|
rescue => e
|
||||||
puts red("[ERROR] #{e.message}")
|
puts red("[ERROR] #{e.message}")
|
||||||
puts red("Trace :")
|
puts red('Trace :')
|
||||||
puts red(e.backtrace.join("\n"))
|
puts red(e.backtrace.join("\n"))
|
||||||
end
|
end
|
||||||
|
|||||||
10
wpstools.rb
10
wpstools.rb
@@ -19,15 +19,15 @@
|
|||||||
#++
|
#++
|
||||||
|
|
||||||
$: << '.'
|
$: << '.'
|
||||||
require File.dirname(__FILE__) + "/lib/wpstools/wpstools_helper"
|
require File.dirname(__FILE__) + '/lib/wpstools/wpstools_helper'
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
banner()
|
banner()
|
||||||
|
|
||||||
option_parser = CustomOptionParser.new("Usage: ./wpstools.rb [options]", 60)
|
option_parser = CustomOptionParser.new('Usage: ./wpstools.rb [options]', 60)
|
||||||
option_parser.separator ""
|
option_parser.separator ''
|
||||||
option_parser.add(["-v", "--verbose", "Verbose output"])
|
option_parser.add(['-v', '--verbose', 'Verbose output'])
|
||||||
|
|
||||||
plugins = Plugins.new(option_parser)
|
plugins = Plugins.new(option_parser)
|
||||||
plugins.register(
|
plugins.register(
|
||||||
@@ -47,6 +47,6 @@ begin
|
|||||||
|
|
||||||
rescue => e
|
rescue => e
|
||||||
puts "[ERROR] #{e.message}"
|
puts "[ERROR] #{e.message}"
|
||||||
puts "Trace :"
|
puts 'Trace :'
|
||||||
puts e.backtrace.join("\n")
|
puts e.backtrace.join("\n")
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user