Add URI query data option to request methods

GSoC/Meterpreter_Web_Console
Matthew Kienow 2018-01-19 16:51:49 -05:00
parent ff9c69c7c8
commit cb4999c1ac
No known key found for this signature in database
GPG Key ID: 40787F8B1EAC6E41
1 changed files with 54 additions and 36 deletions

View File

@ -3,6 +3,7 @@ require 'metasploit/framework/data_service'
require 'metasploit/framework/data_service/remote/http/data_service_auto_loader' require 'metasploit/framework/data_service/remote/http/data_service_auto_loader'
require 'net/http' require 'net/http'
require 'net/https' require 'net/https'
require 'uri'
# #
# Parent data service for managing metasploit data in/on a separate process/machine over HTTP(s) # Parent data service for managing metasploit data in/on a separate process/machine over HTTP(s)
@ -30,70 +31,93 @@ class RemoteHTTPDataService
end end
# #
# POST data and don't wait for the endpoint to process the data before getting a response # POST data to the HTTP endpoint and don't wait for the endpoint to process the data before getting a response
# #
def post_data_async(path, data_hash) # @param path - The URI path to send the request
make_request(POST_REQUEST, path, data_hash.merge(EXEC_ASYNC)) # @param data_hash - A hash representation of the object to be posted. Cannot be nil or empty.
# @param query - A hash representation of the URI query data. Key-value pairs will be URL-encoded.
#
# @return A wrapped response (ResponseWrapper), see below.
#
def post_data_async(path, data_hash, query = nil)
make_request(POST_REQUEST, path, data_hash.merge(EXEC_ASYNC), query)
end end
# #
# POST data to the HTTP endpoint # POST data to the HTTP endpoint
# #
# @param path - The URI path to send the request
# @param data_hash - A hash representation of the object to be posted. Cannot be nil or empty. # @param data_hash - A hash representation of the object to be posted. Cannot be nil or empty.
# @param path - The URI path to post to # @param query - A hash representation of the URI query data. Key-value pairs will be URL-encoded.
# #
# @return A wrapped response (ResponseWrapper), see below. # @return A wrapped response (ResponseWrapper), see below.
# #
def post_data(path, data_hash) def post_data(path, data_hash, query = nil)
make_request(POST_REQUEST, path, data_hash) make_request(POST_REQUEST, path, data_hash, query)
end end
# #
# GET data from the HTTP endpoint # GET data from the HTTP endpoint
# #
# @param path - The URI path to post to # @param path - The URI path to send the request
# @param data_hash - A hash representation of the object to be posted. Can be nil or empty. # @param data_hash - A hash representation of the object to be included. Can be nil or empty.
# @param query - A hash representation of the URI query data. Key-value pairs will be URL-encoded.
# #
# @return A wrapped response (ResponseWrapper), see below. # @return A wrapped response (ResponseWrapper), see below.
# #
def get_data(path, data_hash = nil) def get_data(path, data_hash = nil, query = nil)
make_request(GET_REQUEST, path, data_hash) make_request(GET_REQUEST, path, data_hash, query)
end end
# #
# Send DELETE request to delete the specified resource from the HTTP endpoint # Send DELETE request to delete the specified resource from the HTTP endpoint
# #
# @param path - The URI path to send the delete # @param path - The URI path to send the request
# @param data_hash - A hash representation of the object to be deleted. Cannot be nil or empty. # @param data_hash - A hash representation of the object to be deleted. Cannot be nil or empty.
# @param query - A hash representation of the URI query data. Key-value pairs will be URL-encoded.
# #
# @return A wrapped response (ResponseWrapper), see below. # @return A wrapped response (ResponseWrapper), see below.
# #
def delete_data(path, data_hash) def delete_data(path, data_hash, query = nil)
make_request(DELETE_REQUEST, path, data_hash) make_request(DELETE_REQUEST, path, data_hash, query)
end end
def make_request(request_type, path, data_hash = nil) #
# Make the specified request_type
#
# @param request_type - A string representation of the HTTP method
# @param path - The URI path to send the request
# @param data_hash - A hash representation of the object to be included in the request. Cannot be nil or empty.
# @param query - A hash representation of the URI query data. Key-value pairs will be URL-encoded.
#
# @return A wrapped response (ResponseWrapper)
#
def make_request(request_type, path, data_hash = nil, query = nil)
begin begin
puts "#{Time.now} - HTTP #{request_type} request to #{path} with #{data_hash ? data_hash : "nil"}" query_str = (!query.nil? && !query.empty?) ? URI.encode_www_form(query) : nil
uri = URI::HTTP::build({path: path, query: query_str})
puts "#{Time.now} - HTTP #{request_type} request to #{uri.request_uri} with #{data_hash ? data_hash : "nil"}"
client = @client_pool.pop() client = @client_pool.pop()
case request_type case request_type
when GET_REQUEST when GET_REQUEST
request = Net::HTTP::Get.new(path) request = Net::HTTP::Get.new(uri.request_uri)
when POST_REQUEST when POST_REQUEST
request = Net::HTTP::Post.new(path) request = Net::HTTP::Post.new(uri.request_uri)
when DELETE_REQUEST when DELETE_REQUEST
request = Net::HTTP::Delete.new(path) request = Net::HTTP::Delete.new(uri.request_uri)
else else
raise Exception, 'A request_type must be specified' raise Exception, 'A request_type must be specified'
end end
built_request = build_request(request, data_hash) built_request = build_request(request, data_hash)
response = client.request(built_request) response = client.request(built_request)
if response.code == "200" case response
when Net::HTTPOK
# puts 'request sent successfully' # puts 'request sent successfully'
return SuccessResponse.new(response) return SuccessResponse.new(response)
else else
puts "HTTP #{request_type} request: #{path} failed with code: #{response.code} message: #{response.body}" puts "HTTP #{request_type} request: #{uri.request_uri} failed with code: #{response.code} message: #{response.body}"
return FailedResponse.new(response) return FailedResponse.new(response)
end end
rescue Exception => e rescue Exception => e
@ -142,9 +166,7 @@ class RemoteHTTPDataService
end end
def set_header(key, value) def set_header(key, value)
if (@headers.nil?) @headers = Hash.new() if @headers.nil?
@headers = Hash.new()
end
@headers[key] = value @headers[key] = value
end end
@ -195,24 +217,20 @@ class RemoteHTTPDataService
def append_workspace(data_hash) def append_workspace(data_hash)
workspace = data_hash[:workspace] workspace = data_hash[:workspace]
unless (workspace) workspace = data_hash.delete(:wspace) unless workspace
workspace = data_hash.delete(:wspace)
end
if (workspace && (workspace.is_a?(OpenStruct) || workspace.is_a?(::Mdm::Workspace))) if workspace && (workspace.is_a?(OpenStruct) || workspace.is_a?(::Mdm::Workspace))
data_hash[:workspace] = workspace.name data_hash[:workspace] = workspace.name
end end
if (workspace.nil?) data_hash[:workspace] = current_workspace_name if workspace.nil?
data_hash[:workspace] = current_workspace_name
end
data_hash data_hash
end end
def build_request(request, data_hash) def build_request(request, data_hash)
request.content_type = 'application/json' request.content_type = 'application/json'
if (!data_hash.nil? && !data_hash.empty?) if !data_hash.nil? && !data_hash.empty?
data_hash.each do |k,v| data_hash.each do |k,v|
if v.is_a?(Msf::Session) if v.is_a?(Msf::Session)
puts "#{Time.now} - DEBUG: Dropping Msf::Session object before converting to JSON." puts "#{Time.now} - DEBUG: Dropping Msf::Session object before converting to JSON."
@ -226,7 +244,7 @@ class RemoteHTTPDataService
request.body = json_body request.body = json_body
end end
if (!@headers.nil? && !@headers.empty?) if !@headers.nil? && !@headers.empty?
@headers.each do |key, value| @headers.each do |key, value|
request[key] = value request[key] = value
end end