diff --git a/doc/Array.html b/doc/Array.html deleted file mode 100644 index 2aedb0b7..00000000 --- a/doc/Array.html +++ /dev/null @@ -1,372 +0,0 @@ - - - -
- - -Fix for grep with symbols in ruby <= 1.8.7
- - - --# File lib/common/hacks.rb, line 19 -def _grep_(regexp) - matches = [] - self.each do |value| - value = value.to_s - matches << value if value.match(regexp) - end - matches -end-
Generated with the Darkfish - Rdoc Generator 2.
--# File lib/common/browser.rb, line 146 -def forge_request(url, params = {}) - Typhoeus::Request.new( - url.to_s, - merge_request_params(params) - ) -end-
-# File lib/common/browser.rb, line 126 -def get(url, params = {}) - run_request( - forge_request(url, params.merge(method: :get)) - ) -end-
-# File lib/common/browser.rb, line 138 -def get_and_follow_location(url, params = {}) - params[:maxredirs] ||= 2 - - run_request( - forge_request(url, params.merge(method: :get, followlocation: true)) - ) -end-
-# File lib/common/browser.rb, line 104 -def invalid_proxy_auth_format - 'Invalid proxy auth format, expected username:password or {proxy_username: username, proxy_password: password}' -end-
TODO reload hydra (if the .load_config is called on a -browser object, hydra will not have the new @max_threads and -@request_timeout)
- - - --# File lib/common/browser.rb, line 110 -def load_config(config_file = nil) - @config_file = config_file || @config_file - - if File.symlink?(@config_file) - raise "[ERROR] Config file is a symlink." - else - data = JSON.parse(File.read(@config_file)) - end - - ACCESSOR_OPTIONS.each do |option| - option_name = option.to_s - - self.send(:"#{option_name}=", data[option_name]) - end -end-
-# File lib/common/browser.rb, line 85 -def max_threads=(max_threads) - if max_threads.nil? or max_threads <= 0 - max_threads = 1 - end - @max_threads = max_threads -end-
-# File lib/common/browser.rb, line 153 -def merge_request_params(params = {}) - params = Browser.append_params_header_field( - params, - 'User-Agent', - self.user_agent - ) - - if @proxy - params = params.merge(proxy: @proxy) - - if @proxy_auth - params = params.merge(proxyauth: @proxy_auth) - end - end - - if @basic_auth - params = Browser.append_params_header_field( - params, - 'Authorization', - @basic_auth - ) - end - - # Used to enable the cache system if :cache_ttl > 0 - unless params.has_key?(:cache_ttl) - params = params.merge(cache_ttl: @cache_ttl) - end - - # Disable SSL-Certificate checks - params = params.merge(ssl_verifypeer: false) - params = params.merge(ssl_verifyhost: 0) - - params -end-
-# File lib/common/browser.rb, line 132 -def post(url, params = {}) - run_request( - forge_request(url, params.merge(method: :post)) - ) -end-
-# File lib/common/browser.rb, line 92 -def proxy_auth=(auth) - unless auth.nil? - if auth.is_a?(Hash) && auth.include?(:proxy_username) && auth.include?(:proxy_password) - @proxy_auth = auth[:proxy_username] + ':' + auth[:proxy_password] - elsif auth.is_a?(String) && auth.index(':') != nil - @proxy_auth = auth - else - raise invalid_proxy_auth_format - end - end -end-
return the user agent, according to the user_agent_mode
- - - --# File lib/common/browser.rb, line 73 -def user_agent - case @user_agent_mode - when 'semi-static' - unless @user_agent - @user_agent = @available_user_agents.sample - end - when 'random' - @user_agent = @available_user_agents.sample - end - @user_agent -end-
-# File lib/common/browser.rb, line 59 -def user_agent_mode=(ua_mode) - ua_mode ||= 'static' - - if USER_AGENT_MODES.include?(ua_mode) - @user_agent_mode = ua_mode - # For semi-static user agent mode, the user agent has to - # be nil the first time (it will be set with the getter) - @user_agent = nil if ua_mode === 'semi-static' - else - raise "Unknow user agent mode : '#{ua_mode}'" - end -end-
Generated with the Darkfish - Rdoc Generator 2.
-Counts the number of lines in the wordlist It can take a couple of minutes -on large wordlists, although bareable.
- - - --# File lib/wpscan/modules/brute_force.rb, line 101 -def self.lines_in_file(file_path) - lines = 0 - File.open(file_path, 'r').each { |_| lines += 1 } - lines -end-
param array of WpUsers wp_users param string -wordlist_path param hash options
- -boolean :show_progression If true, will output the details (Sucess, error etc)- - - -
-# File lib/wpscan/modules/brute_force.rb, line 8 -def brute_force(wp_users, wordlist_path, options = {}) - hydra = Browser.instance.hydra - number_of_passwords = BruteForce.lines_in_file(wordlist_path) - login_url = login_url() - found = [] - show_progression = options[:show_progression] || false - - wp_users.each do |wp_user| - queue_count = 0 - request_count = 0 - password_found = false - - File.open(wordlist_path, 'r').each do |password| - # ignore file comments, but will miss passwords if they start with a hash... - next if password[0, 1] == '#' - - password.strip! - - # keep a count of the amount of requests to be sent - request_count += 1 - queue_count += 1 - - # create local vars for on_complete call back, Issue 51. - login = wp_user.login - password = password - - # the request object - request = Browser.instance.forge_request(login_url, - { - method: :post, - body: { log: URI::encode(login), pwd: URI::encode(password) }, - cache_ttl: 0 - } - ) - - # tell hydra what to do when the request completes - request.on_complete do |response| - - puts "\n Trying Username : #{login} Password : #{password}" if @verbose - - if response.body =~ /login_error/ - puts "\nIncorrect login and/or password." if @verbose - elsif response.code == 302 - puts "\n " + green('[SUCCESS]') + " Login : #{login} Password : #{password}\n" if show_progression - found << { name: login, password: password } - password_found = true - elsif response.timed_out? - puts red('ERROR:') + ' Request timed out.' if show_progression - elsif response.code == 0 - puts red('ERROR:') + ' No response from remote server. WAF/IPS?' if show_progression - # code is a fixnum, needs a string for regex - elsif response.code.to_s =~ /^50/ - puts red('ERROR:') + ' Server error, try reducing the number of threads.' if show_progression - else - puts "\n" + red('ERROR:') + " We received an unknown response for #{password}..." if show_progression - - # HACK to get the coverage :/ (otherwise some output is present in the rspec) - puts red("Code: #{response.code.to_s}") if @verbose - puts red("Body: #{response.body}") if @verbose - puts if @verbose - end - end - - # move onto the next login if we have found a valid password - break if password_found - - # queue the request to be sent later - hydra.queue(request) - - # progress indicator - print "\r Brute forcing user '#{login}' with #{number_of_passwords} passwords... #{(request_count * 100) / number_of_passwords}% complete." if show_progression - - # it can take a long time to queue 2 million requests, - # for that reason, we queue @threads, send @threads, queue @threads and so on. - # hydra.run only returns when it has recieved all of its, - # responses. This means that while we are waiting for @threads, - # responses, we are waiting... - if queue_count >= Browser.instance.max_threads - hydra.run - queue_count = 0 - puts "Sent #{Browser.instance.max_threads} requests ..." if @verbose - end - end - - # run all of the remaining requests - hydra.run - end - found -end-
Generated with the Darkfish - Rdoc Generator 2.
-*CREDITS*
- -This file is to give credit to WPScan’s contributors. If you feel your name -should be in here, email ryandewhurst at gmail.
- -*WPScan Team*
- -Erwan.LR - @erwan_lr - (Project Developer) Christian Mehlmauer - -@FireFart - (Project Developer) Gianluca Brindisi - @gbrindisi -(Project Developer) Ryan Dewhurst - @ethicalhack3r (Project Lead)
- -*Other Contributors*
- -Alip AKA Undead - alip.aswalid at gmail.com michee08 - Reported and gave -potential solutions to bugs. Callum Pember - Implemented proxy support - -callumpember at gmail.com g0tmi1k - Additional timthumb checks + bug -reports. Melvin Lammerts - Reported a couple of fake vulnerabilities - -melvin at 12k.nl Paolo Perego - @thesp0nge - Basic authentication
- -Generated with the Darkfish - Rdoc Generator 2.
-The serializer must have the 2 methods .load and .dump
- -(Marshal and YAML have them)- -
YAML is Human Readable, contrary to Marshal which store in a binary format -Marshal does not need any “require”
- - - --# File lib/common/cache_file_store.rb, line 19 -def initialize(storage_path, serializer = Marshal) - @storage_path = File.expand_path(storage_path) - @serializer = serializer - - # File.directory? for ruby <= 1.9 otherwise, - # it makes more sense to do Dir.exist? :/ - unless File.directory?(@storage_path) - Dir.mkdir(@storage_path) - end -end-
-# File lib/common/cache_file_store.rb, line 30 -def clean - Dir[File.join(@storage_path, '*')].each do |f| - File.delete(f) unless File.symlink?(f) - end -end-
-# File lib/common/cache_file_store.rb, line 52 -def get_entry_file_path(key) - File::join(@storage_path, key) -end-
-# File lib/common/cache_file_store.rb, line 36 -def read_entry(key) - entry_file_path = get_entry_file_path(key) - - if File.exists?(entry_file_path) - return @serializer.load(File.read(entry_file_path)) - end -end-
-# File lib/common/cache_file_store.rb, line 44 -def write_entry(key, data_to_store, cache_ttl) - if cache_ttl > 0 - File.open(get_entry_file_path(key), 'w') do |f| - f.write(@serializer.dump(data_to_store)) - end - end -end-
Generated with the Darkfish - Rdoc Generator 2.
-OptionParser
- --# File lib/common/custom_option_parser.rb, line 6 -def initialize(banner = nil, width = 32, indent = ' ' * 4) - @results = {} - @symbols_used = [] - super(banner, width, indent) -end-
param Array option
- - - --# File lib/common/custom_option_parser.rb, line 56 -def self.option_to_symbol(option) - option_name = nil - - option.each do |option_attr| - if option_attr =~ /^--/ - option_name = option_attr - break - end - end - - if option_name - option_name = option_name.gsub(/^--/, '').gsub(/-/, '_').gsub(/ .*$/, '') - :"#{option_name}" - else - raise "Could not find the option name for #{option}" - end -end-
param Array(Array) or Array options
- - - --# File lib/common/custom_option_parser.rb, line 14 -def add(options) - if options.is_a?(Array) - if options[0].is_a?(Array) - options.each do |option| - add_option(option) - end - else - add_option(options) - end - else - raise "Options must be at least an Array, or an Array(Array). #{options.class} supplied" - end -end-
param Array option
- - - --# File lib/common/custom_option_parser.rb, line 29 -def add_option(option) - if option.is_a?(Array) - option_symbol = CustomOptionParser::option_to_symbol(option) - - if !@symbols_used.include?(option_symbol) - @symbols_used << option_symbol - - self.on(*option) do |arg| - @results[option_symbol] = arg - end - else - raise "The option #{option_symbol} is already used !" - end - else - raise "The option must be an array, #{option.class} supplied : '#{option}'" - end -end-
Generated with the Darkfish - Rdoc Generator 2.
-source “rubygems.org”
- -gem “typhoeus”, “>=0.6.2” gem “nokogiri” gem “json”
- -group :development, :test do
- -gem "webmock", ">=1.9.3" -gem "simplecov" -gem "rspec", :require => "spec"- -
end
- -Generated with the Darkfish - Rdoc Generator 2.
-This tool generates a list to use for plugin and theme enumeration
- -type = themes | plugins
- - - --# File lib/wpstools/plugins/list_generator/generate_list.rb, line 8 -def initialize(type, verbose) - if type =~ /plugins/ - @type = 'plugin' - @svn_url = 'http://plugins.svn.wordpress.org/' - @popular_url = 'http://wordpress.org/extend/plugins/browse/popular/' - @popular_regex = %{<h3><a href="http://wordpress.org/extend/plugins/(.+)/">.+</a></h3>} - elsif type =~ /themes/ - @type = 'theme' - @svn_url = 'http://themes.svn.wordpress.org/' - @popular_url = 'http://wordpress.org/extend/themes/browse/popular/' - @popular_regex = %{<h3><a href="http://wordpress.org/extend/themes/(.+)">.+</a></h3>} - else - raise "Type #{type} not defined" - end - @verbose = verbose - @browser = Browser.instance - @hydra = @browser.hydra -end-
-# File lib/wpstools/plugins/list_generator/generate_list.rb, line 52 -def generate_full_list - set_file_name(:full) - items = SvnParser.new(@svn_url).parse - save items -end-
-# File lib/wpstools/plugins/list_generator/generate_list.rb, line 58 -def generate_popular_list(pages) - set_file_name(:popular) - items = get_popular_items(pages) - save items -end-
Send a HTTP request to the WordPress most popular theme or plugin webpage -parse the response for the names.
- - - --# File lib/wpstools/plugins/list_generator/generate_list.rb, line 66 -def get_popular_items(pages) - found_items = [] - page_count = 1 - queue_count = 0 - - (1...(pages.to_i + 1)).each do |page| - # First page has another URL - url = (page == 1) ? @popular_url : @popular_url + 'page/' + page.to_s + '/' - request = @browser.forge_request(url) - - queue_count += 1 - - request.on_complete do |response| - puts "[+] Parsing page #{page_count}" if @verbose - page_count += 1 - response.body.scan(@popular_regex).each do |item| - puts "[+] Found popular #@type: #{item}" if @verbose - found_items << item[0] - end - end - - @hydra.queue(request) - - if queue_count == @browser.max_threads - @hydra.run - queue_count = 0 - end - - end - - @hydra.run - - found_items.sort! - found_items.uniq -end-
Save the file
- - - --# File lib/wpstools/plugins/list_generator/generate_list.rb, line 103 -def save(items) - items.sort! - items.uniq! - puts "[*] We have parsed #{items.length} #@types" - File.open(@file_name, 'w') { |f| f.puts(items) } - puts "New #@file_name file created" -end-
-# File lib/wpstools/plugins/list_generator/generate_list.rb, line 27 -def set_file_name(type) - case @type - when 'plugin' - case type - when :full - @file_name = PLUGINS_FULL_FILE - when :popular - @file_name = PLUGINS_FILE - else - raise 'Unknown type' - end - when 'theme' - case type - when :full - @file_name = THEMES_FULL_FILE - when :popular - @file_name = THEMES_FILE - else - raise 'Unknown type' - end - else - raise "Unknown type #@type" - end -end-
Generated with the Darkfish - Rdoc Generator 2.
--# File lib/common/updater/git_updater.rb, line 21 -def has_local_changes? - %[git #{repo_directory_arguments()} diff --exit-code 2>&1] =~ /diff/ ? true : false -end-
-# File lib/common/updater/git_updater.rb, line 6 -def is_installed? - %[git #{repo_directory_arguments()} status 2>&1] =~ /On branch/ ? true : false -end-
Git has not a revsion number like SVN, so we will take the 7 first chars of -the last commit hash
- - - --# File lib/common/updater/git_updater.rb, line 12 -def local_revision_number - git_log = %[git #{repo_directory_arguments()} log -1 2>&1] - git_log[/commit ([0-9a-z]{7})/, 1].to_s -end-
Generated with the Darkfish - Rdoc Generator 2.
-WPScan - WordPress Security Scanner Copyright (C) 2012-2013
- -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 <www.gnu.org/licenses/>.
- -Generated with the Darkfish - Rdoc Generator 2.
--# File lib/wpstools/plugins/list_generator/list_generator_plugin.rb, line 4 -def initialize - super(author: 'WPScanTeam - @FireFart') - - register_options( - ['--generate-plugin-list [NUMBER_OF_PAGES]', '--gpl', Integer, 'Generate a new data/plugins.txt file. (supply number of *pages* to parse, default : 150)'], - ['--generate-full-plugin-list', '--gfpl', 'Generate a new full data/plugins.txt file'], - - ['--generate-theme-list [NUMBER_OF_PAGES]', '--gtl', Integer, 'Generate a new data/themes.txt file. (supply number of *pages* to parse, default : 150)'], - ['--generate-full-theme-list', '--gftl', 'Generate a new full data/themes.txt file'], - - ['--generate-all', '--ga', 'Generate a new full plugins, full themes, popular plugins and popular themes list'] - ) -end-
-# File lib/wpstools/plugins/list_generator/list_generator_plugin.rb, line 18 -def run(options = {}) - @verbose = options[:verbose] || false - generate_all = options[:generate_all] || false - - if options.has_key?(:generate_plugin_list) || generate_all - most_popular('plugin', options[:generate_plugin_list] || 150) - end - - if options[:generate_full_plugin_list] || generate_all - full('plugin') - end - - if options.has_key?(:generate_theme_list) || generate_all - most_popular('theme', options[:generate_theme_list] || 150) - end - - if options[:generate_full_theme_list] || generate_all - full('theme') - end -end-
Generated with the Darkfish - Rdoc Generator 2.
--# File lib/wpscan/modules/malwares.rb, line 42 -def self.malware_pattern(url_regex) - # no need to escape regex here, because malware.txt contains regex - %{<(?:script|iframe).* src=(?:"|')(#{url_regex}[^"']*)(?:"|')[^>]*>} -end-
-# File lib/wpscan/modules/malwares.rb, line 9 -def has_malwares?(malwares_file_path = nil) - !malwares(malwares_file_path).empty? -end-
return array of string (url of malwares found)
- - - --# File lib/wpscan/modules/malwares.rb, line 14 -def malwares(malwares_file_path = nil) - unless @malwares - malwares_found = [] - malwares_file = Malwares.malwares_file(malwares_file_path) - index_page_body = Browser.instance.get(@uri.to_s).body - - File.open(malwares_file, 'r') do |file| - file.readlines.collect do |url| - chomped_url = url.chomp - - if chomped_url.length > 0 - malwares_found += index_page_body.scan(Malwares.malware_pattern(chomped_url)) - end - end - end - - malwares_found.flatten! - malwares_found.uniq! - - @malwares = malwares_found - end - @malwares -end-
Generated with the Darkfish - Rdoc Generator 2.
-param Array options
- - - --# File lib/common/plugins/plugin.rb, line 15 -def register_options(*options) - options.each do |option| - unless option.is_a?(Array) - raise "Each option must be an array, #{option.class} supplied" - end - end - @registered_options = options -end-
Generated with the Darkfish - Rdoc Generator 2.
--# File lib/common/plugins/plugins.rb, line 6 -def initialize(option_parser = nil) - if option_parser - if option_parser.is_a?(CustomOptionParser) - @option_parser = option_parser - else - raise "The parser must be an instance of CustomOptionParser, #{option_parser.class} supplied" - end - else - @option_parser = CustomOptionParser.new - end -end-
param Array(Plugin) plugins
- - - --# File lib/common/plugins/plugins.rb, line 19 -def register(*plugins) - plugins.each do |plugin| - register_plugin(plugin) - end -end-
param Plugin plugin
- - - --# File lib/common/plugins/plugins.rb, line 26 -def register_plugin(plugin) - if plugin.is_a?(Plugin) - self << plugin - - # A plugin may not have options - if plugin_options = plugin.registered_options - @option_parser.add(plugin_options) - end - else - raise "The argument must be an instance of Plugin, #{plugin.class} supplied" - end -end-
Generated with the Darkfish - Rdoc Generator 2.
-__
- -__ _______ _____ -\ \ / / __ \ / ____| - \ \ /\ / /| |__) | (___ ___ __ _ _ __ - \ \/ \/ / | ___/ \___ \ / __|/ _` | '_ \ - \ /\ / | | ____) | (__| (_| | | | | - \/ \/ |_| |_____/ \___|\__,_|_| |_|- -
__
- -WPScan - WordPress Security Scanner Copyright (C) 2011-2013 The WPScan Team
- -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 <www.gnu.org/licenses/>.
- -ryandewhurst at gmail
- -WPScan comes pre-installed on the following Linux distributions: - - * BackBox Linux - * BackTrack Linux (outdated WPScan installed, update needed) - * Pentoo - * SamuraiWTF - -Prerequisites: - - * Windows not supported - * Ruby => 1.9 - * RubyGems - * Git - --> Installing on Debian/Ubuntu: - - sudo apt-get install libcurl4-gnutls-dev libopenssl-ruby libxml2 libxml2-dev libxslt1-dev ruby-dev - git clone https://github.com/wpscanteam/wpscan.git - cd wpscan - sudo gem install bundler && bundle install --without test development - --> Installing on Fedora: - - sudo yum install libcurl-devel - git clone https://github.com/wpscanteam/wpscan.git - cd wpscan - sudo gem install bundler && bundle install --without test development - --> Installing on Archlinux: - - pacman -Sy ruby - pacman -Sy libyaml - - git clone https://github.com/wpscanteam/wpscan.git - cd wpscan - sudo gem install bundler && bundle install --without test development - - gem install typhoeus - gem install nokogiri - --> Installing on Mac OS X: - - git clone https://github.com/wpscanteam/wpscan.git - cd wpscan - sudo gem install bundler && bundle install --without test development- -
- Typhoeus segmentation fault: - Update cURL to version => 7.21 (may have to install from source) - See http://code.google.com/p/wpscan/issues/detail?id=81 - -- Proxy not working: - Update cURL to version => 7.21.7 (may have to install from source). - - Installation from sources : - - Grab the sources from http://curl.haxx.se/download.html - - Decompress the archive - - Open the folder with the extracted files - - Run ./configure - - Run make - - Run sudo make install - - Run sudo ldconfig - -- cannot load such file -- readline: - Run sudo aptitude install libreadline5-dev libncurses5-dev - - Then, open the directory of the readline gem (you have to locate it) - - cd ~/.rvm/src/ruby-1.9.2-p180/ext/readline - ruby extconf.rb - make - make install - - See http://vvv.tobiassjosten.net/ruby-on-rails/fixing-readline-for-the-ruby-on-rails-console/ for more details - -- no such file to load -- rubygems - Run update-alternatives --config ruby - And select your ruby version - - See https://github.com/wpscanteam/wpscan/issues/148- -
–update Update to the latest revision
- -–url | -u <target url> The WordPress URL/domain to scan.
- -–force | -f Forces WPScan to not check if the remote site is running -WordPress.
- -–enumerate | -e [option(s)] Enumeration.
- -option : - u usernames from id 1 to 10 - u[10-20] usernames from id 10 to 20 (you must write [] chars) - p plugins - vp only vulnerable plugins - ap all plugins (can take a long time) - tt timthumbs - t themes - vp only vulnerable themes - at all themes (can take a long time) -Multiple values are allowed : '-e tt,p' will enumerate timthumbs and plugins -If no option is supplied, the default is 'vt,tt,u,vp'- -
–exclude-content-based ‘<regexp or string>’ Used with the -enumeration option, will exclude all occurrences based on the regexp or -string supplied
- -You do not need to provide the regexp delimiters, but you must write the quotes (simple or double)- -
–config-file | -c <config file> Use the specified config file
- -–follow-redirection If the target url has a redirection, it will be -followed without asking if you wanted to do so or not
- -–wp-content-dir <wp content dir> WPScan try to find the content -directory (ie wp-content) by scanning the index page, however you can -specified it. Subdirectories are allowed
- -–wp-plugins-dir <wp plugins dir> Same thing than –wp-content-dir but -for the plugins directory. If not supplied, WPScan will use -wp-content-dir/plugins. Subdirectories are allowed
- -–proxy <[protocol://]host:port> Supply a proxy (will override the -one from conf/browser.conf.json).
- -HTTP, SOCKS4 SOCKS4A and SOCKS5 are supported. If no protocol is given (format host:port), HTTP will be used- -
–proxy-auth <username:password> Supply the proxy login credentials -(will override the one from conf/browser.conf.json).
- -–basic-auth <username:password> Set the HTTP Basic authentication
- -–wordlist | -w <wordlist> Supply a wordlist for the password bruter -and do the brute.
- -–threads | -t <number of threads> The number of threads to use when -multi-threading requests. (will override the value from -conf/browser.conf.json)
- -–username | -U <username> Only brute force the supplied username.
- -–help | -h This help screen.
- -–verbose | -v Verbose output.
- -Do ‘non-intrusive’ checks…
- -ruby wpscan.rb --url www.example.com- -
Do wordlist password brute force on enumerated users using 50 threads…
- -ruby wpscan.rb --url www.example.com --wordlist darkc0de.lst --threads 50- -
Do wordlist password brute force on the ‘admin’ username only…
- -ruby wpscan.rb --url www.example.com --wordlist darkc0de.lst --username admin- -
Enumerate installed plugins…
- -ruby wpscan.rb --url www.example.com --enumerate p- -
–help | -h This help screen. –Verbose | -v Verbose output. –update -| -u Update to the latest revision. –generate_plugin_list [number of -pages] Generate a new data/plugins.txt file. (supply number of -pages to parse, default : 150) –gpl Alias for –generate_plugin_list -–check-local-vulnerable-files | –clvf <local directory> Perform a -recursive scan in the <local directory> to find vulnerable files or -shells
- -Generate a new ‘most popular’ plugin list, up to 150 pages …
-ruby wpstools.rb –generate_plugin_list 150
-Locally scan a wordpress installation for vulnerable files or shells :
-ruby wpstools.rb -–check-local-vulnerable-files /var/www/wordpress/
- -github.com/wpscanteam/wpscan/issues
- -WPScan is sponsored by the RandomStorm Open Source Initiative.
- -Visit RandomStorm at www.randomstorm.com
- -Generated with the Darkfish - Rdoc Generator 2.
--# File lib/wpstools/plugins/stats/stats_plugin.rb, line 50 -def lines_in_file(file) - IO.readlines(file).size -end-
-# File lib/wpstools/plugins/stats/stats_plugin.rb, line 34 -def plugin_vulns_count(file=PLUGINS_VULNS_FILE) - xml(file).xpath("count(//vulnerability)").to_i -end-
-# File lib/wpstools/plugins/stats/stats_plugin.rb, line 12 -def run(options = {}) - if options[:stats] - puts "Wpscan Databse Statistics:" - puts "--------------------------" - puts "[#] Total vulnerable plugins: #{vuln_plugin_count}" - puts "[#] Total vulnerable themes: #{vuln_theme_count}" - puts "[#] Total plugin vulnerabilities: #{plugin_vulns_count}" - puts "[#] Total theme vulnerabilities: #{theme_vulns_count}" - puts "[#] Total plugins to enumerate: #{total_plugins}" - puts "[#] Total themes to enumerate: #{total_themes}" - puts - end -end-
-# File lib/wpstools/plugins/stats/stats_plugin.rb, line 38 -def theme_vulns_count(file=THEMES_VULNS_FILE) - xml(file).xpath("count(//vulnerability)").to_i -end-
-# File lib/wpstools/plugins/stats/stats_plugin.rb, line 42 -def total_plugins(file=PLUGINS_FULL_FILE) - lines_in_file(file) -end-
-# File lib/wpstools/plugins/stats/stats_plugin.rb, line 46 -def total_themes(file=THEMES_FULL_FILE) - lines_in_file(file) -end-
Generated with the Darkfish - Rdoc Generator 2.
-This Class Parses SVN Repositories via HTTP
- -Generated with the Darkfish - Rdoc Generator 2.
--# File lib/common/updater/svn_updater.rb, line 9 -def is_installed? - %[svn info "#@repo_directory" --xml 2>&1] =~ /revision=/ ? true : false -end-
Generated with the Darkfish - Rdoc Generator 2.
-Implementaion of a cache_key (Typhoeus::Request#hash has too many options)
-This is used in WpItem::Existable
- -Generated with the Darkfish - Rdoc Generator 2.
-Generated with the Darkfish - Rdoc Generator 2.
-Generated with the Darkfish - Rdoc Generator 2.
-Compare the body hash to error_404_hash and homepage_hash returns true if -they are different, false otherwise
- -@return [ Boolean ]
- - - --# File lib/common/hacks.rb, line 40 -def has_valid_hash?(error_404_hash, homepage_hash) - body_hash = Digest::MD5.hexdigest(self.body) - - body_hash != error_404_hash && body_hash != homepage_hash -end-
Generated with the Darkfish - Rdoc Generator 2.
-Generated with the Darkfish - Rdoc Generator 2.
--# File lib/common/hacks.rb, line 8 -def escape(str) - URI::Parser.new.escape(str) -end-
Generated with the Darkfish - Rdoc Generator 2.
-This class act as an absract one
- -TODO : add a last ‘/ to repo_directory if it’s -not present
- - - --# File lib/common/updater/updater.rb, line 8 -def initialize(repo_directory = nil) - @repo_directory = repo_directory -end-
-# File lib/common/updater/updater.rb, line 12 -def is_installed? - raise NotImplementedError -end-
Generated with the Darkfish - Rdoc Generator 2.
--# File lib/common/updater/updater_factory.rb, line 4 -def self.get_updater(repo_directory) - self.available_updaters_classes().each do |updater_symbol| - updater = Object.const_get(updater_symbol).new(repo_directory) - - if updater.is_installed? - return updater - end - end - nil -end-
Generated with the Darkfish - Rdoc Generator 2.
-Generated with the Darkfish - Rdoc Generator 2.
-Generated with the Darkfish - Rdoc Generator 2.
-Create the Vulnerability from the xml_node
- -@param [ Nokogiri::XML::Node ] xml_node
- -@return [ Vulnerability ]
- - - --# File lib/common/models/vulnerability.rb, line 37 -def self.load_from_xml_node(xml_node) - new( - xml_node.search('title').text, - xml_node.search('type').text, - xml_node.search('reference').map(&:text), - xml_node.search('metasploit').map(&:text) - ) -end-
@param [ String ] title The title of the vulnerability @param [ String ] -type The type of the vulnerability @param [ Array -] references References urls @param [ Array ] metasploit_modules -Metasploit modules for the vulnerability
- -@return [ Vulnerability ]
- - - --# File lib/common/models/vulnerability.rb, line 16 -def initialize(title, type, references, metasploit_modules = []) - @title = title - @type = type - @references = references - @metasploit_modules = metasploit_modules -end-
@param [ Vulnerability ] other
- -@return [ Boolean ] :nocov:
- - - --# File lib/common/models/vulnerability.rb, line 27 -def ==(other) - title == other.title && type == other.type && references == other.references -end-
Generated with the Darkfish - Rdoc Generator 2.
-@return [ String ] The url to the metasploit module page
- - - --# File lib/common/models/vulnerability/output.rb, line 18 -def self.metasploit_module_url(module_path) - # remove leading slash - module_path = module_path.sub(/^\//, '') - "http://www.metasploit.com/modules/#{module_path}" -end-
output the vulnerability
- - - --# File lib/common/models/vulnerability/output.rb, line 6 -def output - puts ' |' - puts ' | ' + red("* Title: #{title}") - references.each do |r| - puts ' | ' + red("* Reference: #{r}") - end - metasploit_modules.each do |m| - puts ' | ' + red("* Metasploit module: #{metasploit_module_url(m)}") - end -end-
Generated with the Darkfish - Rdoc Generator 2.
-Return the MD5 hash of a 404 page
- - - --# File lib/wpscan/web_site.rb, line 91 -def error_404_hash - unless @error_404_hash - non_existant_page = Digest::MD5.hexdigest(rand(999_999_999).to_s) + '.html' - @error_404_hash = WebSite.page_hash(@uri.merge(non_existant_page).to_s) - end - @error_404_hash -end-
-# File lib/wpscan/web_site.rb, line 23 -def has_basic_auth? - Browser.instance.get(@uri.to_s).code == 401 -end-
Checks if a robots.txt file exists
- - - --# File lib/wpscan/web_site.rb, line 107 -def has_robots? - Browser.instance.get(robots_url).code == 200 -end-
-# File lib/wpscan/web_site.rb, line 27 -def has_xml_rpc? - !xml_rpc_url.nil? -end-
-# File lib/wpscan/web_site.rb, line 83 -def homepage_hash - unless @homepage_hash - @homepage_hash = WebSite.page_hash(@uri.to_s) - end - @homepage_hash -end-
Checks if the remote website is up.
- - - --# File lib/wpscan/web_site.rb, line 19 -def online? - Browser.instance.get(@uri.to_s).code != 0 -end-
See if the remote url returns 30x redirect This method is recursive Return -a string with the redirection or nil
- - - --# File lib/wpscan/web_site.rb, line 61 -def redirection(url = nil) - redirection = nil - url ||= @uri.to_s - response = Browser.instance.get(url) - - if response.code == 301 || response.code == 302 - redirection = response.headers_hash['location'] - - # Let's check if there is a redirection in the redirection - if other_redirection = redirection(redirection) - redirection = other_redirection - end - end - - redirection -end-
Gets a robots.txt URL
- - - --# File lib/wpscan/web_site.rb, line 112 -def robots_url - robots = @uri.clone - robots.path = '/robots.txt' - robots.to_s -end-
Will try to find the rss url in the homepage Only the first one found iw -returned
- - - --# File lib/wpscan/web_site.rb, line 101 -def rss_url - homepage_body = Browser.instance.get(@uri.to_s).body - homepage_body[%{<link .* type="application/rss\+xml" .* href="([^"]+)" />}, 1] -end-
-# File lib/wpscan/web_site.rb, line 14 -def url - @uri.to_s -end-
-# File lib/wpscan/web_site.rb, line 10 -def url=(url) - @uri = URI.parse(add_trailing_slash(add_http_protocol(url))) -end-
See www.hixie.ch/specs/pingback/pingback-1.0#TOC2.3
- - - --# File lib/wpscan/web_site.rb, line 32 -def xml_rpc_url - unless @xmlrpc_url - @xmlrpc_url = xml_rpc_url_from_headers() || xml_rpc_url_from_body() - end - @xmlrpc_url -end-
-# File lib/wpscan/web_site.rb, line 52 -def xml_rpc_url_from_body - body = Browser.instance.get(@uri.to_s).body - - body[%{<link rel="pingback" href="([^"]+)" ?\/?>}, 1] -end-
-# File lib/wpscan/web_site.rb, line 39 -def xml_rpc_url_from_headers - headers = Browser.instance.get(@uri.to_s).headers_hash - xmlrpc_url = nil - - unless headers.nil? - pingback_url = headers['X-Pingback'] - unless pingback_url.nil? || pingback_url.empty? - xmlrpc_url = pingback_url - end - end - xmlrpc_url -end-
Generated with the Darkfish - Rdoc Generator 2.
-@return Array
- - - --# File lib/wpscan/modules/wp_config_backup.rb, line 39 -def self.config_backup_files - %{ - wp-config.php~ #wp-config.php# wp-config.php.save wp-config.php.swp wp-config.php.swo wp-config.php_bak - wp-config.bak wp-config.php.bak wp-config.save wp-config.old wp-config.php.old wp-config.php.orig - wp-config.orig wp-config.php.original wp-config.original wp-config.txt - } # thanks to Feross.org for these -end-
Checks to see if wp-config.php has a backup See www.feross.org/cmsploit/ return -an array of backup config files url
- - - --# File lib/wpscan/modules/wp_config_backup.rb, line 7 -def config_backup - found = [] - backups = WpConfigBackup.config_backup_files - browser = Browser.instance - hydra = browser.hydra - queue_count = 0 - - backups.each do |file| - file_url = @uri.merge(URI.escape(file)).to_s - request = browser.forge_request(file_url) - - request.on_complete do |response| - if response.body[%{define}] and not response.body[%{<\s?html}] - found << file_url - end - end - - hydra.queue(request) - queue_count += 1 - - if queue_count == browser.max_threads - hydra.run - queue_count = 0 - end - end - - hydra.run - - found -end-
Generated with the Darkfish - Rdoc Generator 2.
--# File lib/wpscan/modules/wp_full_path_disclosure.rb, line 10 -def full_path_disclosure_url - @uri.merge('wp-includes/rss-functions.php').to_s -end-
Check for Full Path Disclosure (FPD)
- - - --# File lib/wpscan/modules/wp_full_path_disclosure.rb, line 5 -def has_full_path_disclosure? - response = Browser.instance.get(full_path_disclosure_url()) - response.body[%{Fatal error}] -end-
Generated with the Darkfish - Rdoc Generator 2.
-@param [ URI ] target_base_uri @param [ Hash ] -options See allowed_option
- -@return [ WpItem ]
- - - --# File lib/common/models/wp_item.rb, line 31 -def initialize(target_base_uri, options = {}) - - options[:wp_content_dir] ||= 'wp-content' - options[:wp_plugins_dir] ||= options[:wp_content_dir] + '/plugins' - - set_options(options) - forge_uri(target_base_uri) -end-
@param [ WpItem ] other
- - - --# File lib/common/models/wp_item.rb, line 88 -def <=>(other) - name <=> other.name -end-
@param [ WpItem ] other
- - - --# File lib/common/models/wp_item.rb, line 93 -def ==(other) - name === other.name -end-
@param [ WpItem ] other
- - - --# File lib/common/models/wp_item.rb, line 98 -def ===(other) - self == other && version === other.version -end-
@return [ Array ] Make it private ?
- - - --# File lib/common/models/wp_item.rb, line 23 -def allowed_options - [:name, :wp_content_dir, :wp_plugins_dir, :path, :version, :vulns_file] -end-
@param [ URI ] target_base_uri
- -@return [ void ]
- - - --# File lib/common/models/wp_item.rb, line 61 -def forge_uri(target_base_uri) - @uri = target_base_uri -end-
Sets the found_from -attribute
- -@param [ String ] method The method which found the WpItem
- -@return [ void ]
- - - --# File lib/common/models/wp_item/findable.rb, line 10 -def found_from=(method) - found = method[%{find_from_(.*)}, 1] - @found_from = found.gsub('_', ' ') if found -end-
Sets the path
- -Variable, such as $wp-plugins$ and $wp-content$ can be used and will be -replace by their value
- -@param [ String ] path
- -@return [ void ]
- - - --# File lib/common/models/wp_item.rb, line 81 -def path=(path) - @path = URI.encode( - path.gsub(/\$wp-plugins\$/, wp_plugins_dir).gsub(/\$wp-content\$/, wp_content_dir) - ) -end-
@return [ String ] The url to the WpItem
- - - --# File lib/common/models/wp_item.rb, line 71 -def url; uri.to_s end-
Generated with the Darkfish - Rdoc Generator 2.
-Check the existence of the WpItem If the -response is supplied, it’s used for the verification Otherwise a new -request is done
- -@param [ Hash ] options See exists_from_response? @param [ Typhoeus::Response ] response
- -@return [ Boolean ]
- - - --# File lib/common/models/wp_item/existable.rb, line 13 -def exists?(options = {}, response = nil) - unless response - response = Browser.instance.get(url) - end - exists_from_response?(response, options) -end-
@param [ Typhoeus::Response ] -response @param [ options ] options
- -@option options [ Hash ] :error_404_hash The hash of the error 404 page -@option options [ Hash ] :homepage_hash The hash of the homepage @option -options [ Hash ] :exclude_content A regexp with the pattern to exclude from -the body of the response
- -@return [ Boolean ]
- - - --# File lib/common/models/wp_item/existable.rb, line 30 -def exists_from_response?(response, options = {}) - # FIXME : The response is supposed to follow locations, so we should not have 301 or 302. - # However, due to an issue with Typhoeus or Webmock, the location is not followed in specs - # See https://github.com/typhoeus/typhoeus/issues/279 - if [200, 301, 302, 401, 403].include?(response.code) - if response.has_valid_hash?(options[:error_404_hash], options[:homepage_hash]) - if options[:exclude_content] - unless response.body.match(options[:exclude_content]) - return true - end - else - return true - end - end - end - false -end-
Generated with the Darkfish - Rdoc Generator 2.
-Generated with the Darkfish - Rdoc Generator 2.
-@uri is used instead of uri to avoid the presence of the :path into it
- -@return [ String ] The url to the changelog file
- - - --# File lib/common/models/wp_item/infos.rb, line 23 -def changelog_url - @uri.merge('changelog.txt').to_s -end-
@return [ String ] The url to the error_log file
- - - --# File lib/common/models/wp_item/infos.rb, line 48 -def error_log_url - @uri.merge('error_log').to_s -end-
@return [ Boolean ]
- - - --# File lib/common/models/wp_item/infos.rb, line 18 -def has_changelog? - Browser.instance.get(changelog_url).code == 200 ? true : false -end-
@return [ Boolean ]
- - - --# File lib/common/models/wp_item/infos.rb, line 28 -def has_directory_listing? - Browser.instance.get(@uri.to_s).body[%{<title>Index of}] ? true : false -end-
Discover any error_log files created by WordPress These are created by the -WordPress error_log() function They are normally found in the /plugins/ -directory, however can also be found in their specific plugin dir. www.exploit-db.com/ghdb/3714/
- -Only the first 700 bytes are checked to avoid the download of the whole -file which can be very huge (like 2 Go)
- -@return [ Boolean ]
- - - --# File lib/common/models/wp_item/infos.rb, line 42 -def has_error_log? - response_body = Browser.instance.get(error_log_url, headers: {'range' => 'bytes=0-700'}).body - response_body[%{PHP Fatal error}] ? true : false -end-
Generated with the Darkfish - Rdoc Generator 2.
-@return [ Void ]
- - - --# File lib/common/models/wp_item/output.rb, line 6 -def output - puts - puts " | Name: #{self}" #this will also output the version number if detected - puts " | Location: #{url}" - #puts " | WordPress: #{wordpress_url}" if wordpress_org_item? - puts ' | Directory listing enabled: Yes' if has_directory_listing? - puts " | Readme: #{readme_url}" if has_readme? - puts " | Changelog: #{changelog_url}" if has_changelog? - - vulnerabilities.output - - if has_error_log? - puts ' | ' + red('[!]') + " An error_log file has been found : #{error_log_url}" - end -end-
Generated with the Darkfish - Rdoc Generator 2.
-@return [ String ]
- - - --# File lib/common/models/wp_item/versionable.rb, line 19 -def to_s - item_version = self.version - "#@name#{' v' + item_version.strip if item_version}" -end-
Get the version from the readme.txt
- -@return [ String ] The version number
- - - --# File lib/common/models/wp_item/versionable.rb, line 10 -def version - unless @version - response = Browser.instance.get(readme_url) - @version = response.body[%{stable tag: #{WpVersion.version_pattern}}, 1] - end - @version -end-
Generated with the Darkfish - Rdoc Generator 2.
-Get the vulnerabilities associated to the WpItem
- -@return [ Vulnerabilities ]
- - - --# File lib/common/models/wp_item/vulnerable.rb, line 9 -def vulnerabilities - xml = xml(vulns_file) - vulnerabilities = Vulnerabilities.new - - xml.xpath(vulns_xpath).each do |node| - vulnerabilities << Vulnerability.load_from_xml_node(node) - end - vulnerabilities -end-
Generated with the Darkfish - Rdoc Generator 2.
-Generated with the Darkfish - Rdoc Generator 2.
-@param [ Wptarget ] wp_target @param [ Hash ] options @option options [ -Boolean ] :show_progression Whether or not output the progress bar @option -options [ Boolean ] :only_vulnerable Only check for vulnerable items -@option options [ String ] :exclude_content
- -@return [ WpItems ]
- - - --# File lib/common/collections/wp_items/detectable.rb, line 14 -def aggressive_detection(wp_target, options = {}) - queue_count = 0 - request_count = 0 - browser = Browser.instance - hydra = browser.hydra - targets = targets_items(wp_target, options) - targets_size = targets.size - show_progression = options[:show_progression] || false - exist_options = { - error_404_hash: wp_target.error_404_hash, - homepage_hash: wp_target.homepage_hash, - exclude_content: options[:exclude_content] ? %{#{options[:exclude_content]}} : nil - } - - # If we only want the vulnerable ones, the passive detection is ignored - # Otherwise, a passive detection is performed, and results will be merged - results = options[:only_vulnerable] ? new : passive_detection(wp_target, options) - - targets.each do |target_item| - request = browser.forge_request(target_item.url, request_params) - request_count += 1 - - request.on_complete do |response| - - print "\rChecking for #{targets_size} total ... #{(request_count * 100) / targets_size}% complete." if show_progression - - if target_item.exists?(exist_options, response) - if !results.include?(target_item) - results << target_item - end - end - end - - hydra.queue(request) - queue_count += 1 - - if queue_count == browser.max_threads - hydra.run - queue_count = 0 - end - end - - hydra.run - results.sort! - results # can't just return results.sort because the #sort returns an array, and we want a WpItems -end-
@param [ WpTarget ] wp_target @param [ Hash -] options
- -@return [ WpItems ]
- - - --# File lib/common/collections/wp_items/detectable.rb, line 65 -def passive_detection(wp_target, options = {}) - results = new - item_class = self.item_class - type = self.to_s.gsub(/Wp/, '').downcase - response = Browser.instance.get(wp_target.url) - item_options = { - wp_content_dir: wp_target.wp_content_dir, - wp_plugins_dir: wp_target.wp_plugins_dir, - vulns_file: self.vulns_file - } - - regex1 = %{(?:[^=:]+)\s?(?:=|:)\s?(?:"|')[^"']+\\?/} - regex2 = %{\\?/} - regex3 = %{\\?/([^/\\"']+)\\?(?:/|"|')} - - names = response.body.scan(/#{regex1}#{Regexp.escape(wp_target.wp_content_dir)}#{regex2}#{Regexp.escape(type)}#{regex3}/) - - names.flatten.uniq.each do |name| - results << item_class.new(wp_target.uri, item_options.merge(name: name)) - end - - results.sort! - results -end-
@param [ Class ] klass @param [ String ] name @param [ WpTarget ] wp_target @option [ String ] vulns_file
- -@return [ WpItem ]
- - - --# File lib/common/collections/wp_items/detectable.rb, line 147 -def create_item(klass, name, wp_target, vulns_file = nil) - klass.new( - wp_target.uri, - name: name, - vulns_file: vulns_file, - wp_content_dir: wp_target.wp_content_dir, - wp_plugins_dir: wp_target.wp_plugins_dir - ) -end-
@return [ Class ]
- - - --# File lib/common/collections/wp_items/detectable.rb, line 180 -def item_class - Object.const_get(self.to_s.gsub(/.$/, '')) -end-
The default request parameters
- -@return [ Hash ]
- - - --# File lib/common/collections/wp_items/detectable.rb, line 95 -def request_params; { cache_ttl: 0, followlocation: true } end-
@param [ WpTarget ] wp_target @param [ -options ] options @option options [ Boolean ] :only_vulnerable @option -options [ String ] :file The path to the file containing the targets
- -@return [ Array<WpItem> ]
- - - --# File lib/common/collections/wp_items/detectable.rb, line 103 -def targets_items(wp_target, options = {}) - item_class = self.item_class - vulns_file = self.vulns_file - - targets = vulnerable_targets_items(wp_target, item_class, vulns_file) - - unless options[:only_vulnerable] - unless options[:file] - raise 'A file must be supplied' - end - - targets += targets_items_from_file(options[:file], wp_target, item_class, vulns_file) - end - - targets.uniq! { |t| t.name } - targets.sort_by { rand } -end-
@param [ String ] file @param [ WpTarget ] -wp_target @param [ Class ] item_class @param [ String ] -vulns_file
- -@return [ WpItem ]
- - - --# File lib/common/collections/wp_items/detectable.rb, line 163 -def targets_items_from_file(file, wp_target, item_class, vulns_file) - targets = [] - - File.open(file, 'r') do |f| - f.readlines.collect do |item_name| - targets << create_item( - item_class, - item_name.strip, - wp_target, - vulns_file - ) - end - end - targets -end-
@param [ WpTarget ] wp_target @param [ Class -] item_class @param [ -String ] vulns_file
- -@return [ Array<WpItem> ]
- - - --# File lib/common/collections/wp_items/detectable.rb, line 126 -def vulnerable_targets_items(wp_target, item_class, vulns_file) - targets = [] - xml = xml(vulns_file) - - xml.xpath(item_xpath).each do |node| - targets << create_item( - item_class, - node.attribute('name').text, - wp_target, - vulns_file - ) - end - targets -end-
Generated with the Darkfish - Rdoc Generator 2.
-Generated with the Darkfish - Rdoc Generator 2.
--# File lib/wpscan/modules/wp_login_protection.rb, line 8 -def has_login_protection? - !login_protection_plugin().nil? -end-
Checks if a login protection plugin is enabled code.google.com/p/wpscan/issues/detail?id=111 -return a WpPlugin object or nil if no one is -found
- - - --# File lib/wpscan/modules/wp_login_protection.rb, line 15 -def login_protection_plugin - unless @login_protection_plugin - protected_methods.grep(LOGIN_PROTECTION_METHOD_PATTERN).each do |symbol_to_call| - - if send(symbol_to_call) - plugin_name = symbol_to_call[LOGIN_PROTECTION_METHOD_PATTERN, 1].gsub('_', '-') - - return @login_protection_plugin = WpPlugin.new( - @uri, - name: plugin_name, - wp_content_dir: wp_content_dir, - wp_plugins_dir: wp_plugins_dir - ) - end - end - @login_protection_plugin = nil - end - @login_protection_plugin -end-
-# File lib/wpscan/modules/wp_login_protection.rb, line 61 -def better_wp_security_url - plugin_url('better-wp-security/') -end-
-# File lib/wpscan/modules/wp_login_protection.rb, line 97 -def bluetrait_event_viewer_url - plugin_url('bluetrait-event-viewer') -end-
wordpress.org/extend/plugins/better-wp-security/
- - - --# File lib/wpscan/modules/wp_login_protection.rb, line 48 -def has_better_wp_security_protection? - Browser.instance.get(better_wp_security_url).code != 404 -end-
wordpress.org/extend/plugins/bluetrait-event-viewer/
- - - --# File lib/wpscan/modules/wp_login_protection.rb, line 93 -def has_bluetrait_event_viewer_protection? - Browser.instance.get(bluetrait_event_viewer_url).code != 404 -end-
wordpress.org/extend/plugins/limit-login-attempts/
- - - --# File lib/wpscan/modules/wp_login_protection.rb, line 84 -def has_limit_login_attempts_protection? - Browser.instance.get(limit_login_attempts_url).code != 404 -end-
wordpress.org/extend/plugins/login-lock/
- - - --# File lib/wpscan/modules/wp_login_protection.rb, line 43 -def has_login_lock_protection? - Browser.instance.get(login_url).body =~ %{LOGIN LOCK} ? true : false -end-
Thanks to Alip Aswalid for providing this method. wordpress.org/extend/plugins/login-lockdown/
- - - --# File lib/wpscan/modules/wp_login_protection.rb, line 38 -def has_login_lockdown_protection? - Browser.instance.get(login_url).body =~ %{Login LockDown} ? true : false -end-
wordpress.org/extend/plugins/login-security-solution/
- - - --# File lib/wpscan/modules/wp_login_protection.rb, line 75 -def has_login_security_solution_protection? - Browser.instance.get(login_security_solution_url()).code != 404 -end-
wordpress.org/extend/plugins/simple-login-lockdown/
- - - --# File lib/wpscan/modules/wp_login_protection.rb, line 66 -def has_simple_login_lockdown_protection? - Browser.instance.get(simple_login_lockdown_url).code != 404 -end-
-# File lib/wpscan/modules/wp_login_protection.rb, line 88 -def limit_login_attempts_url - plugin_url('limit-login-attempts') -end-
-# File lib/wpscan/modules/wp_login_protection.rb, line 79 -def login_security_solution_url - plugin_url('login-security-solution') -end-
-# File lib/wpscan/modules/wp_login_protection.rb, line 52 -def plugin_url(plugin_name) - WpPlugin.new( - @uri, - name: plugin_name, - wp_content_dir: wp_content_dir, - wp_plugins_dir: wp_plugins_dir - ).url -end-
Generated with the Darkfish - Rdoc Generator 2.
-Generated with the Darkfish - Rdoc Generator 2.
-@return [ String ] The path to the file containing vulnerabilities
- - - --# File lib/common/models/wp_plugin/vulnerable.rb, line 6 -def vulns_file - unless @vulns_file - @vulns_file = PLUGINS_VULNS_FILE - end - @vulns_file -end-
Generated with the Darkfish - Rdoc Generator 2.
-Generated with the Darkfish - Rdoc Generator 2.
-Generated with the Darkfish - Rdoc Generator 2.
-Checks to see if the readme.html file exists
- -This file comes by default in a wordpress installation, and if deleted is -reinstated with an upgrade.
- - - --# File lib/wpscan/modules/wp_readme.rb, line 8 -def has_readme? - response = Browser.instance.get(readme_url()) - - unless response.code == 404 - response.body =~ %{wordpress} - end -end-
Generated with the Darkfish - Rdoc Generator 2.
--# File lib/wpscan/wp_target.rb, line 20 -def initialize(target_url, options = {}) - super(target_url) - - @verbose = options[:verbose] - @wp_content_dir = options[:wp_content_dir] - @wp_plugins_dir = options[:wp_plugins_dir] - @multisite = nil - - Browser.instance(options.merge(:max_threads => options[:threads])) -end-
-# File lib/wpscan/wp_target.rb, line 140 -def debug_log_url - @uri.merge("#{wp_content_dir()}/debug.log").to_s -end-
-# File lib/wpscan/wp_target.rb, line 112 -def default_wp_content_dir_exists? - response = Browser.instance.get(@uri.merge('wp-content').to_s) - hash = Digest::MD5.hexdigest(response.body) - - if WpTarget.valid_response_codes.include?(response.code) - return true if hash != error_404_hash and hash != homepage_hash - end - - false -end-
-# File lib/wpscan/wp_target.rb, line 134 -def has_debug_log? - # 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[%{\[[^\]]+\] PHP (?:Warning|Error|Notice):}] ? true : false -end-
-# File lib/wpscan/wp_target.rb, line 86 -def has_plugin?(name, version = nil) - WpPlugin.new( - @uri, - name: name, - version: version, - wp_content_dir: wp_content_dir, - wp_plugins_dir: wp_plugins_dir - ).exists? -end-
-# File lib/wpscan/wp_target.rb, line 179 -def is_multisite? - unless @multisite - # when multi site, there is no redirection or a redirect to the site itself - # otherwise redirect to wp-login.php - url = @uri.merge('wp-signup.php') - resp = Browser.instance.get(url) - if resp.code == 302 and resp.headers_hash['location'] =~ /wp-login\.php\?action=register/ - @multisite = false - elsif resp.code == 302 and resp.headers_hash['location'] =~ /wp-signup\.php/ - @multisite = true - elsif resp.code == 200 - @multisite = true - else - @multisite = false - end - end - @multisite -end-
-# File lib/wpscan/wp_target.rb, line 57 -def login_url - url = @uri.merge('wp-login.php').to_s - - # Let's check if the login url is redirected (to https url for example) - redirection = redirection(url) - if redirection - url = redirection - end - - url -end-
Should check wp-login.php if registration is enabled or not
- - - --# File lib/wpscan/wp_target.rb, line 157 -def registration_enabled? - resp = Browser.instance.get(registration_url) - # redirect only on non multi sites - if resp.code == 302 and resp.headers_hash['location'] =~ /wp-login\.php\?registration=disabled/ - enabled = false - # multi site registration form - elsif resp.code == 200 and resp.body =~ /<form id="setupform" method="post" action="[^"]*wp-signup\.php[^"]*">/ - enabled = true - # normal registration form - elsif resp.code == 200 and resp.body =~ /<form name="registerform" id="registerform" action="[^"]*wp-login\.php[^"]*"/ - enabled = true - # registration disabled - else - enabled = false - end - enabled -end-
-# File lib/wpscan/wp_target.rb, line 175 -def registration_url - is_multisite? ? @uri.merge('wp-signup.php') : @uri.merge('wp-login.php?action=register') -end-
-# File lib/wpscan/wp_target.rb, line 151 -def search_replace_db_2_exists? - resp = Browser.instance.get(search_replace_db_2_url) - resp.code == 200 && resp.body[%{by interconnect}] -end-
Script for replacing strings in wordpress databases reveals databse -credentials after hitting submit interconnectit.com/124/search-and-replace-for-wordpress-databases/
- - - --# File lib/wpscan/wp_target.rb, line 147 -def search_replace_db_2_url - @uri.merge('searchreplacedb2.php').to_s -end-
return WpTheme
- - - --# File lib/wpscan/wp_target.rb, line 75 -def theme - WpTheme.find(@uri) -end-
@param [ String ] versions_xml
- -@return [ WpVersion ]
- - - --# File lib/wpscan/wp_target.rb, line 82 -def version(versions_xml) - WpVersion.find(@uri, wp_content_dir, wp_plugins_dir, versions_xml) -end-
check if the target website is actually running wordpress.
- - - --# File lib/wpscan/wp_target.rb, line 33 -def wordpress? - wordpress = false - - response = Browser.instance.get_and_follow_location(@uri.to_s) - - if response.body =~ /["'][^"']*\/wp-content\/[^"']*["']/ - wordpress = true - else - response = Browser.instance.get_and_follow_location(xml_rpc_url) - - if response.body =~ %{XML-RPC server accepts POST requests only} - wordpress = true - else - response = Browser.instance.get_and_follow_location(login_url) - - if response.code == 200 && response.body =~ %{WordPress} - wordpress = true - end - end - end - - wordpress -end-
-# File lib/wpscan/wp_target.rb, line 96 -def wp_content_dir - unless @wp_content_dir - index_body = Browser.instance.get(@uri.to_s).body - uri_path = @uri.path # Only use the path because domain can be text or an IP - - if index_body[/\/wp-content\/(?:themes|plugins)\//] || default_wp_content_dir_exists? - @wp_content_dir = 'wp-content' - else - domains_excluded = '(?:www\.)?(facebook|twitter)\.com' - @wp_content_dir = index_body[/(?:href|src)\s*=\s*(?:"|').+#{Regexp.escape(uri_path)}((?!#{domains_excluded})[^"']+)\/(?:themes|plugins)\/.*(?:"|')/, 1] - end - end - - @wp_content_dir -end-
Generated with the Darkfish - Rdoc Generator 2.
--# File lib/common/models/wp_theme.rb, line 13 -def allowed_options; super << :style_url end-
Generated with the Darkfish - Rdoc Generator 2.
-Find the main theme of the blog
- -@param [ URI ] target_uri
- -@return [ WpTheme ]
- - - --# File lib/common/models/wp_theme/findable.rb, line 10 -def find(target_uri) - methods.grep(/^find_from_/).each do |method| - if wp_theme = self.send(method, target_uri) - wp_theme.found_from = method - - return wp_theme - end - end - nil -end-
Discover the wordpress theme by parsing the css link rel
- -@param [ URI ] target_uri
- -@return [ WpTheme ]
- - - --# File lib/common/models/wp_theme/findable.rb, line 28 -def find_from_css_link(target_uri) - response = Browser.instance.get_and_follow_location(target_uri.to_s) - - # https + domain is optional because of relative links - matches = %{(?:https?://[^"']+)?/([^/]+)/themes/([^"']+)/style.css}.match(response.body) - if matches - return new( - target_uri, - { - name: matches[2], - style_url: matches[0], - wp_content_dir: matches[1] - } - ) - end -end-
code.google.com/p/wpscan/issues/detail?id=141
- -@param [ URI ] target_uri
- -@return [ WpTheme ]
- - - --# File lib/common/models/wp_theme/findable.rb, line 50 -def find_from_wooframework(target_uri) - body = Browser.instance.get(target_uri.to_s).body - regexp = %{<meta name="generator" content="([^\s"]+)\s?([^"]+)?" />\s+<meta name="generator" content="WooFramework\s?([^"]+)?" />} - - - if matches = regexp.match(body) - woo_theme_name = matches[1] - woo_theme_version = matches[2] - #woo_framework_version = matches[3] # Not used at this time - - return new( - target_uri, - { - name: woo_theme_name, - version: woo_theme_version - } - ) - end -end-
Generated with the Darkfish - Rdoc Generator 2.
--# File lib/common/models/wp_theme/versionable.rb, line 5 -def version - unless @version - @version = Browser.instance.get(style_url).body[%{Version:\s([^\s]+)}, 1] - - # Get Version from readme.txt - @version ||= super - end - @version -end-
Generated with the Darkfish - Rdoc Generator 2.
-@return [ String ] The path to the file containing vulnerabilities
- - - --# File lib/common/models/wp_theme/vulnerable.rb, line 6 -def vulns_file - unless @vulns_file - @vulns_file = THEMES_VULNS_FILE - end - @vulns_file -end-
Generated with the Darkfish - Rdoc Generator 2.
-Generated with the Darkfish - Rdoc Generator 2.
-Generated with the Darkfish - Rdoc Generator 2.
-@param [ WpTimthumb ] other
- -@return [ Boolean ]
- - - --# File lib/common/models/wp_timthumb.rb, line 14 -def ==(other) - url == other.url -end-
Generated with the Darkfish - Rdoc Generator 2.
-@param [ Typhoeus::Response ] -response @param [ Hash ] options
- -@return [ Boolean ]
- - - --# File lib/common/models/wp_timthumb/existable.rb, line 9 -def exists_from_response?(response, options = {}) - response.code == 400 && response.body =~ /no image specified/ ? true : false -end-
Generated with the Darkfish - Rdoc Generator 2.
-Generated with the Darkfish - Rdoc Generator 2.
-@return [ String ]
- - - --# File lib/common/models/wp_timthumb/versionable.rb, line 18 -def to_s - "#{url}#{ ' v' + version if version}" -end-
Get the version from the body of an invalid request See code.google.com/p/timthumb/source/browse/trunk/timthumb.php#426
- -@return [ String ] The version
- - - --# File lib/common/models/wp_timthumb/versionable.rb, line 9 -def version - unless @version - response = Browser.instance.get(url) - @version = response.body[%{TimThumb version\s*: ([^<]+)} , 1] - end - @version -end-
Generated with the Darkfish - Rdoc Generator 2.
-Generated with the Darkfish - Rdoc Generator 2.
-No passive detection
- -@param [ WpTarget ] wp_target @param [ Hash -] options
- -@return [ WpTimthumbs ]
- - - --# File lib/common/collections/wp_timthumbs/detectable.rb, line 11 -def passive_detection(wp_target, options = {}) - new -end-
@param [ WpTarget ] wp_target @option [ -String ] path
- -@return [ WpTimthumb ]
- - - --# File lib/common/collections/wp_timthumbs/detectable.rb, line 71 -def create_item(wp_target, path = nil) - options = { - wp_content_dir: wp_target.wp_content_dir, - wp_plugins_dir: wp_target.wp_plugins_dir - } - - options.merge!(path: path) if path - - WpTimthumb.new(wp_target.uri, options) -end-
@param [ WpTarget ] wp_target @param [ Hash -] options @option options [ String ] :file The path to the file containing -the targets @option options [ String ] :theme_name
- -@return [ Array<WpTimthumb> ]
- - - --# File lib/common/collections/wp_timthumbs/detectable.rb, line 23 -def targets_items(wp_target, options = {}) - targets = options[:theme_name] ? theme_timthumbs(options[:theme_name], wp_target) : [] - - if options[:file] - targets += targets_items_from_file(options[:file], wp_target) - end - - targets.uniq { |i| i.url } -end-
@param [ String ] file @param [ WpTarget ] -wp_target
- -@return [ Array<WpTimthumb> ]
- - - --# File lib/common/collections/wp_timthumbs/detectable.rb, line 56 -def targets_items_from_file(file, wp_target) - targets = [] - - File.open(file, 'r') do |f| - f.readlines.collect do |path| - targets << create_item(wp_target, path.strip) - end - end - targets -end-
@param [ String ] theme_name @param [ WpTarget ] wp_target
- -@return [ Array<WpTimthumb> ]
- - - --# File lib/common/collections/wp_timthumbs/detectable.rb, line 37 -def theme_timthumbs(theme_name, wp_target) - targets = [] - wp_timthumb = create_item(wp_target) - - %{ - timthumb.php lib/timthumb.php inc/timthumb.php includes/timthumb.php - scripts/timthumb.php tools/timthumb.php functions/timthumb.php - }.each do |path| - wp_timthumb.path = "$wp-content$/themes/#{theme_name}/#{path}" - - targets << wp_timthumb.dup - end - targets -end-
Generated with the Darkfish - Rdoc Generator 2.
-@param [ WpUser ] other
- - - --# File lib/common/models/wp_user.rb, line 30 -def <=>(other) - id <=> other.id -end-
@param [ WpUser ] other
- -@return [ Boolean ]
- - - --# File lib/common/models/wp_user.rb, line 37 -def ==(other) - self === other -end-
@param [ WpUser ] other
- -@return [ Boolean ]
- - - --# File lib/common/models/wp_user.rb, line 44 -def ===(other) - id === other.id && login === other.login -end-
@return [ Array<Symbol> ]
- - - --# File lib/common/models/wp_user.rb, line 10 -def allowed_options; [:id, :login, :display_name, :password] end-
@return [ String ]
- - - --# File lib/common/models/wp_user.rb, line 22 -def to_s - s = "#{id}" - s += " | #{login}" if login - s += " | #{display_name}" if display_name - s -end-
@return [ URI ] The uri to the auhor page
- - - --# File lib/common/models/wp_user.rb, line 13 -def uri - if id - return @uri.merge("?author=#{id}") - else - raise 'The id is nil' - end -end-
Generated with the Darkfish - Rdoc Generator 2.
-@note Some bodies are encoded in ASCII-8BIT, and Nokogiri doesn’t support -it
- -So it's forced to UTF-8 when this encoding is detected- -
@param [ String ] body
- -@return [ String ] The display_name
- - - --# File lib/common/models/wp_user/existable.rb, line 63 -def self.display_name_from_body(body) - if title_tag = body[%{<title>([^<]+)</title>}, 1] - title_tag.force_encoding('UTF-8') if title_tag.encoding == Encoding::ASCII_8BIT - title_tag = Nokogiri::HTML::DocumentFragment.parse(title_tag).to_s - # & are not decoded with Nokogiri - title_tag.sub!('&', '&') - - name = title_tag[%{([^|«]+) }, 1] - - return name.strip if name - end -end-
@param [ String ] body
- -@return [ String ] The login
- - - --# File lib/common/models/wp_user/existable.rb, line 45 -def self.login_from_body(body) - # Feed URL with Permalinks - login = WpUser::Existable.login_from_author_pattern(body) - - unless login - # No Permalinks - login = body[%{<body class="archive author author-([^\s]+) author-(\d+)}, 1] - end - - login -end-
@param [ Typhoeus::Response ] -response @param [ Hash ] options
- -@return [ Boolean ]
- - - --# File lib/common/models/wp_user/existable.rb, line 9 -def exists_from_response?(response, options = {}) - load_from_response(response) - - @login ? true : false -end-
Generated with the Darkfish - Rdoc Generator 2.
-Generated with the Darkfish - Rdoc Generator 2.
-No passive detection
- -@return [ WpUsers ]
- - - --# File lib/common/collections/wp_users/detectable.rb, line 11 -def passive_detection(wp_target, options = {}) - new -end-
@param [ WpTarget ] wp_target @param [ Hash -] options @option options [ Range ] :range ((1..10))
- -@return [ Array<WpUser> ]
- - - --# File lib/common/collections/wp_users/detectable.rb, line 22 -def targets_items(wp_target, options = {}) - range = options[:range] || (1..10) - targets = [] - - range.each do |user_id| - targets << WpUser.new(wp_target.uri, id: user_id) - end - targets -end-
Generated with the Darkfish - Rdoc Generator 2.
-TODO : create a generic method to output tabs
- - - --# File lib/common/collections/wp_users/output.rb, line 6 -def output(left_margin = '') - max_id_length = self.sort { |a, b| a.id.to_s.length <=> b.id.to_s.length }.last.id.to_s.length - max_login_length = self.sort { |a, b| a.login.length <=> b.login.length }.last.login.length - max_display_name_length = self.sort { |a, b| a.display_name.length <=> b.display_name.length }.last.display_name.length - - inner_space = 2 - id_length = (max_id_length + inner_space * 2) /2 *2 - login_length = max_login_length + inner_space * 2 - display_name_length = max_display_name_length + inner_space * 2 - - puts left_margin + '+' * (id_length + login_length + display_name_length + 4) - puts left_margin + '|' + 'id'.center(id_length) + '|' + 'login'.center(login_length) + '|' + 'display name'.center(display_name_length) + '|' - puts left_margin + '|' + '+' * (id_length + login_length + display_name_length + 2) + '|' - - self.each do |u| - puts left_margin + '|' + u.id.to_s.center(id_length) + '|' + u.login.center(login_length) + '|' + u.display_name.center(display_name_length) + '|' - end - - puts left_margin + '+' * (id_length + login_length + display_name_length + 4) -end-
Generated with the Darkfish - Rdoc Generator 2.
-@param [ WpVersion ] other
- -@return [ Boolean ]
- - - --# File lib/common/models/wp_version.rb, line 21 -def ==(other) - number == other.number -end-
@return [ Array ]
- - - --# File lib/common/models/wp_version.rb, line 16 -def allowed_options; super << :number << :found_from end-
Generated with the Darkfish - Rdoc Generator 2.
-Find the version of the blog designated from target_uri
- -@param [ URI ] target_uri @param [ String ] -wp_content_dir @param [ String ] wp_plugins_dir
- -@return [ WpVersion ]
- - - --# File lib/common/models/wp_version/findable.rb, line 13 -def find(target_uri, wp_content_dir, wp_plugins_dir, versions_xml) - methods.grep(/find_from_/).each do |method| - - if method === :find_from_advanced_fingerprinting - version = send(method, target_uri, wp_content_dir, wp_plugins_dir, versions_xml) - else - version = send(method, target_uri) - end - - if version - return new(target_uri, number: version, found_from: method) - end - end - nil -end-
Uses data/wp_versions.xml to try to identify a wordpress version.
- -It does this by using client side file hashing
- -/!\ Warning : this method might return false positive if the file used for -fingerprinting is part of a theme (they can be updated)
- -@param [ URI ] target_uri @param [ String ] -wp_content_dir @param [ String ] wp_plugins_dir @param [ String ] -versions_xml The path to the xml containing all versions
- -@return [ String ] The version number
- - - --# File lib/common/models/wp_version/findable.rb, line 153 -def find_from_advanced_fingerprinting(target_uri, wp_content_dir, wp_plugins_dir, versions_xml) - xml = xml(versions_xml) - - # This wp_item will take care of encoding the path - # and replace variables like $wp-content$ & $wp-plugins$ - wp_item = WpItem.new(target_uri, - wp_content_dir: wp_content_dir, - wp_plugins_dir: wp_plugins_dir) - - xml.xpath('//file').each do |node| - wp_item.path = node.attribute('src').text - - response = Browser.instance.get(wp_item.url) - md5sum = Digest::MD5.hexdigest(response.body) - - node.search('hash').each do |hash| - if hash.attribute('md5').text == md5sum - return hash.search('version').text - end - end - end - nil -end-
Attempts to find the WordPress version from, the generator tag in the Atom -source.
- -@param [ URI ] target_uri
- -@return [ String ] The version number
- - - --# File lib/common/models/wp_version/findable.rb, line 120 -def find_from_atom_generator(target_uri) - scan_url( - target_uri, - %{<generator uri="http://wordpress.org/" version="#{version_pattern}">WordPress</generator>}, - 'feed/atom/' - ) -end-
Attempts to find the WordPress version from the p-links-opml.php file.
- -@param [ URI ] target_uri
- -@return [ String ] The version number
- - - --# File lib/common/models/wp_version/findable.rb, line 210 -def find_from_links_opml(target_uri) - scan_url( - target_uri, - %{generator="wordpress/#{version_pattern}"}, - 'wp-links-opml.php' - ) -end-
Attempts to find the wordpress version from, the generator meta tag in the -html source.
- -The meta tag can be removed however it seems, that it is reinstated on -upgrade.
- -@param [ URI ] target_uri
- -@return [ String ] The version number
- - - --# File lib/common/models/wp_version/findable.rb, line 67 -def find_from_meta_generator(target_uri) - scan_url( - target_uri, - %{name="generator" content="wordpress #{version_pattern}"} - ) -end-
Attempts to find WordPress version from, the generator tag in the RDF feed -source.
- -@param [ URI ] target_uri
- -@return [ String ] The version number
- - - --# File lib/common/models/wp_version/findable.rb, line 94 -def find_from_rdf_generator(target_uri) - scan_url( - target_uri, - %{<admin:generatorAgent rdf:resource="http://wordpress.org/\?v=#{version_pattern}" />}, - 'feed/rdf/' - ) -end-
Attempts to find the WordPress version from the readme.html file.
- -@param [ URI ] target_uri
- -@return [ String ] The version number
- - - --# File lib/common/models/wp_version/findable.rb, line 182 -def find_from_readme(target_uri) - scan_url( - target_uri, - %{<br />\sversion #{version_pattern}}, - 'readme.html' - ) -end-
Attempts to find the WordPress version from, the generator tag in the RSS -feed source.
- -@param [ URI ] target_uri
- -@return [ String ] The version number
- - - --# File lib/common/models/wp_version/findable.rb, line 80 -def find_from_rss_generator(target_uri) - scan_url( - target_uri, - %{<generator>http://wordpress.org/\?v=#{version_pattern}</generator>}, - 'feed/' - ) -end-
Attempts to find the WordPress version from the sitemap.xml file.
- -See: code.google.com/p/wpscan/issues/detail?id=109
- -@param [ URI ] target_uri
- -@return [ String ] The version number
- - - --# File lib/common/models/wp_version/findable.rb, line 197 -def find_from_sitemap_generator(target_uri) - scan_url( - target_uri, - %{generator="wordpress/#{version_pattern}"}, - 'sitemap.xml' - ) -end-
Returns the first match of <pattern> in the body of the url
- -@param [ URI ] target_uri @param [ Regex ] -pattern @param [ String ] path
- -@return [ String ]
- - - --# File lib/common/models/wp_version/findable.rb, line 45 -def scan_url(target_uri, pattern, path = nil) - url = path ? target_uri.merge(path).to_s : target_uri.to_s - response = Browser.instance.get_and_follow_location(url) - - response.body[pattern, 1] -end-
Generated with the Darkfish - Rdoc Generator 2.
--# File lib/common/models/wp_version/output.rb, line 5 -def output - puts green('[+]') + " WordPress version #{self.number} identified from #{self.found_from}" - - vulnerabilities = self.vulnerabilities - - unless vulnerabilities.empty? - puts - puts red('[!]') + " We have identified #{vulnerabilities.size} vulnerabilities from the version number :" - - vulnerabilities.output - end -end-
Generated with the Darkfish - Rdoc Generator 2.
-@return [ String ] The path to the file containing vulnerabilities
- - - --# File lib/common/models/wp_version/vulnerable.rb, line 6 -def vulns_file - unless @vulns_file - @vulns_file = WP_VULNS_FILE - end - @vulns_file -end-
Generated with the Darkfish - Rdoc Generator 2.
-Will load the options from ARGV return WpscanOptions
- - - --# File lib/wpscan/wpscan_options.rb, line 148 -def self.load_from_arguments - wpscan_options = WpscanOptions.new - - if ARGV.length > 0 - WpscanOptions.get_opt_long.each do |opt, arg| - wpscan_options.set_option_from_cli(opt, arg) - end - end - - wpscan_options -end-
Will removed the ‘-’ or ‘–’ chars at the beginning of option and replace -any remaining ‘-’ by ‘_’
- -param string option return string
- - - --# File lib/wpscan/wpscan_options.rb, line 246 -def self.clean_option(option) - cleaned_option = option.gsub(/^--?/, '') - cleaned_option.gsub(/-/, '_') -end-
Even if a short option is given (IE : -u), the long one will be returned -(IE : –url)
- - - --# File lib/wpscan/wpscan_options.rb, line 215 -def self.get_opt_long - GetoptLong.new( - ['--url', '-u', GetoptLong::REQUIRED_ARGUMENT], - ['--enumerate', '-e', GetoptLong::OPTIONAL_ARGUMENT], - ['--username', '-U', GetoptLong::REQUIRED_ARGUMENT], - ['--wordlist', '-w', GetoptLong::REQUIRED_ARGUMENT], - ['--threads', '-t', GetoptLong::REQUIRED_ARGUMENT], - ['--force', '-f', GetoptLong::NO_ARGUMENT], - ['--help', '-h', GetoptLong::NO_ARGUMENT], - ['--verbose', '-v', GetoptLong::NO_ARGUMENT], - ['--proxy', GetoptLong::REQUIRED_ARGUMENT], - ['--proxy-auth', GetoptLong::REQUIRED_ARGUMENT], - ['--update', GetoptLong::NO_ARGUMENT], - ['--follow-redirection', GetoptLong::NO_ARGUMENT], - ['--wp-content-dir', GetoptLong::REQUIRED_ARGUMENT], - ['--wp-plugins-dir', GetoptLong::REQUIRED_ARGUMENT], - ['--config-file', '-c', GetoptLong::REQUIRED_ARGUMENT], - ['--exclude-content-based', GetoptLong::REQUIRED_ARGUMENT], - ['--basic-auth', GetoptLong::REQUIRED_ARGUMENT] - ) -end-
-# File lib/wpscan/wpscan_options.rb, line 237 -def self.is_long_option?(option) - ACCESSOR_OPTIONS.include?(:"#{WpscanOptions.clean_option(option)}") -end-
-# File lib/wpscan/wpscan_options.rb, line 251 -def self.option_to_instance_variable_setter(option) - cleaned_option = WpscanOptions.clean_option(option) - option_syms = ACCESSOR_OPTIONS.grep(%{^#{cleaned_option}$}) - - option_syms.length == 1 ? :"#{option_syms.at(0)}=" : nil -end-
-# File lib/wpscan/wpscan_options.rb, line 123 -def basic_auth=(basic_auth) - raise 'Invalid basic authentication format, login:password expected' if basic_auth.index(':').nil? - @basic_auth = "Basic #{Base64.encode64(basic_auth).chomp}" -end-
-# File lib/wpscan/wpscan_options.rb, line 91 -def enumerate_all_plugins=(enumerate_all_plugins) - if enumerate_all_plugins === true and (@enumerate_plugins === true or @enumerate_only_vulnerable_plugins === true) - raise 'Please choose only one plugin enumeration option' - else - @enumerate_all_plugins = enumerate_all_plugins - end -end-
-# File lib/wpscan/wpscan_options.rb, line 115 -def enumerate_all_themes=(enumerate_all_themes) - if enumerate_all_themes === true and (@enumerate_themes === true or @enumerate_only_vulnerable_themes === true) - raise 'Please choose only one theme enumeration option' - else - @enumerate_all_themes = enumerate_all_themes - end -end-
-# File lib/wpscan/wpscan_options.rb, line 83 -def enumerate_only_vulnerable_plugins=(enumerate_only_vulnerable_plugins) - if enumerate_only_vulnerable_plugins === true and (@enumerate_all_plugins === true or @enumerate_plugins === true) - raise 'Please choose only one plugin enumeration option' - else - @enumerate_only_vulnerable_plugins = enumerate_only_vulnerable_plugins - end -end-
-# File lib/wpscan/wpscan_options.rb, line 107 -def enumerate_only_vulnerable_themes=(enumerate_only_vulnerable_themes) - if enumerate_only_vulnerable_themes === true and (@enumerate_all_themes === true or @enumerate_themes === true) - raise 'Please choose only one theme enumeration option' - else - @enumerate_only_vulnerable_themes = enumerate_only_vulnerable_themes - end -end-
Will set enumerate_* from the string value IE : if value = vp => -:enumerate_only_vulnerable_plugins will be set to true multiple enumeration -are possible : ‘u,p’ => :enumerate_usernames and :enumerate_plugins -Special case for usernames, a range is possible : u will enumerate usernames from 1 to 10
- - - --# File lib/wpscan/wpscan_options.rb, line 183 -def enumerate_options_from_string(value) - # Usage of self is mandatory because there are overridden setters - - value = value.split(',').map { |c| c.downcase } - - self.enumerate_only_vulnerable_plugins = true if value.include?('vp') - - self.enumerate_plugins = true if value.include?('p') - - self.enumerate_all_plugins = true if value.include?('ap') - - @enumerate_timthumbs = true if value.include?('tt') - - self.enumerate_only_vulnerable_themes = true if value.include?('vt') - - self.enumerate_themes = true if value.include?('t') - - self.enumerate_all_themes = true if value.include?('at') - - value.grep(/^u/) do |username_enum_value| - @enumerate_usernames = true - # Check for usernames range - matches = %{\[([\d]+)-([\d]+)\]}.match(username_enum_value) - if matches - @enumerate_usernames_range = (matches[1].to_i..matches[2].to_i) - end - end - -end-
-# File lib/wpscan/wpscan_options.rb, line 75 -def enumerate_plugins=(enumerate_plugins) - if enumerate_plugins === true and (@enumerate_all_plugins === true or @enumerate_only_vulnerable_plugins === true) - raise 'Please choose only one plugin enumeration option' - else - @enumerate_plugins = enumerate_plugins - end -end-
-# File lib/wpscan/wpscan_options.rb, line 99 -def enumerate_themes=(enumerate_themes) - if enumerate_themes === true and (@enumerate_all_themes === true or @enumerate_only_vulnerable_themes === true) - raise 'Please choose only one theme enumeration option' - else - @enumerate_themes = enumerate_themes - end -end-
-# File lib/wpscan/wpscan_options.rb, line 128 -def has_options? - !to_h.empty? -end-
-# File lib/wpscan/wpscan_options.rb, line 59 -def proxy=(proxy) - if proxy.index(':') == nil - raise 'Invalid proxy format. Should be host:port.' - else - @proxy = proxy - end -end-
-# File lib/wpscan/wpscan_options.rb, line 67 -def proxy_auth=(auth) - if auth.index(':') == nil - raise 'Invalid proxy auth format, username:password expected' - else - @proxy_auth = auth - end -end-
string cli_option : –url, -u, –proxy etc string cli_value : the option -value
- - - --# File lib/wpscan/wpscan_options.rb, line 162 -def set_option_from_cli(cli_option, cli_value) - - if WpscanOptions.is_long_option?(cli_option) - self.send( - WpscanOptions.option_to_instance_variable_setter(cli_option), - cli_value - ) - elsif cli_option === '--enumerate' # Special cases - # Default value if no argument is given - cli_value = 'vt,tt,u,vp' if cli_value.length == 0 - - enumerate_options_from_string(cli_value) - else - raise "Unknow option : #{cli_option} with value #{cli_value}" - end -end-
-# File lib/wpscan/wpscan_options.rb, line 47 -def threads=(threads) - @threads = threads.is_a?(Integer) ? threads : threads.to_i -end-
return Hash
- - - --# File lib/wpscan/wpscan_options.rb, line 133 -def to_h - options = {} - - ACCESSOR_OPTIONS.each do |option| - instance_variable = instance_variable_get("@#{option}") - - unless instance_variable.nil? - options[:"#{option}"] = instance_variable - end - end - options -end-
Generated with the Darkfish - Rdoc Generator 2.
-This is the API documentation for 'RDoc Documentation'.
- - - - -Generated with the Darkfish - Rdoc Generator 2.
-