Skip to content

Commit 80e0bbe

Browse files
committed
Add the interactive shell prompt with sessions
1 parent d8c850a commit 80e0bbe

File tree

3 files changed

+66
-12
lines changed

3 files changed

+66
-12
lines changed

lib/rex/post/meterpreter/extensions/powershell/powershell.rb

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,29 @@ def initialize(client)
3131
end
3232

3333

34-
def execute_string(code)
34+
def execute_string(opts={})
35+
return nil unless opts[:code]
36+
3537
request = Packet.create_request('powershell_execute')
36-
request.add_tlv(TLV_TYPE_POWERSHELL_CODE, code)
38+
request.add_tlv(TLV_TYPE_POWERSHELL_CODE, opts[:code])
39+
request.add_tlv(TLV_TYPE_POWERSHELL_SESSIONID, opts[:session_id]) if opts[:session_id]
3740

3841
response = client.send_request(request)
3942
return response.get_tlv_value(TLV_TYPE_POWERSHELL_RESULT)
4043
end
4144

45+
def shell(opts={})
46+
request = Packet.create_request('powershell_shell')
47+
request.add_tlv(TLV_TYPE_POWERSHELL_SESSIONID, opts[:session_id]) if opts[:session_id]
48+
49+
response = client.send_request(request)
50+
channel_id = response.get_tlv_value(TLV_TYPE_CHANNEL_ID)
51+
if channel_id.nil?
52+
raise Exception, "We did not get a channel back!"
53+
end
54+
Rex::Post::Meterpreter::Channels::Pools::StreamPool.new(client, channel_id, 'powershell_psh', CHANNEL_FLAG_SYNCHRONOUS)
55+
end
56+
4257
end
4358

4459
end; end; end; end; end

lib/rex/post/meterpreter/extensions/powershell/tlv.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ module Meterpreter
55
module Extensions
66
module Powershell
77

8-
TLV_TYPE_POWERSHELL_CODE = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 1)
9-
TLV_TYPE_POWERSHELL_RESULT = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 2)
8+
TLV_TYPE_POWERSHELL_SESSIONID = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 1)
9+
TLV_TYPE_POWERSHELL_CODE = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 2)
10+
TLV_TYPE_POWERSHELL_RESULT = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 3)
1011

1112
end
1213
end

lib/rex/post/meterpreter/ui/console/command_dispatcher/powershell.rb

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,52 @@ def name
2929
#
3030
def commands
3131
{
32-
'powershell_execute' => 'Execute a Powershell command string',
32+
'powershell_shell' => 'Create an interactive Powershell prompt',
33+
'powershell_execute' => 'Execute a Powershell command string'
3334
}
3435
end
3536

37+
@@powershell_shell_opts = Rex::Parser::Arguments.new(
38+
'-s' => [true, 'Specify the id/name of the Powershell session to interact with.'],
39+
'-h' => [false, 'Help banner']
40+
)
41+
42+
def powershell_shell_usage
43+
print_line('Usage: powershell_shell [-s session-id]')
44+
print_line
45+
print_line('Creates an interactive Powershell prompt.')
46+
print_line(@@powershell_shell_opts.usage)
47+
end
48+
49+
#
50+
# Create an interactive powershell prompts
51+
#
52+
def cmd_powershell_shell(*args)
53+
if args.include?('-h')
54+
powershell_shell_usage
55+
return false
56+
end
57+
58+
opts = {}
59+
60+
@@powershell_shell_opts.parse(args) { |opt, idx, val|
61+
case opt
62+
when '-s'
63+
opts[:session_id] = val
64+
end
65+
}
66+
67+
channel = client.powershell.shell(opts)
68+
shell.interact_with_channel(channel)
69+
end
70+
3671
@@powershell_execute_opts = Rex::Parser::Arguments.new(
72+
'-s' => [true, 'Specify the id/name of the Powershell session to run the command in.'],
3773
'-h' => [false, 'Help banner']
3874
)
3975

4076
def powershell_execute_usage
41-
print_line('Usage: powershell_execute <powershell code>')
77+
print_line('Usage: powershell_execute <powershell code> [-s session-id]')
4278
print_line
4379
print_line('Runs the given Powershell string on the target.')
4480
print_line(@@powershell_execute_opts.usage)
@@ -53,16 +89,18 @@ def cmd_powershell_execute(*args)
5389
return false
5490
end
5591

56-
code = args.shift
92+
opts = {
93+
code: args.shift
94+
}
5795

5896
@@powershell_execute_opts.parse(args) { |opt, idx, val|
59-
#case opt
60-
#when '-r'
61-
# result_var = val
62-
#end
97+
case opt
98+
when '-s'
99+
opts[:session_id] = val
100+
end
63101
}
64102

65-
result = client.powershell.execute_string(code)
103+
result = client.powershell.execute_string(opts)
66104
print_good("Command execution completed:\n#{result}")
67105
end
68106

0 commit comments

Comments
 (0)