123 lines
4.4 KiB
Ruby
123 lines
4.4 KiB
Ruby
# -*- coding: binary -*-
|
|
module Msf::HTTP::Wordpress::Helpers
|
|
|
|
# Helper methods are private and should not be called by modules
|
|
private
|
|
|
|
# Returns the POST data for a Wordpress login request
|
|
#
|
|
# @param user [String] Username
|
|
# @param pass [String] Password
|
|
# @param redirect URL [String] to redirect after successful login
|
|
# @return [Hash] The post data for vars_post Parameter
|
|
def wordpress_helper_login_post_data(user, pass, redirect=nil)
|
|
post_data = {
|
|
'log' => user.to_s,
|
|
'pwd' => pass.to_s,
|
|
'redirect_to' => redirect.to_s,
|
|
'wp-submit' => 'Login'
|
|
}
|
|
post_data
|
|
end
|
|
|
|
# Helper method to post a comment to Wordpress
|
|
#
|
|
# @param comment [String] The comment
|
|
# @param comment_post_id [Integer] The Post ID to post the comment to
|
|
# @param login_cookie [String] The valid login_cookie
|
|
# @param author [String] The author name
|
|
# @param email [String] The author email
|
|
# @param url [String] The author url
|
|
# @return [String,nil] The location of the new comment/post, nil on error
|
|
def wordpress_helper_post_comment(comment, comment_post_id, login_cookie, author, email, url)
|
|
vars_post = {
|
|
'comment' => comment,
|
|
'submit' => 'Post+Comment',
|
|
'comment_post_ID' => comment_post_id.to_s,
|
|
'comment_parent' => '0'
|
|
}
|
|
vars_post.merge!({
|
|
'author' => author,
|
|
'email' => email,
|
|
'url' => url,
|
|
}) unless login_cookie
|
|
|
|
options = {
|
|
'uri' => normalize_uri(target_uri.path, 'wp-comments-post.php'),
|
|
'method' => 'POST'
|
|
}
|
|
options.merge!({'vars_post' => vars_post})
|
|
options.merge!({'cookie' => login_cookie}) if login_cookie
|
|
res = send_request_cgi(options)
|
|
if res and (res.code == 301 or res.code == 302) and res.headers['Location']
|
|
return wordpress_helper_parse_location_header(res)
|
|
else
|
|
message = "#{peer} - Post comment failed."
|
|
message << " Status Code: #{res.code}" if res
|
|
print_error(message)
|
|
return nil
|
|
end
|
|
end
|
|
|
|
# Helper method for bruteforcing a valid post id
|
|
#
|
|
# @param range [Range] The Range of post_ids to bruteforce
|
|
# @param comments_enabled [Boolean] If true try to find a post id with comments enabled, otherwise return the first found
|
|
# @param login_cookie [String] A valid login cookie to perform the bruteforce as an authenticated user
|
|
# @return [Integer,nil] The post id, nil when nothing found
|
|
def wordpress_helper_bruteforce_valid_post_id(range, comments_enabled=false, login_cookie=nil)
|
|
range.each { |id|
|
|
vprint_status("#{peer} - Checking POST ID #{id}...") if (id % 100) == 0
|
|
body = wordpress_helper_check_post_id(wordpress_url_post(id), comments_enabled, login_cookie)
|
|
return id if body
|
|
}
|
|
# no post found
|
|
return nil
|
|
end
|
|
|
|
# Helper method to check if a post is valid an has comments enabled
|
|
#
|
|
# @param uri [String] the Post URI Path
|
|
# @param comments_enabled [Boolean] Check if comments are enabled on this post
|
|
# @param login_cookie [String] A valid login cookie to perform the check as an authenticated user
|
|
# @return [String,nil] the HTTP response body of the post, nil otherwise
|
|
def wordpress_helper_check_post_id(uri, comments_enabled=false, login_cookie=nil)
|
|
options = {
|
|
'method' => 'GET',
|
|
'uri' => uri
|
|
}
|
|
options.merge!({'cookie' => login_cookie}) if login_cookie
|
|
res = send_request_cgi(options)
|
|
# post exists
|
|
if res and res.code == 200
|
|
# also check if comments are enabled
|
|
if comments_enabled
|
|
if res.body =~ /form.*action.*wp-comments-post\.php/
|
|
return res.body
|
|
else
|
|
return nil
|
|
end
|
|
# valid post found, not checking for comments
|
|
else
|
|
return res.body
|
|
end
|
|
elsif res and (res.code == 301 or res.code == 302) and res.headers['Location']
|
|
path = wordpress_helper_parse_location_header(res)
|
|
return wordpress_helper_check_post_id(path, comments_enabled, login_cookie)
|
|
end
|
|
return nil
|
|
end
|
|
|
|
# Helper method parse a Location header and returns only the path and query. Returns nil on error
|
|
#
|
|
# @param res [Rex::Proto::Http::Response] The HTTP response
|
|
# @return [String,nil] the path and query, nil on error
|
|
def wordpress_helper_parse_location_header(res)
|
|
return nil unless res and (res.code == 301 or res.code == 302) and res.headers['Location']
|
|
|
|
location = res.headers['Location']
|
|
path_from_uri(location)
|
|
end
|
|
|
|
end
|