-) 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 }
ACCESSOR_OPTIONS = [
:user_agent,
:user_agent_mode,
:available_user_agents,
:proxy,
:max_threads,
:cache_timeout,
:request_timeout
:user_agent,
:user_agent_mode,
:available_user_agents,
:proxy,
:max_threads,
:cache_timeout,
:request_timeout
]
attr_reader :hydra, :config_file
attr_reader :hydra, :config_file
attr_accessor *ACCESSOR_OPTIONS
def initialize(options = {})
@@ -52,6 +52,7 @@ class Browser
# might be in CacheFileStore
setup_cache_handlers
end
private_class_method :new
def self.instance(options = {})
@@ -113,9 +114,9 @@ class Browser
def setup_cache_handlers
@hydra.cache_setter do |request|
@cache.write_entry(
Browser.generate_cache_key_from_request(request),
request.response,
request.cache_timeout
Browser.generate_cache_key_from_request(request),
request.response,
request.cache_timeout
)
end
@@ -123,24 +124,25 @@ class Browser
@cache.read_entry(Browser.generate_cache_key_from_request(request)) rescue nil
end
end
private :setup_cache_handlers
def get(url, params = {})
run_request(
forge_request(url, params.merge(:method => :get))
forge_request(url, params.merge(:method => :get))
)
end
def post(url, params = {})
run_request(
forge_request(url, params.merge(:method => :post))
forge_request(url, params.merge(:method => :post))
)
end
def forge_request(url, params = {})
Typhoeus::Request.new(
url.to_s,
merge_request_params(params)
url.to_s,
merge_request_params(params)
)
end

View File

@@ -33,7 +33,7 @@ class CacheFileStore
# Marshal does not need any "require"
def initialize(storage_path, serializer = Marshal)
@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? :/
unless File.directory?(@storage_path)

View File

@@ -66,7 +66,7 @@ def get_equal_string_end(stringarray = [""])
break
end
end
if looping == false or (counter * -1 ) > base.length
if looping == false or (counter * -1) > base.length
break
end
already_found = "#{character if character}#{already_found}"
@@ -87,6 +87,7 @@ if RUBY_VERSION < "1.9"
end
matches
end
alias_method :grep, :_grep_
end
end
@@ -125,5 +126,10 @@ def colorize(text, color_code)
"\e[#{color_code}m#{text}\e[0m"
end
def red(text); colorize(text, 31) end
def green(text); colorize(text, 32) end
def red(text)
; 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
@@revision_pattern = /revision="(\d+)"/i
@@trunk_url = "https://wpscan.googlecode.com/svn/trunk"
REVISION_PATTERN = /revision="(\d+)"/i
TRUNK_URL = "https://github.com/wpscanteam/wpscan"
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
def local_revision_number
local_revision = %x[svn info "#{@repo_directory}" --xml 2>&1]
local_revision[@@revision_pattern, 1].to_s
local_revision = %x[svn info "#@repo_directory" --xml 2>&1]
local_revision[REVISION_PATTERN, 1].to_s
end
def update
%x[svn up "#{@repo_directory}"]
%x[svn up "#@repo_directory"]
end
end

View File

@@ -27,8 +27,8 @@ module Malwares
# return array of string (url of malwares found)
def malwares(malwares_file_path = nil)
if @malwares.nil?
malwares_found = []
malwares_file = Malwares.malwares_file(malwares_file_path)
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|

View File

@@ -24,14 +24,14 @@ module WebSite
wordpress = false
response = Browser.instance.get(login_url(),
{ :follow_location => true, :max_redirects => 2 }
{:follow_location => true, :max_redirects => 2}
)
if response.body =~ %r{WordPress}i
wordpress = true
else
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

View File

