Ref #1518 for XMLrPC multicall

This commit is contained in:
erwanlr
2020-07-16 17:50:43 +02:00
parent b0260327c4
commit cfb98c5139

View File

@@ -22,6 +22,28 @@ module WPScan
target.multi_call(methods, cache_ttl: 0).run
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 [ String ] wordlist_path
# @param [ Hash ] opts
@@ -34,18 +56,21 @@ module WPScan
#
# rubocop:disable all
def attack(users, wordlist_path, opts = {})
wordlist_index = 0
passwords = File.open(wordlist_path).reduce([]) { |acc, elem| acc << elem.chomp }
checked_passwords = 0
wordlist = File.open(wordlist_path)
wordlist_size = wordlist.count
max_passwords = opts[:multicall_max_passwords]
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])
wordlist.sysseek(0) # reset the descriptor to the beginning of the file as it changed with #count
loop do
current_users = users.select { |user| user.password.nil? }
current_passwords = passwords[wordlist_index, current_passwords_size]
wordlist_index += current_passwords_size
current_users = users.select { |user| user.password.nil? }
current_passwords = passwords_from_wordlist(wordlist, current_passwords_size)
checked_passwords += current_passwords_size
break if current_users.empty? || current_passwords.nil? || current_passwords.empty?
@@ -78,12 +103,14 @@ module WPScan
end
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
end
end
end
# Maybe a progress_bar.stop ?
ensure
wordlist.close
end
# rubocop:enable all