3
3
require 'metasploit/framework/data_service/remote/http/data_service_auto_loader'
4
4
require 'net/http'
5
5
require 'net/https'
6
+ require 'uri'
6
7
7
8
#
8
9
# Parent data service for managing metasploit data in/on a separate process/machine over HTTP(s)
@@ -30,71 +31,94 @@ def initialize(endpoint)
30
31
end
31
32
32
33
#
33
- # POST data and don't wait for the endpoint to process the data before getting a response
34
+ # POST data to the HTTP endpoint and don't wait for the endpoint to process the data before getting a response
34
35
#
35
- def post_data_async ( path , data_hash )
36
- make_request ( POST_REQUEST , path , data_hash . merge ( EXEC_ASYNC ) )
36
+ # @param path - The URI path to send the request
37
+ # @param data_hash - A hash representation of the object to be posted. Cannot be nil or empty.
38
+ # @param query - A hash representation of the URI query data. Key-value pairs will be URL-encoded.
39
+ #
40
+ # @return A wrapped response (ResponseWrapper), see below.
41
+ #
42
+ def post_data_async ( path , data_hash , query = nil )
43
+ make_request ( POST_REQUEST , path , data_hash . merge ( EXEC_ASYNC ) , query )
37
44
end
38
45
39
46
#
40
47
# POST data to the HTTP endpoint
41
48
#
49
+ # @param path - The URI path to send the request
42
50
# @param data_hash - A hash representation of the object to be posted. Cannot be nil or empty.
43
- # @param path - The URI path to post to
51
+ # @param query - A hash representation of the URI query data. Key-value pairs will be URL-encoded.
44
52
#
45
53
# @return A wrapped response (ResponseWrapper), see below.
46
54
#
47
- def post_data ( path , data_hash )
48
- make_request ( POST_REQUEST , path , data_hash )
55
+ def post_data ( path , data_hash , query = nil )
56
+ make_request ( POST_REQUEST , path , data_hash , query )
49
57
end
50
58
51
59
#
52
60
# GET data from the HTTP endpoint
53
61
#
54
- # @param path - The URI path to post to
55
- # @param data_hash - A hash representation of the object to be posted. Can be nil or empty.
62
+ # @param path - The URI path to send the request
63
+ # @param data_hash - A hash representation of the object to be included. Can be nil or empty.
64
+ # @param query - A hash representation of the URI query data. Key-value pairs will be URL-encoded.
56
65
#
57
66
# @return A wrapped response (ResponseWrapper), see below.
58
67
#
59
- def get_data ( path , data_hash = nil )
60
- make_request ( GET_REQUEST , path , data_hash )
68
+ def get_data ( path , data_hash = nil , query = nil )
69
+ make_request ( GET_REQUEST , path , data_hash , query )
61
70
end
62
71
63
72
#
64
73
# Send DELETE request to delete the specified resource from the HTTP endpoint
65
74
#
66
- # @param path - The URI path to send the delete
75
+ # @param path - The URI path to send the request
67
76
# @param data_hash - A hash representation of the object to be deleted. Cannot be nil or empty.
77
+ # @param query - A hash representation of the URI query data. Key-value pairs will be URL-encoded.
68
78
#
69
79
# @return A wrapped response (ResponseWrapper), see below.
70
80
#
71
- def delete_data ( path , data_hash )
72
- make_request ( DELETE_REQUEST , path , data_hash )
81
+ def delete_data ( path , data_hash , query = nil )
82
+ make_request ( DELETE_REQUEST , path , data_hash , query )
73
83
end
74
84
75
- def make_request ( request_type , path , data_hash = nil )
85
+ #
86
+ # Make the specified request_type
87
+ #
88
+ # @param request_type - A string representation of the HTTP method
89
+ # @param path - The URI path to send the request
90
+ # @param data_hash - A hash representation of the object to be included in the request. Cannot be nil or empty.
91
+ # @param query - A hash representation of the URI query data. Key-value pairs will be URL-encoded.
92
+ #
93
+ # @return A wrapped response (ResponseWrapper)
94
+ #
95
+ def make_request ( request_type , path , data_hash = nil , query = nil )
76
96
begin
77
- puts "#{ Time . now } - HTTP #{ request_type } request to #{ path } with #{ data_hash ? data_hash : "nil" } "
97
+ query_str = ( !query . nil? && !query . empty? ) ? URI . encode_www_form ( query ) : nil
98
+ uri = URI ::HTTP ::build ( { path : path , query : query_str } )
99
+ puts "#{ Time . now } - HTTP #{ request_type } request to #{ uri . request_uri } with #{ data_hash ? data_hash : "nil" } "
100
+
78
101
client = @client_pool . pop ( )
79
102
case request_type
80
103
when GET_REQUEST
81
- request = Net ::HTTP ::Get . new ( path )
104
+ request = Net ::HTTP ::Get . new ( uri . request_uri )
82
105
when POST_REQUEST
83
- request = Net ::HTTP ::Post . new ( path )
106
+ request = Net ::HTTP ::Post . new ( uri . request_uri )
84
107
when DELETE_REQUEST
85
- request = Net ::HTTP ::Delete . new ( path )
108
+ request = Net ::HTTP ::Delete . new ( uri . request_uri )
86
109
else
87
110
raise Exception , 'A request_type must be specified'
88
111
end
89
112
built_request = build_request ( request , data_hash )
90
113
response = client . request ( built_request )
91
114
92
- if response . code == "200"
93
- # puts 'request sent successfully'
94
- return SuccessResponse . new ( response )
95
- else
96
- puts "HTTP #{ request_type } request: #{ path } failed with code: #{ response . code } message: #{ response . body } "
97
- return FailedResponse . new ( response )
115
+ case response
116
+ when Net ::HTTPOK
117
+ # puts 'request sent successfully'
118
+ return SuccessResponse . new ( response )
119
+ else
120
+ puts "HTTP #{ request_type } request: #{ uri . request_uri } failed with code: #{ response . code } message: #{ response . body } "
121
+ return FailedResponse . new ( response )
98
122
end
99
123
rescue Exception => e
100
124
puts "Problem with HTTP #{ request_type } request: #{ e . message } "
@@ -142,9 +166,7 @@ def name
142
166
end
143
167
144
168
def set_header ( key , value )
145
- if ( @headers . nil? )
146
- @headers = Hash . new ( )
147
- end
169
+ @headers = Hash . new ( ) if @headers . nil?
148
170
149
171
@headers [ key ] = value
150
172
end
@@ -195,24 +217,20 @@ def validate_endpoint(endpoint)
195
217
196
218
def append_workspace ( data_hash )
197
219
workspace = data_hash [ :workspace ]
198
- unless ( workspace )
199
- workspace = data_hash . delete ( :wspace )
200
- end
220
+ workspace = data_hash . delete ( :wspace ) unless workspace
201
221
202
- if ( workspace && ( workspace . is_a? ( OpenStruct ) || workspace . is_a? ( ::Mdm ::Workspace ) ) )
222
+ if workspace && ( workspace . is_a? ( OpenStruct ) || workspace . is_a? ( ::Mdm ::Workspace ) )
203
223
data_hash [ :workspace ] = workspace . name
204
224
end
205
225
206
- if ( workspace . nil? )
207
- data_hash [ :workspace ] = current_workspace_name
208
- end
226
+ data_hash [ :workspace ] = current_workspace_name if workspace . nil?
209
227
210
228
data_hash
211
229
end
212
230
213
231
def build_request ( request , data_hash )
214
232
request . content_type = 'application/json'
215
- if ( !data_hash . nil? && !data_hash . empty? )
233
+ if !data_hash . nil? && !data_hash . empty?
216
234
data_hash . each do |k , v |
217
235
if v . is_a? ( Msf ::Session )
218
236
puts "#{ Time . now } - DEBUG: Dropping Msf::Session object before converting to JSON."
@@ -226,7 +244,7 @@ def build_request(request, data_hash)
226
244
request . body = json_body
227
245
end
228
246
229
- if ( !@headers . nil? && !@headers . empty? )
247
+ if !@headers . nil? && !@headers . empty?
230
248
@headers . each do |key , value |
231
249
request [ key ] = value
232
250
end
0 commit comments