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/gadget_chains/data_set.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/formatters/json_net_formatter.rb,
lib/msf/util/dot_net_deserialization/gadget_chains/claims_principal.rb,
lib/msf/util/dot_net_deserialization/gadget_chains/windows_identity.rb,
lib/msf/util/dot_net_deserialization/gadget_chains/data_set_type_spoof.rb,
lib/msf/util/dot_net_deserialization/gadget_chains/object_data_provider.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
- .encode_7bit_int(int) ⇒ Object
-
.formatter_compatible_gadget_chains(formatter) ⇒ Array<Symbol>
Get a list of gadget chains that are compatible with the specified formatter.
-
.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.
-
.generate_formatted(stream, formatter: DEFAULT_FORMATTER) ⇒ String
Take the specified serialized blob and encapsulate it with the specified formatter.
-
.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.
- .get_ancestor(obj, ancestor_type, required: true) ⇒ Object
Class Method Details
.encode_7bit_int(int) ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/msf/util/dot_net_deserialization.rb', line 14 def self.encode_7bit_int(int) return "\x00".b if int == 0 # 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 |
.formatter_compatible_gadget_chains(formatter) ⇒ Array<Symbol>
Get a list of gadget chains that are compatible with the specified formatter.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/msf/util/dot_net_deserialization.rb', line 87 def self.formatter_compatible_gadget_chains(formatter) case formatter when :BinaryFormatter, :LosFormatter chains = GadgetChains::NAMES.select { |name| GadgetChains.const_get(name) <= (Types::SerializedStream) } when :JsonNetFormatter chains = %i[ ObjectDataProvider ] when :SoapFormatter chains = %i[ ClaimsPrincipal TextFormattingRunProperties WindowsIdentity ] else raise NotImplementedError, 'The specified formatter is not implemented' end chains 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.
52 53 54 55 |
# File 'lib/msf/util/dot_net_deserialization.rb', line 52 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.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/msf/util/dot_net_deserialization.rb', line 66 def self.generate_formatted(stream, formatter: DEFAULT_FORMATTER) case formatter when :BinaryFormatter formatted = Formatters::BinaryFormatter.generate(stream) when :JsonNetFormatter formatted = Formatters::JsonNetFormatter.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.
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/msf/util/dot_net_deserialization.rb', line 110 def self.generate_gadget_chain(cmd, gadget_chain: DEFAULT_GADGET_CHAIN) case gadget_chain when :ClaimsPrincipal stream = GadgetChains::ClaimsPrincipal.generate(cmd) when :DataSet stream = GadgetChains::DataSet.generate(cmd) when :DataSetTypeSpoof stream = GadgetChains::DataSetTypeSpoof.generate(cmd) when :ObjectDataProvider stream = GadgetChains::ObjectDataProvider.generate(cmd) 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
29 30 31 32 33 34 35 36 37 |
# File 'lib/msf/util/dot_net_deserialization.rb', line 29 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 |