Skip to content

Commit cadf66f

Browse files
author
Brent Cook
committed
Land rapid7#6691, initial meterpreter powershell extension support
2 parents 18604c3 + 1fe40d9 commit cadf66f

File tree

5 files changed

+191
-3
lines changed

5 files changed

+191
-3
lines changed

Gemfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ PATH
1313
metasploit-concern
1414
metasploit-credential (= 1.1.0)
1515
metasploit-model (= 1.1.0)
16-
metasploit-payloads (= 1.1.3)
16+
metasploit-payloads (= 1.1.4)
1717
metasploit_data_models (= 1.3.0)
1818
msgpack
1919
network_interface (~> 0.0.1)
@@ -124,7 +124,7 @@ GEM
124124
activemodel (>= 4.0.9, < 4.1.0)
125125
activesupport (>= 4.0.9, < 4.1.0)
126126
railties (>= 4.0.9, < 4.1.0)
127-
metasploit-payloads (1.1.3)
127+
metasploit-payloads (1.1.4)
128128
metasploit_data_models (1.3.0)
129129
activerecord (>= 4.0.9, < 4.1.0)
130130
activesupport (>= 4.0.9, < 4.1.0)
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# -*- coding: binary -*-
2+
3+
require 'rex/post/meterpreter/extensions/powershell/tlv'
4+
5+
module Rex
6+
module Post
7+
module Meterpreter
8+
module Extensions
9+
module Powershell
10+
11+
###
12+
#
13+
# This meterpreter extensions a privilege escalation interface that is capable
14+
# of doing things like dumping password hashes and performing local
15+
# exploitation.
16+
#
17+
###
18+
class Powershell < Extension
19+
20+
21+
def initialize(client)
22+
super(client, 'powershell')
23+
24+
client.register_extension_aliases(
25+
[
26+
{
27+
'name' => 'powershell',
28+
'ext' => self
29+
},
30+
])
31+
end
32+
33+
34+
def execute_string(opts={})
35+
return nil unless opts[:code]
36+
37+
request = Packet.create_request('powershell_execute')
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]
40+
41+
response = client.send_request(request)
42+
return response.get_tlv_value(TLV_TYPE_POWERSHELL_RESULT)
43+
end
44+
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+
57+
end
58+
59+
end; end; end; end; end
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# -*- coding: binary -*-
2+
module Rex
3+
module Post
4+
module Meterpreter
5+
module Extensions
6+
module Powershell
7+
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)
11+
12+
end
13+
end
14+
end
15+
end
16+
end
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# -*- coding: binary -*-
2+
require 'rex/post/meterpreter'
3+
4+
module Rex
5+
module Post
6+
module Meterpreter
7+
module Ui
8+
9+
###
10+
#
11+
# Powershell extension - interact with a Powershell interpreter
12+
#
13+
###
14+
class Console::CommandDispatcher::Powershell
15+
16+
Klass = Console::CommandDispatcher::Powershell
17+
18+
include Console::CommandDispatcher
19+
20+
#
21+
# Name for this dispatcher
22+
#
23+
def name
24+
'Powershell'
25+
end
26+
27+
#
28+
# List of supported commands.
29+
#
30+
def commands
31+
{
32+
'powershell_shell' => 'Create an interactive Powershell prompt',
33+
'powershell_execute' => 'Execute a Powershell command string'
34+
}
35+
end
36+
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+
71+
@@powershell_execute_opts = Rex::Parser::Arguments.new(
72+
'-s' => [true, 'Specify the id/name of the Powershell session to run the command in.'],
73+
'-h' => [false, 'Help banner']
74+
)
75+
76+
def powershell_execute_usage
77+
print_line('Usage: powershell_execute <powershell code> [-s session-id]')
78+
print_line
79+
print_line('Runs the given Powershell string on the target.')
80+
print_line(@@powershell_execute_opts.usage)
81+
end
82+
83+
#
84+
# Execute a simple Powershell command string
85+
#
86+
def cmd_powershell_execute(*args)
87+
if args.length == 0 || args.include?('-h')
88+
powershell_execute_usage
89+
return false
90+
end
91+
92+
opts = {
93+
code: args.shift
94+
}
95+
96+
@@powershell_execute_opts.parse(args) { |opt, idx, val|
97+
case opt
98+
when '-s'
99+
opts[:session_id] = val
100+
end
101+
}
102+
103+
result = client.powershell.execute_string(opts)
104+
print_good("Command execution completed:\n#{result}")
105+
end
106+
107+
end
108+
109+
end
110+
end
111+
end
112+
end
113+

metasploit-framework.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ Gem::Specification.new do |spec|
7070
# are needed when there's no database
7171
spec.add_runtime_dependency 'metasploit-model', '1.1.0'
7272
# Needed for Meterpreter
73-
spec.add_runtime_dependency 'metasploit-payloads', '1.1.3'
73+
spec.add_runtime_dependency 'metasploit-payloads', '1.1.4'
7474
# Needed by msfgui and other rpc components
7575
spec.add_runtime_dependency 'msgpack'
7676
# get list of network interfaces, like eth* from OS.

0 commit comments

Comments
 (0)