-) Code formatting

-) rspec tests
This commit is contained in:
Christian Mehlmauer
2012-09-22 15:44:41 +02:00
parent 55fa6422b2
commit ae96d93cee
52 changed files with 897 additions and 463 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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|

View 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

View File

@@ -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]

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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]}")

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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"

View File

@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
</body>
</html>

View 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 &raquo; Feed" href="http://10.211.55.8/wordpress/?feed=rss2" />
<link rel="alternate" type="application/rss+xml" title="test &raquo; 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>

View 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>

View 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>

View 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

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View 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

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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|

View File

@@ -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