1
1
require 'metasploit/framework/data_service/remote/http/remote_service_endpoint'
2
2
require 'metasploit/framework/data_service'
3
3
require 'metasploit/framework/data_service/remote/http/data_service_auto_loader'
4
+ require 'net/http'
5
+ require 'net/https'
4
6
5
7
#
6
8
# Parent data service for managing metasploit data in/on a separate process/machine over HTTP(s)
@@ -13,7 +15,7 @@ class RemoteHTTPDataService
13
15
include DataServiceAutoLoader
14
16
15
17
ONLINE_TEST_URL = "/api/1/msf/online"
16
- EXEC_ASYNC = { :exec_async => true }
18
+ EXEC_ASYNC = { :exec_async => true }
17
19
GET_REQUEST = 'GET'
18
20
POST_REQUEST = 'POST'
19
21
@@ -30,7 +32,7 @@ def initialize(endpoint)
30
32
# POST data and don't wait for the endpoint to process the data before getting a response
31
33
#
32
34
def post_data_async ( path , data_hash )
33
- post_data ( path , data_hash . merge ( EXEC_ASYNC ) )
35
+ make_request ( POST_REQUEST , path , data_hash . merge ( EXEC_ASYNC ) )
34
36
end
35
37
36
38
#
@@ -42,30 +44,7 @@ def post_data_async(path, data_hash)
42
44
# @return A wrapped response (ResponseWrapper), see below.
43
45
#
44
46
def post_data ( path , data_hash )
45
- begin
46
- raise 'Data to post to remote service cannot be null or empty' if ( data_hash . nil? || data_hash . empty? )
47
-
48
- puts "#{ Time . now } - Posting #{ data_hash } to #{ path } "
49
- client = @client_pool . pop ( )
50
- request_opts = build_request_opts ( POST_REQUEST , data_hash , path )
51
- request = client . request_raw ( request_opts )
52
- response = client . _send_recv ( request )
53
-
54
- if response . code == 200
55
- #puts "POST request: #{path} with body: #{json_body} sent successfully"
56
- return SuccessResponse . new ( response )
57
- else
58
- puts "POST request: #{ path } with body: #{ json_body } failed with code: #{ response . code } message: #{ response . body } "
59
- return FailedResponse . new ( response )
60
- end
61
- rescue Exception => e
62
- puts "Problem with POST request: #{ e . message } "
63
- e . backtrace . each do |line |
64
- puts "#{ line } \n "
65
- end
66
- ensure
67
- @client_pool << client
68
- end
47
+ make_request ( POST_REQUEST , path , data_hash )
69
48
end
70
49
71
50
#
@@ -77,23 +56,34 @@ def post_data(path, data_hash)
77
56
# @return A wrapped response (ResponseWrapper), see below.
78
57
#
79
58
def get_data ( path , data_hash = nil )
80
- begin
59
+ make_request ( GET_REQUEST , path , data_hash )
60
+ end
81
61
82
- puts "#{ Time . now } - Getting #{ path } with #{ data_hash ? data_hash : "nil" } "
62
+ def make_request ( request_type , path , data_hash = nil )
63
+ begin
64
+ puts "#{ Time . now } - HTTP #{ request_type } request to #{ path } with #{ data_hash ? data_hash : "nil" } "
83
65
client = @client_pool . pop ( )
84
- request_opts = build_request_opts ( GET_REQUEST , data_hash , path )
85
- request = client . request_raw ( request_opts )
86
- response = client . _send_recv ( request )
66
+ case request_type
67
+ when GET_REQUEST
68
+ request = Net ::HTTP ::Get . new ( path )
69
+ when POST_REQUEST
70
+ request = Net ::HTTP ::Post . new ( path )
71
+ else
72
+ raise Exception , 'A request_type must be specified'
73
+ end
74
+ built_request = build_request ( request , data_hash )
75
+ response = client . request ( built_request )
87
76
88
- if ( response . code == 200 )
77
+ if response . code == " 200"
89
78
# puts 'request sent successfully'
90
79
return SuccessResponse . new ( response )
91
80
else
92
- puts "GET request: #{ path } failed with code: #{ response . code } message: #{ response . body } "
81
+ puts "HTTP #{ request_type } request: #{ path } failed with code: #{ response . code } message: #{ response . body } "
93
82
return FailedResponse . new ( response )
94
83
end
95
84
rescue Exception => e
96
- puts "Problem with GET request: #{ e . message } "
85
+ puts "Problem with HTTP #{ request_type } request: #{ e . message } "
86
+ e . backtrace . each { |line | puts "#{ line } \n " }
97
87
ensure
98
88
@client_pool << client
99
89
end
@@ -205,13 +195,8 @@ def append_workspace(data_hash)
205
195
data_hash
206
196
end
207
197
208
- def build_request_opts ( request_type , data_hash , path )
209
- request_opts = {
210
- 'method' => request_type ,
211
- 'ctype' => 'application/json' ,
212
- 'uri' => path
213
- }
214
-
198
+ def build_request ( request , data_hash )
199
+ request . content_type = 'application/json'
215
200
if ( !data_hash . nil? && !data_hash . empty? )
216
201
data_hash . each do |k , v |
217
202
if v . is_a? ( Msf ::Session )
@@ -223,25 +208,24 @@ def build_request_opts(request_type, data_hash, path)
223
208
end
224
209
end
225
210
json_body = append_workspace ( data_hash ) . to_json
226
- request_opts [ 'data' ] = json_body
211
+ request . body = json_body
227
212
end
228
213
229
214
if ( !@headers . nil? && !@headers . empty? )
230
- request_opts [ 'headers' ] = @headers
215
+ @headers . each do |key , value |
216
+ request [ key ] = value
217
+ end
231
218
end
232
219
233
- request_opts
220
+ request
234
221
end
235
222
236
223
def build_client_pool ( size )
237
224
@client_pool = Queue . new ( )
238
225
( 1 ..size ) . each {
239
- @client_pool << Rex ::Proto ::Http ::Client . new (
240
- @endpoint . host ,
241
- @endpoint . port ,
242
- { } ,
243
- @endpoint . use_ssl ,
244
- @endpoint . ssl_version )
226
+ http = Net ::HTTP . new ( @endpoint . host , @endpoint . port )
227
+ http . use_ssl = true if @endpoint . use_ssl
228
+ @client_pool << http
245
229
}
246
230
end
247
231
0 commit comments