@@ -22,14 +22,14 @@ module WpConfigBackup
# See http://www.feross.org/cmsploit/
# return an array of backup config files url
def config_backup
found = []
backups = WpConfigBackup.config_backup_files
browser = Browser.instance
hydra = browser.hydra
found = []
backups = WpConfigBackup.config_backup_files
browser = Browser.instance
hydra = browser.hydra
backups.each do |file|
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|
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
def plugins_from_aggressive_detection(options)
options[:file] = options[:file] || "#{DATA_DIR}/plugins.txt"
options[:vulns_file] = options[:vulns_file] || "#{DATA_DIR}/plugin_vulns.xml"
options[:vulns_xpath] = "//plugin[@name='#{@name}']/vulnerability"
options[:file] = options[:file] || "#{DATA_DIR}/plugins.txt"
options[:vulns_file] = options[:vulns_file] || "#{DATA_DIR}/plugin_vulns.xml"
options[:vulns_xpath] = "//plugin[@name='#{@name}']/vulnerability"
options[:vulns_xpath_2] = "//plugin"
options[:type] = "plugins"
result = WpDetector.aggressive_detection(options)
options[:type] = "plugins"
result = WpDetector.aggressive_detection(options)
plugins = []
result.each do |r|
plugins << WpPlugin.new(
:url => r[:url],
:path => r[:path],
:url => r[:url],
:path => r[:path],
:wp_content_dir => r[:wp_content_dir],
:name => r[:name]
:name => r[:name]
)
end
plugins.sort_by { |p| p.name }
@@ -52,9 +52,9 @@ module WpPlugins
temp.each do |item|
plugins << WpPlugin.new(
:url => item[:url],
:name => item[:name],
:path => item[:path],
:url => item[:url],
:name => item[:name],
:path => item[:path],
:wp_content_dir => options[:wp_content_dir]
)
end

View File

@@ -19,19 +19,19 @@
module WpThemes
def themes_from_aggressive_detection(options)
options[:file] = options[:file] || "#{DATA_DIR}/themes.txt"
options[:vulns_file] = options[:vulns_file] || "#{DATA_DIR}/wp_theme_vulns.xml"
options[:vulns_xpath] = "//theme[@name='#{@name}']/vulnerability"
options[:file] = options[:file] || "#{DATA_DIR}/themes.txt"
options[:vulns_file] = options[:vulns_file] || "#{DATA_DIR}/wp_theme_vulns.xml"
options[:vulns_xpath] = "//theme[@name='#{@name}']/vulnerability"
options[:vulns_xpath_2] = "//theme"
options[:type] = "themes"
result = WpDetector.aggressive_detection(options)
options[:type] = "themes"
result = WpDetector.aggressive_detection(options)
themes = []
result.each do |r|
themes << WpTheme.new(
:url => r[:url],
:path => r[:path],
:url => r[:url],
:path => r[:path],
:wp_content_dir => r[:wp_content_dir],
:name => r[:name]
:name => r[:name]
)
end
themes.sort_by { |t| t.name }
@@ -43,9 +43,9 @@ module WpThemes
temp.each do |item|
themes << WpTheme.new(
:url => item[:url],
:name => item[:name],
:path => item[:path],
:url => item[:url],
:name => item[:name],
:path => item[:path],
:wp_content_dir => options[:wp_content_dir]
)
end

View File

@@ -47,7 +47,7 @@ module WpTimthumbs
protected
def targets_url_from_theme(theme_name, options)
targets = []
targets = []
theme_name = URI.escape(theme_name)
%w{
@@ -55,10 +55,10 @@ module WpTimthumbs
scripts/timthumb.php tools/timthumb.php functions/timthumb.php
}.each do |file|
targets << {
:url => options[:url],
:path => "themes/#{theme_name}/#{file}",
:url => options[:url],
:path => "themes/#{theme_name}/#{file}",
:wp_content_dir => options[:wp_content_dir],
:name => options[:name]
:name => options[:name]
}
end
targets

View File

@@ -26,9 +26,9 @@ module WpUsernames
#
# returns an array of WpUser (can be empty)
def usernames(options = {})
range = options[:range] || (1..10)
browser = Browser.instance
usernames = []
range = options[:range] || (1..10)
browser = Browser.instance
usernames = []
range.each do |author_id|
url = author_url(author_id)
@@ -58,7 +58,7 @@ module WpUsernames
end
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
if resp.code == 200
nickname = extract_nickname_from_body(resp.body)

View File

@@ -24,11 +24,11 @@ class WpItem < Vulnerable
def initialize(options = {})
@wp_content_dir = options[:wp_content_dir] || "wp-content"
@url = options[:url]
@path = options[:path]
@name = options[:name] || extract_name_from_url
@vulns_xml = options[:vulns_xml]
@vulns_xpath = options[:vulns_xpath].sub(/\$name\$/, @name)
@url = options[:url]
@path = options[:path]
@name = options[:name] || extract_name_from_url
@vulns_xml = options[:vulns_xml]
@vulns_xpath = options[:vulns_xpath].sub(/\$name\$/, @name)
raise("url not set") unless @url
raise("path not set") unless @path

