-) Code formatting
-) rspec tests
This commit is contained in:
@@ -21,16 +21,16 @@ class Browser
|
|||||||
@@user_agent_modes = %w{ static semi-static random }
|
@@user_agent_modes = %w{ static semi-static random }
|
||||||
|
|
||||||
ACCESSOR_OPTIONS = [
|
ACCESSOR_OPTIONS = [
|
||||||
:user_agent,
|
:user_agent,
|
||||||
:user_agent_mode,
|
:user_agent_mode,
|
||||||
:available_user_agents,
|
:available_user_agents,
|
||||||
:proxy,
|
:proxy,
|
||||||
:max_threads,
|
:max_threads,
|
||||||
:cache_timeout,
|
:cache_timeout,
|
||||||
:request_timeout
|
:request_timeout
|
||||||
]
|
]
|
||||||
|
|
||||||
attr_reader :hydra, :config_file
|
attr_reader :hydra, :config_file
|
||||||
attr_accessor *ACCESSOR_OPTIONS
|
attr_accessor *ACCESSOR_OPTIONS
|
||||||
|
|
||||||
def initialize(options = {})
|
def initialize(options = {})
|
||||||
@@ -52,6 +52,7 @@ class Browser
|
|||||||
# might be in CacheFileStore
|
# might be in CacheFileStore
|
||||||
setup_cache_handlers
|
setup_cache_handlers
|
||||||
end
|
end
|
||||||
|
|
||||||
private_class_method :new
|
private_class_method :new
|
||||||
|
|
||||||
def self.instance(options = {})
|
def self.instance(options = {})
|
||||||
@@ -113,9 +114,9 @@ class Browser
|
|||||||
def setup_cache_handlers
|
def setup_cache_handlers
|
||||||
@hydra.cache_setter do |request|
|
@hydra.cache_setter do |request|
|
||||||
@cache.write_entry(
|
@cache.write_entry(
|
||||||
Browser.generate_cache_key_from_request(request),
|
Browser.generate_cache_key_from_request(request),
|
||||||
request.response,
|
request.response,
|
||||||
request.cache_timeout
|
request.cache_timeout
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -123,24 +124,25 @@ class Browser
|
|||||||
@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
|
||||||
|
|
||||||
private :setup_cache_handlers
|
private :setup_cache_handlers
|
||||||
|
|
||||||
def get(url, params = {})
|
def get(url, params = {})
|
||||||
run_request(
|
run_request(
|
||||||
forge_request(url, params.merge(:method => :get))
|
forge_request(url, params.merge(:method => :get))
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def post(url, params = {})
|
def post(url, params = {})
|
||||||
run_request(
|
run_request(
|
||||||
forge_request(url, params.merge(:method => :post))
|
forge_request(url, params.merge(:method => :post))
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def forge_request(url, params = {})
|
def forge_request(url, params = {})
|
||||||
Typhoeus::Request.new(
|
Typhoeus::Request.new(
|
||||||
url.to_s,
|
url.to_s,
|
||||||
merge_request_params(params)
|
merge_request_params(params)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class CacheFileStore
|
|||||||
# 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)
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ def get_equal_string_end(stringarray = [""])
|
|||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if looping == false or (counter * -1 ) > base.length
|
if looping == false or (counter * -1) > base.length
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
already_found = "#{character if character}#{already_found}"
|
already_found = "#{character if character}#{already_found}"
|
||||||
@@ -87,6 +87,7 @@ if RUBY_VERSION < "1.9"
|
|||||||
end
|
end
|
||||||
matches
|
matches
|
||||||
end
|
end
|
||||||
|
|
||||||
alias_method :grep, :_grep_
|
alias_method :grep, :_grep_
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -125,5 +126,10 @@ def colorize(text, color_code)
|
|||||||
"\e[#{color_code}m#{text}\e[0m"
|
"\e[#{color_code}m#{text}\e[0m"
|
||||||
end
|
end
|
||||||
|
|
||||||
def red(text); colorize(text, 31) end
|
def red(text)
|
||||||
def green(text); colorize(text, 32) end
|
; colorize(text, 31)
|
||||||
|
end
|
||||||
|
|
||||||
|
def green(text)
|
||||||
|
; colorize(text, 32)
|
||||||
|
end
|
||||||
|
|||||||
@@ -20,20 +20,20 @@ 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://wpscan.googlecode.com/svn/trunk"
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
def local_revision_number
|
def local_revision_number
|
||||||
local_revision = %x[svn info "#{@repo_directory}" --xml 2>&1]
|
local_revision = %x[svn info "#@repo_directory" --xml 2>&1]
|
||||||
local_revision[@@revision_pattern, 1].to_s
|
local_revision[REVISION_PATTERN, 1].to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
%x[svn up "#{@repo_directory}"]
|
%x[svn up "#@repo_directory"]
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ module Malwares
|
|||||||
# return array of string (url of malwares found)
|
# return array of string (url of malwares found)
|
||||||
def malwares(malwares_file_path = nil)
|
def malwares(malwares_file_path = nil)
|
||||||
if @malwares.nil?
|
if @malwares.nil?
|
||||||
malwares_found = []
|
malwares_found = []
|
||||||
malwares_file = Malwares.malwares_file(malwares_file_path)
|
malwares_file = Malwares.malwares_file(malwares_file_path)
|
||||||
index_page_body = Browser.instance.get(@uri.to_s).body
|
index_page_body = Browser.instance.get(@uri.to_s).body
|
||||||
|
|
||||||
File.open(malwares_file, 'r') do |file|
|
File.open(malwares_file, 'r') do |file|
|
||||||
|
|||||||
@@ -24,14 +24,14 @@ module WebSite
|
|||||||
wordpress = false
|
wordpress = false
|
||||||
|
|
||||||
response = Browser.instance.get(login_url(),
|
response = Browser.instance.get(login_url(),
|
||||||
{ :follow_location => true, :max_redirects => 2 }
|
{:follow_location => true, :max_redirects => 2}
|
||||||
)
|
)
|
||||||
|
|
||||||
if response.body =~ %r{WordPress}i
|
if response.body =~ %r{WordPress}i
|
||||||
wordpress = true
|
wordpress = true
|
||||||
else
|
else
|
||||||
response = Browser.instance.get(xmlrpc_url(),
|
response = Browser.instance.get(xmlrpc_url(),
|
||||||
{ :follow_location => true, :max_redirects => 2 }
|
{:follow_location => true, :max_redirects => 2}
|
||||||
)
|
)
|
||||||
|
|
||||||
if response.body =~ %r{XML-RPC server accepts POST requests only}i
|
if response.body =~ %r{XML-RPC server accepts POST requests only}i
|
||||||
|
|||||||
@@ -22,14 +22,14 @@ module WpConfigBackup
|
|||||||
# See http://www.feross.org/cmsploit/
|
# See http://www.feross.org/cmsploit/
|
||||||
# return an array of backup config files url
|
# return an array of backup config files url
|
||||||
def config_backup
|
def config_backup
|
||||||
found = []
|
found = []
|
||||||
backups = WpConfigBackup.config_backup_files
|
backups = WpConfigBackup.config_backup_files
|
||||||
browser = Browser.instance
|
browser = Browser.instance
|
||||||
hydra = browser.hydra
|
hydra = browser.hydra
|
||||||
|
|
||||||
backups.each do |file|
|
backups.each do |file|
|
||||||
file_url = @uri.merge(URI.escape(file)).to_s
|
file_url = @uri.merge(URI.escape(file)).to_s
|
||||||
request = browser.forge_request(file_url)
|
request = browser.forge_request(file_url)
|
||||||
|
|
||||||
request.on_complete do |response|
|
request.on_complete do |response|
|
||||||
if response.body[%r{define}i] and not response.body[%r{<\s?html}i]
|
if response.body[%r{define}i] and not response.body[%r{<\s?html}i]
|
||||||
|
|||||||
@@ -22,19 +22,19 @@ module WpPlugins
|
|||||||
#
|
#
|
||||||
# return array of WpPlugin
|
# return array of WpPlugin
|
||||||
def plugins_from_aggressive_detection(options)
|
def plugins_from_aggressive_detection(options)
|
||||||
options[:file] = options[:file] || "#{DATA_DIR}/plugins.txt"
|
options[:file] = options[:file] || "#{DATA_DIR}/plugins.txt"
|
||||||
options[:vulns_file] = options[:vulns_file] || "#{DATA_DIR}/plugin_vulns.xml"
|
options[:vulns_file] = options[:vulns_file] || "#{DATA_DIR}/plugin_vulns.xml"
|
||||||
options[:vulns_xpath] = "//plugin[@name='#{@name}']/vulnerability"
|
options[:vulns_xpath] = "//plugin[@name='#{@name}']/vulnerability"
|
||||||
options[:vulns_xpath_2] = "//plugin"
|
options[:vulns_xpath_2] = "//plugin"
|
||||||
options[:type] = "plugins"
|
options[:type] = "plugins"
|
||||||
result = WpDetector.aggressive_detection(options)
|
result = WpDetector.aggressive_detection(options)
|
||||||
plugins = []
|
plugins = []
|
||||||
result.each do |r|
|
result.each do |r|
|
||||||
plugins << WpPlugin.new(
|
plugins << WpPlugin.new(
|
||||||
:url => r[:url],
|
:url => r[:url],
|
||||||
:path => r[:path],
|
:path => r[:path],
|
||||||
:wp_content_dir => r[:wp_content_dir],
|
:wp_content_dir => r[:wp_content_dir],
|
||||||
:name => r[:name]
|
:name => r[:name]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
plugins.sort_by { |p| p.name }
|
plugins.sort_by { |p| p.name }
|
||||||
@@ -52,9 +52,9 @@ module WpPlugins
|
|||||||
|
|
||||||
temp.each do |item|
|
temp.each do |item|
|
||||||
plugins << WpPlugin.new(
|
plugins << WpPlugin.new(
|
||||||
:url => item[:url],
|
:url => item[:url],
|
||||||
:name => item[:name],
|
:name => item[:name],
|
||||||
:path => item[:path],
|
:path => item[:path],
|
||||||
:wp_content_dir => options[:wp_content_dir]
|
:wp_content_dir => options[:wp_content_dir]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -19,19 +19,19 @@
|
|||||||
module WpThemes
|
module WpThemes
|
||||||
|
|
||||||
def themes_from_aggressive_detection(options)
|
def themes_from_aggressive_detection(options)
|
||||||
options[:file] = options[:file] || "#{DATA_DIR}/themes.txt"
|
options[:file] = options[:file] || "#{DATA_DIR}/themes.txt"
|
||||||
options[:vulns_file] = options[:vulns_file] || "#{DATA_DIR}/wp_theme_vulns.xml"
|
options[:vulns_file] = options[:vulns_file] || "#{DATA_DIR}/wp_theme_vulns.xml"
|
||||||
options[:vulns_xpath] = "//theme[@name='#{@name}']/vulnerability"
|
options[:vulns_xpath] = "//theme[@name='#{@name}']/vulnerability"
|
||||||
options[:vulns_xpath_2] = "//theme"
|
options[:vulns_xpath_2] = "//theme"
|
||||||
options[:type] = "themes"
|
options[:type] = "themes"
|
||||||
result = WpDetector.aggressive_detection(options)
|
result = WpDetector.aggressive_detection(options)
|
||||||
themes = []
|
themes = []
|
||||||
result.each do |r|
|
result.each do |r|
|
||||||
themes << WpTheme.new(
|
themes << WpTheme.new(
|
||||||
:url => r[:url],
|
:url => r[:url],
|
||||||
:path => r[:path],
|
:path => r[:path],
|
||||||
:wp_content_dir => r[:wp_content_dir],
|
:wp_content_dir => r[:wp_content_dir],
|
||||||
:name => r[:name]
|
:name => r[:name]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
themes.sort_by { |t| t.name }
|
themes.sort_by { |t| t.name }
|
||||||
@@ -43,9 +43,9 @@ module WpThemes
|
|||||||
|
|
||||||
temp.each do |item|
|
temp.each do |item|
|
||||||
themes << WpTheme.new(
|
themes << WpTheme.new(
|
||||||
:url => item[:url],
|
:url => item[:url],
|
||||||
:name => item[:name],
|
:name => item[:name],
|
||||||
:path => item[:path],
|
:path => item[:path],
|
||||||
:wp_content_dir => options[:wp_content_dir]
|
:wp_content_dir => options[:wp_content_dir]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ module WpTimthumbs
|
|||||||
|
|
||||||
protected
|
protected
|
||||||
def targets_url_from_theme(theme_name, options)
|
def targets_url_from_theme(theme_name, options)
|
||||||
targets = []
|
targets = []
|
||||||
theme_name = URI.escape(theme_name)
|
theme_name = URI.escape(theme_name)
|
||||||
|
|
||||||
%w{
|
%w{
|
||||||
@@ -55,10 +55,10 @@ module WpTimthumbs
|
|||||||
scripts/timthumb.php tools/timthumb.php functions/timthumb.php
|
scripts/timthumb.php tools/timthumb.php functions/timthumb.php
|
||||||
}.each do |file|
|
}.each do |file|
|
||||||
targets << {
|
targets << {
|
||||||
:url => options[:url],
|
:url => options[:url],
|
||||||
:path => "themes/#{theme_name}/#{file}",
|
:path => "themes/#{theme_name}/#{file}",
|
||||||
:wp_content_dir => options[:wp_content_dir],
|
:wp_content_dir => options[:wp_content_dir],
|
||||||
:name => options[:name]
|
:name => options[:name]
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
targets
|
targets
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ module WpUsernames
|
|||||||
#
|
#
|
||||||
# returns an array of WpUser (can be empty)
|
# returns an array of WpUser (can be empty)
|
||||||
def usernames(options = {})
|
def usernames(options = {})
|
||||||
range = options[:range] || (1..10)
|
range = options[:range] || (1..10)
|
||||||
browser = Browser.instance
|
browser = Browser.instance
|
||||||
usernames = []
|
usernames = []
|
||||||
|
|
||||||
range.each do |author_id|
|
range.each do |author_id|
|
||||||
url = author_url(author_id)
|
url = author_url(author_id)
|
||||||
@@ -58,7 +58,7 @@ module WpUsernames
|
|||||||
end
|
end
|
||||||
|
|
||||||
def get_nickname_from_url(url)
|
def get_nickname_from_url(url)
|
||||||
resp = Browser.instance.get(url, { :follow_location => true, :max_redirects => 2 })
|
resp = Browser.instance.get(url, {:follow_location => true, :max_redirects => 2})
|
||||||
nickname = nil
|
nickname = nil
|
||||||
if resp.code == 200
|
if resp.code == 200
|
||||||
nickname = extract_nickname_from_body(resp.body)
|
nickname = extract_nickname_from_body(resp.body)
|
||||||
|
|||||||
@@ -24,11 +24,11 @@ class WpItem < Vulnerable
|
|||||||
|
|
||||||
def initialize(options = {})
|
def initialize(options = {})
|
||||||
@wp_content_dir = options[:wp_content_dir] || "wp-content"
|
@wp_content_dir = options[:wp_content_dir] || "wp-content"
|
||||||
@url = options[:url]
|
@url = options[:url]
|
||||||
@path = options[:path]
|
@path = options[:path]
|
||||||
@name = options[:name] || extract_name_from_url
|
@name = options[:name] || extract_name_from_url
|
||||||
@vulns_xml = options[:vulns_xml]
|
@vulns_xml = options[:vulns_xml]
|
||||||
@vulns_xpath = options[:vulns_xpath].sub(/\$name\$/, @name)
|
@vulns_xpath = options[:vulns_xpath].sub(/\$name\$/, @name)
|
||||||
|
|
||||||
raise("url not set") unless @url
|
raise("url not set") unless @url
|
||||||
raise("path not set") unless @path
|
raise("path not set") unless @path
|
||||||
|
|||||||
@@ -32,16 +32,16 @@
|
|||||||
# * +type+ - Type: plugins, themes
|
# * +type+ - Type: plugins, themes
|
||||||
class WpOptions
|
class WpOptions
|
||||||
def self.check_options(options)
|
def self.check_options(options)
|
||||||
raise("url must be set") unless options[:url] != nil and options[:url].to_s.length > 0
|
raise("url must be set") unless options[:url] != nil and options[:url].to_s.length > 0
|
||||||
raise("only_vulnerable_ones must be set") unless options[:only_vulnerable_ones] != nil
|
raise("only_vulnerable_ones must be set") unless options[:only_vulnerable_ones] != nil
|
||||||
raise("file must be set") unless options[:file] != nil and options[:file].length > 0
|
raise("file must be set") unless options[:file] != nil and options[:file].length > 0
|
||||||
raise("vulns_file must be set") unless options[:vulns_file] != nil and options[:vulns_file].length > 0
|
raise("vulns_file must be set") unless options[:vulns_file] != nil and options[:vulns_file].length > 0
|
||||||
raise("vulns_xpath must be set") unless options[:vulns_xpath] != nil and options[:vulns_xpath].length > 0
|
raise("vulns_xpath must be set") unless options[:vulns_xpath] != nil and options[:vulns_xpath].length > 0
|
||||||
raise("vulns_xpath_2 must be set") unless options[:vulns_xpath_2] != nil and options[:vulns_xpath_2].length > 0
|
raise("vulns_xpath_2 must be set") unless options[:vulns_xpath_2] != nil and options[:vulns_xpath_2].length > 0
|
||||||
raise("wp_content_dir must be set") unless options[:wp_content_dir] != nil and options[:wp_content_dir].length > 0
|
raise("wp_content_dir must be set") unless options[:wp_content_dir] != nil and options[:wp_content_dir].length > 0
|
||||||
raise("show_progress_bar must be set") unless options[:show_progress_bar] != nil
|
raise("show_progress_bar must be set") unless options[:show_progress_bar] != nil
|
||||||
raise("error_404_hash must be set") unless options[:error_404_hash] != nil and options[:error_404_hash].length > 0
|
raise("error_404_hash must be set") unless options[:error_404_hash] != nil and options[:error_404_hash].length > 0
|
||||||
raise("type must be set") unless options[:type] != nil and options[:type].length > 0
|
raise("type must be set") unless options[:type] != nil and options[:type].length > 0
|
||||||
|
|
||||||
unless options[:type] =~ /plugins/i or options[:type] =~ /themes/i or options[:type] =~ /timthumbs/i
|
unless options[:type] =~ /plugins/i or options[:type] =~ /themes/i or options[:type] =~ /timthumbs/i
|
||||||
raise("Unknown type #{options[:type]}")
|
raise("Unknown type #{options[:type]}")
|
||||||
|
|||||||
@@ -18,10 +18,10 @@
|
|||||||
|
|
||||||
class WpPlugin < WpItem
|
class WpPlugin < WpItem
|
||||||
def initialize(options = {})
|
def initialize(options = {})
|
||||||
options[:vulns_xml] = options[:vulns_xml] || DATA_DIR + '/plugin_vulns.xml'
|
options[:vulns_xml] = options[:vulns_xml] || DATA_DIR + '/plugin_vulns.xml'
|
||||||
options[:vulns_xpath] = "//plugin[@name='$name$']/vulnerability"
|
options[:vulns_xpath] = "//plugin[@name='$name$']/vulnerability"
|
||||||
options[:vulns_xpath_2] = "//plugin"
|
options[:vulns_xpath_2] = "//plugin"
|
||||||
options[:type] = "plugins"
|
options[:type] = "plugins"
|
||||||
super(options)
|
super(options)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ class WpPlugin < WpItem
|
|||||||
# however can also be found in their specific plugin dir.
|
# however can also be found in their specific plugin dir.
|
||||||
# http://www.exploit-db.com/ghdb/3714/
|
# http://www.exploit-db.com/ghdb/3714/
|
||||||
def error_log?
|
def error_log?
|
||||||
response_body = Browser.instance.get(error_log_url(), :headers => { "range" => "bytes=0-700"}).body
|
response_body = Browser.instance.get(error_log_url(), :headers => {"range" => "bytes=0-700"}).body
|
||||||
response_body[%r{PHP Fatal error}i] ? true : false
|
response_body[%r{PHP Fatal error}i] ? true : false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ class WpTarget
|
|||||||
attr_reader :uri, :verbose
|
attr_reader :uri, :verbose
|
||||||
|
|
||||||
def initialize(target_url, options = {})
|
def initialize(target_url, options = {})
|
||||||
@uri = URI.parse(add_trailing_slash(add_http_protocol(target_url)))
|
@uri = URI.parse(add_trailing_slash(add_http_protocol(target_url)))
|
||||||
@verbose = options[:verbose]
|
@verbose = options[:verbose]
|
||||||
@wp_content_dir = options[:wp_content_dir]
|
@wp_content_dir = options[:wp_content_dir]
|
||||||
@wp_plugins_dir = options[:wp_plugins_dir]
|
@wp_plugins_dir = options[:wp_plugins_dir]
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ class WpTarget
|
|||||||
|
|
||||||
def has_debug_log?
|
def has_debug_log?
|
||||||
# We only get the first 700 bytes of the file to avoid loading huge file (like 2Go)
|
# We only get the first 700 bytes of the file to avoid loading huge file (like 2Go)
|
||||||
response_body = Browser.instance.get(debug_log_url(), :headers => { "range" => "bytes=0-700"}).body
|
response_body = Browser.instance.get(debug_log_url(), :headers => {"range" => "bytes=0-700"}).body
|
||||||
response_body[%r{\[[^\]]+\] PHP (?:Warning|Error|Notice):}] ? true : false
|
response_body[%r{\[[^\]]+\] PHP (?:Warning|Error|Notice):}] ? true : false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -23,10 +23,10 @@ class WpTheme < WpItem
|
|||||||
attr_reader :name, :style_url, :version
|
attr_reader :name, :style_url, :version
|
||||||
|
|
||||||
def initialize(options = {})
|
def initialize(options = {})
|
||||||
options[:vulns_xml] = options[:vulns_xml] || DATA_DIR + '/wp_theme_vulns.xml'
|
options[:vulns_xml] = options[:vulns_xml] || DATA_DIR + '/wp_theme_vulns.xml'
|
||||||
options[:vulns_xpath] = "//theme[@name='$name$']/vulnerability"
|
options[:vulns_xpath] = "//theme[@name='$name$']/vulnerability"
|
||||||
@version = options[:version]
|
@version = options[:version]
|
||||||
@style_url = options[:style_url]
|
@style_url = options[:style_url]
|
||||||
super(options)
|
super(options)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -56,18 +56,18 @@ class WpTheme < WpItem
|
|||||||
|
|
||||||
# Discover the wordpress theme name by parsing the css link rel
|
# Discover the wordpress theme name by parsing the css link rel
|
||||||
def self.find_from_css_link(target_uri)
|
def self.find_from_css_link(target_uri)
|
||||||
response = Browser.instance.get(target_uri.to_s, { :follow_location => true, :max_redirects => 2 })
|
response = Browser.instance.get(target_uri.to_s, {:follow_location => true, :max_redirects => 2})
|
||||||
|
|
||||||
matches = %r{https?://[^"']+/themes/([^"']+)/style.css}i.match(response.body)
|
matches = %r{https?://[^"']+/themes/([^"']+)/style.css}i.match(response.body)
|
||||||
if matches
|
if matches
|
||||||
style_url = matches[0]
|
style_url = matches[0]
|
||||||
theme_name = matches[1]
|
theme_name = matches[1]
|
||||||
|
|
||||||
return new(:name => theme_name,
|
return new(:name => theme_name,
|
||||||
:style_url => style_url,
|
:style_url => style_url,
|
||||||
:url => style_url,
|
:url => style_url,
|
||||||
:path => "",
|
:path => "",
|
||||||
:wp_content_dir => ""
|
:wp_content_dir => ""
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -79,15 +79,15 @@ class WpTheme < WpItem
|
|||||||
|
|
||||||
matches = regexp.match(body)
|
matches = regexp.match(body)
|
||||||
if matches
|
if matches
|
||||||
woo_theme_name = matches[1]
|
woo_theme_name = matches[1]
|
||||||
woo_theme_version = matches[2]
|
woo_theme_version = matches[2]
|
||||||
woo_framework_version = matches[3] # Not used at this time
|
woo_framework_version = matches[3] # Not used at this time
|
||||||
|
|
||||||
return new(:name => woo_theme_name,
|
return new(:name => woo_theme_name,
|
||||||
:version => woo_theme_version,
|
:version => woo_theme_version,
|
||||||
:url => matches[0],
|
:url => matches[0],
|
||||||
:path => "",
|
:path => "",
|
||||||
:wp_content_dir => ""
|
:wp_content_dir => ""
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -23,10 +23,10 @@ class WpVersion < Vulnerable
|
|||||||
attr_reader :number, :discovery_method
|
attr_reader :number, :discovery_method
|
||||||
|
|
||||||
def initialize(number, options = {})
|
def initialize(number, options = {})
|
||||||
@number = number
|
@number = number
|
||||||
@discovery_method = options[:discovery_method]
|
@discovery_method = options[:discovery_method]
|
||||||
@vulns_xml = options[:vulns_xml] || DATA_DIR + '/wp_vulns.xml'
|
@vulns_xml = options[:vulns_xml] || DATA_DIR + '/wp_vulns.xml'
|
||||||
@vulns_xpath = "//wordpress[@version='#{@number}']/vulnerability"
|
@vulns_xpath = "//wordpress[@version='#{@number}']/vulnerability"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Will use all method self.find_from_* to try to detect the version
|
# Will use all method self.find_from_* to try to detect the version
|
||||||
@@ -38,7 +38,7 @@ class WpVersion < Vulnerable
|
|||||||
# (find_from_meta_generator, find_from_rss_generator etc)
|
# (find_from_meta_generator, find_from_rss_generator etc)
|
||||||
def self.find(target_uri, wp_content_dir)
|
def self.find(target_uri, wp_content_dir)
|
||||||
options = {
|
options = {
|
||||||
:url => target_uri,
|
:url => target_uri,
|
||||||
:wp_content_dir => wp_content_dir
|
:wp_content_dir => wp_content_dir
|
||||||
}
|
}
|
||||||
self.methods.grep(/find_from_/).each do |method_to_call|
|
self.methods.grep(/find_from_/).each do |method_to_call|
|
||||||
@@ -60,14 +60,14 @@ class WpVersion < Vulnerable
|
|||||||
# that it is reinstated on upgrade.
|
# that it is reinstated on upgrade.
|
||||||
def self.find_from_meta_generator(options)
|
def self.find_from_meta_generator(options)
|
||||||
target_uri = options[:url]
|
target_uri = options[:url]
|
||||||
response = Browser.instance.get(target_uri.to_s, { :follow_location => true, :max_redirects => 2 })
|
response = Browser.instance.get(target_uri.to_s, {:follow_location => true, :max_redirects => 2})
|
||||||
|
|
||||||
response.body[%r{name="generator" content="wordpress ([^"]+)"}i, 1]
|
response.body[%r{name="generator" content="wordpress ([^"]+)"}i, 1]
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.find_from_rss_generator(options)
|
def self.find_from_rss_generator(options)
|
||||||
target_uri = options[:url]
|
target_uri = options[:url]
|
||||||
response = Browser.instance.get(target_uri.merge("feed/").to_s, { :follow_location => true, :max_redirects => 2 })
|
response = Browser.instance.get(target_uri.merge("feed/").to_s, {:follow_location => true, :max_redirects => 2})
|
||||||
|
|
||||||
response.body[%r{<generator>http://wordpress.org/\?v=([^<]+)</generator>}i, 1]
|
response.body[%r{<generator>http://wordpress.org/\?v=([^<]+)</generator>}i, 1]
|
||||||
end
|
end
|
||||||
@@ -105,11 +105,11 @@ class WpVersion < Vulnerable
|
|||||||
file_url = target_uri.merge(node.attribute('src').text).to_s
|
file_url = target_uri.merge(node.attribute('src').text).to_s
|
||||||
file_url = file_url.gsub(/\$wp-plugins\$/i, wp_plugins).gsub(/\$wp-content\$/i, wp_content)
|
file_url = file_url.gsub(/\$wp-plugins\$/i, wp_plugins).gsub(/\$wp-content\$/i, wp_content)
|
||||||
response = Browser.instance.get(file_url)
|
response = Browser.instance.get(file_url)
|
||||||
md5sum = Digest::MD5.hexdigest(response.body)
|
md5sum = Digest::MD5.hexdigest(response.body)
|
||||||
|
|
||||||
node.search('hash').each do |hash|
|
node.search('hash').each do |hash|
|
||||||
if hash.attribute('md5').text == md5sum
|
if hash.attribute('md5').text == md5sum
|
||||||
return hash.search('versions').text
|
return hash.search('versions').text
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ class WpVulnerability
|
|||||||
attr_accessor :title, :reference, :type
|
attr_accessor :title, :reference, :type
|
||||||
|
|
||||||
def initialize(title, reference, type)
|
def initialize(title, reference, type)
|
||||||
@title = title
|
@title = title
|
||||||
@reference = reference
|
@reference = reference
|
||||||
@type = type
|
@type = type
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -19,27 +19,27 @@
|
|||||||
class WpscanOptions
|
class WpscanOptions
|
||||||
|
|
||||||
ACCESSOR_OPTIONS = [
|
ACCESSOR_OPTIONS = [
|
||||||
:enumerate_plugins,
|
:enumerate_plugins,
|
||||||
:enumerate_only_vulnerable_plugins,
|
:enumerate_only_vulnerable_plugins,
|
||||||
:enumerate_themes,
|
:enumerate_themes,
|
||||||
:enumerate_only_vulnerable_themes,
|
:enumerate_only_vulnerable_themes,
|
||||||
:enumerate_timthumbs,
|
:enumerate_timthumbs,
|
||||||
:enumerate_usernames,
|
:enumerate_usernames,
|
||||||
:enumerate_usernames_range,
|
:enumerate_usernames_range,
|
||||||
:proxy,
|
:proxy,
|
||||||
:threads,
|
:threads,
|
||||||
:url,
|
:url,
|
||||||
:wordlist,
|
:wordlist,
|
||||||
:force,
|
:force,
|
||||||
:update,
|
:update,
|
||||||
:verbose,
|
:verbose,
|
||||||
:username,
|
:username,
|
||||||
:password,
|
:password,
|
||||||
:follow_redirection,
|
:follow_redirection,
|
||||||
:wp_content_dir,
|
:wp_content_dir,
|
||||||
:wp_plugins_dir,
|
:wp_plugins_dir,
|
||||||
:help,
|
:help,
|
||||||
:config_file
|
:config_file
|
||||||
]
|
]
|
||||||
|
|
||||||
attr_accessor *ACCESSOR_OPTIONS
|
attr_accessor *ACCESSOR_OPTIONS
|
||||||
@@ -131,7 +131,7 @@ class WpscanOptions
|
|||||||
|
|
||||||
if ARGV.length > 0
|
if ARGV.length > 0
|
||||||
WpscanOptions.get_opt_long.each do |opt, arg|
|
WpscanOptions.get_opt_long.each do |opt, arg|
|
||||||
wpscan_options.set_option_from_cli(opt, arg)
|
wpscan_options.set_option_from_cli(opt, arg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -144,11 +144,11 @@ class WpscanOptions
|
|||||||
|
|
||||||
if WpscanOptions.is_long_option?(cli_option)
|
if WpscanOptions.is_long_option?(cli_option)
|
||||||
self.send(
|
self.send(
|
||||||
WpscanOptions.option_to_instance_variable_setter(cli_option),
|
WpscanOptions.option_to_instance_variable_setter(cli_option),
|
||||||
cli_value
|
cli_value
|
||||||
)
|
)
|
||||||
elsif cli_option === "--enumerate" # Special cases
|
elsif cli_option === "--enumerate" # Special cases
|
||||||
# Default value if no argument is given
|
# Default value if no argument is given
|
||||||
cli_value = "T!tup!" if cli_value.length == 0
|
cli_value = "T!tup!" if cli_value.length == 0
|
||||||
|
|
||||||
enumerate_options_from_string(cli_value)
|
enumerate_options_from_string(cli_value)
|
||||||
@@ -188,20 +188,20 @@ class WpscanOptions
|
|||||||
# Even if a short option is given (IE : -u), the long one will be returned (IE : --url)
|
# Even if a short option is given (IE : -u), the long one will be returned (IE : --url)
|
||||||
def self.get_opt_long
|
def self.get_opt_long
|
||||||
GetoptLong.new(
|
GetoptLong.new(
|
||||||
["--url", "-u", GetoptLong::REQUIRED_ARGUMENT],
|
["--url", "-u", GetoptLong::REQUIRED_ARGUMENT],
|
||||||
["--enumerate", "-e", GetoptLong::OPTIONAL_ARGUMENT],
|
["--enumerate", "-e", GetoptLong::OPTIONAL_ARGUMENT],
|
||||||
["--username", "-U", GetoptLong::REQUIRED_ARGUMENT],
|
["--username", "-U", GetoptLong::REQUIRED_ARGUMENT],
|
||||||
["--wordlist", "-w", GetoptLong::REQUIRED_ARGUMENT],
|
["--wordlist", "-w", GetoptLong::REQUIRED_ARGUMENT],
|
||||||
["--threads", "-t",GetoptLong::REQUIRED_ARGUMENT],
|
["--threads", "-t", GetoptLong::REQUIRED_ARGUMENT],
|
||||||
["--force", "-f",GetoptLong::NO_ARGUMENT],
|
["--force", "-f", GetoptLong::NO_ARGUMENT],
|
||||||
["--help", "-h", GetoptLong::NO_ARGUMENT],
|
["--help", "-h", GetoptLong::NO_ARGUMENT],
|
||||||
["--verbose", "-v", GetoptLong::NO_ARGUMENT] ,
|
["--verbose", "-v", GetoptLong::NO_ARGUMENT],
|
||||||
["--proxy", GetoptLong::OPTIONAL_ARGUMENT],
|
["--proxy", GetoptLong::OPTIONAL_ARGUMENT],
|
||||||
["--update", GetoptLong::NO_ARGUMENT],
|
["--update", GetoptLong::NO_ARGUMENT],
|
||||||
["--follow-redirection", GetoptLong::NO_ARGUMENT],
|
["--follow-redirection", GetoptLong::NO_ARGUMENT],
|
||||||
["--wp-content-dir", GetoptLong::REQUIRED_ARGUMENT],
|
["--wp-content-dir", GetoptLong::REQUIRED_ARGUMENT],
|
||||||
["--wp-plugins-dir", GetoptLong::REQUIRED_ARGUMENT],
|
["--wp-plugins-dir", GetoptLong::REQUIRED_ARGUMENT],
|
||||||
["--config-file", "-c", GetoptLong::REQUIRED_ARGUMENT]
|
["--config-file", "-c", GetoptLong::REQUIRED_ARGUMENT]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -221,7 +221,7 @@ class WpscanOptions
|
|||||||
|
|
||||||
def self.option_to_instance_variable_setter(option)
|
def self.option_to_instance_variable_setter(option)
|
||||||
cleaned_option = WpscanOptions.clean_option(option)
|
cleaned_option = WpscanOptions.clean_option(option)
|
||||||
option_syms = ACCESSOR_OPTIONS.grep(%r{^#{cleaned_option}})
|
option_syms = ACCESSOR_OPTIONS.grep(%r{^#{cleaned_option}})
|
||||||
|
|
||||||
option_syms.length == 1 ? :"#{option_syms.at(0)}=" : nil
|
option_syms.length == 1 ? :"#{option_syms.at(0)}=" : nil
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -49,14 +49,14 @@ class Generate_List
|
|||||||
items = Svn_Parser.new(@svn_url, @verbose).parse
|
items = Svn_Parser.new(@svn_url, @verbose).parse
|
||||||
save items
|
save items
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_popular_list(pages)
|
def generate_popular_list(pages)
|
||||||
popular = get_popular_items(pages)
|
popular = get_popular_items(pages)
|
||||||
items = Svn_Parser.new(@svn_url, @verbose).parse(popular)
|
items = Svn_Parser.new(@svn_url, @verbose).parse(popular)
|
||||||
save items
|
save items
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# Send a HTTP request to the WordPress most popular theme or plugin webpage
|
# Send a HTTP request to the WordPress most popular theme or plugin webpage
|
||||||
# parse the response for the names.
|
# parse the response for the names.
|
||||||
def get_popular_items(pages)
|
def get_popular_items(pages)
|
||||||
@@ -83,9 +83,9 @@ class Generate_List
|
|||||||
@hydra.queue(request)
|
@hydra.queue(request)
|
||||||
|
|
||||||
if queue_count == @browser.max_threads
|
if queue_count == @browser.max_threads
|
||||||
@hydra.run
|
@hydra.run
|
||||||
queue_count = 0
|
queue_count = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class Svn_Parser
|
|||||||
@svn_browser = Browser.instance
|
@svn_browser = Browser.instance
|
||||||
@svn_hydra = @svn_browser.hydra
|
@svn_hydra = @svn_browser.hydra
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse(dirs=nil)
|
def parse(dirs=nil)
|
||||||
if dirs == nil
|
if dirs == nil
|
||||||
dirs = get_root_directories
|
dirs = get_root_directories
|
||||||
@@ -64,14 +64,14 @@ class Svn_Parser
|
|||||||
# trunk folder present
|
# trunk folder present
|
||||||
if contains_trunk(response)
|
if contains_trunk(response)
|
||||||
puts "[+] Adding trunk on #{dir}" if @verbose
|
puts "[+] Adding trunk on #{dir}" if @verbose
|
||||||
urls << { :name => dir, :folder => "trunk"}
|
urls << {:name => dir, :folder => "trunk"}
|
||||||
# no trunk folder. This is true on theme svn repos
|
# no trunk folder. This is true on theme svn repos
|
||||||
else
|
else
|
||||||
folders = response.body.scan(%r{^\s*<li><a href="(.+)/">.+/</a></li>$}i)
|
folders = response.body.scan(%r{^\s*<li><a href="(.+)/">.+/</a></li>$}i)
|
||||||
if folders != nil and folders.length > 0
|
if folders != nil and folders.length > 0
|
||||||
last_version = folders.last[0]
|
last_version = folders.last[0]
|
||||||
puts "[+] Adding #{last_version} on #{dir}" if @verbose
|
puts "[+] Adding #{last_version} on #{dir}" if @verbose
|
||||||
urls << { :name => dir, :folder => last_version}
|
urls << {:name => dir, :folder => last_version}
|
||||||
else
|
else
|
||||||
puts "[+] No content in #{dir}" if @verbose
|
puts "[+] No content in #{dir}" if @verbose
|
||||||
end
|
end
|
||||||
@@ -89,7 +89,7 @@ class Svn_Parser
|
|||||||
@svn_hydra.run
|
@svn_hydra.run
|
||||||
urls
|
urls
|
||||||
end
|
end
|
||||||
|
|
||||||
# Get a file in each directory
|
# Get a file in each directory
|
||||||
# TODO: exclude files like Thumbs.db (Example: wordpress-23-related-posts-plugin/)
|
# TODO: exclude files like Thumbs.db (Example: wordpress-23-related-posts-plugin/)
|
||||||
def get_svn_file_entries(dirs)
|
def get_svn_file_entries(dirs)
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ def help()
|
|||||||
puts "--gpl Alias for --generate_plugin_list"
|
puts "--gpl Alias for --generate_plugin_list"
|
||||||
puts "--generate_full_plugin_list Generate a new full data/plugins.txt file"
|
puts "--generate_full_plugin_list Generate a new full data/plugins.txt file"
|
||||||
puts "--gfpl Alias for --generate_full_plugin_list"
|
puts "--gfpl Alias for --generate_full_plugin_list"
|
||||||
|
|
||||||
puts "--generate_theme_list [number of pages] Generate a new data/themes.txt file. (supply number of *pages* to parse, default : 150)"
|
puts "--generate_theme_list [number of pages] Generate a new data/themes.txt file. (supply number of *pages* to parse, default : 150)"
|
||||||
puts "--gtl Alias for --generate_theme_list"
|
puts "--gtl Alias for --generate_theme_list"
|
||||||
puts "--generate_full_theme_list Generate a new full data/themes.txt file"
|
puts "--generate_full_theme_list Generate a new full data/themes.txt file"
|
||||||
|
|||||||
9
spec/fixtures/wpscan/modules/wp_themes/passive_detection/no_theme.htm
vendored
Normal file
9
spec/fixtures/wpscan/modules/wp_themes/passive_detection/no_theme.htm
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
179
spec/fixtures/wpscan/modules/wp_themes/passive_detection/one_theme.htm
vendored
Normal file
179
spec/fixtures/wpscan/modules/wp_themes/passive_detection/one_theme.htm
vendored
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html dir="ltr" lang="en-US">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>ddd</title>
|
||||||
|
<link rel="profile" href="http://gmpg.org/xfn/11" />
|
||||||
|
<link rel="stylesheet" type="text/css" media="all" href="http://10.211.55.8/wordpress/wp-content/themes/custom-twentyten/style.css" />
|
||||||
|
<link rel="pingback" href="http://10.211.55.8/wordpress/xmlrpc.php" />
|
||||||
|
<meta name='robots' content='noindex,nofollow' />
|
||||||
|
<link rel="alternate" type="application/rss+xml" title="test » Feed" href="http://10.211.55.8/wordpress/?feed=rss2" />
|
||||||
|
<link rel="alternate" type="application/rss+xml" title="test » Comments Feed" href="http://10.211.55.8/wordpress/?feed=comments-rss2" />
|
||||||
|
<!-- AL2FB CSS -->
|
||||||
|
<style type="text/css" media="screen">
|
||||||
|
.al2fb_widget_comments { }
|
||||||
|
.al2fb_widget_comments li { }
|
||||||
|
.al2fb_widget_picture { width: 32px; height: 32px; }
|
||||||
|
.al2fb_widget_name { }
|
||||||
|
.al2fb_widget_comment { }
|
||||||
|
.al2fb_widget_date { font-size: smaller; }
|
||||||
|
</style>
|
||||||
|
<link rel='stylesheet' id='al2fb_style-css' href='http://10.211.55.8/wordpress/wp-content/plugins/add-link-to-facebook/add-link-to-facebook.css?ver=3.3.1' type='text/css' media='all' />
|
||||||
|
<link rel='stylesheet' id='events-manager-css' href='http://10.211.55.8/wordpress/wp-content/plugins/events-manager/includes/css/events_manager.css?ver=3.3.1' type='text/css' media='all' />
|
||||||
|
<link rel='stylesheet' id='NextGEN-css' href='http://10.211.55.8/wordpress/wp-content/plugins/nextgen-gallery/css/nggallery.css?ver=1.0.0' type='text/css' media='screen' />
|
||||||
|
<link rel='stylesheet' id='shutter-css' href='http://10.211.55.8/wordpress/wp-content/plugins/nextgen-gallery/shutter/shutter-reloaded.css?ver=1.3.4' type='text/css' media='screen' />
|
||||||
|
<link rel='stylesheet' id='contact-form-7-css' href='http://10.211.55.8/wordpress/wp-content/plugins/contact-form-7/includes/css/styles.css?ver=3.2.1' type='text/css' media='all' />
|
||||||
|
<link rel='stylesheet' id='cntctfrmStylesheet-css' href='http://10.211.55.8/wordpress/wp-content/plugins/contact-form-plugin/css/style.css?ver=3.3.1' type='text/css' media='all' />
|
||||||
|
<script type='text/javascript' src='http://10.211.55.8/wordpress/wp-includes/js/jquery/jquery.js?ver=1.7.1'></script>
|
||||||
|
<script type='text/javascript' src='http://10.211.55.8/wordpress/wp-includes/js/jquery/ui/jquery.ui.core.min.js?ver=1.8.16'></script>
|
||||||
|
<script type='text/javascript' src='http://10.211.55.8/wordpress/wp-includes/js/jquery/ui/jquery.ui.widget.min.js?ver=1.8.16'></script>
|
||||||
|
<script type='text/javascript' src='http://10.211.55.8/wordpress/wp-includes/js/jquery/ui/jquery.ui.position.min.js?ver=1.8.16'></script>
|
||||||
|
<script type='text/javascript' src='http://10.211.55.8/wordpress/wp-includes/js/jquery/ui/jquery.ui.mouse.min.js?ver=1.8.16'></script>
|
||||||
|
<script type='text/javascript' src='http://10.211.55.8/wordpress/wp-includes/js/jquery/ui/jquery.ui.sortable.min.js?ver=1.8.16'></script>
|
||||||
|
<script type='text/javascript' src='http://10.211.55.8/wordpress/wp-includes/js/jquery/ui/jquery.ui.datepicker.min.js?ver=1.8.16'></script>
|
||||||
|
<script type='text/javascript' src='http://10.211.55.8/wordpress/wp-includes/js/jquery/ui/jquery.ui.autocomplete.min.js?ver=1.8.16'></script>
|
||||||
|
<script type='text/javascript' src='http://10.211.55.8/wordpress/wp-includes/js/jquery/ui/jquery.ui.resizable.min.js?ver=1.8.16'></script>
|
||||||
|
<script type='text/javascript' src='http://10.211.55.8/wordpress/wp-includes/js/jquery/ui/jquery.ui.draggable.min.js?ver=1.8.16'></script>
|
||||||
|
<script type='text/javascript' src='http://10.211.55.8/wordpress/wp-includes/js/jquery/ui/jquery.ui.button.min.js?ver=1.8.16'></script>
|
||||||
|
<script type='text/javascript' src='http://10.211.55.8/wordpress/wp-includes/js/jquery/ui/jquery.ui.dialog.min.js?ver=1.8.16'></script>
|
||||||
|
<script type='text/javascript'>
|
||||||
|
/* <![CDATA[ */
|
||||||
|
var EM = {"ajaxurl":"http:\/\/10.211.55.8\/wordpress\/wp-admin\/admin-ajax.php","bookingajaxurl":"http:\/\/10.211.55.8\/wordpress\/wp-admin\/admin-ajax.php","locationajaxurl":"http:\/\/10.211.55.8\/wordpress\/wp-admin\/admin-ajax.php?action=locations_search","firstDay":"1","locale":"en","dateFormat":"dd\/mm\/yy","bookingInProgress":"Please wait while the booking is being submitted.","ui_css":"http:\/\/10.211.55.8\/wordpress\/wp-content\/plugins\/events-manager\/includes\/css\/ui-lightness.css","show24hours":"","is_ssl":"","tickets_save":"Save Ticket","bookings_export_save":"Export Bookings","bookings_settings_save":"Save Settings","booking_delete":"Are you sure you want to delete?","bb_full":"Sold Out","bb_book":"Book Now","bb_booking":"Booking...","bb_booked":"Booking Submitted","bb_error":"Booking Error. Try again?","bb_cancel":"Cancel","bb_canceling":"Canceling...","bb_cancelled":"Cancelled","bb_cancel_error":"Cancellation Error. Try again?","txt_search":"Search","txt_searching":"Searching...","txt_loading":"Loading..."};
|
||||||
|
/* ]]> */
|
||||||
|
</script>
|
||||||
|
<script type='text/javascript' src='http://10.211.55.8/wordpress/wp-content/plugins/events-manager/includes/js/events-manager.js?ver=3.3.1'></script>
|
||||||
|
<script type='text/javascript'>
|
||||||
|
/* <![CDATA[ */
|
||||||
|
var shutterSettings = {"msgLoading":"L O A D I N G","msgClose":"Click to Close","imageCount":"1"};
|
||||||
|
/* ]]> */
|
||||||
|
</script>
|
||||||
|
<script type='text/javascript' src='http://10.211.55.8/wordpress/wp-content/plugins/nextgen-gallery/shutter/shutter-reloaded.js?ver=1.3.3'></script>
|
||||||
|
<script type='text/javascript' src='http://10.211.55.8/wordpress/wp-content/plugins/nextgen-gallery/js/jquery.cycle.all.min.js?ver=2.9995'></script>
|
||||||
|
<script type='text/javascript' src='http://10.211.55.8/wordpress/wp-content/plugins/nextgen-gallery/js/ngg.slideshow.min.js?ver=1.06'></script>
|
||||||
|
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://10.211.55.8/wordpress/xmlrpc.php?rsd" />
|
||||||
|
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://10.211.55.8/wordpress/wp-includes/wlwmanifest.xml" />
|
||||||
|
<meta name="generator" content="WordPress 3.3.1" />
|
||||||
|
|
||||||
|
<!-- All in One SEO Pack 1.6.15 by Michael Torbert of Semper Fi Web Design[78,119] -->
|
||||||
|
<meta name="description" content="ddddd" />
|
||||||
|
<meta name="keywords" content="dd" />
|
||||||
|
<link rel="canonical" href="http://10.211.55.8/wordpress/" />
|
||||||
|
<!-- /all in one seo pack -->
|
||||||
|
<!-- <meta name="NextGEN" version="1.9.6" /> -->
|
||||||
|
<script charset="utf-8" type="text/javascript">var switchTo5x=true;</script><script charset="utf-8" type="text/javascript" src="http://w.sharethis.com/button/buttons.js"></script><script type="text/javascript">stLight.options({publisher:'wp.d54da82c-32aa-4efc-ab15-d4e2ed4f0b4d'});var st_type='wordpress3.3.1';</script></head>
|
||||||
|
|
||||||
|
<body class="home blog">
|
||||||
|
<div id="wrapper" class="hfeed">
|
||||||
|
<div id="header">
|
||||||
|
<div id="masthead">
|
||||||
|
<div id="branding" role="banner">
|
||||||
|
<h1 id="site-title">
|
||||||
|
<span>
|
||||||
|
<a href="http://10.211.55.8/wordpress/" title="test" rel="home">test</a>
|
||||||
|
</span>
|
||||||
|
</h1>
|
||||||
|
<div id="site-description">Just another WordPress site</div>
|
||||||
|
|
||||||
|
<img src="http://10.211.55.8/wordpress/wp-content/themes/custom-twentyten/images/headers/path.jpg" width="940" height="198" alt="" />
|
||||||
|
</div><!-- #branding -->
|
||||||
|
|
||||||
|
<div id="access" role="navigation">
|
||||||
|
<div class="skip-link screen-reader-text"><a href="#content" title="Skip to content">Skip to content</a></div>
|
||||||
|
<div class="menu"><ul><li class="current_page_item"><a href="http://10.211.55.8/wordpress/" title="Home">Home</a></li><li class="page_item page-item-11"><a href="http://10.211.55.8/wordpress/?page_id=11">Events</a><ul class='children'><li class="page_item page-item-13"><a href="http://10.211.55.8/wordpress/?page_id=13">Categories</a></li><li class="page_item page-item-12"><a href="http://10.211.55.8/wordpress/?page_id=12">Locations</a></li><li class="page_item page-item-14"><a href="http://10.211.55.8/wordpress/?page_id=14">My Bookings</a></li></ul></li><li class="page_item page-item-2"><a href="http://10.211.55.8/wordpress/?page_id=2">Sample Page</a></li></ul></div>
|
||||||
|
</div><!-- #access -->
|
||||||
|
</div><!-- #masthead -->
|
||||||
|
</div><!-- #header -->
|
||||||
|
|
||||||
|
<div id="main">
|
||||||
|
|
||||||
|
<div id="container">
|
||||||
|
<div id="content" role="main">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div id="post-1" class="post-1 post type-post status-publish format-standard hentry category-uncategorized">
|
||||||
|
<h2 class="entry-title"><a href="http://10.211.55.8/wordpress/?p=1" title="Permalink to Hello world!" rel="bookmark">Hello world!</a></h2>
|
||||||
|
|
||||||
|
<div class="entry-meta">
|
||||||
|
<span class="meta-prep meta-prep-author">Posted on</span> <a href="http://10.211.55.8/wordpress/?p=1" title="8:41 pm" rel="bookmark"><span class="entry-date">September 15, 2012</span></a> <span class="meta-sep">by</span> <span class="author vcard"><a class="url fn n" href="http://10.211.55.8/wordpress/?author=1" title="View all posts by admin">admin</a></span> </div><!-- .entry-meta -->
|
||||||
|
|
||||||
|
<div class="entry-content">
|
||||||
|
<p>Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!</p>
|
||||||
|
<p><span class='st_facebook_buttons' st_title='Hello world!' st_url='http://10.211.55.8/wordpress/?p=1' displayText='Facebook'></span><span class='st_twitter_buttons' st_title='Hello world!' st_url='http://10.211.55.8/wordpress/?p=1' displayText='Twitter'></span><span class='st_email_buttons' st_title='Hello world!' st_url='http://10.211.55.8/wordpress/?p=1' displayText='Email'></span><span class='st_sharethis_buttons' st_title='Hello world!' st_url='http://10.211.55.8/wordpress/?p=1' displayText='ShareThis'></span><span class='st_fblike_buttons' st_title='Hello world!' st_url='http://10.211.55.8/wordpress/?p=1' displayText='Facebook Like'></span><span class='st_plusone_buttons' st_title='Hello world!' st_url='http://10.211.55.8/wordpress/?p=1' displayText='Google +1'></span><span class='st_pinterest _buttons' st_title='Hello world!' st_url='http://10.211.55.8/wordpress/?p=1' displayText='Pinterest'></span></p> </div><!-- .entry-content -->
|
||||||
|
|
||||||
|
<div class="entry-utility">
|
||||||
|
<span class="cat-links">
|
||||||
|
<span class="entry-utility-prep entry-utility-prep-cat-links">Posted in</span> <a href="http://10.211.55.8/wordpress/?cat=1" title="View all posts in Uncategorized" rel="category">Uncategorized</a> </span>
|
||||||
|
<span class="meta-sep">|</span>
|
||||||
|
<span class="comments-link"><a href="http://10.211.55.8/wordpress/?p=1#comments" title="Comment on Hello world!">1 Comment</a></span>
|
||||||
|
</div><!-- .entry-utility -->
|
||||||
|
</div><!-- #post-## -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div><!-- #content -->
|
||||||
|
</div><!-- #container -->
|
||||||
|
|
||||||
|
|
||||||
|
<div id="primary" class="widget-area" role="complementary">
|
||||||
|
<ul class="xoxo">
|
||||||
|
|
||||||
|
<li id="search-2" class="widget-container widget_search"><form role="search" method="get" id="searchform" action="http://10.211.55.8/wordpress/" >
|
||||||
|
<div><label class="screen-reader-text" for="s">Search for:</label>
|
||||||
|
<input type="text" value="" name="s" id="s" />
|
||||||
|
<input type="submit" id="searchsubmit" value="Search" />
|
||||||
|
</div>
|
||||||
|
</form></li> <li id="recent-posts-2" class="widget-container widget_recent_entries"> <h3 class="widget-title">Recent Posts</h3> <ul>
|
||||||
|
<li><a href="http://10.211.55.8/wordpress/?p=1" title="Hello world!">Hello world!</a></li>
|
||||||
|
</ul>
|
||||||
|
</li><li id="recent-comments-2" class="widget-container widget_recent_comments"><h3 class="widget-title">Recent Comments</h3><ul id="recentcomments"><li class="recentcomments"><a href='http://wordpress.org/' rel='external nofollow' class='url'>Mr WordPress</a> on <a href="http://10.211.55.8/wordpress/?p=1#comment-1">Hello world!</a></li></ul></li><li id="archives-2" class="widget-container widget_archive"><h3 class="widget-title">Archives</h3> <ul>
|
||||||
|
<li><a href='http://10.211.55.8/wordpress/?m=201209' title='September 2012'>September 2012</a></li>
|
||||||
|
</ul>
|
||||||
|
</li><li id="categories-2" class="widget-container widget_categories"><h3 class="widget-title">Categories</h3> <ul>
|
||||||
|
<li class="cat-item cat-item-1"><a href="http://10.211.55.8/wordpress/?cat=1" title="View all posts filed under Uncategorized">Uncategorized</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li><li id="meta-2" class="widget-container widget_meta"><h3 class="widget-title">Meta</h3> <ul>
|
||||||
|
<li><a href="http://10.211.55.8/wordpress/wp-login.php">Log in</a></li>
|
||||||
|
<li><a href="http://10.211.55.8/wordpress/?feed=rss2" title="Syndicate this site using RSS 2.0">Entries <abbr title="Really Simple Syndication">RSS</abbr></a></li>
|
||||||
|
<li><a href="http://10.211.55.8/wordpress/?feed=comments-rss2" title="The latest comments to all posts in RSS">Comments <abbr title="Really Simple Syndication">RSS</abbr></a></li>
|
||||||
|
<li><a href="http://wordpress.org/" title="Powered by WordPress, state-of-the-art semantic personal publishing platform.">WordPress.org</a></li>
|
||||||
|
</ul>
|
||||||
|
</li> </ul>
|
||||||
|
</div><!-- #primary .widget-area -->
|
||||||
|
|
||||||
|
</div><!-- #main -->
|
||||||
|
|
||||||
|
<div id="footer" role="contentinfo">
|
||||||
|
<div id="colophon">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div id="site-info">
|
||||||
|
<a href="http://10.211.55.8/wordpress/" title="test" rel="home">
|
||||||
|
test </a>
|
||||||
|
</div><!-- #site-info -->
|
||||||
|
|
||||||
|
<div id="site-generator">
|
||||||
|
<a href="http://wordpress.org/" title="Semantic Personal Publishing Platform" rel="generator">Proudly powered by WordPress.</a>
|
||||||
|
</div><!-- #site-generator -->
|
||||||
|
|
||||||
|
</div><!-- #colophon -->
|
||||||
|
</div><!-- #footer -->
|
||||||
|
|
||||||
|
</div><!-- #wrapper -->
|
||||||
|
|
||||||
|
<script type='text/javascript' src='http://10.211.55.8/wordpress/wp-content/plugins/contact-form-7/includes/js/jquery.form.js?ver=3.14'></script>
|
||||||
|
<script type='text/javascript'>
|
||||||
|
/* <![CDATA[ */
|
||||||
|
var _wpcf7 = {"loaderUrl":"http:\/\/10.211.55.8\/wordpress\/wp-content\/plugins\/contact-form-7\/images\/ajax-loader.gif","sending":"Sending ..."};
|
||||||
|
/* ]]> */
|
||||||
|
</script>
|
||||||
|
<script type='text/javascript' src='http://10.211.55.8/wordpress/wp-content/plugins/contact-form-7/includes/js/scripts.js?ver=3.2.1'></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
26
spec/fixtures/wpscan/modules/wp_themes/passive_detection/various_themes.htm
vendored
Normal file
26
spec/fixtures/wpscan/modules/wp_themes/passive_detection/various_themes.htm
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="fr-FR">
|
||||||
|
<head profile="http://gmpg.org/xfn/11">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||||
|
<meta property="fb:page_id" content="18968879441564"/>
|
||||||
|
<title>Example.com</title>
|
||||||
|
<link rel="alternate" type="application/rss+xml" title="Example RSS Feed" href="http://example.com/feed"/>
|
||||||
|
<link rel="alternate" type="application/atom+xml" title="Example Atom Feed" href="http://example.com/feed/atom"/>
|
||||||
|
<link rel="pingback" href="http://example.com/xmlrpc.php"/>
|
||||||
|
|
||||||
|
<link type="text/css" rel="stylesheet" href="http://example.localhost/wp-content/themes/theme1/style.css" />
|
||||||
|
<link type="text/css" rel="stylesheet" href="http://example.localhost/wp-content/themes/theme2/javascript.js" />
|
||||||
|
<link type="text/css" rel="stylesheet" href="http://example.localhost/wp-content/themes/theme3/test.png" />
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="top">
|
||||||
|
<div class="header">
|
||||||
|
<h1 class="logo">
|
||||||
|
Blablabla
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<script type='text/javascript' src='http://platform.twitter.com/widgets.js?ver=1.0.0'></script>
|
||||||
|
</html>
|
||||||
25
spec/fixtures/wpscan/modules/wp_themes/theme_vulns.xml
vendored
Normal file
25
spec/fixtures/wpscan/modules/wp_themes/theme_vulns.xml
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<themes>
|
||||||
|
<theme name="shopperpress">
|
||||||
|
<vulnerability>
|
||||||
|
<title>ShopperPress WordPress Theme 2.7 Cross Site Scripting</title>
|
||||||
|
<reference>http://packetstormsecurity.org/files/115630/</reference>
|
||||||
|
<type>XSS</type>
|
||||||
|
</vulnerability>
|
||||||
|
</theme>
|
||||||
|
|
||||||
|
<theme name="wise">
|
||||||
|
<vulnerability>
|
||||||
|
<title>Site5 Wordpress Themes Email Spoofing</title>
|
||||||
|
<reference>http://packetstormsecurity.org/files/114750/</reference>
|
||||||
|
<type>UNKNOWN</type>
|
||||||
|
</vulnerability>
|
||||||
|
</theme>
|
||||||
|
|
||||||
|
<theme name="webfolio">
|
||||||
|
<vulnerability>
|
||||||
|
<title>Site5 Wordpress Themes Email Spoofing</title>
|
||||||
|
<reference>http://packetstormsecurity.org/files/114750/</reference>
|
||||||
|
<type>UNKNOWN</type>
|
||||||
|
</vulnerability>
|
||||||
|
</theme>
|
||||||
|
</themes>
|
||||||
10
spec/fixtures/wpscan/modules/wp_themes/themes.txt
vendored
Normal file
10
spec/fixtures/wpscan/modules/wp_themes/themes.txt
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
zenpro/404.php
|
||||||
|
zeta-zip/404.php
|
||||||
|
zfirst/404.php
|
||||||
|
zgrey/404.php
|
||||||
|
zindi-ii/404.php
|
||||||
|
zindi/404.php
|
||||||
|
zombie-apocalypse/404.php
|
||||||
|
zsofa/404.php
|
||||||
|
zwei-seiten/404.php
|
||||||
|
twentyten/404.php
|
||||||
@@ -20,12 +20,12 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|||||||
|
|
||||||
describe Browser do
|
describe Browser do
|
||||||
CONFIG_FILE_WITHOUT_PROXY = SPEC_FIXTURES_CONF_DIR + '/browser/browser.conf.json'
|
CONFIG_FILE_WITHOUT_PROXY = SPEC_FIXTURES_CONF_DIR + '/browser/browser.conf.json'
|
||||||
CONFIG_FILE_WITH_PROXY = SPEC_FIXTURES_CONF_DIR + '/browser/browser.conf_proxy.json'
|
CONFIG_FILE_WITH_PROXY = SPEC_FIXTURES_CONF_DIR + '/browser/browser.conf_proxy.json'
|
||||||
INSTANCE_VARS_TO_CHECK = ['user_agent', 'user_agent_mode', 'available_user_agents', 'proxy', 'max_threads', 'request_timeout', 'cache_timeout']
|
INSTANCE_VARS_TO_CHECK = ['user_agent', 'user_agent_mode', 'available_user_agents', 'proxy', 'max_threads', 'request_timeout', 'cache_timeout']
|
||||||
|
|
||||||
before :all do
|
before :all do
|
||||||
@json_config_without_proxy = JSON.parse(File.read(CONFIG_FILE_WITHOUT_PROXY))
|
@json_config_without_proxy = JSON.parse(File.read(CONFIG_FILE_WITHOUT_PROXY))
|
||||||
@json_config_with_proxy = JSON.parse(File.read(CONFIG_FILE_WITH_PROXY))
|
@json_config_with_proxy = JSON.parse(File.read(CONFIG_FILE_WITH_PROXY))
|
||||||
end
|
end
|
||||||
|
|
||||||
before :each do
|
before :each do
|
||||||
@@ -115,8 +115,8 @@ describe Browser do
|
|||||||
it "will check the instance vars" do
|
it "will check the instance vars" do
|
||||||
Browser.reset
|
Browser.reset
|
||||||
check_instance_variables(
|
check_instance_variables(
|
||||||
Browser.instance(:config_file => CONFIG_FILE_WITHOUT_PROXY),
|
Browser.instance(:config_file => CONFIG_FILE_WITHOUT_PROXY),
|
||||||
@json_config_without_proxy
|
@json_config_without_proxy
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -125,8 +125,8 @@ describe Browser do
|
|||||||
it "will check the instance vars" do
|
it "will check the instance vars" do
|
||||||
Browser.reset
|
Browser.reset
|
||||||
check_instance_variables(
|
check_instance_variables(
|
||||||
Browser.instance(:config_file => CONFIG_FILE_WITH_PROXY),
|
Browser.instance(:config_file => CONFIG_FILE_WITH_PROXY),
|
||||||
@json_config_with_proxy
|
@json_config_with_proxy
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -136,22 +136,22 @@ describe Browser do
|
|||||||
it "will check the instance vars, with an overriden one" do
|
it "will check the instance vars, with an overriden one" do
|
||||||
Browser.reset
|
Browser.reset
|
||||||
check_instance_variables(
|
check_instance_variables(
|
||||||
Browser.instance(
|
Browser.instance(
|
||||||
:config_file => CONFIG_FILE_WITHOUT_PROXY,
|
:config_file => CONFIG_FILE_WITHOUT_PROXY,
|
||||||
:user_agent => "fake IE"
|
:user_agent => "fake IE"
|
||||||
),
|
),
|
||||||
@json_config_without_proxy.merge("user_agent" => "fake IE")
|
@json_config_without_proxy.merge("user_agent" => "fake IE")
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should not override the max_threads if max_threads = nil" do
|
it "should not override the max_threads if max_threads = nil" do
|
||||||
Browser.reset
|
Browser.reset
|
||||||
check_instance_variables(
|
check_instance_variables(
|
||||||
Browser.instance(
|
Browser.instance(
|
||||||
:config_file => CONFIG_FILE_WITHOUT_PROXY,
|
:config_file => CONFIG_FILE_WITHOUT_PROXY,
|
||||||
:max_threads => nil
|
:max_threads => nil
|
||||||
),
|
),
|
||||||
@json_config_without_proxy
|
@json_config_without_proxy
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -163,10 +163,10 @@ describe Browser do
|
|||||||
describe "#merge_request_params without proxy" do
|
describe "#merge_request_params without proxy" do
|
||||||
it "should return the default params" do
|
it "should return the default params" do
|
||||||
expected_params = {
|
expected_params = {
|
||||||
:disable_ssl_host_verification => true,
|
:disable_ssl_host_verification => true,
|
||||||
:disable_ssl_peer_verification => true,
|
:disable_ssl_peer_verification => true,
|
||||||
:headers => {'user-agent' => @browser.user_agent},
|
:headers => {'user-agent' => @browser.user_agent},
|
||||||
:cache_timeout => @json_config_without_proxy['cache_timeout']
|
:cache_timeout => @json_config_without_proxy['cache_timeout']
|
||||||
}
|
}
|
||||||
|
|
||||||
@browser.merge_request_params().should == expected_params
|
@browser.merge_request_params().should == expected_params
|
||||||
@@ -174,25 +174,25 @@ describe Browser do
|
|||||||
|
|
||||||
it "should return the default params with some values overriden" do
|
it "should return the default params with some values overriden" do
|
||||||
expected_params = {
|
expected_params = {
|
||||||
:disable_ssl_host_verification => false,
|
:disable_ssl_host_verification => false,
|
||||||
:disable_ssl_peer_verification => true,
|
:disable_ssl_peer_verification => true,
|
||||||
:headers => {'user-agent' => 'Fake IE'},
|
:headers => {'user-agent' => 'Fake IE'},
|
||||||
:cache_timeout => 0
|
:cache_timeout => 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@browser.merge_request_params(
|
@browser.merge_request_params(
|
||||||
:disable_ssl_host_verification => false,
|
:disable_ssl_host_verification => false,
|
||||||
:headers => {'user-agent' => 'Fake IE'},
|
:headers => {'user-agent' => 'Fake IE'},
|
||||||
:cache_timeout => 0
|
:cache_timeout => 0
|
||||||
).should == expected_params
|
).should == expected_params
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return the defaul params with :headers:accept = 'text/html' (should not override :headers:user-agent)" do
|
it "should return the defaul params with :headers:accept = 'text/html' (should not override :headers:user-agent)" do
|
||||||
expected_params = {
|
expected_params = {
|
||||||
:disable_ssl_host_verification => true,
|
:disable_ssl_host_verification => true,
|
||||||
:disable_ssl_peer_verification => true,
|
:disable_ssl_peer_verification => true,
|
||||||
:headers => {'user-agent' => @browser.user_agent, 'accept' => 'text/html'},
|
:headers => {'user-agent' => @browser.user_agent, 'accept' => 'text/html'},
|
||||||
:cache_timeout => @json_config_without_proxy['cache_timeout']
|
:cache_timeout => @json_config_without_proxy['cache_timeout']
|
||||||
}
|
}
|
||||||
|
|
||||||
@browser.merge_request_params(:headers => {'accept' => 'text/html'}).should == expected_params
|
@browser.merge_request_params(:headers => {'accept' => 'text/html'}).should == expected_params
|
||||||
@@ -205,11 +205,11 @@ describe Browser do
|
|||||||
browser = Browser.instance(:config_file => CONFIG_FILE_WITH_PROXY)
|
browser = Browser.instance(:config_file => CONFIG_FILE_WITH_PROXY)
|
||||||
|
|
||||||
expected_params = {
|
expected_params = {
|
||||||
:proxy => @json_config_with_proxy['proxy'],
|
:proxy => @json_config_with_proxy['proxy'],
|
||||||
:disable_ssl_host_verification => true,
|
:disable_ssl_host_verification => true,
|
||||||
:disable_ssl_peer_verification => true,
|
:disable_ssl_peer_verification => true,
|
||||||
:headers => {'user-agent' => @json_config_with_proxy['user_agent']},
|
:headers => {'user-agent' => @json_config_with_proxy['user_agent']},
|
||||||
:cache_timeout => @json_config_with_proxy['cache_timeout']
|
:cache_timeout => @json_config_with_proxy['cache_timeout']
|
||||||
}
|
}
|
||||||
|
|
||||||
browser.merge_request_params().should == expected_params
|
browser.merge_request_params().should == expected_params
|
||||||
@@ -226,11 +226,11 @@ describe Browser do
|
|||||||
url = 'http://example.com/'
|
url = 'http://example.com/'
|
||||||
|
|
||||||
stub_request(:post, url).
|
stub_request(:post, url).
|
||||||
with(:body => "login=master&password=it's me !").
|
with(:body => "login=master&password=it's me !").
|
||||||
to_return(:status => 200, :body => "Welcome Master")
|
to_return(:status => 200, :body => "Welcome Master")
|
||||||
|
|
||||||
response = @browser.post(url,
|
response = @browser.post(url,
|
||||||
:params => {:login => "master", :password => "it's me !"}
|
:params => {:login => "master", :password => "it's me !"}
|
||||||
)
|
)
|
||||||
|
|
||||||
response.should be_a Typhoeus::Response
|
response.should be_a Typhoeus::Response
|
||||||
@@ -243,7 +243,7 @@ describe Browser do
|
|||||||
url = 'http://example.com/'
|
url = 'http://example.com/'
|
||||||
|
|
||||||
stub_request(:get, url).
|
stub_request(:get, url).
|
||||||
to_return(:status => 200, :body => "Hello World !")
|
to_return(:status => 200, :body => "Hello World !")
|
||||||
|
|
||||||
response = @browser.get(url)
|
response = @browser.get(url)
|
||||||
|
|
||||||
@@ -278,7 +278,7 @@ describe Browser do
|
|||||||
url = 'http://example.localhost'
|
url = 'http://example.localhost'
|
||||||
|
|
||||||
stub_request(:get, url).
|
stub_request(:get, url).
|
||||||
to_return(:status => 200, :body => "Hello World !")
|
to_return(:status => 200, :body => "Hello World !")
|
||||||
|
|
||||||
response1 = @browser.get(url)
|
response1 = @browser.get(url)
|
||||||
response2 = @browser.get(url)
|
response2 = @browser.get(url)
|
||||||
|
|||||||
@@ -74,16 +74,16 @@ describe CacheFileStore do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "should get the correct entry (string)" do
|
it "should get the correct entry (string)" do
|
||||||
@timeout = 10
|
@timeout = 10
|
||||||
@key = "some_key"
|
@key = "some_key"
|
||||||
@data = "Hello World !"
|
@data = "Hello World !"
|
||||||
@expected = @data
|
@expected = @data
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should not write the entry" do
|
it "should not write the entry" do
|
||||||
@timeout = 0
|
@timeout = 0
|
||||||
@key = "another_key"
|
@key = "another_key"
|
||||||
@data = "Another Hello World !"
|
@data = "Another Hello World !"
|
||||||
@expected = nil
|
@expected = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -14,12 +14,12 @@ describe GitUpdater do
|
|||||||
|
|
||||||
it "should return false if the command is not found" do
|
it "should return false if the command is not found" do
|
||||||
@stub_value = "git: command not found"
|
@stub_value = "git: command not found"
|
||||||
@expected = false
|
@expected = false
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return true if the repo is a git one" do
|
it "should return true if the repo is a git one" do
|
||||||
@stub_value = "# On branch master\n# Changed but not updated:"
|
@stub_value = "# On branch master\n# Changed but not updated:"
|
||||||
@expected = true
|
@expected = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -19,9 +19,9 @@
|
|||||||
shared_examples_for "Malwares" do
|
shared_examples_for "Malwares" do
|
||||||
|
|
||||||
before :each do
|
before :each do
|
||||||
@module = WpScanModuleSpec.new('http://example.localhost')
|
@module = WpScanModuleSpec.new('http://example.localhost')
|
||||||
@target_url = @module.uri.to_s
|
@target_url = @module.uri.to_s
|
||||||
@fixtures_dir = SPEC_FIXTURES_WPSCAN_MODULES_DIR + '/malwares'
|
@fixtures_dir = SPEC_FIXTURES_WPSCAN_MODULES_DIR + '/malwares'
|
||||||
@malwares_file_path = @fixtures_dir + '/malwares.txt'
|
@malwares_file_path = @fixtures_dir + '/malwares.txt'
|
||||||
|
|
||||||
@module.extend(Malwares)
|
@module.extend(Malwares)
|
||||||
|
|||||||
@@ -50,14 +50,14 @@ shared_examples_for "WebSite" do
|
|||||||
|
|
||||||
it "should return true if the wp-login is found and is a valid wordpress one" do
|
it "should return true if the wp-login is found and is a valid wordpress one" do
|
||||||
stub_request(:get, @module.login_url).
|
stub_request(:get, @module.login_url).
|
||||||
to_return(:status => 200, :body => File.new(fixtures_dir + '/wp-login.php'))
|
to_return(:status => 200, :body => File.new(fixtures_dir + '/wp-login.php'))
|
||||||
|
|
||||||
@module.is_wordpress?.should be_true
|
@module.is_wordpress?.should be_true
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return true if the xmlrpc is found" do
|
it "should return true if the xmlrpc is found" do
|
||||||
stub_request(:get, @module.xmlrpc_url).
|
stub_request(:get, @module.xmlrpc_url).
|
||||||
to_return(:status => 200, :body => File.new(fixtures_dir + '/xmlrpc.php'))
|
to_return(:status => 200, :body => File.new(fixtures_dir + '/xmlrpc.php'))
|
||||||
|
|
||||||
@module.is_wordpress?.should be_true
|
@module.is_wordpress?.should be_true
|
||||||
end
|
end
|
||||||
@@ -85,7 +85,7 @@ shared_examples_for "WebSite" do
|
|||||||
[301, 302].each do |status_code|
|
[301, 302].each do |status_code|
|
||||||
it "should return http://new-location.com if the status code is #{status_code}" do
|
it "should return http://new-location.com if the status code is #{status_code}" do
|
||||||
stub_request(:get, @module.url).
|
stub_request(:get, @module.url).
|
||||||
to_return(:status => status_code, :headers => { :location => "http://new-location.com" })
|
to_return(:status => status_code, :headers => {:location => "http://new-location.com"})
|
||||||
|
|
||||||
@module.redirection.should === "http://new-location.com"
|
@module.redirection.should === "http://new-location.com"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -19,8 +19,8 @@
|
|||||||
shared_examples_for "WpConfigBackup" do
|
shared_examples_for "WpConfigBackup" do
|
||||||
|
|
||||||
before :all do
|
before :all do
|
||||||
@module = WpScanModuleSpec.new('http://example.localhost')
|
@module = WpScanModuleSpec.new('http://example.localhost')
|
||||||
@fixtures_dir = SPEC_FIXTURES_WPSCAN_MODULES_DIR + '/wp_config_backup'
|
@fixtures_dir = SPEC_FIXTURES_WPSCAN_MODULES_DIR + '/wp_config_backup'
|
||||||
@config_backup_files = WpConfigBackup.config_backup_files
|
@config_backup_files = WpConfigBackup.config_backup_files
|
||||||
|
|
||||||
@module.extend(WpConfigBackup)
|
@module.extend(WpConfigBackup)
|
||||||
@@ -34,7 +34,7 @@ shared_examples_for "WpConfigBackup" do
|
|||||||
file_url = @module.uri.merge(URI.escape(backup_file)).to_s
|
file_url = @module.uri.merge(URI.escape(backup_file)).to_s
|
||||||
|
|
||||||
stub_request(:get, file_url).
|
stub_request(:get, file_url).
|
||||||
to_return(:status => 404, :body => "")
|
to_return(:status => 404, :body => "")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ shared_examples_for "WpConfigBackup" do
|
|||||||
expected << file_url
|
expected << file_url
|
||||||
|
|
||||||
stub_request(:get, file_url).
|
stub_request(:get, file_url).
|
||||||
to_return(:status => 200, :body => File.new(@fixtures_dir + '/wp-config.php'))
|
to_return(:status => 200, :body => File.new(@fixtures_dir + '/wp-config.php'))
|
||||||
end
|
end
|
||||||
|
|
||||||
wp_config_backup = @module.config_backup
|
wp_config_backup = @module.config_backup
|
||||||
@@ -67,7 +67,7 @@ shared_examples_for "WpConfigBackup" do
|
|||||||
expected << file_url
|
expected << file_url
|
||||||
|
|
||||||
stub_request(:get, file_url).
|
stub_request(:get, file_url).
|
||||||
to_return(:status => 200, :body => File.new(@fixtures_dir + '/wp-config.php'))
|
to_return(:status => 200, :body => File.new(@fixtures_dir + '/wp-config.php'))
|
||||||
end
|
end
|
||||||
|
|
||||||
wp_config_backup = @module.config_backup
|
wp_config_backup = @module.config_backup
|
||||||
|
|||||||
@@ -35,21 +35,21 @@ shared_examples_for "WpFullPathDisclosure" do
|
|||||||
|
|
||||||
it "should return false on a 404" do
|
it "should return false on a 404" do
|
||||||
stub_request(:get, @module.full_path_disclosure_url).
|
stub_request(:get, @module.full_path_disclosure_url).
|
||||||
to_return(:status => 404)
|
to_return(:status => 404)
|
||||||
|
|
||||||
@module.has_full_path_disclosure?.should be_false
|
@module.has_full_path_disclosure?.should be_false
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return false if no fpd found (blank page for example)" do
|
it "should return false if no fpd found (blank page for example)" do
|
||||||
stub_request(:get, @module.full_path_disclosure_url).
|
stub_request(:get, @module.full_path_disclosure_url).
|
||||||
to_return(:status => 200, :body => "")
|
to_return(:status => 200, :body => "")
|
||||||
|
|
||||||
@module.has_full_path_disclosure?.should be_false
|
@module.has_full_path_disclosure?.should be_false
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return true" do
|
it "should return true" do
|
||||||
stub_request(:get, @module.full_path_disclosure_url).
|
stub_request(:get, @module.full_path_disclosure_url).
|
||||||
to_return(:status => 200, :body => File.new(@fixtures_dir + '/rss-functions-disclosure.php'))
|
to_return(:status => 200, :body => File.new(@fixtures_dir + '/rss-functions-disclosure.php'))
|
||||||
|
|
||||||
@module.has_full_path_disclosure?.should be_true
|
@module.has_full_path_disclosure?.should be_true
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ shared_examples_for "WpLoginProtection" do
|
|||||||
# there is not false positive : for example the login-lock must not be detected as login-lockdown
|
# there is not false positive : for example the login-lock must not be detected as login-lockdown
|
||||||
describe "#has_.*_protection?" do
|
describe "#has_.*_protection?" do
|
||||||
|
|
||||||
pattern = WpLoginProtection::LOGIN_PROTECTION_METHOD_PATTERN
|
pattern = WpLoginProtection::LOGIN_PROTECTION_METHOD_PATTERN
|
||||||
fixtures =
|
fixtures =
|
||||||
%w{
|
%w{
|
||||||
wp-login-clean.php wp-login-login_lockdown.php wp-login-login_lock.php
|
wp-login-clean.php wp-login-login_lockdown.php wp-login-login_lock.php
|
||||||
wp-login-better_wp_security.php wp-login-simple_login_lockdown.php wp-login-login_security_solution.php
|
wp-login-better_wp_security.php wp-login-simple_login_lockdown.php wp-login-login_security_solution.php
|
||||||
@@ -69,10 +69,10 @@ shared_examples_for "WpLoginProtection" do
|
|||||||
expected = plugin_name_from_fixture === plugin_name_from_symbol ? true : false
|
expected = plugin_name_from_fixture === plugin_name_from_symbol ? true : false
|
||||||
|
|
||||||
it "#{symbol_to_call} with #{fixture} should return #{expected}" do
|
it "#{symbol_to_call} with #{fixture} should return #{expected}" do
|
||||||
@plugin_name = plugin_name_from_fixture
|
@plugin_name = plugin_name_from_fixture
|
||||||
@fixture = @fixtures_dir + '/' + fixture
|
@fixture = @fixtures_dir + '/' + fixture
|
||||||
@symbol_to_call = symbol_to_call
|
@symbol_to_call = symbol_to_call
|
||||||
@expected = expected
|
@expected = expected
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -19,8 +19,8 @@
|
|||||||
shared_examples_for "WpPlugins" do
|
shared_examples_for "WpPlugins" do
|
||||||
|
|
||||||
before :all do
|
before :all do
|
||||||
@fixtures_dir = SPEC_FIXTURES_WPSCAN_MODULES_DIR + '/wp_plugins'
|
@fixtures_dir = SPEC_FIXTURES_WPSCAN_MODULES_DIR + '/wp_plugins'
|
||||||
@plugins_file = @fixtures_dir + "/plugins.txt"
|
@plugins_file = @fixtures_dir + "/plugins.txt"
|
||||||
@plugin_vulns_file = @fixtures_dir + "/plugin_vulns.xml"
|
@plugin_vulns_file = @fixtures_dir + "/plugin_vulns.xml"
|
||||||
|
|
||||||
@wp_url = "http://example.localhost/"
|
@wp_url = "http://example.localhost/"
|
||||||
@@ -31,42 +31,42 @@ shared_examples_for "WpPlugins" do
|
|||||||
@module.error_404_hash = Digest::MD5.hexdigest("Error 404!")
|
@module.error_404_hash = Digest::MD5.hexdigest("Error 404!")
|
||||||
@module.extend(WpPlugins)
|
@module.extend(WpPlugins)
|
||||||
|
|
||||||
@options = { :url => @wp_url,
|
@options = {:url => @wp_url,
|
||||||
:only_vulnerable_ones => false,
|
:only_vulnerable_ones => false,
|
||||||
:show_progress_bar => false,
|
:show_progress_bar => false,
|
||||||
:error_404_hash => Digest::MD5.hexdigest("Error 404!"),
|
:error_404_hash => Digest::MD5.hexdigest("Error 404!"),
|
||||||
:vulns_file => @plugin_vulns_file,
|
:vulns_file => @plugin_vulns_file,
|
||||||
:file => @plugins_file,
|
:file => @plugins_file,
|
||||||
:type => "plugins",
|
:type => "plugins",
|
||||||
:wp_content_dir => "wp-content",
|
:wp_content_dir => "wp-content",
|
||||||
:vulns_xpath_2 => "//plugin"
|
:vulns_xpath_2 => "//plugin"
|
||||||
}
|
}
|
||||||
File.exist?(@plugin_vulns_file).should == true
|
File.exist?(@plugin_vulns_file).should == true
|
||||||
File.exist?(@plugins_file).should == true
|
File.exist?(@plugins_file).should == true
|
||||||
@targets = [WpPlugin.new({:url=>"http://example.localhost/",
|
@targets = [WpPlugin.new({:url => "http://example.localhost/",
|
||||||
:path=>"plugins/exclude-pages/exclude_pages.php",
|
:path => "plugins/exclude-pages/exclude_pages.php",
|
||||||
:wp_content_dir=>"wp-content",
|
:wp_content_dir => "wp-content",
|
||||||
:name=>"exclude-pages"}),
|
:name => "exclude-pages"}),
|
||||||
WpPlugin.new({:url=>"http://example.localhost/",
|
WpPlugin.new({:url => "http://example.localhost/",
|
||||||
:path=>"plugins/display-widgets/display-widgets.php",
|
:path => "plugins/display-widgets/display-widgets.php",
|
||||||
:wp_content_dir=>"wp-content",
|
:wp_content_dir => "wp-content",
|
||||||
:name=>"display-widgets"}),
|
:name => "display-widgets"}),
|
||||||
WpPlugin.new({:url=>"http://example.localhost/",
|
WpPlugin.new({:url => "http://example.localhost/",
|
||||||
:path=>"plugins/media-library",
|
:path => "plugins/media-library",
|
||||||
:wp_content_dir=>"wp-content",
|
:wp_content_dir => "wp-content",
|
||||||
:name=>"media-library"}),
|
:name => "media-library"}),
|
||||||
WpPlugin.new({:url=>"http://example.localhost/",
|
WpPlugin.new({:url => "http://example.localhost/",
|
||||||
:path=>"plugins/deans",
|
:path => "plugins/deans",
|
||||||
:wp_content_dir=>"wp-content",
|
:wp_content_dir => "wp-content",
|
||||||
:name=>"deans"}),
|
:name => "deans"}),
|
||||||
WpPlugin.new({:url=>"http://example.localhost/",
|
WpPlugin.new({:url => "http://example.localhost/",
|
||||||
:path=>"plugins/formidable/formidable.php",
|
:path => "plugins/formidable/formidable.php",
|
||||||
:wp_content_dir=>"wp-content",
|
:wp_content_dir => "wp-content",
|
||||||
:name=>"formidable"}),
|
:name => "formidable"}),
|
||||||
WpPlugin.new({:url=>"http://example.localhost/",
|
WpPlugin.new({:url => "http://example.localhost/",
|
||||||
:path=>"plugins/regenerate-thumbnails/readme.txt",
|
:path => "plugins/regenerate-thumbnails/readme.txt",
|
||||||
:wp_content_dir=>"wp-content",
|
:wp_content_dir => "wp-content",
|
||||||
:name=>"regenerate-thumbnails"})]
|
:name => "regenerate-thumbnails"})]
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#plugins_from_passive_detection" do
|
describe "#plugins_from_passive_detection" do
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
shared_examples_for "WpReadme" do
|
shared_examples_for "WpReadme" do
|
||||||
|
|
||||||
before :all do
|
before :all do
|
||||||
@module = WpScanModuleSpec.new('http://example.localhost')
|
@module = WpScanModuleSpec.new('http://example.localhost')
|
||||||
@fixtures_dir = SPEC_FIXTURES_WPSCAN_MODULES_DIR + '/wp_readme'
|
@fixtures_dir = SPEC_FIXTURES_WPSCAN_MODULES_DIR + '/wp_readme'
|
||||||
|
|
||||||
@module.extend(WpReadme)
|
@module.extend(WpReadme)
|
||||||
@@ -35,14 +35,14 @@ shared_examples_for "WpReadme" do
|
|||||||
|
|
||||||
it "should return false on a 404" do
|
it "should return false on a 404" do
|
||||||
stub_request(:get, @module.readme_url).
|
stub_request(:get, @module.readme_url).
|
||||||
to_return(:status => 404)
|
to_return(:status => 404)
|
||||||
|
|
||||||
@module.has_readme?.should be_false
|
@module.has_readme?.should be_false
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return true if it exists" do
|
it "should return true if it exists" do
|
||||||
stub_request(:get, @module.readme_url).
|
stub_request(:get, @module.readme_url).
|
||||||
to_return(:status => 200, :body => File.new(@fixtures_dir + '/readme-3.2.1.html'))
|
to_return(:status => 200, :body => File.new(@fixtures_dir + '/readme-3.2.1.html'))
|
||||||
|
|
||||||
@module.has_readme?.should be_true
|
@module.has_readme?.should be_true
|
||||||
end
|
end
|
||||||
@@ -50,7 +50,7 @@ shared_examples_for "WpReadme" do
|
|||||||
# http://code.google.com/p/wpscan/issues/detail?id=108
|
# http://code.google.com/p/wpscan/issues/detail?id=108
|
||||||
it "should return true even if the readme.html is not in english" do
|
it "should return true even if the readme.html is not in english" do
|
||||||
stub_request(:get, @module.readme_url).
|
stub_request(:get, @module.readme_url).
|
||||||
to_return(:status => 200, :body => File.new(@fixtures_dir + '/readme-3.3.2-fr.html'))
|
to_return(:status => 200, :body => File.new(@fixtures_dir + '/readme-3.3.2-fr.html'))
|
||||||
|
|
||||||
@module.has_readme?.should be_true
|
@module.has_readme?.should be_true
|
||||||
end
|
end
|
||||||
|
|||||||
176
spec/lib/wpscan/modules/wp_themes_spec.rb
Normal file
176
spec/lib/wpscan/modules/wp_themes_spec.rb
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
#--
|
||||||
|
# WPScan - WordPress Security Scanner
|
||||||
|
# Copyright (C) 2012
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#++
|
||||||
|
|
||||||
|
shared_examples_for "WpThemes" do
|
||||||
|
|
||||||
|
before :all do
|
||||||
|
@fixtures_dir = SPEC_FIXTURES_WPSCAN_MODULES_DIR + '/wp_themes'
|
||||||
|
@themes_file = @fixtures_dir + "/themes.txt"
|
||||||
|
@theme_vulns_file = @fixtures_dir + "/theme_vulns.xml"
|
||||||
|
|
||||||
|
@wp_url = "http://example.localhost/"
|
||||||
|
end
|
||||||
|
|
||||||
|
before :each do
|
||||||
|
@module = WpScanModuleSpec.new(@wp_url)
|
||||||
|
@module.error_404_hash = Digest::MD5.hexdigest("Error 404!")
|
||||||
|
@module.extend(WpThemes)
|
||||||
|
|
||||||
|
@options = {:url => @wp_url,
|
||||||
|
:only_vulnerable_ones => false,
|
||||||
|
:show_progress_bar => false,
|
||||||
|
:error_404_hash => Digest::MD5.hexdigest("Error 404!"),
|
||||||
|
:vulns_file => @theme_vulns_file,
|
||||||
|
:file => @themes_file,
|
||||||
|
:type => "themes",
|
||||||
|
:wp_content_dir => "wp-content",
|
||||||
|
:vulns_xpath_2 => "//theme"
|
||||||
|
}
|
||||||
|
File.exist?(@theme_vulns_file).should == true
|
||||||
|
File.exist?(@themes_file).should == true
|
||||||
|
@targets = [WpTheme.new({:url => "http://example.localhost/",
|
||||||
|
:path => "themes/zenpro/404.php",
|
||||||
|
:wp_content_dir => "wp-content",
|
||||||
|
:name => "zenpro"}),
|
||||||
|
WpTheme.new({:url => "http://example.localhost/",
|
||||||
|
:path => "themes/zeta-zip/404.php",
|
||||||
|
:wp_content_dir => "wp-content",
|
||||||
|
:name => "zeta-zip"}),
|
||||||
|
WpTheme.new({:url => "http://example.localhost/",
|
||||||
|
:path => "themes/zfirst/404.php",
|
||||||
|
:wp_content_dir => "wp-content",
|
||||||
|
:name => "zfirst"}),
|
||||||
|
WpTheme.new({:url => "http://example.localhost/",
|
||||||
|
:path => "themes/zgrey/404.php",
|
||||||
|
:wp_content_dir => "wp-content",
|
||||||
|
:name => "zgrey"}),
|
||||||
|
WpTheme.new({:url => "http://example.localhost/",
|
||||||
|
:path => "themes/zindi-ii/404.php",
|
||||||
|
:wp_content_dir => "wp-content",
|
||||||
|
:name => "zindi-ii"}),
|
||||||
|
WpTheme.new({:url => "http://example.localhost/",
|
||||||
|
:path => "themes/zindi/404.php",
|
||||||
|
:wp_content_dir => "wp-content",
|
||||||
|
:name => "zindi"}),
|
||||||
|
WpTheme.new({:url => "http://example.localhost/",
|
||||||
|
:path => "themes/zombie-apocalypse/404.php",
|
||||||
|
:wp_content_dir => "wp-content",
|
||||||
|
:name => "zombie-apocalypse"}),
|
||||||
|
WpTheme.new({:url => "http://example.localhost/",
|
||||||
|
:path => "themes/zsofa/404.php",
|
||||||
|
:wp_content_dir => "wp-content",
|
||||||
|
:name => "zsofa"}),
|
||||||
|
WpTheme.new({:url => "http://example.localhost/",
|
||||||
|
:path => "themes/zwei-seiten/404.php",
|
||||||
|
:wp_content_dir => "wp-content",
|
||||||
|
:name => "zwei-seiten"}),
|
||||||
|
WpTheme.new({:url => "http://example.localhost/",
|
||||||
|
:path => "themes/twentyten/404.php",
|
||||||
|
:wp_content_dir => "wp-content",
|
||||||
|
:name => "twentyten"}),
|
||||||
|
WpTheme.new({:url => "http://example.localhost/",
|
||||||
|
:path => "themes/shopperpress",
|
||||||
|
:wp_content_dir => "wp-content",
|
||||||
|
:name => "shopperpress"}),
|
||||||
|
WpTheme.new({:url => "http://example.localhost/",
|
||||||
|
:path => "themes/wise",
|
||||||
|
:wp_content_dir => "wp-content",
|
||||||
|
:name => "wise"}),
|
||||||
|
WpTheme.new({:url => "http://example.localhost/",
|
||||||
|
:path => "themes/webfolio",
|
||||||
|
:wp_content_dir => "wp-content",
|
||||||
|
:name => "webfolio"})]
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#themes_from_passive_detection" do
|
||||||
|
let(:passive_detection_fixtures) { @fixtures_dir + '/passive_detection' }
|
||||||
|
|
||||||
|
it "should return an empty array" do
|
||||||
|
stub_request_to_fixture(:url => @module.url, :fixture => File.new(passive_detection_fixtures + '/no_theme.htm'))
|
||||||
|
themes = @module.themes_from_passive_detection(:url => @module.url, :wp_content_dir => "wp-content")
|
||||||
|
themes.should be_empty
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return the expected themes" do
|
||||||
|
stub_request_to_fixture(:url => @module.url, :fixture => File.new(passive_detection_fixtures + '/various_themes.htm'))
|
||||||
|
|
||||||
|
expected_theme_names = %w{ theme1 theme2 theme3 }
|
||||||
|
expected_themes = []
|
||||||
|
expected_theme_names.each do |theme_name|
|
||||||
|
expected_themes << WpTheme.new(:url => @module.url,
|
||||||
|
:path => "/themes/#{theme_name}/",
|
||||||
|
:name => theme_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
themes = @module.themes_from_passive_detection(:url => @module.url, :wp_content_dir => "wp-content")
|
||||||
|
themes.should_not be_empty
|
||||||
|
themes.length.should == expected_themes.length
|
||||||
|
themes.sort.should == expected_themes.sort
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#themes_from_aggressive_detection" do
|
||||||
|
|
||||||
|
before :each do
|
||||||
|
stub_request(:get, @module.uri.to_s).to_return(:status => 200)
|
||||||
|
# Point all targets to a 404
|
||||||
|
@targets.each do |target|
|
||||||
|
stub_request(:get, target.get_url.to_s).to_return(:status => 404)
|
||||||
|
# to_s calls readme_url
|
||||||
|
stub_request(:get, target.readme_url.to_s).to_return(:status => 404)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
after :each do
|
||||||
|
@passive_detection_fixture = SPEC_FIXTURES_DIR + "/empty-file" unless @passive_detection_fixture
|
||||||
|
stub_request_to_fixture(:url => "#{@module.uri}/".sub(/\/\/$/, "/"), :fixture => @passive_detection_fixture)
|
||||||
|
detected = @module.themes_from_aggressive_detection(@options)
|
||||||
|
detected.length.should == @expected_themes.length
|
||||||
|
detected.sort.should == @expected_themes.sort
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return an empty array" do
|
||||||
|
@expected_themes = []
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return an array with 3 WpTheme (1 detected from passive method)" do
|
||||||
|
@passive_detection_fixture = @fixtures_dir + "/passive_detection/one_theme.htm"
|
||||||
|
@expected_themes = @targets.sample(2)
|
||||||
|
@expected_themes.each do |p|
|
||||||
|
stub_request(:get, p.get_url.to_s).to_return(:status => 200)
|
||||||
|
end
|
||||||
|
new_theme = WpTheme.new(:url => "http://example.localhost/",
|
||||||
|
:path => "/themes/custom-twentyten/",
|
||||||
|
:name => "custom-twentyten")
|
||||||
|
stub_request(:get, new_theme.readme_url.to_s).to_return(:status => 200)
|
||||||
|
@expected_themes << new_theme
|
||||||
|
end
|
||||||
|
|
||||||
|
# testing response codes
|
||||||
|
WpTarget.valid_response_codes.each do |valid_response_code|
|
||||||
|
it "should detect the theme if the reponse.code is #{valid_response_code}" do
|
||||||
|
@expected_themes = []
|
||||||
|
theme_url = [@targets.sample(1)[0]]
|
||||||
|
theme_url.should_not be_nil
|
||||||
|
theme_url.length.should == 1
|
||||||
|
@expected_themes = theme_url
|
||||||
|
stub_request(:get, theme_url[0].get_url.to_s).to_return(:status => valid_response_code)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -19,33 +19,33 @@
|
|||||||
shared_examples_for "WpTimthumbs" do
|
shared_examples_for "WpTimthumbs" do
|
||||||
|
|
||||||
before :each do
|
before :each do
|
||||||
@options = {}
|
@options = {}
|
||||||
@url = "http://example.localhost/"
|
@url = "http://example.localhost/"
|
||||||
@theme_name = "bueno"
|
@theme_name = "bueno"
|
||||||
@options[:url] = @url
|
@options[:url] = @url
|
||||||
@options[:wp_content_dir] = "wp-content"
|
@options[:wp_content_dir] = "wp-content"
|
||||||
@options[:name] = @theme_name
|
@options[:name] = @theme_name
|
||||||
@options[:error_404_hash] = "xx"
|
@options[:error_404_hash] = "xx"
|
||||||
@options[:show_progress_bar] = false
|
@options[:show_progress_bar] = false
|
||||||
@options[:only_vulnerable_ones] = false
|
@options[:only_vulnerable_ones] = false
|
||||||
@module = WpScanModuleSpec.new(@url)
|
@module = WpScanModuleSpec.new(@url)
|
||||||
@fixtures_dir = SPEC_FIXTURES_WPSCAN_MODULES_DIR + "/wp_timthumbs"
|
@fixtures_dir = SPEC_FIXTURES_WPSCAN_MODULES_DIR + "/wp_timthumbs"
|
||||||
@timthumbs_file = @fixtures_dir + "/timthumbs.txt"
|
@timthumbs_file = @fixtures_dir + "/timthumbs.txt"
|
||||||
@targets_from_file =
|
@targets_from_file =
|
||||||
%w{
|
%w{
|
||||||
http://example.localhost/wp-content/plugins/fotoslide/timthumb.php
|
http://example.localhost/wp-content/plugins/fotoslide/timthumb.php
|
||||||
http://example.localhost/wp-content/plugins/feature-slideshow/timthumb.php
|
http://example.localhost/wp-content/plugins/feature-slideshow/timthumb.php
|
||||||
}
|
}
|
||||||
@targets_from_theme =
|
@targets_from_theme =
|
||||||
[
|
[
|
||||||
"http://example.localhost/wp-content/themes/" + @theme_name + "/timthumb.php",
|
"http://example.localhost/wp-content/themes/" + @theme_name + "/timthumb.php",
|
||||||
"http://example.localhost/wp-content/themes/" + @theme_name + "/lib/timthumb.php",
|
"http://example.localhost/wp-content/themes/" + @theme_name + "/lib/timthumb.php",
|
||||||
"http://example.localhost/wp-content/themes/" + @theme_name + "/inc/timthumb.php",
|
"http://example.localhost/wp-content/themes/" + @theme_name + "/inc/timthumb.php",
|
||||||
"http://example.localhost/wp-content/themes/" + @theme_name + "/includes/timthumb.php",
|
"http://example.localhost/wp-content/themes/" + @theme_name + "/includes/timthumb.php",
|
||||||
"http://example.localhost/wp-content/themes/" + @theme_name + "/scripts/timthumb.php",
|
"http://example.localhost/wp-content/themes/" + @theme_name + "/scripts/timthumb.php",
|
||||||
"http://example.localhost/wp-content/themes/" + @theme_name + "/tools/timthumb.php",
|
"http://example.localhost/wp-content/themes/" + @theme_name + "/tools/timthumb.php",
|
||||||
"http://example.localhost/wp-content/themes/" + @theme_name + "/functions/timthumb.php"
|
"http://example.localhost/wp-content/themes/" + @theme_name + "/functions/timthumb.php"
|
||||||
]
|
]
|
||||||
|
|
||||||
@module.extend(WpTimthumbs)
|
@module.extend(WpTimthumbs)
|
||||||
end
|
end
|
||||||
@@ -93,7 +93,7 @@ shared_examples_for "WpTimthumbs" do
|
|||||||
urls.sample(2).each do |target_url|
|
urls.sample(2).each do |target_url|
|
||||||
expected << target_url
|
expected << target_url
|
||||||
stub_request(:get, target_url).
|
stub_request(:get, target_url).
|
||||||
to_return(:status => 200, :body => File.new(@fixtures_dir + "/timthumb.php"))
|
to_return(:status => 200, :body => File.new(@fixtures_dir + "/timthumb.php"))
|
||||||
end
|
end
|
||||||
|
|
||||||
timthumbs = @module.timthumbs(nil, @options)
|
timthumbs = @module.timthumbs(nil, @options)
|
||||||
|
|||||||
@@ -19,8 +19,8 @@
|
|||||||
shared_examples_for "WpUsernames" do
|
shared_examples_for "WpUsernames" do
|
||||||
|
|
||||||
before :each do
|
before :each do
|
||||||
@target_url = 'http://example.localhost/'
|
@target_url = 'http://example.localhost/'
|
||||||
@module = WpScanModuleSpec.new(@target_url)
|
@module = WpScanModuleSpec.new(@target_url)
|
||||||
@fixtures_dir = SPEC_FIXTURES_WPSCAN_MODULES_DIR + '/wp_usernames'
|
@fixtures_dir = SPEC_FIXTURES_WPSCAN_MODULES_DIR + '/wp_usernames'
|
||||||
|
|
||||||
@module.extend(WpUsernames)
|
@module.extend(WpUsernames)
|
||||||
@@ -33,7 +33,7 @@ shared_examples_for "WpUsernames" do
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe "#usernames" do
|
describe "#usernames" do
|
||||||
before :each do
|
before :each do
|
||||||
(1..10).each do |index|
|
(1..10).each do |index|
|
||||||
stub_request(:get, @module.author_url(index)).to_return(:status => 404)
|
stub_request(:get, @module.author_url(index)).to_return(:status => 404)
|
||||||
end
|
end
|
||||||
@@ -45,7 +45,7 @@ shared_examples_for "WpUsernames" do
|
|||||||
|
|
||||||
it "should return an array with 1 username (from header location)" do
|
it "should return an array with 1 username (from header location)" do
|
||||||
stub_request(:get, @module.author_url(3)).
|
stub_request(:get, @module.author_url(3)).
|
||||||
to_return(:status => 301, :headers => { 'location' => '/author/Youhou/'})
|
to_return(:status => 301, :headers => {'location' => '/author/Youhou/'})
|
||||||
|
|
||||||
usernames = @module.usernames
|
usernames = @module.usernames
|
||||||
usernames.should_not be_empty
|
usernames.should_not be_empty
|
||||||
@@ -57,7 +57,7 @@ shared_examples_for "WpUsernames" do
|
|||||||
|
|
||||||
it "should return an array with 1 username (from in the body response)" do
|
it "should return an array with 1 username (from in the body response)" do
|
||||||
stub_request(:get, @module.author_url(2)).
|
stub_request(:get, @module.author_url(2)).
|
||||||
to_return(:status => 200, :body => File.new(@fixtures_dir + '/admin.htm'))
|
to_return(:status => 200, :body => File.new(@fixtures_dir + '/admin.htm'))
|
||||||
|
|
||||||
usernames = @module.usernames(:range => (1..2))
|
usernames = @module.usernames(:range => (1..2))
|
||||||
usernames.should_not be_empty
|
usernames.should_not be_empty
|
||||||
@@ -66,17 +66,17 @@ shared_examples_for "WpUsernames" do
|
|||||||
|
|
||||||
it "should return an array with 2 usernames (one is a duplicate and should not be present twice)" do
|
it "should return an array with 2 usernames (one is a duplicate and should not be present twice)" do
|
||||||
stub_request(:get, @module.author_url(4)).
|
stub_request(:get, @module.author_url(4)).
|
||||||
to_return(:status => 301, :headers => { 'location' => '/author/Youhou/'})
|
to_return(:status => 301, :headers => {'location' => '/author/Youhou/'})
|
||||||
|
|
||||||
stub_request(:get, @module.author_url(2)).
|
stub_request(:get, @module.author_url(2)).
|
||||||
to_return(:status => 200, :body => File.new(@fixtures_dir + '/admin.htm'))
|
to_return(:status => 200, :body => File.new(@fixtures_dir + '/admin.htm'))
|
||||||
|
|
||||||
usernames = @module.usernames(:range => (1..5))
|
usernames = @module.usernames(:range => (1..5))
|
||||||
usernames.should_not be_empty
|
usernames.should_not be_empty
|
||||||
expected = [WpUser.new("admin", 2, "admin | Wordpress 3.3.2"),
|
expected = [WpUser.new("admin", 2, "admin | Wordpress 3.3.2"),
|
||||||
WpUser.new("Youhou", 4, "empty")]
|
WpUser.new("Youhou", 4, "empty")]
|
||||||
|
|
||||||
usernames.sort_by {|u| u.name}.eql?(expected.sort_by {|u| u.name}).should be_true
|
usernames.sort_by { |u| u.name }.eql?(expected.sort_by { |u| u.name }).should be_true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -20,11 +20,11 @@ require File.expand_path(File.dirname(__FILE__) + '/wpscan_helper')
|
|||||||
|
|
||||||
describe WpPlugin do
|
describe WpPlugin do
|
||||||
before :each do
|
before :each do
|
||||||
@instance = WpItem.new(:url => "http://sub.example.com/path/to/wordpress/",
|
@instance = WpItem.new(:url => "http://sub.example.com/path/to/wordpress/",
|
||||||
:path => "plugins/test/asdf.php",
|
:path => "plugins/test/asdf.php",
|
||||||
:vulns_xml => "XXX.xml",
|
:vulns_xml => "XXX.xml",
|
||||||
:name => "test",
|
:name => "test",
|
||||||
:vulns_xpath => "XX"
|
:vulns_xpath => "XX"
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -174,19 +174,19 @@ describe WpPlugin do
|
|||||||
|
|
||||||
describe "#==" do
|
describe "#==" do
|
||||||
it "should return false" do
|
it "should return false" do
|
||||||
instance2 = WpItem.new(:url => "http://sub.example.com/path/to/wordpress/",
|
instance2 = WpItem.new(:url => "http://sub.example.com/path/to/wordpress/",
|
||||||
:path => "plugins/newname/asdf.php",
|
:path => "plugins/newname/asdf.php",
|
||||||
:vulns_xml => "XXX.xml",
|
:vulns_xml => "XXX.xml",
|
||||||
:vulns_xpath => "XX"
|
:vulns_xpath => "XX"
|
||||||
)
|
)
|
||||||
(@instance==instance2).should == false
|
(@instance==instance2).should == false
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return true" do
|
it "should return true" do
|
||||||
instance2 = WpItem.new(:url => "http://sub.example.com/path/to/wordpress/",
|
instance2 = WpItem.new(:url => "http://sub.example.com/path/to/wordpress/",
|
||||||
:path => "plugins/test/asdf.php",
|
:path => "plugins/test/asdf.php",
|
||||||
:vulns_xml => "XXX.xml",
|
:vulns_xml => "XXX.xml",
|
||||||
:vulns_xpath => "XX"
|
:vulns_xpath => "XX"
|
||||||
)
|
)
|
||||||
(@instance==instance2).should == true
|
(@instance==instance2).should == true
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -22,16 +22,16 @@ describe WpOptions do
|
|||||||
describe "#check_options" do
|
describe "#check_options" do
|
||||||
before :each do
|
before :each do
|
||||||
@options = {}
|
@options = {}
|
||||||
@options[:url] = "url"
|
@options[:url] = "url"
|
||||||
@options[:only_vulnerable_ones] = false
|
@options[:only_vulnerable_ones] = false
|
||||||
@options[:file] = "file"
|
@options[:file] = "file"
|
||||||
@options[:vulns_file] = "vulns_file"
|
@options[:vulns_file] = "vulns_file"
|
||||||
@options[:vulns_xpath] = "vulns_xpath"
|
@options[:vulns_xpath] = "vulns_xpath"
|
||||||
@options[:vulns_xpath_2] = "vulns_xpath_2"
|
@options[:vulns_xpath_2] = "vulns_xpath_2"
|
||||||
@options[:wp_content_dir] = "wp_content_dir"
|
@options[:wp_content_dir] = "wp_content_dir"
|
||||||
@options[:show_progress_bar] = true
|
@options[:show_progress_bar] = true
|
||||||
@options[:error_404_hash] = "error_404_hash"
|
@options[:error_404_hash] = "error_404_hash"
|
||||||
@options[:type] = "type"
|
@options[:type] = "type"
|
||||||
|
|
||||||
@message = ""
|
@message = ""
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -43,16 +43,16 @@ describe WpPlugin do
|
|||||||
|
|
||||||
describe "#error_log_url" do
|
describe "#error_log_url" do
|
||||||
it "should return a correct url" do
|
it "should return a correct url" do
|
||||||
temp = WpPlugin.new(:url => "http://wordpress.com",
|
temp = WpPlugin.new(:url => "http://wordpress.com",
|
||||||
:path => "plugins/test/asdf.php")
|
:path => "plugins/test/asdf.php")
|
||||||
temp.error_log_url.to_s.should == "http://wordpress.com/wp-content/plugins/test/error_log"
|
temp.error_log_url.to_s.should == "http://wordpress.com/wp-content/plugins/test/error_log"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#error_log?" do
|
describe "#error_log?" do
|
||||||
before :each do
|
before :each do
|
||||||
@temp = WpPlugin.new(:url => "http://wordpress.com",
|
@temp = WpPlugin.new(:url => "http://wordpress.com",
|
||||||
:path => "plugins/test/asdf.php")
|
:path => "plugins/test/asdf.php")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return true" do
|
it "should return true" do
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ describe WpTarget do
|
|||||||
it_should_behave_like "WpUsernames"
|
it_should_behave_like "WpUsernames"
|
||||||
it_should_behave_like "WpTimthumbs"
|
it_should_behave_like "WpTimthumbs"
|
||||||
it_should_behave_like "WpPlugins"
|
it_should_behave_like "WpPlugins"
|
||||||
|
it_should_behave_like "WpThemes"
|
||||||
|
|
||||||
describe "#initialize" do
|
describe "#initialize" do
|
||||||
it "should raise an error if the target_url is nil or empty" do
|
it "should raise an error if the target_url is nil or empty" do
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ describe WpTheme do
|
|||||||
@target_uri = URI.parse("http://example.localhost/")
|
@target_uri = URI.parse("http://example.localhost/")
|
||||||
|
|
||||||
Browser.instance(
|
Browser.instance(
|
||||||
:config_file => SPEC_FIXTURES_CONF_DIR + "/browser/browser.conf.json",
|
:config_file => SPEC_FIXTURES_CONF_DIR + "/browser/browser.conf.json",
|
||||||
:cache_timeout => 0
|
:cache_timeout => 0
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -70,20 +70,20 @@ describe WpTheme do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "should return a WpTheme object with .name = twentyeleven" do
|
it "should return a WpTheme object with .name = twentyeleven" do
|
||||||
@fixture = fixtures_dir + "/wordpress-twentyeleven.htm"
|
@fixture = fixtures_dir + "/wordpress-twentyeleven.htm"
|
||||||
@expected_name = "twentyeleven"
|
@expected_name = "twentyeleven"
|
||||||
end
|
end
|
||||||
|
|
||||||
# http://code.google.com/p/wpscan/issues/detail?id=131
|
# http://code.google.com/p/wpscan/issues/detail?id=131
|
||||||
# Theme name with spaces raises bad URI(is not URI?)
|
# Theme name with spaces raises bad URI(is not URI?)
|
||||||
it "should not raise an error if the theme name has spaces or special chars" do
|
it "should not raise an error if the theme name has spaces or special chars" do
|
||||||
@fixture = fixtures_dir + "/theme-name-with-spaces.html"
|
@fixture = fixtures_dir + "/theme-name-with-spaces.html"
|
||||||
@expected_name = "Copia di simplefolio"
|
@expected_name = "Copia di simplefolio"
|
||||||
end
|
end
|
||||||
|
|
||||||
# https://github.com/wpscanteam/wpscan/issues/18
|
# https://github.com/wpscanteam/wpscan/issues/18
|
||||||
it "should get the theme if the <link> is inline with some other tags" do
|
it "should get the theme if the <link> is inline with some other tags" do
|
||||||
@fixture = fixtures_dir + "/inline_link_tag.html"
|
@fixture = fixtures_dir + "/inline_link_tag.html"
|
||||||
@expected_name = "inline"
|
@expected_name = "inline"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -128,7 +128,7 @@ describe WpTheme do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "should return nil if no theme is found" do
|
it "should return nil if no theme is found" do
|
||||||
@fixture = SPEC_FIXTURES_DIR + "/empty-file"
|
@fixture = SPEC_FIXTURES_DIR + "/empty-file"
|
||||||
@expected_name = nil
|
@expected_name = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ describe WpTheme do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "should return nil if the version is not found" do
|
it "should return nil if the version is not found" do
|
||||||
@fixture = fixtures_dir + "/twentyeleven-unknow.css"
|
@fixture = fixtures_dir + "/twentyeleven-unknow.css"
|
||||||
@expected = nil
|
@expected = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -167,69 +167,69 @@ describe WpTheme do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "should return 1.3" do
|
it "should return 1.3" do
|
||||||
@fixture = fixtures_dir + "/twentyeleven-1.3.css"
|
@fixture = fixtures_dir + "/twentyeleven-1.3.css"
|
||||||
@expected = "1.3"
|
@expected = "1.3"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return 1.5.1" do
|
it "should return 1.5.1" do
|
||||||
@fixture = fixtures_dir + "/bueno-1.5.1.css"
|
@fixture = fixtures_dir + "/bueno-1.5.1.css"
|
||||||
@expected = "1.5.1"
|
@expected = "1.5.1"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#===" do
|
describe "#===" do
|
||||||
it "should return false (name not equal)" do
|
it "should return false (name not equal)" do
|
||||||
instance = WpTheme.new(:url => "http://sub.example.com/path/to/wordpress/",
|
instance = WpTheme.new(:url => "http://sub.example.com/path/to/wordpress/",
|
||||||
:path => "themes/name/asdf.php",
|
:path => "themes/name/asdf.php",
|
||||||
:vulns_xml => "XXX.xml",
|
:vulns_xml => "XXX.xml",
|
||||||
:version => "1.0"
|
:version => "1.0"
|
||||||
)
|
)
|
||||||
instance2 = WpTheme.new(:url => "http://sub.example.com/path/to/wordpress/",
|
instance2 = WpTheme.new(:url => "http://sub.example.com/path/to/wordpress/",
|
||||||
:path => "themes/newname/asdf.php",
|
:path => "themes/newname/asdf.php",
|
||||||
:vulns_xml => "XXX.xml",
|
:vulns_xml => "XXX.xml",
|
||||||
:version => "1.0"
|
:version => "1.0"
|
||||||
)
|
)
|
||||||
(instance===instance2).should == false
|
(instance===instance2).should == false
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return false (version not equal)" do
|
it "should return false (version not equal)" do
|
||||||
instance = WpTheme.new(:url => "http://sub.example.com/path/to/wordpress/",
|
instance = WpTheme.new(:url => "http://sub.example.com/path/to/wordpress/",
|
||||||
:path => "themes/name/asdf.php",
|
:path => "themes/name/asdf.php",
|
||||||
:vulns_xml => "XXX.xml",
|
:vulns_xml => "XXX.xml",
|
||||||
:version => "1.0"
|
:version => "1.0"
|
||||||
)
|
)
|
||||||
instance2 = WpTheme.new(:url => "http://sub.example.com/path/to/wordpress/",
|
instance2 = WpTheme.new(:url => "http://sub.example.com/path/to/wordpress/",
|
||||||
:path => "themes/name/asdf.php",
|
:path => "themes/name/asdf.php",
|
||||||
:vulns_xml => "XXX.xml",
|
:vulns_xml => "XXX.xml",
|
||||||
:version => "2.0"
|
:version => "2.0"
|
||||||
)
|
)
|
||||||
(instance===instance2).should == false
|
(instance===instance2).should == false
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return false (version and name not equal)" do
|
it "should return false (version and name not equal)" do
|
||||||
instance = WpTheme.new(:url => "http://sub.example.com/path/to/wordpress/",
|
instance = WpTheme.new(:url => "http://sub.example.com/path/to/wordpress/",
|
||||||
:path => "themes/name/asdf.php",
|
:path => "themes/name/asdf.php",
|
||||||
:vulns_xml => "XXX.xml",
|
:vulns_xml => "XXX.xml",
|
||||||
:version => "1.0"
|
:version => "1.0"
|
||||||
)
|
)
|
||||||
instance2 = WpTheme.new(:url => "http://sub.example.com/path/to/wordpress/",
|
instance2 = WpTheme.new(:url => "http://sub.example.com/path/to/wordpress/",
|
||||||
:path => "themes/newname/asdf.php",
|
:path => "themes/newname/asdf.php",
|
||||||
:vulns_xml => "XXX.xml",
|
:vulns_xml => "XXX.xml",
|
||||||
:version => "2.0"
|
:version => "2.0"
|
||||||
)
|
)
|
||||||
(instance===instance2).should == false
|
(instance===instance2).should == false
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return true" do
|
it "should return true" do
|
||||||
instance = WpTheme.new(:url => "http://sub.example.com/path/to/wordpress/",
|
instance = WpTheme.new(:url => "http://sub.example.com/path/to/wordpress/",
|
||||||
:path => "themes/test/asdf.php",
|
:path => "themes/test/asdf.php",
|
||||||
:vulns_xml => "XXX.xml",
|
:vulns_xml => "XXX.xml",
|
||||||
:version => "1.0"
|
:version => "1.0"
|
||||||
)
|
)
|
||||||
instance2 = WpTheme.new(:url => "http://sub.example.com/path/to/wordpress/",
|
instance2 = WpTheme.new(:url => "http://sub.example.com/path/to/wordpress/",
|
||||||
:path => "themes/test/asdf.php",
|
:path => "themes/test/asdf.php",
|
||||||
:vulns_xml => "XXX.xml",
|
:vulns_xml => "XXX.xml",
|
||||||
:version => "1.0"
|
:version => "1.0"
|
||||||
)
|
)
|
||||||
(instance===instance2).should == true
|
(instance===instance2).should == true
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -73,13 +73,13 @@ describe WpUser do
|
|||||||
it "should return true" do
|
it "should return true" do
|
||||||
user1 = WpUser.new("a", "id", "nick")
|
user1 = WpUser.new("a", "id", "nick")
|
||||||
user2 = WpUser.new("a", "id", "nick")
|
user2 = WpUser.new("a", "id", "nick")
|
||||||
(user1.eql?user2).should be_true
|
(user1.eql? user2).should be_true
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return false" do
|
it "should return false" do
|
||||||
user1 = WpUser.new("a", "id", "nick")
|
user1 = WpUser.new("a", "id", "nick")
|
||||||
user2 = WpUser.new("b", "id", "nick")
|
user2 = WpUser.new("b", "id", "nick")
|
||||||
(user1.eql?user2).should be_false
|
(user1.eql? user2).should be_false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -21,8 +21,8 @@ require File.expand_path(File.dirname(__FILE__) + '/wpscan_helper')
|
|||||||
describe WpVersion do
|
describe WpVersion do
|
||||||
|
|
||||||
before :all do
|
before :all do
|
||||||
@target_uri = URI.parse('http://example.localhost/')
|
@target_uri = URI.parse('http://example.localhost/')
|
||||||
@browser = Browser.instance(:config_file => SPEC_FIXTURES_CONF_DIR + '/browser/browser.conf.json')
|
@browser = Browser.instance(:config_file => SPEC_FIXTURES_CONF_DIR + '/browser/browser.conf.json')
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#find_from_meta_generator" do
|
describe "#find_from_meta_generator" do
|
||||||
@@ -35,17 +35,17 @@ describe WpVersion do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "should return nil if the meta-generator is not found" do
|
it "should return nil if the meta-generator is not found" do
|
||||||
@fixture = fixtures_dir + "/no-meta-generator.htm"
|
@fixture = fixtures_dir + "/no-meta-generator.htm"
|
||||||
@expected = nil
|
@expected = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return 3.3.2" do
|
it "should return 3.3.2" do
|
||||||
@fixture = fixtures_dir + "/3.3.2.htm"
|
@fixture = fixtures_dir + "/3.3.2.htm"
|
||||||
@expected = "3.3.2"
|
@expected = "3.3.2"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return 3.4-beta4" do
|
it "should return 3.4-beta4" do
|
||||||
@fixture = fixtures_dir + "/3.4-beta4.htm"
|
@fixture = fixtures_dir + "/3.4-beta4.htm"
|
||||||
@expected = "3.4-beta4"
|
@expected = "3.4-beta4"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -62,27 +62,27 @@ describe WpVersion do
|
|||||||
|
|
||||||
it "should return nil on a 404" do
|
it "should return nil on a 404" do
|
||||||
@status_code = 404
|
@status_code = 404
|
||||||
@fixture = SPEC_FIXTURES_WPSCAN_WP_VERSION_DIR + "/404.htm"
|
@fixture = SPEC_FIXTURES_WPSCAN_WP_VERSION_DIR + "/404.htm"
|
||||||
@expected = nil
|
@expected = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return nil if the rss-generator is not found" do
|
it "should return nil if the rss-generator is not found" do
|
||||||
@fixture = fixtures_dir + "/no-rss-generator.htm"
|
@fixture = fixtures_dir + "/no-rss-generator.htm"
|
||||||
@expected = nil
|
@expected = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return nil if the version is not found (but the rss-generator is present)" do
|
it "should return nil if the version is not found (but the rss-generator is present)" do
|
||||||
@fixture = fixtures_dir + "/no-version.htm"
|
@fixture = fixtures_dir + "/no-version.htm"
|
||||||
@expected = nil
|
@expected = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "shuld return 3.3.2" do
|
it "shuld return 3.3.2" do
|
||||||
@fixture = fixtures_dir + "/3.3.2.htm"
|
@fixture = fixtures_dir + "/3.3.2.htm"
|
||||||
@expected = "3.3.2"
|
@expected = "3.3.2"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return 3.4-beta4" do
|
it "should return 3.4-beta4" do
|
||||||
@fixture = fixtures_dir + "/3.4-beta4.htm"
|
@fixture = fixtures_dir + "/3.4-beta4.htm"
|
||||||
@expected = "3.4-beta4"
|
@expected = "3.4-beta4"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -90,23 +90,23 @@ describe WpVersion do
|
|||||||
describe "#find_from_sitemap_generator" do
|
describe "#find_from_sitemap_generator" do
|
||||||
after :each do
|
after :each do
|
||||||
stub_request(:get, @target_uri.merge("sitemap.xml").to_s).
|
stub_request(:get, @target_uri.merge("sitemap.xml").to_s).
|
||||||
to_return(:status => 200, :body => @body)
|
to_return(:status => 200, :body => @body)
|
||||||
|
|
||||||
WpVersion.find_from_sitemap_generator(:url => @target_uri).should === @expected
|
WpVersion.find_from_sitemap_generator(:url => @target_uri).should === @expected
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return nil if the generator is not found" do
|
it "should return nil if the generator is not found" do
|
||||||
@body = ''
|
@body = ''
|
||||||
@expected = nil
|
@expected = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return the version : 3.3.2" do
|
it "should return the version : 3.3.2" do
|
||||||
@body = "<!-- generator=\"wordpress/3.3.2\" -->"
|
@body = "<!-- generator=\"wordpress/3.3.2\" -->"
|
||||||
@expected = "3.3.2"
|
@expected = "3.3.2"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return nil if it's not a valid version, must contains at least one '.'" do
|
it "should return nil if it's not a valid version, must contains at least one '.'" do
|
||||||
@body = "<!-- generator=\"wordpress/5065\" -->"
|
@body = "<!-- generator=\"wordpress/5065\" -->"
|
||||||
@expected = nil
|
@expected = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -123,17 +123,17 @@ describe WpVersion do
|
|||||||
|
|
||||||
it "should return nil on a 404" do
|
it "should return nil on a 404" do
|
||||||
@status_code = 404
|
@status_code = 404
|
||||||
@fixture = SPEC_FIXTURES_WPSCAN_WP_VERSION_DIR + "/404.htm"
|
@fixture = SPEC_FIXTURES_WPSCAN_WP_VERSION_DIR + "/404.htm"
|
||||||
@expected = nil
|
@expected = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return nil if the version number is not present" do
|
it "should return nil if the version number is not present" do
|
||||||
@fixture = fixtures_dir + "/empty-version.html"
|
@fixture = fixtures_dir + "/empty-version.html"
|
||||||
@expected = nil
|
@expected = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return 3.3.2" do
|
it "should return 3.3.2" do
|
||||||
@fixture = fixtures_dir + "/readme-3.3.2.html"
|
@fixture = fixtures_dir + "/readme-3.3.2.html"
|
||||||
@expected = "3.3.2"
|
@expected = "3.3.2"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -154,7 +154,7 @@ describe WpVersion do
|
|||||||
|
|
||||||
describe "#initialize" do
|
describe "#initialize" do
|
||||||
it "should initialize a WpVersion object" do
|
it "should initialize a WpVersion object" do
|
||||||
v = WpVersion.new(1, { :discovery_method => "method", :vulns_xml => "asdf.xml" })
|
v = WpVersion.new(1, {:discovery_method => "method", :vulns_xml => "asdf.xml"})
|
||||||
v.number.should == 1
|
v.number.should == 1
|
||||||
v.discovery_method.should == "method"
|
v.discovery_method.should == "method"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ class WpScanModuleSpec
|
|||||||
def initialize(target_url)
|
def initialize(target_url)
|
||||||
@uri = URI.parse(add_http_protocol(target_url))
|
@uri = URI.parse(add_http_protocol(target_url))
|
||||||
Browser.instance(
|
Browser.instance(
|
||||||
:config_file => SPEC_FIXTURES_CONF_DIR + '/browser/browser.conf.json',
|
:config_file => SPEC_FIXTURES_CONF_DIR + '/browser/browser.conf.json',
|
||||||
:cache_timeout => 0
|
:cache_timeout => 0
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ describe "WpscanOptions" do
|
|||||||
it "should raise an error" do
|
it "should raise an error" do
|
||||||
@wpscan_options.enumerate_only_vulnerable_plugins = true
|
@wpscan_options.enumerate_only_vulnerable_plugins = true
|
||||||
expect { @wpscan_options.enumerate_plugins = true }.to raise_error(RuntimeError,
|
expect { @wpscan_options.enumerate_plugins = true }.to raise_error(RuntimeError,
|
||||||
"You can't enumerate plugins and only vulnerable plugins at the same time, please choose only one")
|
"You can't enumerate plugins and only vulnerable plugins at the same time, please choose only one")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should not raise an error" do
|
it "should not raise an error" do
|
||||||
@@ -104,7 +104,7 @@ describe "WpscanOptions" do
|
|||||||
it "should raise an error" do
|
it "should raise an error" do
|
||||||
@wpscan_options.enumerate_only_vulnerable_themes = true
|
@wpscan_options.enumerate_only_vulnerable_themes = true
|
||||||
expect { @wpscan_options.enumerate_themes = true }.to raise_error(RuntimeError,
|
expect { @wpscan_options.enumerate_themes = true }.to raise_error(RuntimeError,
|
||||||
"You can't enumerate themes and only vulnerable themes at the same time, please choose only one")
|
"You can't enumerate themes and only vulnerable themes at the same time, please choose only one")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should not raise an error" do
|
it "should not raise an error" do
|
||||||
@@ -119,7 +119,7 @@ describe "WpscanOptions" do
|
|||||||
it "should raise an error" do
|
it "should raise an error" do
|
||||||
@wpscan_options.enumerate_plugins = true
|
@wpscan_options.enumerate_plugins = true
|
||||||
expect { @wpscan_options.enumerate_only_vulnerable_plugins = true }.to raise_error(RuntimeError,
|
expect { @wpscan_options.enumerate_only_vulnerable_plugins = true }.to raise_error(RuntimeError,
|
||||||
"You can't enumerate plugins and only vulnerable plugins at the same time, please choose only one")
|
"You can't enumerate plugins and only vulnerable plugins at the same time, please choose only one")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should not raise an error" do
|
it "should not raise an error" do
|
||||||
@@ -134,7 +134,7 @@ describe "WpscanOptions" do
|
|||||||
it "should raise an error" do
|
it "should raise an error" do
|
||||||
@wpscan_options.enumerate_themes = true
|
@wpscan_options.enumerate_themes = true
|
||||||
expect { @wpscan_options.enumerate_only_vulnerable_themes = true }.to raise_error(RuntimeError,
|
expect { @wpscan_options.enumerate_only_vulnerable_themes = true }.to raise_error(RuntimeError,
|
||||||
"You can't enumerate themes and only vulnerable themes at the same time, please choose only one")
|
"You can't enumerate themes and only vulnerable themes at the same time, please choose only one")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should not raise an error" do
|
it "should not raise an error" do
|
||||||
@@ -176,12 +176,12 @@ describe "WpscanOptions" do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "should return 'url'" do
|
it "should return 'url'" do
|
||||||
@option = "--url"
|
@option = "--url"
|
||||||
@expected = "url"
|
@expected = "url"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return 'u'" do
|
it "should return 'u'" do
|
||||||
@option = "-u"
|
@option = "-u"
|
||||||
@expected = 'u'
|
@expected = 'u'
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -275,8 +275,8 @@ describe "WpscanOptions" do
|
|||||||
it "should set enumerate_timthumbs to true, enumerate_usernames to true, enumerate_usernames_range to (1..2)" do
|
it "should set enumerate_timthumbs to true, enumerate_usernames to true, enumerate_usernames_range to (1..2)" do
|
||||||
@argument = "u[1-2]t"
|
@argument = "u[1-2]t"
|
||||||
@expected_hash = {
|
@expected_hash = {
|
||||||
:enumerate_usernames => true, :enumerate_usernames_range => (1..2),
|
:enumerate_usernames => true, :enumerate_usernames_range => (1..2),
|
||||||
:enumerate_timthumbs => true
|
:enumerate_timthumbs => true
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ def stub_request_to_fixture(arguments = {})
|
|||||||
raise "No arguments[:fixture] supplied" if arguments[:fixture].nil?
|
raise "No arguments[:fixture] supplied" if arguments[:fixture].nil?
|
||||||
|
|
||||||
stub_request(arguments[:method], arguments[:url].to_s).
|
stub_request(arguments[:method], arguments[:url].to_s).
|
||||||
to_return(:status => arguments[:status], :body => File.new(arguments[:fixture]))
|
to_return(:status => arguments[:status], :body => File.new(arguments[:fixture]))
|
||||||
end
|
end
|
||||||
|
|
||||||
# The object must be given as we will mock the Kernel#` or Kernel#system (Kernel is a module)
|
# The object must be given as we will mock the Kernel#` or Kernel#system (Kernel is a module)
|
||||||
|
|||||||
34
wpscan.rb
34
wpscan.rb
@@ -181,11 +181,11 @@ begin
|
|||||||
puts
|
puts
|
||||||
|
|
||||||
options = {}
|
options = {}
|
||||||
options[:url] = wp_target.uri
|
options[:url] = wp_target.uri
|
||||||
options[:only_vulnerable_ones] = wpscan_options.enumerate_only_vulnerable_plugins || false
|
options[:only_vulnerable_ones] = wpscan_options.enumerate_only_vulnerable_plugins || false
|
||||||
options[:show_progress_bar] = true
|
options[:show_progress_bar] = true
|
||||||
options[:wp_content_dir] = wp_target.wp_content_dir
|
options[:wp_content_dir] = wp_target.wp_content_dir
|
||||||
options[:error_404_hash] = wp_target.error_404_hash
|
options[:error_404_hash] = wp_target.error_404_hash
|
||||||
|
|
||||||
plugins = wp_target.plugins_from_aggressive_detection(options)
|
plugins = wp_target.plugins_from_aggressive_detection(options)
|
||||||
unless plugins.empty?
|
unless plugins.empty?
|
||||||
@@ -235,11 +235,11 @@ begin
|
|||||||
puts
|
puts
|
||||||
|
|
||||||
options = {}
|
options = {}
|
||||||
options[:url] = wp_target.uri
|
options[:url] = wp_target.uri
|
||||||
options[:only_vulnerable_ones] = wpscan_options.enumerate_only_vulnerable_themes || false
|
options[:only_vulnerable_ones] = wpscan_options.enumerate_only_vulnerable_themes || false
|
||||||
options[:show_progress_bar] = true
|
options[:show_progress_bar] = true
|
||||||
options[:wp_content_dir] = wp_target.wp_content_dir
|
options[:wp_content_dir] = wp_target.wp_content_dir
|
||||||
options[:error_404_hash] = wp_target.error_404_hash
|
options[:error_404_hash] = wp_target.error_404_hash
|
||||||
|
|
||||||
themes = wp_target.themes_from_aggressive_detection(options)
|
themes = wp_target.themes_from_aggressive_detection(options)
|
||||||
unless themes.empty?
|
unless themes.empty?
|
||||||
@@ -280,11 +280,11 @@ begin
|
|||||||
puts green("[+]") + " Enumerating timthumb files ..."
|
puts green("[+]") + " Enumerating timthumb files ..."
|
||||||
puts
|
puts
|
||||||
|
|
||||||
options = {}
|
options = {}
|
||||||
options[:url] = wp_target.uri
|
options[:url] = wp_target.uri
|
||||||
options[:show_progress_bar] = true
|
options[:show_progress_bar] = true
|
||||||
options[:wp_content_dir] = wp_target.wp_content_dir
|
options[:wp_content_dir] = wp_target.wp_content_dir
|
||||||
options[:error_404_hash] = wp_target.error_404_hash
|
options[:error_404_hash] = wp_target.error_404_hash
|
||||||
|
|
||||||
theme_name = wp_theme ? wp_theme.name : nil
|
theme_name = wp_theme ? wp_theme.name : nil
|
||||||
if wp_target.has_timthumbs?(theme_name, options)
|
if wp_target.has_timthumbs?(theme_name, options)
|
||||||
@@ -323,9 +323,9 @@ begin
|
|||||||
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 <=> b.id}.last.id.to_s.length
|
max_id_length = usernames.sort { |a, b| a.id <=> b.id }.last.id.to_s.length
|
||||||
max_name_length = usernames.sort{|a,b| a.name <=> b.name}.last.name.length
|
max_name_length = usernames.sort { |a, b| a.name <=> b.name }.last.name.length
|
||||||
max_nickname_length = usernames.sort{|a,b| a.nickname <=> b.nickname}.last.nickname.length
|
max_nickname_length = usernames.sort { |a, b| a.nickname <=> b.nickname }.last.nickname.length
|
||||||
|
|
||||||
space = 1
|
space = 1
|
||||||
usernames.each do |u|
|
usernames.each do |u|
|
||||||
|
|||||||
84
wpstools.rb
84
wpstools.rb
@@ -32,50 +32,50 @@ begin
|
|||||||
# A better way to do that should be to create a wpstools_options.rb file like wpscan_options.rb
|
# A better way to do that should be to create a wpstools_options.rb file like wpscan_options.rb
|
||||||
# and a wps_options.rb with common options code
|
# and a wps_options.rb with common options code
|
||||||
options = GetoptLong.new(
|
options = GetoptLong.new(
|
||||||
["--help", "-h", GetoptLong::NO_ARGUMENT],
|
["--help", "-h", GetoptLong::NO_ARGUMENT],
|
||||||
["--verbose", "-v", GetoptLong::NO_ARGUMENT],
|
["--verbose", "-v", GetoptLong::NO_ARGUMENT],
|
||||||
["--generate_plugin_list", GetoptLong::OPTIONAL_ARGUMENT],
|
["--generate_plugin_list", GetoptLong::OPTIONAL_ARGUMENT],
|
||||||
["--generate_full_plugin_list", GetoptLong::NO_ARGUMENT],
|
["--generate_full_plugin_list", GetoptLong::NO_ARGUMENT],
|
||||||
["--generate_theme_list", GetoptLong::OPTIONAL_ARGUMENT],
|
["--generate_theme_list", GetoptLong::OPTIONAL_ARGUMENT],
|
||||||
["--generate_full_theme_list", GetoptLong::NO_ARGUMENT],
|
["--generate_full_theme_list", GetoptLong::NO_ARGUMENT],
|
||||||
["--gpl", GetoptLong::OPTIONAL_ARGUMENT],
|
["--gpl", GetoptLong::OPTIONAL_ARGUMENT],
|
||||||
["--gfpl", GetoptLong::OPTIONAL_ARGUMENT],
|
["--gfpl", GetoptLong::OPTIONAL_ARGUMENT],
|
||||||
["--gtl", GetoptLong::OPTIONAL_ARGUMENT],
|
["--gtl", GetoptLong::OPTIONAL_ARGUMENT],
|
||||||
["--gftl", GetoptLong::OPTIONAL_ARGUMENT],
|
["--gftl", GetoptLong::OPTIONAL_ARGUMENT],
|
||||||
["--update", "-u", GetoptLong::NO_ARGUMENT]
|
["--update", "-u", GetoptLong::NO_ARGUMENT]
|
||||||
)
|
)
|
||||||
|
|
||||||
options.each do |option, argument|
|
options.each do |option, argument|
|
||||||
case option
|
case option
|
||||||
when "--help"
|
when "--help"
|
||||||
help()
|
help()
|
||||||
exit
|
exit
|
||||||
when "--verbose"
|
when "--verbose"
|
||||||
@verbose = true
|
@verbose = true
|
||||||
when "--generate_plugin_list", "--gpl"
|
when "--generate_plugin_list", "--gpl"
|
||||||
if argument == ''
|
if argument == ''
|
||||||
puts "Number of pages not supplied, defaulting to 150 pages ..."
|
puts "Number of pages not supplied, defaulting to 150 pages ..."
|
||||||
@number_of_pages = 150
|
@number_of_pages = 150
|
||||||
else
|
else
|
||||||
@number_of_pages = argument.to_i
|
@number_of_pages = argument.to_i
|
||||||
end
|
end
|
||||||
|
|
||||||
@generate_plugin_list = true
|
@generate_plugin_list = true
|
||||||
when "--generate_theme_list", "--gtl"
|
when "--generate_theme_list", "--gtl"
|
||||||
if argument == ''
|
if argument == ''
|
||||||
puts "Number of pages not supplied, defaulting to 150 pages ..."
|
puts "Number of pages not supplied, defaulting to 150 pages ..."
|
||||||
@number_of_pages = 150
|
@number_of_pages = 150
|
||||||
else
|
else
|
||||||
@number_of_pages = argument.to_i
|
@number_of_pages = argument.to_i
|
||||||
end
|
end
|
||||||
|
|
||||||
@generate_theme_list = true
|
@generate_theme_list = true
|
||||||
when "--update"
|
when "--update"
|
||||||
@update = true
|
@update = true
|
||||||
when "--generate_full_plugin_list", "--gfpl"
|
when "--generate_full_plugin_list", "--gfpl"
|
||||||
@generate_full_plugin_list = true
|
@generate_full_plugin_list = true
|
||||||
when "--generate_full_theme_list", "--gftl"
|
when "--generate_full_theme_list", "--gftl"
|
||||||
@generate_full_theme_list = true
|
@generate_full_theme_list = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -84,19 +84,19 @@ begin
|
|||||||
puts
|
puts
|
||||||
Generate_List.new('plugins', @verbose).generate_popular_list(@number_of_pages)
|
Generate_List.new('plugins', @verbose).generate_popular_list(@number_of_pages)
|
||||||
end
|
end
|
||||||
|
|
||||||
if @generate_full_plugin_list
|
if @generate_full_plugin_list
|
||||||
puts "[+] Generating new full plugin list"
|
puts "[+] Generating new full plugin list"
|
||||||
puts
|
puts
|
||||||
Generate_List.new('plugins', @verbose).generate_full_list
|
Generate_List.new('plugins', @verbose).generate_full_list
|
||||||
end
|
end
|
||||||
|
|
||||||
if @generate_theme_list
|
if @generate_theme_list
|
||||||
puts "[+] Generating new most popular theme list"
|
puts "[+] Generating new most popular theme list"
|
||||||
puts
|
puts
|
||||||
Generate_List.new('themes', @verbose).generate_popular_list(@number_of_pages)
|
Generate_List.new('themes', @verbose).generate_popular_list(@number_of_pages)
|
||||||
end
|
end
|
||||||
|
|
||||||
if @generate_full_theme_list
|
if @generate_full_theme_list
|
||||||
puts "[+] Generating new full theme list"
|
puts "[+] Generating new full theme list"
|
||||||
puts
|
puts
|
||||||
|
|||||||
Reference in New Issue
Block a user