Rubocop -A
This commit is contained in:
parent
ddebdbc770
commit
07204dc99e
|
@ -1,10 +1,9 @@
|
||||||
# -*- coding: binary -*-
|
# -*- coding: binary -*-
|
||||||
#
|
|
||||||
require 'rex/post/meterpreter/extensions/stdapi/command_ids'
|
require 'rex/post/meterpreter/extensions/stdapi/command_ids'
|
||||||
require 'rex/post/file_stat'
|
require 'rex/post/file_stat'
|
||||||
|
|
||||||
module Msf::Post::File
|
module Msf::Post::File
|
||||||
|
|
||||||
include Msf::Post::Common
|
include Msf::Post::Common
|
||||||
|
|
||||||
def initialize(info = {})
|
def initialize(info = {})
|
||||||
|
@ -37,8 +36,12 @@ module Msf::Post::File
|
||||||
#
|
#
|
||||||
# @return [void]
|
# @return [void]
|
||||||
def cd(path)
|
def cd(path)
|
||||||
e_path = expand_path(path) rescue path
|
e_path = begin
|
||||||
if session.type == "meterpreter"
|
expand_path(path)
|
||||||
|
rescue StandardError
|
||||||
|
path
|
||||||
|
end
|
||||||
|
if session.type == 'meterpreter'
|
||||||
session.fs.dir.chdir(e_path)
|
session.fs.dir.chdir(e_path)
|
||||||
elsif session.type == 'powershell'
|
elsif session.type == 'powershell'
|
||||||
cmd_exec("Set-Location -Path \"#{e_path}\"")
|
cmd_exec("Set-Location -Path \"#{e_path}\"")
|
||||||
|
@ -56,23 +59,19 @@ module Msf::Post::File
|
||||||
#
|
#
|
||||||
# @return [String]
|
# @return [String]
|
||||||
def pwd
|
def pwd
|
||||||
if session.type == "meterpreter"
|
if session.type == 'meterpreter'
|
||||||
return session.fs.dir.getwd
|
return session.fs.dir.getwd
|
||||||
elsif session.type == 'powershell'
|
elsif session.type == 'powershell'
|
||||||
return cmd_exec('(Get-Location).Path').strip
|
return cmd_exec('(Get-Location).Path').strip
|
||||||
else
|
elsif session.platform == 'windows'
|
||||||
if session.platform == 'windows'
|
return session.shell_command_token('echo %CD%').to_s.strip
|
||||||
# XXX: %CD% only exists on XP and newer, figure something out for NT4
|
# XXX: %CD% only exists on XP and newer, figure something out for NT4
|
||||||
# and 2k
|
# and 2k
|
||||||
return session.shell_command_token("echo %CD%").to_s.strip
|
elsif command_exists?('pwd')
|
||||||
else
|
return session.shell_command_token('pwd').to_s.strip
|
||||||
if command_exists?("pwd")
|
|
||||||
return session.shell_command_token("pwd").to_s.strip
|
|
||||||
else
|
else
|
||||||
# Result on systems without pwd command
|
# Result on systems without pwd command
|
||||||
return session.shell_command_token("echo $PWD").to_s.strip
|
return session.shell_command_token('echo $PWD').to_s.strip
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -100,13 +99,13 @@ module Msf::Post::File
|
||||||
|
|
||||||
# Result on systems without ls command
|
# Result on systems without ls command
|
||||||
if directory[-1] != '/'
|
if directory[-1] != '/'
|
||||||
directory = directory + "/"
|
directory += '/'
|
||||||
end
|
end
|
||||||
result = []
|
result = []
|
||||||
data = session.shell_command_token("for fn in #{directory}*; do echo $fn; done")
|
data = session.shell_command_token("for fn in #{directory}*; do echo $fn; done")
|
||||||
parts = data.split("\n")
|
parts = data.split("\n")
|
||||||
parts.each do |line|
|
parts.each do |line|
|
||||||
line = line.split("/")[-1]
|
line = line.split('/')[-1]
|
||||||
result.insert(-1, line)
|
result.insert(-1, line)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -124,13 +123,11 @@ module Msf::Post::File
|
||||||
result = session.fs.dir.mkdir(path) unless directory?(path)
|
result = session.fs.dir.mkdir(path) unless directory?(path)
|
||||||
elsif session.type == 'powershell'
|
elsif session.type == 'powershell'
|
||||||
result = cmd_exec("New-Item \"#{path}\" -itemtype directory")
|
result = cmd_exec("New-Item \"#{path}\" -itemtype directory")
|
||||||
else
|
elsif session.platform == 'windows'
|
||||||
if session.platform == 'windows'
|
|
||||||
result = cmd_exec("mkdir \"#{path}\"")
|
result = cmd_exec("mkdir \"#{path}\"")
|
||||||
else
|
else
|
||||||
result = cmd_exec("mkdir -p '#{path}'")
|
result = cmd_exec("mkdir -p '#{path}'")
|
||||||
end
|
end
|
||||||
end
|
|
||||||
vprint_status("#{path} created")
|
vprint_status("#{path} created")
|
||||||
register_dir_for_cleanup(path)
|
register_dir_for_cleanup(path)
|
||||||
result
|
result
|
||||||
|
@ -142,8 +139,13 @@ module Msf::Post::File
|
||||||
# @param path [String] Remote filename to check
|
# @param path [String] Remote filename to check
|
||||||
def directory?(path)
|
def directory?(path)
|
||||||
if session.type == 'meterpreter'
|
if session.type == 'meterpreter'
|
||||||
stat = session.fs.file.stat(path) rescue nil
|
stat = begin
|
||||||
|
session.fs.file.stat(path)
|
||||||
|
rescue StandardError
|
||||||
|
nil
|
||||||
|
end
|
||||||
return false unless stat
|
return false unless stat
|
||||||
|
|
||||||
return stat.directory?
|
return stat.directory?
|
||||||
elsif session.type == 'powershell'
|
elsif session.type == 'powershell'
|
||||||
return cmd_exec("Test-Path -Path \"#{path}\" -PathType Container").include?('True')
|
return cmd_exec("Test-Path -Path \"#{path}\" -PathType Container").include?('True')
|
||||||
|
@ -155,6 +157,7 @@ module Msf::Post::File
|
||||||
end
|
end
|
||||||
return false if f.nil? || f.empty?
|
return false if f.nil? || f.empty?
|
||||||
return false unless f =~ /true/
|
return false unless f =~ /true/
|
||||||
|
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -164,7 +167,7 @@ module Msf::Post::File
|
||||||
#
|
#
|
||||||
# @return [String]
|
# @return [String]
|
||||||
def expand_path(path)
|
def expand_path(path)
|
||||||
if session.type == "meterpreter"
|
if session.type == 'meterpreter'
|
||||||
return session.fs.file.expand_path(path)
|
return session.fs.file.expand_path(path)
|
||||||
elsif session.type == 'powershell'
|
elsif session.type == 'powershell'
|
||||||
return cmd_exec("[Environment]::ExpandEnvironmentVariables(\"#{path}\")")
|
return cmd_exec("[Environment]::ExpandEnvironmentVariables(\"#{path}\")")
|
||||||
|
@ -179,11 +182,16 @@ module Msf::Post::File
|
||||||
# @param path [String] Remote filename to check
|
# @param path [String] Remote filename to check
|
||||||
def file?(path)
|
def file?(path)
|
||||||
if session.type == 'meterpreter'
|
if session.type == 'meterpreter'
|
||||||
stat = session.fs.file.stat(path) rescue nil
|
stat = begin
|
||||||
|
session.fs.file.stat(path)
|
||||||
|
rescue StandardError
|
||||||
|
nil
|
||||||
|
end
|
||||||
return false unless stat
|
return false unless stat
|
||||||
|
|
||||||
return stat.file?
|
return stat.file?
|
||||||
elsif session.type == 'powershell'
|
elsif session.type == 'powershell'
|
||||||
return cmd_exec("[System.IO.File]::Exists( \"#{path}\")")&.include?("True")
|
return cmd_exec("[System.IO.File]::Exists( \"#{path}\")")&.include?('True')
|
||||||
else
|
else
|
||||||
if session.platform == 'windows'
|
if session.platform == 'windows'
|
||||||
f = cmd_exec("cmd.exe /C IF exist \"#{path}\" ( echo true )")
|
f = cmd_exec("cmd.exe /C IF exist \"#{path}\" ( echo true )")
|
||||||
|
@ -195,6 +203,7 @@ module Msf::Post::File
|
||||||
end
|
end
|
||||||
return false if f.nil? || f.empty?
|
return false if f.nil? || f.empty?
|
||||||
return false unless f =~ /true/
|
return false unless f =~ /true/
|
||||||
|
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -261,14 +270,15 @@ module Msf::Post::File
|
||||||
# @return [Boolean] true if +path+ exists and is readable
|
# @return [Boolean] true if +path+ exists and is readable
|
||||||
#
|
#
|
||||||
def readable?(path)
|
def readable?(path)
|
||||||
verification_token = Rex::Text::rand_text_alpha(8)
|
verification_token = Rex::Text.rand_text_alpha(8)
|
||||||
return false unless exists?(path)
|
return false unless exists?(path)
|
||||||
|
|
||||||
if session.type == 'powershell'
|
if session.type == 'powershell'
|
||||||
unless directory?(path)
|
if directory?(path)
|
||||||
|
return cmd_exec("[System.IO.Directory]::GetFiles('#{path}'); if($?) {echo #{verification_token}}").include?(verification_token)
|
||||||
|
else
|
||||||
return cmd_exec("[System.IO.File]::OpenRead(\"#{path}\");if($?){echo\
|
return cmd_exec("[System.IO.File]::OpenRead(\"#{path}\");if($?){echo\
|
||||||
#{verification_token}}").include?(verification_token)
|
#{verification_token}}").include?(verification_token)
|
||||||
else
|
|
||||||
return cmd_exec("[System.IO.Directory]::GetFiles('#{path}'); if($?) {echo #{verification_token}}").include?(verification_token)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -283,10 +293,14 @@ module Msf::Post::File
|
||||||
# @param path [String] Remote filename to check
|
# @param path [String] Remote filename to check
|
||||||
def exist?(path)
|
def exist?(path)
|
||||||
if session.type == 'meterpreter'
|
if session.type == 'meterpreter'
|
||||||
stat = session.fs.file.stat(path) rescue nil
|
stat = begin
|
||||||
return !!(stat)
|
session.fs.file.stat(path)
|
||||||
|
rescue StandardError
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
return !!stat
|
||||||
elsif session.type == 'powershell'
|
elsif session.type == 'powershell'
|
||||||
return cmd_exec("[System.IO.File]::Exists( \"#{path}\")")&.include?("True")
|
return cmd_exec("[System.IO.File]::Exists( \"#{path}\")")&.include?('True')
|
||||||
else
|
else
|
||||||
if session.platform == 'windows'
|
if session.platform == 'windows'
|
||||||
f = cmd_exec("cmd.exe /C IF exist \"#{path}\" ( echo true )")
|
f = cmd_exec("cmd.exe /C IF exist \"#{path}\" ( echo true )")
|
||||||
|
@ -295,11 +309,12 @@ module Msf::Post::File
|
||||||
end
|
end
|
||||||
return false if f.nil? || f.empty?
|
return false if f.nil? || f.empty?
|
||||||
return false unless f =~ /true/
|
return false unless f =~ /true/
|
||||||
|
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
alias :exists? :exist?
|
alias exists? exist?
|
||||||
|
|
||||||
#
|
#
|
||||||
# Retrieve file attributes for +path+ on the remote system
|
# Retrieve file attributes for +path+ on the remote system
|
||||||
|
@ -322,7 +337,7 @@ module Msf::Post::File
|
||||||
unless ::File.exist?(fname)
|
unless ::File.exist?(fname)
|
||||||
::FileUtils.touch(fname)
|
::FileUtils.touch(fname)
|
||||||
end
|
end
|
||||||
output = ::File.open(fname, "a")
|
output = ::File.open(fname, 'a')
|
||||||
data.each_line do |d|
|
data.each_line do |d|
|
||||||
output.puts(d)
|
output.puts(d)
|
||||||
end
|
end
|
||||||
|
@ -414,8 +429,8 @@ module Msf::Post::File
|
||||||
# @param data [String] Contents to put in the file
|
# @param data [String] Contents to put in the file
|
||||||
# @return [void]
|
# @return [void]
|
||||||
def write_file(file_name, data)
|
def write_file(file_name, data)
|
||||||
if session.type == "meterpreter"
|
if session.type == 'meterpreter'
|
||||||
fd = session.fs.file.new(file_name, "wb")
|
fd = session.fs.file.new(file_name, 'wb')
|
||||||
fd.write(data)
|
fd.write(data)
|
||||||
fd.close
|
fd.close
|
||||||
elsif session.type == 'powershell'
|
elsif session.type == 'powershell'
|
||||||
|
@ -440,8 +455,8 @@ module Msf::Post::File
|
||||||
# @param data [String] Contents to put in the file
|
# @param data [String] Contents to put in the file
|
||||||
# @return bool
|
# @return bool
|
||||||
def append_file(file_name, data)
|
def append_file(file_name, data)
|
||||||
if session.type == "meterpreter"
|
if session.type == 'meterpreter'
|
||||||
fd = session.fs.file.new(file_name, "ab")
|
fd = session.fs.file.new(file_name, 'ab')
|
||||||
fd.write(data)
|
fd.write(data)
|
||||||
fd.close
|
fd.close
|
||||||
elsif session.type == 'powershell'
|
elsif session.type == 'powershell'
|
||||||
|
@ -488,7 +503,7 @@ module Msf::Post::File
|
||||||
#
|
#
|
||||||
# @param path [String] Path on the remote filesystem
|
# @param path [String] Path on the remote filesystem
|
||||||
# @param mode [Fixnum] Mode as an octal number
|
# @param mode [Fixnum] Mode as an octal number
|
||||||
def chmod(path, mode = 0700)
|
def chmod(path, mode = 0o700)
|
||||||
if session.platform == 'windows'
|
if session.platform == 'windows'
|
||||||
raise "`chmod' method does not support Windows systems"
|
raise "`chmod' method does not support Windows systems"
|
||||||
end
|
end
|
||||||
|
@ -506,7 +521,7 @@ module Msf::Post::File
|
||||||
# @param path [String] Directory in the exploits folder
|
# @param path [String] Directory in the exploits folder
|
||||||
# @param path [String] Filename in the data folder
|
# @param path [String] Filename in the data folder
|
||||||
def exploit_data(data_directory, file)
|
def exploit_data(data_directory, file)
|
||||||
file_path = ::File.join(::Msf::Config.data_directory, "exploits", data_directory, file)
|
file_path = ::File.join(::Msf::Config.data_directory, 'exploits', data_directory, file)
|
||||||
::File.binread(file_path)
|
::File.binread(file_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -518,19 +533,17 @@ module Msf::Post::File
|
||||||
# @return [void]
|
# @return [void]
|
||||||
def rm_f(*remote_files)
|
def rm_f(*remote_files)
|
||||||
remote_files.each do |remote|
|
remote_files.each do |remote|
|
||||||
if session.type == "meterpreter"
|
if session.type == 'meterpreter'
|
||||||
session.fs.file.delete(remote) if file?(remote)
|
session.fs.file.delete(remote) if file?(remote)
|
||||||
elsif session.type == 'powershell'
|
elsif session.type == 'powershell'
|
||||||
cmd_exec("[System.IO.File]::Delete(\"#{remote}\")") if file?(remote)
|
cmd_exec("[System.IO.File]::Delete(\"#{remote}\")") if file?(remote)
|
||||||
else
|
elsif session.platform == 'windows'
|
||||||
if session.platform == 'windows'
|
|
||||||
cmd_exec("del /q /f \"#{remote}\"")
|
cmd_exec("del /q /f \"#{remote}\"")
|
||||||
else
|
else
|
||||||
cmd_exec("rm -f \"#{remote}\"")
|
cmd_exec("rm -f \"#{remote}\"")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Delete remote directories
|
# Delete remote directories
|
||||||
|
@ -540,21 +553,19 @@ module Msf::Post::File
|
||||||
# @return [void]
|
# @return [void]
|
||||||
def rm_rf(*remote_dirs)
|
def rm_rf(*remote_dirs)
|
||||||
remote_dirs.each do |remote|
|
remote_dirs.each do |remote|
|
||||||
if session.type == "meterpreter"
|
if session.type == 'meterpreter'
|
||||||
session.fs.dir.rmdir(remote) if exist?(remote)
|
session.fs.dir.rmdir(remote) if exist?(remote)
|
||||||
elsif session.type == 'powershell'
|
elsif session.type == 'powershell'
|
||||||
cmd_exec("Remove-Item -Path \"#{remote}\" -Force -Recurse")
|
cmd_exec("Remove-Item -Path \"#{remote}\" -Force -Recurse")
|
||||||
else
|
elsif session.platform == 'windows'
|
||||||
if session.platform == 'windows'
|
|
||||||
cmd_exec("rd /s /q \"#{remote}\"")
|
cmd_exec("rd /s /q \"#{remote}\"")
|
||||||
else
|
else
|
||||||
cmd_exec("rm -rf \"#{remote}\"")
|
cmd_exec("rm -rf \"#{remote}\"")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
alias file_rm rm_f
|
||||||
alias :file_rm :rm_f
|
alias dir_rm rm_rf
|
||||||
alias :dir_rm :rm_rf
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Renames a remote file. If the new file path is a directory, the file will be
|
# Renames a remote file. If the new file path is a directory, the file will be
|
||||||
|
@ -564,9 +575,8 @@ module Msf::Post::File
|
||||||
# @param new_file [String] The new name for the remote file
|
# @param new_file [String] The new name for the remote file
|
||||||
# @return [Boolean] Return true on success and false on failure
|
# @return [Boolean] Return true on success and false on failure
|
||||||
def rename_file(old_file, new_file)
|
def rename_file(old_file, new_file)
|
||||||
|
|
||||||
verification_token = Rex::Text.rand_text_alphanumeric(8)
|
verification_token = Rex::Text.rand_text_alphanumeric(8)
|
||||||
if session.type == "meterpreter"
|
if session.type == 'meterpreter'
|
||||||
begin
|
begin
|
||||||
new_file = new_file + session.fs.file.separator + session.fs.file.basename(old_file) if directory?(new_file)
|
new_file = new_file + session.fs.file.separator + session.fs.file.basename(old_file) if directory?(new_file)
|
||||||
return (session.fs.file.mv(old_file, new_file).result == 0)
|
return (session.fs.file.mv(old_file, new_file).result == 0)
|
||||||
|
@ -577,13 +587,14 @@ module Msf::Post::File
|
||||||
cmd_exec("Move-Item \"#{old_file}\" \"#{new_file}\" -Force; if($?){echo #{verification_token}}").include?(verification_token)
|
cmd_exec("Move-Item \"#{old_file}\" \"#{new_file}\" -Force; if($?){echo #{verification_token}}").include?(verification_token)
|
||||||
elsif session.platform == 'windows'
|
elsif session.platform == 'windows'
|
||||||
return false unless file?(old_file) # adding this because when the old_file is not present it hangs for a while, should be removed after this issue is fixed.
|
return false unless file?(old_file) # adding this because when the old_file is not present it hangs for a while, should be removed after this issue is fixed.
|
||||||
cmd_exec(%Q|move #{directory?(new_file) ? "" : "/y"} "#{old_file}" "#{new_file}" & if not errorlevel 1 echo #{verification_token}|).include?(verification_token)
|
|
||||||
|
cmd_exec(%(move #{directory?(new_file) ? '' : '/y'} "#{old_file}" "#{new_file}" & if not errorlevel 1 echo #{verification_token})).include?(verification_token)
|
||||||
else
|
else
|
||||||
cmd_exec(%Q|mv #{directory?(new_file) ? "" : "-f"} "#{old_file}" "#{new_file}" && echo #{verification_token}|).include?(verification_token)
|
cmd_exec(%(mv #{directory?(new_file) ? '' : '-f'} "#{old_file}" "#{new_file}" && echo #{verification_token})).include?(verification_token)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
alias :move_file :rename_file
|
alias move_file rename_file
|
||||||
alias :mv_file :rename_file
|
alias mv_file rename_file
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
@ -593,9 +604,10 @@ module Msf::Post::File
|
||||||
# @param dst_file [String] The name for the remote destination file
|
# @param dst_file [String] The name for the remote destination file
|
||||||
# @return [Boolean] Return true on success and false on failure
|
# @return [Boolean] Return true on success and false on failure
|
||||||
def copy_file(src_file, dst_file)
|
def copy_file(src_file, dst_file)
|
||||||
return false if directory?(dst_file) or directory?(src_file)
|
return false if directory?(dst_file) || directory?(src_file)
|
||||||
|
|
||||||
verification_token = Rex::Text.rand_text_alpha_upper(8)
|
verification_token = Rex::Text.rand_text_alpha_upper(8)
|
||||||
if session.type == "meterpreter"
|
if session.type == 'meterpreter'
|
||||||
begin
|
begin
|
||||||
return (session.fs.file.cp(src_file, dst_file).result == 0)
|
return (session.fs.file.cp(src_file, dst_file).result == 0)
|
||||||
rescue Rex::Post::Meterpreter::RequestError => e # when the source file is not present meterpreter will raise an error
|
rescue Rex::Post::Meterpreter::RequestError => e # when the source file is not present meterpreter will raise an error
|
||||||
|
@ -603,15 +615,13 @@ module Msf::Post::File
|
||||||
end
|
end
|
||||||
elsif session.type == 'powershell'
|
elsif session.type == 'powershell'
|
||||||
cmd_exec("Copy-Item \"#{src_file}\" -Destination \"#{dst_file}\"; if($?){echo #{verification_token}}").include?(verification_token)
|
cmd_exec("Copy-Item \"#{src_file}\" -Destination \"#{dst_file}\"; if($?){echo #{verification_token}}").include?(verification_token)
|
||||||
|
elsif session.platform == 'windows'
|
||||||
|
cmd_exec(%(copy /y "#{src_file}" "#{dst_file}" & if not errorlevel 1 echo #{verification_token})).include?(verification_token)
|
||||||
else
|
else
|
||||||
if session.platform == 'windows'
|
cmd_exec(%(cp -f "#{src_file}" "#{dst_file}" && echo #{verification_token})).include?(verification_token)
|
||||||
cmd_exec(%Q|copy /y "#{src_file}" "#{dst_file}" & if not errorlevel 1 echo #{verification_token}|).include?(verification_token)
|
|
||||||
else
|
|
||||||
cmd_exec(%Q|cp -f "#{src_file}" "#{dst_file}" && echo #{verification_token}|).include?(verification_token)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
alias cp_file copy_file
|
||||||
alias :cp_file :copy_file
|
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
|
@ -635,9 +645,9 @@ protected
|
||||||
compressed_chunk = Rex::Text.gzip(chunk)
|
compressed_chunk = Rex::Text.gzip(chunk)
|
||||||
encoded_chunk = Base64.strict_encode64(compressed_chunk)
|
encoded_chunk = Base64.strict_encode64(compressed_chunk)
|
||||||
if offset > 0 || append
|
if offset > 0 || append
|
||||||
file_mode = "Append"
|
file_mode = 'Append'
|
||||||
else
|
else
|
||||||
file_mode = "Create"
|
file_mode = 'Create'
|
||||||
end
|
end
|
||||||
pwsh_code = %($encoded=\"#{encoded_chunk}\";
|
pwsh_code = %($encoded=\"#{encoded_chunk}\";
|
||||||
$mstream = [System.IO.MemoryStream]::new([System.Convert]::FromBase64String($encoded));
|
$mstream = [System.IO.MemoryStream]::new([System.Convert]::FromBase64String($encoded));
|
||||||
|
@ -659,6 +669,7 @@ protected
|
||||||
loop do
|
loop do
|
||||||
chunk = _read_file_powershell_fragment(filename, chunk_size, offset)
|
chunk = _read_file_powershell_fragment(filename, chunk_size, offset)
|
||||||
break if chunk.nil?
|
break if chunk.nil?
|
||||||
|
|
||||||
data << chunk
|
data << chunk
|
||||||
offset += chunk_size
|
offset += chunk_size
|
||||||
break if chunk.length < chunk_size
|
break if chunk.length < chunk_size
|
||||||
|
@ -674,9 +685,9 @@ protected
|
||||||
$gzipstream.Close();\
|
$gzipstream.Close();\
|
||||||
[Convert]::ToBase64String($mstream.ToArray())")
|
[Convert]::ToBase64String($mstream.ToArray())")
|
||||||
return nil if b64_data.empty?
|
return nil if b64_data.empty?
|
||||||
|
|
||||||
uncompressed_fragment = Zlib::GzipReader.new(StringIO.new(Base64.decode64(b64_data))).read
|
uncompressed_fragment = Zlib::GzipReader.new(StringIO.new(Base64.decode64(b64_data))).read
|
||||||
return uncompressed_fragment
|
return uncompressed_fragment
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Checks to see if there are non-ansi or newline characters in a given string
|
# Checks to see if there are non-ansi or newline characters in a given string
|
||||||
|
@ -701,12 +712,10 @@ protected
|
||||||
#
|
#
|
||||||
# @return [String]
|
# @return [String]
|
||||||
def _read_file_meterpreter(file_name)
|
def _read_file_meterpreter(file_name)
|
||||||
fd = session.fs.file.new(file_name, "rb")
|
fd = session.fs.file.new(file_name, 'rb')
|
||||||
|
|
||||||
data = fd.read
|
data = fd.read
|
||||||
until fd.eof?
|
data << fd.read until fd.eof?
|
||||||
data << fd.read
|
|
||||||
end
|
|
||||||
|
|
||||||
data
|
data
|
||||||
rescue EOFError
|
rescue EOFError
|
||||||
|
@ -718,6 +727,7 @@ protected
|
||||||
ensure
|
ensure
|
||||||
fd.close if fd
|
fd.close if fd
|
||||||
end
|
end
|
||||||
|
|
||||||
# Windows ANSI file write for shell sessions. Writes given object content to a remote file.
|
# Windows ANSI file write for shell sessions. Writes given object content to a remote file.
|
||||||
#
|
#
|
||||||
# NOTE: *This is not binary-safe on Windows shell sessions!*
|
# NOTE: *This is not binary-safe on Windows shell sessions!*
|
||||||
|
@ -750,10 +760,10 @@ protected
|
||||||
while start_index < data.length
|
while start_index < data.length
|
||||||
begin
|
begin
|
||||||
session.shell_command_token("<nul set /p=\"#{data[start_index, write_length]}\" >> \"#{file_name}\"")
|
session.shell_command_token("<nul set /p=\"#{data[start_index, write_length]}\" >> \"#{file_name}\"")
|
||||||
start_index = start_index + write_length
|
start_index += write_length
|
||||||
write_length = [chunk_size, data.length - start_index].min
|
write_length = [chunk_size, data.length - start_index].min
|
||||||
rescue ::Exception => e
|
rescue ::Exception => e
|
||||||
print_error("Exception while running #{__method__.to_s}: #{e.to_s}")
|
print_error("Exception while running #{__method__}: #{e}")
|
||||||
file_rm(file_name)
|
file_rm(file_name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -772,7 +782,7 @@ protected
|
||||||
_win_ansi_write_file(b64_filename, b64_data, chunk_size)
|
_win_ansi_write_file(b64_filename, b64_data, chunk_size)
|
||||||
cmd_exec("certutil -decode #{b64_filename} #{file_name}")
|
cmd_exec("certutil -decode #{b64_filename} #{file_name}")
|
||||||
rescue ::Exception => e
|
rescue ::Exception => e
|
||||||
print_error("Exception while running #{__method__.to_s}: #{e.to_s}")
|
print_error("Exception while running #{__method__}: #{e}")
|
||||||
ensure
|
ensure
|
||||||
file_rm(b64_filename)
|
file_rm(b64_filename)
|
||||||
end
|
end
|
||||||
|
@ -793,14 +803,13 @@ protected
|
||||||
cmd_exec("certutil -decode #{b64_filename} #{tmp_filename}")
|
cmd_exec("certutil -decode #{b64_filename} #{tmp_filename}")
|
||||||
cmd_exec("copy /b #{file_name}+#{tmp_filename} #{file_name}")
|
cmd_exec("copy /b #{file_name}+#{tmp_filename} #{file_name}")
|
||||||
rescue ::Exception => e
|
rescue ::Exception => e
|
||||||
print_error("Exception while running #{__method__.to_s}: #{e.to_s}")
|
print_error("Exception while running #{__method__}: #{e}")
|
||||||
ensure
|
ensure
|
||||||
file_rm(b64_filename)
|
file_rm(b64_filename)
|
||||||
file_rm(tmp_filename)
|
file_rm(tmp_filename)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Write +data+ to the remote file +file_name+.
|
# Write +data+ to the remote file +file_name+.
|
||||||
#
|
#
|
||||||
|
@ -812,22 +821,22 @@ protected
|
||||||
#
|
#
|
||||||
# @return [void]
|
# @return [void]
|
||||||
def _write_file_unix_shell(file_name, data, append = false)
|
def _write_file_unix_shell(file_name, data, append = false)
|
||||||
redirect = (append ? ">>" : ">")
|
redirect = (append ? '>>' : '>')
|
||||||
|
|
||||||
# Short-circuit an empty string. The : builtin is part of posix
|
# Short-circuit an empty string. The : builtin is part of posix
|
||||||
# standard and should theoretically exist everywhere.
|
# standard and should theoretically exist everywhere.
|
||||||
if data.length == 0
|
if data.empty?
|
||||||
session.shell_command_token(": #{redirect} #{file_name}")
|
session.shell_command_token(": #{redirect} #{file_name}")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
d = data.dup
|
d = data.dup
|
||||||
d.force_encoding("binary") if d.respond_to? :force_encoding
|
d.force_encoding('binary') if d.respond_to? :force_encoding
|
||||||
|
|
||||||
chunks = []
|
chunks = []
|
||||||
command = nil
|
command = nil
|
||||||
encoding = :hex
|
encoding = :hex
|
||||||
cmd_name = ""
|
cmd_name = ''
|
||||||
|
|
||||||
line_max = _unix_max_line_length
|
line_max = _unix_max_line_length
|
||||||
# Leave plenty of room for the filename we're writing to and the
|
# Leave plenty of room for the filename we're writing to and the
|
||||||
|
@ -847,40 +856,40 @@ protected
|
||||||
# first.
|
# first.
|
||||||
#
|
#
|
||||||
# Both of these work for sure on Linux and FreeBSD
|
# Both of these work for sure on Linux and FreeBSD
|
||||||
{ :cmd => %q^/usr/bin/printf 'CONTENTS'^ , :enc => :octal, :name => "printf" },
|
{ cmd: %q{/usr/bin/printf 'CONTENTS'}, enc: :octal, name: 'printf' },
|
||||||
{ :cmd => %q^printf 'CONTENTS'^ , :enc => :octal, :name => "printf" },
|
{ cmd: %q{printf 'CONTENTS'}, enc: :octal, name: 'printf' },
|
||||||
# Works on Solaris
|
# Works on Solaris
|
||||||
{ :cmd => %q^/usr/bin/printf %b 'CONTENTS'^ , :enc => :octal, :name => "printf" },
|
{ cmd: %q{/usr/bin/printf %b 'CONTENTS'}, enc: :octal, name: 'printf' },
|
||||||
{ :cmd => %q^printf %b 'CONTENTS'^ , :enc => :octal, :name => "printf" },
|
{ cmd: %q{printf %b 'CONTENTS'}, enc: :octal, name: 'printf' },
|
||||||
# Perl supports both octal and hex escapes, but octal is usually
|
# Perl supports both octal and hex escapes, but octal is usually
|
||||||
# shorter (e.g. 0 becomes \0 instead of \x00)
|
# shorter (e.g. 0 becomes \0 instead of \x00)
|
||||||
{ :cmd => %q^perl -e 'print("CONTENTS")'^ , :enc => :octal, :name => "perl" },
|
{ cmd: %q{perl -e 'print("CONTENTS")'}, enc: :octal, name: 'perl' },
|
||||||
# POSIX awk doesn't have \xNN escapes, use gawk to ensure we're
|
# POSIX awk doesn't have \xNN escapes, use gawk to ensure we're
|
||||||
# getting the GNU version.
|
# getting the GNU version.
|
||||||
{ :cmd => %q^gawk 'BEGIN {ORS="";print "CONTENTS"}' </dev/null^ , :enc => :hex, :name => "awk" },
|
{ cmd: %q^gawk 'BEGIN {ORS="";print "CONTENTS"}' </dev/null^, enc: :hex, name: 'awk' },
|
||||||
# xxd's -p flag specifies a postscript-style hexdump of unadorned hex
|
# xxd's -p flag specifies a postscript-style hexdump of unadorned hex
|
||||||
# digits, e.g. ABCD would be 41424344
|
# digits, e.g. ABCD would be 41424344
|
||||||
{ :cmd => %q^echo 'CONTENTS'|xxd -p -r^ , :enc => :bare_hex, :name => "xxd" },
|
{ cmd: %q{echo 'CONTENTS'|xxd -p -r}, enc: :bare_hex, name: 'xxd' },
|
||||||
# Use echo as a last resort since it frequently doesn't support -e
|
# Use echo as a last resort since it frequently doesn't support -e
|
||||||
# or -n. bash and zsh's echo builtins are apparently the only ones
|
# or -n. bash and zsh's echo builtins are apparently the only ones
|
||||||
# that support both. Most others treat all options as just more
|
# that support both. Most others treat all options as just more
|
||||||
# arguments to print. In particular, the standalone /bin/echo or
|
# arguments to print. In particular, the standalone /bin/echo or
|
||||||
# /usr/bin/echo appear never to have -e so don't bother trying
|
# /usr/bin/echo appear never to have -e so don't bother trying
|
||||||
# them.
|
# them.
|
||||||
{ :cmd => %q^echo -ne 'CONTENTS'^ , :enc => :hex },
|
{ cmd: %q{echo -ne 'CONTENTS'}, enc: :hex },
|
||||||
].each { |foo|
|
].each do |foo|
|
||||||
# Some versions of printf mangle %.
|
# Some versions of printf mangle %.
|
||||||
test_str = "\0\xff\xfe#{Rex::Text.rand_text_alpha_upper(4)}\x7f%%\r\n"
|
test_str = "\0\xff\xfe#{Rex::Text.rand_text_alpha_upper(4)}\x7f%%\r\n"
|
||||||
# test_str = "\0\xff\xfe"
|
# test_str = "\0\xff\xfe"
|
||||||
case foo[:enc]
|
case foo[:enc]
|
||||||
when :hex
|
when :hex
|
||||||
cmd = foo[:cmd].sub("CONTENTS"){ Rex::Text.to_hex(test_str) }
|
cmd = foo[:cmd].sub('CONTENTS') { Rex::Text.to_hex(test_str) }
|
||||||
when :octal
|
when :octal
|
||||||
cmd = foo[:cmd].sub("CONTENTS"){ Rex::Text.to_octal(test_str) }
|
cmd = foo[:cmd].sub('CONTENTS') { Rex::Text.to_octal(test_str) }
|
||||||
when :bare_hex
|
when :bare_hex
|
||||||
cmd = foo[:cmd].sub("CONTENTS"){ Rex::Text.to_hex(test_str,'') }
|
cmd = foo[:cmd].sub('CONTENTS') { Rex::Text.to_hex(test_str, '') }
|
||||||
end
|
end
|
||||||
a = session.shell_command_token("#{cmd}")
|
a = session.shell_command_token(cmd.to_s)
|
||||||
|
|
||||||
if test_str == a
|
if test_str == a
|
||||||
command = foo[:cmd]
|
command = foo[:cmd]
|
||||||
|
@ -890,7 +899,7 @@ protected
|
||||||
else
|
else
|
||||||
vprint_status("#{cmd} Failed: #{a.inspect} != #{test_str.inspect}")
|
vprint_status("#{cmd} Failed: #{a.inspect} != #{test_str.inspect}")
|
||||||
end
|
end
|
||||||
}
|
end
|
||||||
|
|
||||||
if command.nil?
|
if command.nil?
|
||||||
raise RuntimeError, "Can't find command on the victim for writing binary data", caller
|
raise RuntimeError, "Can't find command on the victim for writing binary data", caller
|
||||||
|
@ -918,17 +927,17 @@ protected
|
||||||
|
|
||||||
# The first command needs to use the provided redirection for either
|
# The first command needs to use the provided redirection for either
|
||||||
# appending or truncating.
|
# appending or truncating.
|
||||||
cmd = command.sub("CONTENTS") { chunks.shift }
|
cmd = command.sub('CONTENTS') { chunks.shift }
|
||||||
session.shell_command_token("#{cmd} #{redirect} \"#{file_name}\"")
|
session.shell_command_token("#{cmd} #{redirect} \"#{file_name}\"")
|
||||||
|
|
||||||
# After creating/truncating or appending with the first command, we
|
# After creating/truncating or appending with the first command, we
|
||||||
# need to append from here on out.
|
# need to append from here on out.
|
||||||
chunks.each { |chunk|
|
chunks.each do |chunk|
|
||||||
vprint_status("Next chunk is #{chunk.length} bytes")
|
vprint_status("Next chunk is #{chunk.length} bytes")
|
||||||
cmd = command.sub("CONTENTS") { chunk }
|
cmd = command.sub('CONTENTS') { chunk }
|
||||||
|
|
||||||
session.shell_command_token("#{cmd} >> '#{file_name}'")
|
session.shell_command_token("#{cmd} >> '#{file_name}'")
|
||||||
}
|
end
|
||||||
|
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
@ -963,11 +972,11 @@ protected
|
||||||
else
|
else
|
||||||
raise NotImplementedError if session.platform == 'windows'
|
raise NotImplementedError if session.platform == 'windows'
|
||||||
raise "`stat' command doesn't exist on target system" unless command_exists?('stat')
|
raise "`stat' command doesn't exist on target system" unless command_exists?('stat')
|
||||||
|
|
||||||
return FileStat.new(filename, session)
|
return FileStat.new(filename, session)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
class FileStat < Rex::Post::FileStat
|
class FileStat < Rex::Post::FileStat
|
||||||
|
|
||||||
attr_accessor :stathash
|
attr_accessor :stathash
|
||||||
|
@ -975,7 +984,8 @@ protected
|
||||||
def initialize(filename, session)
|
def initialize(filename, session)
|
||||||
data = session.shell_command_token("stat --format='%d,%i,%h,%u,%g,%t,%s,%B,%o,%X,%Y,%Z,%f' '#{filename}'").to_s.chomp
|
data = session.shell_command_token("stat --format='%d,%i,%h,%u,%g,%t,%s,%B,%o,%X,%Y,%Z,%f' '#{filename}'").to_s.chomp
|
||||||
raise 'format argument of stat command not behaving as expected' unless data =~ /(\d+,){12}\w+/
|
raise 'format argument of stat command not behaving as expected' unless data =~ /(\d+,){12}\w+/
|
||||||
data = data.split(",")
|
|
||||||
|
data = data.split(',')
|
||||||
@stathash = Hash.new
|
@stathash = Hash.new
|
||||||
@stathash['st_dev'] = data[0].to_i
|
@stathash['st_dev'] = data[0].to_i
|
||||||
@stathash['st_ino'] = data[1].to_i
|
@stathash['st_ino'] = data[1].to_i
|
||||||
|
@ -992,5 +1002,4 @@ protected
|
||||||
@stathash['st_mode'] = data[12].to_i(16) # stat command returns hex value of mode"
|
@stathash['st_mode'] = data[12].to_i(16) # stat command returns hex value of mode"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
|
lib = File.join(Msf::Config.install_root, 'test', 'lib')
|
||||||
lib = File.join(Msf::Config.install_root, "test", "lib")
|
$LOAD_PATH.push(lib) unless $LOAD_PATH.include?(lib)
|
||||||
$:.push(lib) unless $:.include?(lib)
|
|
||||||
require 'module_test'
|
require 'module_test'
|
||||||
|
|
||||||
# load 'test/lib/module_test.rb'
|
# load 'test/lib/module_test.rb'
|
||||||
|
@ -14,19 +13,23 @@ class MetasploitModule < Msf::Post
|
||||||
include Msf::Post::File
|
include Msf::Post::File
|
||||||
|
|
||||||
def initialize(info = {})
|
def initialize(info = {})
|
||||||
super( update_info( info,
|
super(
|
||||||
|
update_info(
|
||||||
|
info,
|
||||||
'Name' => 'Testing Remote File Manipulation',
|
'Name' => 'Testing Remote File Manipulation',
|
||||||
'Description' => %q{ This module will test Post::File API methods },
|
'Description' => %q{ This module will test Post::File API methods },
|
||||||
'License' => MSF_LICENSE,
|
'License' => MSF_LICENSE,
|
||||||
'Author' => [ 'egypt'],
|
'Author' => [ 'egypt'],
|
||||||
'Platform' => [ 'windows', 'linux', 'java' ],
|
'Platform' => [ 'windows', 'linux', 'java' ],
|
||||||
'SessionTypes' => [ 'meterpreter', 'shell' ]
|
'SessionTypes' => [ 'meterpreter', 'shell' ]
|
||||||
))
|
)
|
||||||
|
)
|
||||||
|
|
||||||
register_options(
|
register_options(
|
||||||
[
|
[
|
||||||
OptString.new("BaseFileName" , [true, "File name to create", "meterpreter-test"])
|
OptString.new('BaseFileName', [true, 'File name to create', 'meterpreter-test'])
|
||||||
], self.class)
|
], self.class
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -36,7 +39,7 @@ class MetasploitModule < Msf::Post
|
||||||
#
|
#
|
||||||
def setup
|
def setup
|
||||||
@old_pwd = pwd
|
@old_pwd = pwd
|
||||||
tmp = (directory?("/tmp")) ? "/tmp" : "%TEMP%"
|
tmp = directory?('/tmp') ? '/tmp' : '%TEMP%'
|
||||||
vprint_status("Setup: changing working directory to #{tmp}")
|
vprint_status("Setup: changing working directory to #{tmp}")
|
||||||
cd(tmp)
|
cd(tmp)
|
||||||
|
|
||||||
|
@ -44,45 +47,45 @@ class MetasploitModule < Msf::Post
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_file
|
def test_file
|
||||||
it "should test for file existence" do
|
it 'should test for file existence' do
|
||||||
ret = false
|
ret = false
|
||||||
[
|
[
|
||||||
"c:\\boot.ini",
|
'c:\\boot.ini',
|
||||||
"c:\\pagefile.sys",
|
'c:\\pagefile.sys',
|
||||||
"/etc/passwd",
|
'/etc/passwd',
|
||||||
"/etc/master.passwd",
|
'/etc/master.passwd',
|
||||||
"%WINDIR%\\system32\\notepad.exe",
|
'%WINDIR%\\system32\\notepad.exe',
|
||||||
"%WINDIR%\\system32\\calc.exe"
|
'%WINDIR%\\system32\\calc.exe'
|
||||||
].each { |path|
|
].each do |path|
|
||||||
ret = true if file?(path)
|
ret = true if file?(path)
|
||||||
}
|
end
|
||||||
|
|
||||||
ret
|
ret
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should test for directory existence" do
|
it 'should test for directory existence' do
|
||||||
ret = false
|
ret = false
|
||||||
[
|
[
|
||||||
"c:\\",
|
'c:\\',
|
||||||
"/etc/",
|
'/etc/',
|
||||||
"/tmp"
|
'/tmp'
|
||||||
].each { |path|
|
].each do |path|
|
||||||
ret = true if directory?(path)
|
ret = true if directory?(path)
|
||||||
}
|
end
|
||||||
|
|
||||||
ret
|
ret
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should create text files" do
|
it 'should create text files' do
|
||||||
rm_f(datastore["BaseFileName"])
|
rm_f(datastore['BaseFileName'])
|
||||||
write_file(datastore["BaseFileName"], "foo")
|
write_file(datastore['BaseFileName'], 'foo')
|
||||||
|
|
||||||
file?(datastore["BaseFileName"])
|
file?(datastore['BaseFileName'])
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should read the text we just wrote" do
|
it 'should read the text we just wrote' do
|
||||||
f = read_file(datastore["BaseFileName"])
|
f = read_file(datastore['BaseFileName'])
|
||||||
ret = ("foo" == f)
|
ret = (f == 'foo')
|
||||||
unless ret
|
unless ret
|
||||||
print_error("Didn't read what we wrote, actual file on target: |#{f}|")
|
print_error("Didn't read what we wrote, actual file on target: |#{f}|")
|
||||||
end
|
end
|
||||||
|
@ -90,14 +93,14 @@ class MetasploitModule < Msf::Post
|
||||||
ret
|
ret
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should append text files" do
|
it 'should append text files' do
|
||||||
ret = true
|
ret = true
|
||||||
append_file(datastore["BaseFileName"], "bar")
|
append_file(datastore['BaseFileName'], 'bar')
|
||||||
|
|
||||||
ret &&= read_file(datastore["BaseFileName"]) == "foobar"
|
ret &&= read_file(datastore['BaseFileName']) == 'foobar'
|
||||||
append_file(datastore["BaseFileName"], "baz")
|
append_file(datastore['BaseFileName'], 'baz')
|
||||||
final_contents = read_file(datastore["BaseFileName"])
|
final_contents = read_file(datastore['BaseFileName'])
|
||||||
ret &&= final_contents == "foobarbaz"
|
ret &&= final_contents == 'foobarbaz'
|
||||||
unless ret
|
unless ret
|
||||||
print_error("Didn't read what we wrote, actual file on target: #{final_contents}")
|
print_error("Didn't read what we wrote, actual file on target: #{final_contents}")
|
||||||
end
|
end
|
||||||
|
@ -105,68 +108,81 @@ class MetasploitModule < Msf::Post
|
||||||
ret
|
ret
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should delete text files" do
|
it 'should delete text files' do
|
||||||
rm_f(datastore["BaseFileName"])
|
rm_f(datastore['BaseFileName'])
|
||||||
|
|
||||||
not file_exist?(datastore["BaseFileName"])
|
!file_exist?(datastore['BaseFileName'])
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should move files" do
|
it 'should move files' do
|
||||||
# Make sure we don't have leftovers from a previous run
|
# Make sure we don't have leftovers from a previous run
|
||||||
moved_file = datastore["BaseFileName"] + "-moved"
|
moved_file = datastore['BaseFileName'] + '-moved'
|
||||||
rm _f(datastore["BaseFileName"]) rescue nil
|
begin
|
||||||
rm_f(moved_file) rescue nil
|
rm _f(datastore['BaseFileName'])
|
||||||
|
rescue StandardError
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
begin
|
||||||
|
rm_f(moved_file)
|
||||||
|
rescue StandardError
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
# touch a new file
|
# touch a new file
|
||||||
write_file(datastore["BaseFileName"], "")
|
write_file(datastore['BaseFileName'], '')
|
||||||
|
|
||||||
rename_file(datastore["BaseFileName"], moved_file)
|
rename_file(datastore['BaseFileName'], moved_file)
|
||||||
res &&= exist?(moved_file)
|
res &&= exist?(moved_file)
|
||||||
res &&= !exist?(datastore["BaseFileName"])
|
res &&= !exist?(datastore['BaseFileName'])
|
||||||
|
|
||||||
# clean up
|
# clean up
|
||||||
rm_f(datastore["BaseFileName"]) rescue nil
|
begin
|
||||||
rm_f(moved_file) rescue nil
|
rm_f(datastore['BaseFileName'])
|
||||||
|
rescue StandardError
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
begin
|
||||||
|
rm_f(moved_file)
|
||||||
|
rescue StandardError
|
||||||
|
nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_binary_files
|
def test_binary_files
|
||||||
|
|
||||||
# binary_data = ::File.read("/bin/ls")
|
# binary_data = ::File.read("/bin/ls")
|
||||||
binary_data = ::File.read("/bin/echo")
|
binary_data = ::File.read('/bin/echo')
|
||||||
# binary_data = "\xff\x00\xff\xfe\xff\`$(echo blha)\`"
|
# binary_data = "\xff\x00\xff\xfe\xff\`$(echo blha)\`"
|
||||||
it "should write binary data" do
|
it 'should write binary data' do
|
||||||
vprint_status "Writing #{binary_data.length} bytes"
|
vprint_status "Writing #{binary_data.length} bytes"
|
||||||
t = Time.now
|
t = Time.now
|
||||||
write_file(datastore["BaseFileName"], binary_data)
|
write_file(datastore['BaseFileName'], binary_data)
|
||||||
vprint_status("Finished in #{Time.now - t}")
|
vprint_status("Finished in #{Time.now - t}")
|
||||||
|
|
||||||
file_exist?(datastore["BaseFileName"])
|
file_exist?(datastore['BaseFileName'])
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should read the binary data we just wrote" do
|
it 'should read the binary data we just wrote' do
|
||||||
bin = read_file(datastore["BaseFileName"])
|
bin = read_file(datastore['BaseFileName'])
|
||||||
vprint_status "Read #{bin.length} bytes"
|
vprint_status "Read #{bin.length} bytes"
|
||||||
|
|
||||||
bin == binary_data
|
bin == binary_data
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should delete binary files" do
|
it 'should delete binary files' do
|
||||||
rm_f(datastore["BaseFileName"])
|
rm_f(datastore['BaseFileName'])
|
||||||
|
|
||||||
not file_exist?(datastore["BaseFileName"])
|
!file_exist?(datastore['BaseFileName'])
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should append binary data" do
|
it 'should append binary data' do
|
||||||
write_file(datastore["BaseFileName"], "\xde\xad")
|
write_file(datastore['BaseFileName'], "\xde\xad")
|
||||||
append_file(datastore["BaseFileName"], "\xbe\xef")
|
append_file(datastore['BaseFileName'], "\xbe\xef")
|
||||||
bin = read_file(datastore["BaseFileName"])
|
bin = read_file(datastore['BaseFileName'])
|
||||||
rm_f(datastore["BaseFileName"])
|
rm_f(datastore['BaseFileName'])
|
||||||
|
|
||||||
bin == "\xde\xad\xbe\xef"
|
bin == "\xde\xad\xbe\xef"
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def cleanup
|
def cleanup
|
||||||
|
@ -176,4 +192,3 @@ class MetasploitModule < Msf::Post
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue