Ref #1518 for XMLrPC multicall
This commit is contained in:
@@ -22,6 +22,28 @@ module WPScan
|
|||||||
target.multi_call(methods, cache_ttl: 0).run
|
target.multi_call(methods, cache_ttl: 0).run
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @param [ IO ] file
|
||||||
|
# @param [ Integer ] passwords_size
|
||||||
|
# @return [ Array<String> ] The passwords from the last checked position in the file until there are
|
||||||
|
# passwords_size passwords retrieved
|
||||||
|
def passwords_from_wordlist(file, passwords_size)
|
||||||
|
pwds = []
|
||||||
|
added_pwds = 0
|
||||||
|
|
||||||
|
return pwds if passwords_size.zero?
|
||||||
|
|
||||||
|
# Make sure that the main code does not call #sysseek or #count etc
|
||||||
|
# otherwise the file descriptor will be set to somwehere else
|
||||||
|
file.each_line(chomp: true) do |line|
|
||||||
|
pwds << line
|
||||||
|
added_pwds += 1
|
||||||
|
|
||||||
|
break if added_pwds == passwords_size
|
||||||
|
end
|
||||||
|
|
||||||
|
pwds
|
||||||
|
end
|
||||||
|
|
||||||
# @param [ Array<Model::User> ] users
|
# @param [ Array<Model::User> ] users
|
||||||
# @param [ String ] wordlist_path
|
# @param [ String ] wordlist_path
|
||||||
# @param [ Hash ] opts
|
# @param [ Hash ] opts
|
||||||
@@ -34,18 +56,21 @@ module WPScan
|
|||||||
#
|
#
|
||||||
# rubocop:disable all
|
# rubocop:disable all
|
||||||
def attack(users, wordlist_path, opts = {})
|
def attack(users, wordlist_path, opts = {})
|
||||||
wordlist_index = 0
|
checked_passwords = 0
|
||||||
passwords = File.open(wordlist_path).reduce([]) { |acc, elem| acc << elem.chomp }
|
wordlist = File.open(wordlist_path)
|
||||||
|
wordlist_size = wordlist.count
|
||||||
max_passwords = opts[:multicall_max_passwords]
|
max_passwords = opts[:multicall_max_passwords]
|
||||||
current_passwords_size = passwords_size(max_passwords, users.size)
|
current_passwords_size = passwords_size(max_passwords, users.size)
|
||||||
|
|
||||||
create_progress_bar(total: (passwords.size / current_passwords_size.round(1)).ceil,
|
create_progress_bar(total: (wordlist_size / current_passwords_size.round(1)).ceil,
|
||||||
show_progression: opts[:show_progression])
|
show_progression: opts[:show_progression])
|
||||||
|
|
||||||
|
wordlist.sysseek(0) # reset the descriptor to the beginning of the file as it changed with #count
|
||||||
|
|
||||||
loop do
|
loop do
|
||||||
current_users = users.select { |user| user.password.nil? }
|
current_users = users.select { |user| user.password.nil? }
|
||||||
current_passwords = passwords[wordlist_index, current_passwords_size]
|
current_passwords = passwords_from_wordlist(wordlist, current_passwords_size)
|
||||||
wordlist_index += current_passwords_size
|
checked_passwords += current_passwords_size
|
||||||
|
|
||||||
break if current_users.empty? || current_passwords.nil? || current_passwords.empty?
|
break if current_users.empty? || current_passwords.nil? || current_passwords.empty?
|
||||||
|
|
||||||
@@ -78,12 +103,14 @@ module WPScan
|
|||||||
end
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
progress_bar.total = progress_bar.progress + ((passwords.size - wordlist_index) / current_passwords_size.round(1)).ceil
|
progress_bar.total = progress_bar.progress + ((wordlist_size - checked_passwords) / current_passwords_size.round(1)).ceil
|
||||||
rescue ProgressBar::InvalidProgressError
|
rescue ProgressBar::InvalidProgressError
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# Maybe a progress_bar.stop ?
|
# Maybe a progress_bar.stop ?
|
||||||
|
ensure
|
||||||
|
wordlist.close
|
||||||
end
|
end
|
||||||
# rubocop:enable all
|
# rubocop:enable all
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user