Enumerate over a given set of items and check if they exist
Enumerate the given Targets
targets - targets to enumerate
:base_url - Base URL
:wp_content - wp-content directory
:path - Path to plugin
type - "plugins" or "themes", item to enumerate
filename - filename in the data directory with paths
show_progression - Show a progress bar during enumeration
# File lib/wpscan/wp_enumerator.rb, line 33 def self.enumerate(options = {}, items = nil) WpOptions.check_options(options) targets = self.generate_items(options) unless items == nil items.each do |i| targets << i end end found = [] queue_count = 0 request_count = 0 enum_browser = Browser.instance enum_hydra = enum_browser.hydra enumerate_size = targets.size exclude_regexp = options[:exclude_content_based] ? %r{#{options[:exclude_content_based]}} : nil show_progression = options[:show_progression] || false targets.each do |target| url = target.get_full_url request = enum_browser.forge_request(url, { cache_timeout: 0, follow_location: true }) request_count += 1 request.on_complete do |response| page_hash = Digest::MD5.hexdigest(response.body) print "\rChecking for #{enumerate_size} total #{options[:type]}... #{(request_count * 100) / enumerate_size}% complete." if show_progression if WpTarget.valid_response_codes.include?(response.code) if page_hash != options[:error_404_hash] and page_hash != options[:homepage_hash] if options[:exclude_content_based] unless response.body[exclude_regexp] found << target end else found << target end end end end enum_hydra.queue(request) queue_count += 1 if queue_count == enum_browser.max_threads enum_hydra.run queue_count = 0 end end enum_hydra.run found end
# File lib/wpscan/wp_enumerator.rb, line 93 def self.generate_items(options = {}) only_vulnerable = options[:only_vulnerable_ones] file = options[:file] vulns_file = options[:vulns_file] wp_content_dir = options[:wp_content_dir] url = options[:base_url] type = options[:type] plugins_dir = options[:wp_plugins_dir] targets_url = [] unless only_vulnerable # Open and parse the 'most popular' plugin list... File.open(file, 'r') do |f| f.readlines.collect do |line| l = line.strip targets_url << WpItem.new( base_url: url, path: l, wp_content_dir: wp_content_dir, name: l =~ %r.+\/.+/ ? File.dirname(l) : l.sub(%r\/$/, ''), vulns_file: vulns_file, type: type, wp_plugins_dir: plugins_dir ) end end end # Timthumbs have no XML file unless type =~ %rtimthumbs/ xml = Nokogiri::XML(File.open(vulns_file)) do |config| config.noblanks end # We check if the plugin name from the plugin_vulns_file is already in targets, otherwise we add it xml.xpath(options[:vulns_xpath_2]).each do |node| name = node.attribute('name').text targets_url << WpItem.new( base_url: url, path: name, wp_content_dir: wp_content_dir, name: name, vulns_file: vulns_file, type: type, wp_plugins_dir: plugins_dir ) end end targets_url.flatten! { |t| t.name } targets_url.uniq! { |t| t.name } # randomize the plugins array to *maybe* help in some crappy IDS/IPS/WAF detection targets_url.sort_by! { rand } end