Permalink
Browse files

This adds support for the old exe format to msfencode using -t exe-sm…

…all and allows encoder modules to change preferences based on the platform, which fully solves #430.

git-svn-id: file:///home/svn/framework3/trunk@7840 4d416f70-5f16-0410-b530-b9f4589650da
  • Loading branch information...
1 parent c287573 commit 7e4d03be8636f687726f79d3a3954cf6fdd3fe0f HD Moore committed Dec 13, 2009
@@ -155,7 +155,7 @@ def encode
# Try encoding with the current encoder
begin
- self.encoded = self.encoder.encode(self.raw, reqs['BadChars'])
+ self.encoded = self.encoder.encode(self.raw, reqs['BadChars'], nil, pinst.platform)
rescue EncodingError
wlog("#{pinst.refname}: Encoder #{encoder.refname} failed: #{$!}", 'core', LEV_1)
dlog("#{pinst.refname}: Call stack\n#{$@.join("\n")}", 'core', LEV_3)
View
@@ -213,7 +213,11 @@ def decoder_hash
# an exception will be thrown if an error is encountered during the
# encoding process.
#
- def encode(buf, badchars = nil, state = nil)
+ def encode(buf, badchars = nil, state = nil, platform = nil)
+
+ # Configure platform hints if necessary
+ init_platform(platform) if platform
+
# Initialize an empty set of bad characters
badchars = '' if (!badchars)
@@ -394,6 +398,13 @@ def init_state(state)
end
#
+ # This provides a hook method for platform specific
+ # processing prior to the rest of encode() running
+ #
+ def init_platform(platform)
+
+ end
+ #
# Obtains the key to use during encoding. If context encoding is enabled,
# special steps are taken. Otherwise, the derived class is given an
# opportunity to find the key.
View
@@ -212,7 +212,7 @@ def self.to_win32pe_old(framework, code, opts={})
rc = pe[ci+320, cd-ci-320]
# 640 + rc.length bytes of room to store an encoded rc at offset ci
- enc = encode_stub(framework, [ARCH_X86], rc)
+ enc = encode_stub(framework, [ARCH_X86], rc, ::Msf::Module::PlatformList.win32)
lft = 640+rc.length - enc.length
buf = enc + Rex::Text.rand_text(640+rc.length - enc.length)
@@ -541,12 +541,12 @@ def self.to_dotnetmem(base=0x12340000, data="")
end
- def self.encode_stub(framework, arch, code)
+ def self.encode_stub(framework, arch, code, platform = nil)
return code if not framework.encoders
framework.encoders.each_module_ranked('Arch' => arch) do |name, mod|
begin
enc = framework.encoders.create(name)
- raw = enc.encode(code, '')
+ raw = enc.encode(code, '', nil, platform)
return raw if raw
rescue
end
@@ -47,7 +47,7 @@ def decoder_stub(state)
# We need to create a GetEIP stub for the exploit
if (not reg)
- if(datastore['AllowWin32SEH'])
+ if(datastore['AllowWin32SEH'] and datastore['AllowWin32SEH'].to_s =~ /^(t|y|1)/i)
buf = 'VTX630VXH49HHHPhYAAQhZYYYYAAQQDDDd36FFFFTXVj0PPTUPPa301089'
reg = 'ECX'
off = 0
@@ -64,7 +64,16 @@ def decoder_stub(state)
buf + Rex::Encoder::Alpha2::AlphaMixed::gen_decoder(reg, off)
end
-
+
+ #
+ # Configure SEH getpc code on Windows
+ #
+ def init_platform(platform)
+ if(platform.supports?(::Msf::Module::PlatformList.win32))
+ datastore['AllowWin32SEH'] = true
+ end
+ end
+
#
# Encodes a one byte block with the current index of the length of the
# payload.
@@ -47,7 +47,7 @@ def decoder_stub(state)
# We need to create a GetEIP stub for the exploit
if (not reg)
- if(datastore['AllowWin32SEH'])
+ if(datastore['AllowWin32SEH'] and datastore['AllowWin32SEH'].to_s =~ /^(t|y|1)/i)
buf = 'VTX630WTX638VXH49HHHPVX5AAQQPVX5YYYYP5YYYD5KKYAPTTX638TDDNVDDX4Z4A63861816'
reg = 'ECX'
off = 0
@@ -65,6 +65,16 @@ def decoder_stub(state)
buf + Rex::Encoder::Alpha2::AlphaUpper::gen_decoder(reg, off)
end
+
+ #
+ # Configure SEH getpc code on Windows
+ #
+ def init_platform(platform)
+ if(platform.supports?(::Msf::Module::PlatformList.win32))
+ datastore['AllowWin32SEH'] = true
+ end
+ end
+
#
# Encodes a one byte block with the current index of the length of the
# payload.
View
@@ -19,6 +19,7 @@ $args = Rex::Parser::Arguments.new(
"-i" => [ true, "Encode the contents of the supplied file path" ],
"-m" => [ true, "Specifies an additional module search path" ],
"-a" => [ true, "The architecture to encode as" ],
+ "-p" => [ true, "The platform to encode for" ],
"-t" => [ true, "The format to display the encoded buffer with (c, elf, exe, java, perl, raw, ruby, vba, vbs, loop-vbs)" ],
"-b" => [ true, "The list of characters to avoid: '\\x00\\xff'" ],
"-s" => [ true, "The maximum size of the encoded data" ],
@@ -94,6 +95,7 @@ delim = '_|_'
output = nil
ecount = 1
altexe = nil
+plat = nil
# Parse the argument and rock that shit.
$args.parse(ARGV) { |opt, idx, val|
@@ -117,10 +119,12 @@ $args.parse(ARGV) { |opt, idx, val|
ecount = val.to_i
when "-b"
badchars = Rex::Text.hex_to_raw(val)
+ when "-p"
+ plat = Msf::Module::PlatformList.transform(val)
when "-s"
space = val.to_i
when "-t"
- if (val =~ /^(perl|ruby|rb|raw|c|js_le|js_be|java|exe|elf|vba|vbs|loop-vbs)$/)
+ if (val =~ /^(perl|ruby|rb|raw|c|js_le|js_be|java|exe|exe-small|elf|vba|vbs|loop-vbs)$/)
fmt = val
else
$stderr.puts(OutError + "Invalid format: #{val}")
@@ -185,7 +189,7 @@ case cmd
1.upto(ecount) do |iteration|
# Encode it up
- raw = enc.encode(eout, badchars)
+ raw = enc.encode(eout, badchars, nil, plat)
# Is it too big?
if (space and space > 0 and raw.length > space)
@@ -219,6 +223,19 @@ case cmd
fd.write(exe)
end
end
+ when 'exe-small'
+ exe = nil
+ if(not arch or (arch.index(ARCH_X86)))
+ exe = Msf::Util::EXE.to_win32pe_old($framework, raw)
+ end
+
+ if(not output)
+ $stdout.write(exe)
+ else
+ File.open(output, "wb") do |fd|
+ fd.write(exe)
+ end
+ end
when 'elf'
elf = Msf::Util::EXE.to_linux_x86_elf($framework, raw)
if(not output)

0 comments on commit 7e4d03b

Please sign in to comment.