View File

@@ -32,16 +32,16 @@
# * +type+ - Type: plugins, themes
class WpOptions
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("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_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("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("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("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_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("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("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
unless options[:type] =~ /plugins/i or options[:type] =~ /themes/i or options[:type] =~ /timthumbs/i
raise("Unknown type #{options[:type]}")

View File

@@ -18,10 +18,10 @@
class WpPlugin < WpItem
def initialize(options = {})
options[:vulns_xml] = options[:vulns_xml] || DATA_DIR + '/plugin_vulns.xml'
options[:vulns_xpath] = "//plugin[@name='$name$']/vulnerability"
options[:vulns_xml] = options[:vulns_xml] || DATA_DIR + '/plugin_vulns.xml'
options[:vulns_xpath] = "//plugin[@name='$name$']/vulnerability"
options[:vulns_xpath_2] = "//plugin"
options[:type] = "plugins"
options[:type] = "plugins"
super(options)
end
@@ -31,7 +31,7 @@ class WpPlugin < WpItem
# however can also be found in their specific plugin dir.
# http://www.exploit-db.com/ghdb/3714/
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
end

View File

@@ -34,8 +34,8 @@ class WpTarget
attr_reader :uri, :verbose
def initialize(target_url, options = {})
@uri = URI.parse(add_trailing_slash(add_http_protocol(target_url)))
@verbose = options[:verbose]
@uri = URI.parse(add_trailing_slash(add_http_protocol(target_url)))
@verbose = options[:verbose]
@wp_content_dir = options[:wp_content_dir]
@wp_plugins_dir = options[:wp_plugins_dir]
@@ -111,7 +111,7 @@ class WpTarget
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 = Browser.instance.get(debug_log_url(), :headers => {"range" => "bytes=0-700"}).body
response_body[%r{\[[^\]]+\] PHP (?:Warning|Error|Notice):}] ? true : false
end

View File

@@ -23,10 +23,10 @@ class WpTheme < WpItem
attr_reader :name, :style_url, :version
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"
@version = options[:version]
@style_url = options[:style_url]
@version = options[:version]
@style_url = options[:style_url]
super(options)
end
@@ -56,18 +56,18 @@ class WpTheme < WpItem
# Discover the wordpress theme name by parsing the css link rel
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)
if matches
style_url = matches[0]
theme_name = matches[1]
return new(:name => theme_name,
:style_url => style_url,
:url => style_url,
:path => "",
:wp_content_dir => ""
return new(:name => theme_name,
:style_url => style_url,
:url => style_url,
:path => "",
:wp_content_dir => ""
)
end
end
@@ -79,15 +79,15 @@ class WpTheme < WpItem
matches = regexp.match(body)
if matches
woo_theme_name = matches[1]
woo_theme_version = matches[2]
woo_theme_name = matches[1]
woo_theme_version = matches[2]
woo_framework_version = matches[3] # Not used at this time
return new(:name => woo_theme_name,
:version => woo_theme_version,
:url => matches[0],
:path => "",
:wp_content_dir => ""
return new(:name => woo_theme_name,
:version => woo_theme_version,
:url => matches[0],
:path => "",
:wp_content_dir => ""
)
end
end

View File

@@ -23,10 +23,10 @@ class WpVersion < Vulnerable
attr_reader :number, :discovery_method
def initialize(number, options = {})
@number = number
@number = number
@discovery_method = options[:discovery_method]
@vulns_xml = options[:vulns_xml] || DATA_DIR + '/wp_vulns.xml'
@vulns_xpath = "//wordpress[@version='#{@number}']/vulnerability"
@vulns_xml = options[:vulns_xml] || DATA_DIR + '/wp_vulns.xml'
@vulns_xpath = "//wordpress[@version='#{@number}']/vulnerability"
end
# 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)
def self.find(target_uri, wp_content_dir)
options = {
:url => target_uri,
:url => target_uri,
:wp_content_dir => wp_content_dir
}
self.methods.grep(/find_from_/).each do |method_to_call|
@@ -60,14 +60,14 @@ class WpVersion < Vulnerable
# that it is reinstated on upgrade.
def self.find_from_meta_generator(options)
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]
end
def self.find_from_rss_generator(options)
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]
end
@@ -105,11 +105,11 @@ class WpVersion < Vulnerable
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)
response = Browser.instance.get(file_url)
md5sum = Digest::MD5.hexdigest(response.body)
md5sum = Digest::MD5.hexdigest(response.body)
node.search('hash').each do |hash|
if hash.attribute('md5').text == md5sum
return hash.search('versions').text
return hash.search('versions').text
end
end
end

