2005-12-17 06:46:23 +00:00
|
|
|
#!/usr/bin/env ruby
|
2005-10-01 21:25:42 +00:00
|
|
|
|
2006-07-31 15:36:08 +00:00
|
|
|
msfbase = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
|
|
|
|
$:.unshift(File.join(File.dirname(msfbase), 'lib'))
|
2008-02-02 21:29:46 +00:00
|
|
|
$:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB']
|
2005-10-01 21:25:42 +00:00
|
|
|
|
|
|
|
require 'rex'
|
|
|
|
require 'msf/ui'
|
|
|
|
require 'msf/base'
|
|
|
|
|
|
|
|
OutStatus = "[*] "
|
|
|
|
OutError = "[-] "
|
|
|
|
|
|
|
|
$args = Rex::Parser::Arguments.new(
|
|
|
|
"-i" => [ true, "Encode the contents of the supplied file path" ],
|
2007-02-18 12:27:17 +00:00
|
|
|
"-m" => [ true, "Specifies an additional module search path" ],
|
2005-10-01 21:25:42 +00:00
|
|
|
"-a" => [ true, "The architecture to encode as" ],
|
2008-11-12 19:15:24 +00:00
|
|
|
"-t" => [ true, "The format to display the encoded buffer with (raw, ruby, perl, c, exe, vba)" ],
|
2005-10-01 21:25:42 +00:00
|
|
|
"-b" => [ true, "The list of characters to avoid: '\\x00\\xff'" ],
|
|
|
|
"-s" => [ true, "The maximum size of the encoded data" ],
|
|
|
|
"-e" => [ true, "The encoder to use" ],
|
2008-09-26 22:34:51 +00:00
|
|
|
"-o" => [ true, "The output file" ],
|
2005-10-01 21:25:42 +00:00
|
|
|
"-n" => [ false, "Dump encoder information" ],
|
|
|
|
"-h" => [ false, "Help banner" ],
|
|
|
|
"-l" => [ false, "List available encoders" ])
|
|
|
|
|
|
|
|
#
|
|
|
|
# Dump the list of encoders
|
|
|
|
#
|
|
|
|
def dump_encoders(arch = nil)
|
|
|
|
tbl = Rex::Ui::Text::Table.new(
|
|
|
|
'Indent' => 4,
|
|
|
|
'Header' => "Framework Encoders" + ((arch) ? " (architectures: #{arch})" : ""),
|
|
|
|
'Columns' =>
|
|
|
|
[
|
|
|
|
"Name",
|
|
|
|
"Rank",
|
|
|
|
"Description"
|
|
|
|
])
|
|
|
|
cnt = 0
|
|
|
|
|
|
|
|
$framework.encoders.each_module(
|
|
|
|
'Arch' => arch ? arch.split(',') : nil) { |name, mod|
|
2006-01-08 01:12:00 +00:00
|
|
|
tbl << [ name, mod.rank_to_s, mod.new.name ]
|
2005-10-01 21:25:42 +00:00
|
|
|
|
|
|
|
cnt += 1
|
|
|
|
}
|
|
|
|
|
|
|
|
(cnt > 0) ? "\n" + tbl.to_s + "\n" : "\nNo compatible encoders found.\n\n"
|
|
|
|
end
|
|
|
|
|
|
|
|
#
|
|
|
|
# Returns the list of encoders to try
|
|
|
|
#
|
|
|
|
def get_encoders(arch, encoder)
|
|
|
|
encoders = []
|
|
|
|
|
|
|
|
if (encoder)
|
|
|
|
encoders << $framework.encoders.create(encoder)
|
|
|
|
else
|
|
|
|
$framework.encoders.each_module_ranked(
|
|
|
|
'Arch' => arch ? arch.split(',') : nil) { |name, mod|
|
|
|
|
encoders << mod.new
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
encoders
|
|
|
|
end
|
|
|
|
|
|
|
|
#
|
|
|
|
# Nuff said.
|
|
|
|
#
|
|
|
|
def usage
|
2005-10-01 21:32:11 +00:00
|
|
|
$stderr.puts("\n" + " Usage: #{$0} <options>\n" + $args.usage)
|
2005-10-01 21:25:42 +00:00
|
|
|
exit
|
|
|
|
end
|
|
|
|
|
|
|
|
# Defaults
|
|
|
|
cmd = "encode"
|
|
|
|
arch = nil
|
|
|
|
badchars = ''
|
|
|
|
space = nil
|
|
|
|
encoder = nil
|
|
|
|
fmt = "c"
|
|
|
|
input = $stdin
|
2005-10-01 21:32:11 +00:00
|
|
|
options = ''
|
2006-03-16 16:33:32 +00:00
|
|
|
delim = '_|_'
|
2008-09-26 22:34:51 +00:00
|
|
|
output = nil
|
2005-10-01 21:25:42 +00:00
|
|
|
|
|
|
|
# Parse the argument and rock that shit.
|
|
|
|
$args.parse(ARGV) { |opt, idx, val|
|
|
|
|
case opt
|
|
|
|
when "-i"
|
|
|
|
begin
|
|
|
|
input = File.new(val)
|
|
|
|
rescue
|
|
|
|
$stderr.puts(OutError + "Failed to open file #{val}: #{$!}")
|
|
|
|
exit
|
|
|
|
end
|
2007-02-18 12:27:17 +00:00
|
|
|
when "-m"
|
|
|
|
$framework.modules.add_module_path(val)
|
2005-10-01 21:25:42 +00:00
|
|
|
when "-l"
|
|
|
|
cmd = "list"
|
|
|
|
when "-n"
|
|
|
|
cmd = "dump"
|
|
|
|
when "-a"
|
|
|
|
arch = val
|
|
|
|
when "-b"
|
|
|
|
badchars = Rex::Text.hex_to_raw(val)
|
|
|
|
when "-s"
|
|
|
|
space = val.to_i
|
|
|
|
when "-t"
|
2009-01-09 22:51:29 +00:00
|
|
|
if (val =~ /^(perl|ruby|raw|c|js_le|js_be|java|exe|vba)$/)
|
2005-10-01 21:25:42 +00:00
|
|
|
fmt = val
|
|
|
|
else
|
|
|
|
$stderr.puts(OutError + "Invalid format: #{val}")
|
|
|
|
exit
|
|
|
|
end
|
2008-09-26 22:34:51 +00:00
|
|
|
when "-o"
|
|
|
|
output = val
|
2005-10-01 21:25:42 +00:00
|
|
|
when "-e"
|
|
|
|
encoder = val
|
|
|
|
when "-h"
|
|
|
|
usage
|
2005-10-01 21:32:11 +00:00
|
|
|
else
|
|
|
|
if (val =~ /=/)
|
2006-03-16 16:33:32 +00:00
|
|
|
options += ((options.length > 0) ? delim : "") + "#{val}"
|
2005-10-01 21:32:11 +00:00
|
|
|
end
|
2005-10-01 21:25:42 +00:00
|
|
|
end
|
|
|
|
}
|
|
|
|
|
2009-01-02 21:25:25 +00:00
|
|
|
# Initialize the simplified framework instance.
|
|
|
|
$framework = Msf::Simple::Framework.create(
|
|
|
|
:module_types => [ Msf::MODULE_ENCODER ]
|
|
|
|
)
|
|
|
|
|
2005-10-01 21:25:42 +00:00
|
|
|
# Get the list of encoders to try
|
|
|
|
encoders = get_encoders(arch, encoder)
|
|
|
|
|
|
|
|
# Process the actual command
|
|
|
|
case cmd
|
|
|
|
when "list"
|
|
|
|
$stderr.puts(dump_encoders(arch))
|
|
|
|
when "dump"
|
2006-09-26 16:03:53 +00:00
|
|
|
enc = encoder ? $framework.encoders.create(encoder) : nil
|
2005-10-01 21:25:42 +00:00
|
|
|
|
|
|
|
if (enc)
|
|
|
|
$stderr.puts(Msf::Serializer::ReadableText.dump_module(enc))
|
|
|
|
else
|
|
|
|
$stderr.puts(OutError + "Invalid encoder specified.")
|
|
|
|
end
|
|
|
|
when "encode"
|
2006-12-17 07:03:00 +00:00
|
|
|
buf = input.read
|
2005-10-01 21:25:42 +00:00
|
|
|
|
|
|
|
encoders.each { |enc|
|
2006-01-29 21:47:51 +00:00
|
|
|
next if not enc
|
2005-10-01 21:25:42 +00:00
|
|
|
begin
|
2005-10-01 21:32:11 +00:00
|
|
|
# Imports options
|
2006-03-16 16:33:32 +00:00
|
|
|
enc.datastore.import_options_from_s(options, delim)
|
2005-10-01 21:32:11 +00:00
|
|
|
|
2008-09-26 22:34:51 +00:00
|
|
|
# Encode it up
|
2005-10-01 21:25:42 +00:00
|
|
|
raw = enc.encode(buf, badchars)
|
|
|
|
|
|
|
|
# Is it too big?
|
|
|
|
if (space and space > 0 and raw.length > space)
|
|
|
|
$stderr.puts(OutError + "#{enc.refname} created buffer that is too big (#{raw.length})")
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
|
|
|
# Print it out
|
|
|
|
$stderr.puts(OutStatus + "#{enc.refname} succeeded, final size #{raw.length}\n\n")
|
2008-09-26 22:34:51 +00:00
|
|
|
|
2008-11-12 19:15:24 +00:00
|
|
|
case fmt
|
|
|
|
when 'exe'
|
2008-12-24 08:41:35 +00:00
|
|
|
exe = Rex::Text.to_win32pe(raw, "")
|
2008-09-26 22:34:51 +00:00
|
|
|
if(not output)
|
2008-11-12 19:15:24 +00:00
|
|
|
$stdout.write(exe)
|
2008-09-26 22:34:51 +00:00
|
|
|
else
|
|
|
|
File.open(output, "wb") do |fd|
|
2008-11-12 19:15:24 +00:00
|
|
|
fd.write(exe)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
when 'vba'
|
2008-12-24 08:41:35 +00:00
|
|
|
exe = Rex::Text.to_win32pe(raw, "")
|
2008-11-12 19:15:24 +00:00
|
|
|
vba = Rex::Text.to_exe_vba(exe)
|
2008-09-26 22:34:51 +00:00
|
|
|
if(not output)
|
2008-11-12 19:15:24 +00:00
|
|
|
$stdout.write(vba)
|
2008-09-26 22:34:51 +00:00
|
|
|
else
|
|
|
|
File.open(output, "wb") do |fd|
|
2008-11-12 19:15:24 +00:00
|
|
|
fd.write(vba)
|
2008-09-26 22:34:51 +00:00
|
|
|
end
|
2008-11-12 19:15:24 +00:00
|
|
|
end
|
|
|
|
else
|
|
|
|
if(not output)
|
|
|
|
$stdout.print(Msf::Simple::Buffer.transform(raw, fmt))
|
|
|
|
else
|
|
|
|
File.open(output, "wb") do |fd|
|
|
|
|
fd.write(Msf::Simple::Buffer.transform(raw, fmt))
|
|
|
|
end
|
2008-09-26 22:34:51 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2005-10-01 21:25:42 +00:00
|
|
|
exit
|
|
|
|
|
|
|
|
rescue
|
|
|
|
$stderr.puts(OutError + "#{enc.refname} failed: #{$!}")
|
|
|
|
end
|
|
|
|
}
|
|
|
|
|
|
|
|
$stderr.puts(OutError + "No encoders succeeded.")
|
2008-11-12 19:15:24 +00:00
|
|
|
end
|