View File

@@ -20,8 +20,8 @@ class WpVulnerability
attr_accessor :title, :reference, :type
def initialize(title, reference, type)
@title = title
@title = title
@reference = reference
@type = type
@type = type
end
end

View File

@@ -19,27 +19,27 @@
class WpscanOptions
ACCESSOR_OPTIONS = [
:enumerate_plugins,
:enumerate_only_vulnerable_plugins,
:enumerate_themes,
:enumerate_only_vulnerable_themes,
:enumerate_timthumbs,
:enumerate_usernames,
:enumerate_usernames_range,
:proxy,
:threads,
:url,
:wordlist,
:force,
:update,
:verbose,
:username,
:password,
:follow_redirection,
:wp_content_dir,
:wp_plugins_dir,
:help,
:config_file
:enumerate_plugins,
:enumerate_only_vulnerable_plugins,
:enumerate_themes,
:enumerate_only_vulnerable_themes,
:enumerate_timthumbs,
:enumerate_usernames,
:enumerate_usernames_range,
:proxy,
:threads,
:url,
:wordlist,
:force,
:update,
:verbose,
:username,
:password,
:follow_redirection,
:wp_content_dir,
:wp_plugins_dir,
:help,
:config_file
]
attr_accessor *ACCESSOR_OPTIONS
@@ -131,7 +131,7 @@ class WpscanOptions
if ARGV.length > 0
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
@@ -144,11 +144,11 @@ class WpscanOptions
if WpscanOptions.is_long_option?(cli_option)
self.send(
WpscanOptions.option_to_instance_variable_setter(cli_option),
cli_value
WpscanOptions.option_to_instance_variable_setter(cli_option),
cli_value
)
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
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)
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::OPTIONAL_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]
["--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::OPTIONAL_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]
)
end
@@ -221,7 +221,7 @@ class WpscanOptions
def self.option_to_instance_variable_setter(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
end

View File

@@ -49,14 +49,14 @@ class Generate_List
items = Svn_Parser.new(@svn_url, @verbose).parse
save items
end
def generate_popular_list(pages)
popular = get_popular_items(pages)
items = Svn_Parser.new(@svn_url, @verbose).parse(popular)
save items
end
# Send a HTTP request to the WordPress most popular theme or plugin webpage
# parse the response for the names.
def get_popular_items(pages)
@@ -83,9 +83,9 @@ class Generate_List
@hydra.queue(request)
if queue_count == @browser.max_threads
@hydra.run
queue_count = 0
end
@hydra.run
queue_count = 0
end
end

View File

@@ -30,7 +30,7 @@ class Svn_Parser
@svn_browser = Browser.instance
@svn_hydra = @svn_browser.hydra
end
def parse(dirs=nil)
if dirs == nil
dirs = get_root_directories
@@ -64,14 +64,14 @@ class Svn_Parser
# trunk folder present
if contains_trunk(response)
puts "[+] Adding trunk on #{dir}" if @verbose
urls << { :name => dir, :folder => "trunk"}
# no trunk folder. This is true on theme svn repos
urls << {:name => dir, :folder => "trunk"}
# no trunk folder. This is true on theme svn repos
else
folders = response.body.scan(%r{^\s*<li><a href="(.+)/">.+/</a></li>$}i)
if folders != nil and folders.length > 0
last_version = folders.last[0]
puts "[+] Adding #{last_version} on #{dir}" if @verbose
urls << { :name => dir, :folder => last_version}
urls << {:name => dir, :folder => last_version}
else
puts "[+] No content in #{dir}" if @verbose
end
@@ -89,7 +89,7 @@ class Svn_Parser
@svn_hydra.run
urls
end
# Get a file in each directory
# TODO: exclude files like Thumbs.db (Example: wordpress-23-related-posts-plugin/)
def get_svn_file_entries(dirs)

View File

@@ -53,7 +53,7 @@ def help()
puts "--gpl Alias for --generate_plugin_list"
puts "--generate_full_plugin_list Generate a new full data/plugins.txt file"
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 "--gtl Alias for --generate_theme_list"
puts "--generate_full_theme_list Generate a new full data/themes.txt file"