2012-06-29 00:18:28 -05:00
# -*- coding: binary -*-
2010-08-03 16:00:45 +00:00
2005-07-13 18:06:12 +00:00
module Msf
###
#
# This class wrappers an encoded payload buffer and the means used to create
# one.
#
###
class EncodedPayload
include Framework :: Offspring
2013-08-30 16:28:33 -05:00
2005-07-13 18:06:12 +00:00
#
2005-10-19 03:20:20 +00:00
# This method creates an encoded payload instance and returns it to the
# caller.
2005-07-13 18:06:12 +00:00
#
2008-05-26 07:59:03 +00:00
def self . create ( pinst , reqs = { } )
2005-07-13 18:06:12 +00:00
# Create the encoded payload instance
2005-07-13 21:09:07 +00:00
p = EncodedPayload . new ( pinst . framework , pinst , reqs )
2013-08-30 16:28:33 -05:00
2008-05-26 07:59:03 +00:00
p . generate ( reqs [ 'Raw' ] )
2014-11-03 12:33:11 -06:00
2005-07-13 18:06:12 +00:00
return p
end
2013-08-30 16:28:33 -05:00
2005-11-02 16:49:45 +00:00
#
# Creates an instance of an EncodedPayload.
#
2005-07-13 18:06:12 +00:00
def initialize ( framework , pinst , reqs )
self . framework = framework
self . pinst = pinst
self . reqs = reqs
2015-03-04 19:25:04 -06:00
self . space = reqs [ 'Space' ]
2005-07-13 18:06:12 +00:00
end
2013-08-30 16:28:33 -05:00
2005-07-13 18:06:12 +00:00
#
2011-08-30 22:23:00 +00:00
# This method generates the full encoded payload and returns the encoded
2005-11-02 16:49:45 +00:00
# payload buffer.
2005-07-13 18:06:12 +00:00
#
2013-01-15 10:34:31 -06:00
# @return [String] The encoded payload.
2008-05-26 07:59:03 +00:00
def generate ( raw = nil )
self . raw = raw
2005-07-13 21:09:07 +00:00
self . encoded = nil
self . nop_sled_size = 0
self . nop_sled = nil
self . encoder = nil
self . nop = nil
2013-08-30 16:28:33 -05:00
2006-07-30 18:45:36 +00:00
# Increase thread priority as necessary. This is done
# to ensure that the encoding and sled generation get
# enough time slices from the ruby thread scheduler.
priority = Thread . current . priority
2013-08-30 16:28:33 -05:00
2006-07-30 18:45:36 +00:00
if ( priority == 0 )
Thread . current . priority = 1
end
2014-11-03 12:33:11 -06:00
2006-07-30 18:45:36 +00:00
begin
# First, validate
pinst . validate ( )
2013-08-30 16:28:33 -05:00
2020-09-23 16:21:12 -04:00
# Propagate space information when set
unless self . space . nil?
# Tell the payload how much space is available
pinst . available_space = self . space
# Reserve 10% of the available space if encoding is required
pinst . available_space -= ( self . space * 0 . 1 ) . ceil if needs_encoding
end
2015-03-04 19:25:04 -06:00
2006-07-30 18:45:36 +00:00
# Generate the raw version of the payload first
2008-05-26 07:59:03 +00:00
generate_raw ( ) if self . raw . nil?
2013-08-30 16:28:33 -05:00
2014-10-06 09:41:07 +02:00
# If encoder is set, it could be an encoders list
# The form is "<encoder>:<iteration>, <encoder2>:<iteration>"...
2022-02-25 15:40:32 -05:00
unless reqs [ 'Encoder' ] . blank?
2014-10-06 09:41:07 +02:00
encoder_str = reqs [ 'Encoder' ]
encoder_str . scan ( / ([^:, ]+):?([^,]+)? / ) . map do | encoder_opt |
reqs [ 'Encoder' ] = encoder_opt [ 0 ]
self . iterations = ( encoder_opt [ 1 ] || reqs [ 'Iterations' ] ) . to_i
self . iterations = 1 if self . iterations < 1
# Encode the payload with every encoders in the list
encode ( )
2014-10-06 15:52:40 +02:00
# Encoded payload is now the raw payload to be encoded by the next encoder
self . raw = self . encoded
2014-10-06 09:41:07 +02:00
end
else
2014-10-07 09:59:26 +02:00
self . iterations = reqs [ 'Iterations' ] . to_i
self . iterations = 1 if self . iterations < 1
2014-10-06 09:41:07 +02:00
# No specified encoder, let BadChars or ForceEncode do their job
encode ( )
end
2013-08-30 16:28:33 -05:00
2006-07-30 18:45:36 +00:00
# Build the NOP sled
generate_sled ( )
2013-08-30 16:28:33 -05:00
2006-07-30 18:45:36 +00:00
# Finally, set the complete payload definition
self . encoded = ( self . nop_sled || '' ) + self . encoded
2010-08-03 16:00:45 +00:00
ensure
2006-07-30 18:45:36 +00:00
# Restore the thread priority
Thread . current . priority = priority
end
2013-08-30 16:28:33 -05:00
2005-07-13 18:06:12 +00:00
# Return the complete payload
return encoded
end
2013-08-30 16:28:33 -05:00
2005-07-13 18:06:12 +00:00
#
# Generates the raw payload from the payload instance. This populates the
2013-01-15 10:34:31 -06:00
# {#raw} attribute.
2005-07-13 18:06:12 +00:00
#
2013-01-15 10:34:31 -06:00
# @return [String] The raw, unencoded payload.
2005-07-13 18:06:12 +00:00
def generate_raw
2015-03-12 02:30:06 -05:00
self . raw = ( reqs [ 'Prepend' ] || '' ) + pinst . generate_complete + ( reqs [ 'Append' ] || '' )
2013-08-30 16:28:33 -05:00
2006-10-16 23:59:14 +00:00
# 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
2005-07-13 18:06:12 +00:00
end
2013-08-30 16:28:33 -05:00
2005-07-13 18:06:12 +00:00
#
# Scans for a compatible encoder using ranked precedence and populates the
# encoded attribute.
#
def encode
2022-02-25 15:40:32 -05:00
# Get the minimum number of nops to use
min = ( reqs [ 'MinNops' ] || 0 ) . to_i
min = 0 if reqs [ 'DisableNops' ]
2020-09-23 10:26:13 -04:00
# If the exploit needs the payload to be encoded, we need to run the list of
# encoders in ranked precedence and try to encode with them.
if needs_encoding
2014-10-06 18:55:52 -05:00
# Make sure the encoder name from the user has the same String#encoding
# as the framework's list of encoder names so we can compare them later.
# This is important for when we get input from RPC.
2012-01-20 21:06:53 -06:00
if reqs [ 'Encoder' ]
2024-01-15 14:56:46 +00:00
reqs [ 'Encoder' ] = reqs [ 'Encoder' ] . encode ( framework . encoders . module_refnames [ 0 ] . encoding )
2012-01-20 21:06:53 -06:00
end
2014-10-06 16:33:21 -05:00
2008-11-09 22:23:29 +00:00
# If the caller had a preferred encoder, use this encoder only
if ( ( reqs [ 'Encoder' ] ) and ( preferred = framework . encoders [ reqs [ 'Encoder' ] ] ) )
encoders = [ [ reqs [ 'Encoder' ] , preferred ] ]
2005-07-13 21:09:07 +00:00
elsif ( reqs [ 'Encoder' ] )
wlog ( " #{ pinst . refname } : Failed to find preferred encoder #{ reqs [ 'Encoder' ] } " )
2008-11-09 22:23:29 +00:00
raise NoEncodersSucceededError , " Failed to find preferred encoder #{ reqs [ 'Encoder' ] } "
2023-03-01 12:10:54 -05:00
else
encoders = compatible_encoders
2007-10-02 03:36:45 +00:00
end
2013-08-30 16:28:33 -05:00
2005-07-14 14:46:18 +00:00
encoders . each { | encname , encmod |
2005-07-13 21:09:07 +00:00
self . encoder = encmod . new
2005-09-24 19:17:07 +00:00
self . encoded = nil
2013-08-30 16:28:33 -05:00
2014-02-21 15:49:39 -06:00
# If the encoding is requested by an exploit check compatibility
# options first of all. For the 'generic/none' encoder compatibility
# options don't apply.
2014-02-21 16:02:27 -06:00
if ( reqs [ 'Exploit' ] &&
2014-02-24 08:47:25 -06:00
! reqs [ 'Exploit' ] . compatible? ( self . encoder ) &&
2014-02-21 16:02:27 -06:00
encname !~ / generic \/ none / )
wlog ( " #{ pinst . refname } : Encoder #{ encoder . refname } doesn't match the exploit Compat options " ,
'core' , LEV_1 )
next
2014-02-21 15:49:39 -06:00
end
2006-01-06 02:25:47 +00:00
# If there is an encoder type restriction, check to see if this
# encoder matches with what we're searching for.
if ( ( reqs [ 'EncoderType' ] ) and
( self . encoder . encoder_type . split ( / \ s+ / ) . include? ( reqs [ 'EncoderType' ] ) == false ) )
wlog ( " #{ pinst . refname } : Encoder #{ encoder . refname } is not a compatible encoder type: #{ reqs [ 'EncoderType' ] } != #{ self . encoder . encoder_type } " ,
'core' , LEV_1 )
next
end
2013-08-30 16:28:33 -05:00
2006-09-12 05:34:58 +00:00
# If the exploit did not explicitly request a kind of encoder and
# the current encoder has a manual ranking, then it should not be
# considered as a valid encoder. A manual ranking tells the
# framework that an encoder must be explicitly defined as the
# encoder of choice for an exploit.
if ( ( reqs [ 'EncoderType' ] . nil? ) and
2006-12-28 05:19:31 +00:00
( reqs [ 'Encoder' ] . nil? ) and
2006-09-12 05:34:58 +00:00
( self . encoder . rank == ManualRanking ) )
wlog ( " #{ pinst . refname } : Encoder #{ encoder . refname } is manual ranked and was not defined as a preferred encoder. " ,
'core' , LEV_1 )
next
end
2013-08-30 16:28:33 -05:00
2015-04-13 13:21:41 +05:00
# If the caller explicitly requires register preservation, make sure
2014-09-09 14:21:51 -05:00
# that the module in question can handle it. This is mostly used by
# the stage encoder path.
if ( reqs [ 'ForceSaveRegisters' ] and
reqs [ 'EncoderOptions' ] and
( reqs [ 'EncoderOptions' ] [ 'SaveRegisters' ] . to_s . length > 0 ) and
2014-10-06 16:33:21 -05:00
( ! self . encoder . can_preserve_registers? ) )
2014-09-09 14:21:51 -05:00
wlog ( " #{ pinst . refname } : Encoder #{ encoder . refname } does not preserve registers and the caller needs #{ reqs [ 'EncoderOptions' ] [ 'SaveRegisters' ] } preserved. " ,
'core' , LEV_1 )
next
end
2012-03-12 23:23:15 -05:00
# Import the datastore from payload (and likely exploit by proxy)
self . encoder . share_datastore ( pinst . datastore )
2013-08-30 16:28:33 -05:00
2006-01-06 02:25:47 +00:00
# If we have any encoder options, import them into the datastore
# of the encoder.
if ( reqs [ 'EncoderOptions' ] )
self . encoder . datastore . import_options_from_hash ( reqs [ 'EncoderOptions' ] )
end
2013-08-30 16:28:33 -05:00
2006-01-06 02:25:47 +00:00
# Validate the encoder to make sure it's properly initialized.
2010-08-03 16:00:45 +00:00
begin
2006-01-06 02:25:47 +00:00
self . encoder . validate
rescue :: Exception
wlog ( " #{ pinst . refname } : Failed to validate encoder #{ encoder . refname } : #{ $! } " ,
'core' , LEV_1 )
next
end
2013-08-30 16:28:33 -05:00
2015-03-04 19:25:04 -06:00
# Tell the encoder how much space is available
self . encoder . available_space = self . space
2010-07-23 20:22:36 +00:00
eout = self . raw . dup
2013-08-30 16:28:33 -05:00
2010-08-03 16:00:45 +00:00
next_encoder = false
2013-08-30 16:28:33 -05:00
2010-07-23 20:22:36 +00:00
# Try encoding with the current encoder
2010-08-03 16:00:45 +00:00
#
# NOTE: Using more than one iteration may cause successive iterations to switch
# to using a different encoder.
#
2010-07-23 20:22:36 +00:00
1 . upto ( self . iterations ) do | iter |
2010-08-03 16:00:45 +00:00
err_start = " #{ pinst . refname } : iteration #{ iter } "
2013-08-30 16:28:33 -05:00
2010-07-23 20:22:36 +00:00
begin
eout = self . encoder . encode ( eout , reqs [ 'BadChars' ] , nil , pinst . platform )
2024-01-16 13:31:51 +00:00
rescue EncodingError = > e
2024-01-19 14:30:34 +00:00
wlog ( " #{ err_start } : Encoder #{ encoder . refname } failed: #{ e } " , 'core' , LEV_1 )
dlog ( " #{ err_start } : Call stack \n #{ e . backtrace } " , 'core' , LEV_3 )
2010-08-03 16:00:45 +00:00
next_encoder = true
break
2013-08-30 16:28:33 -05:00
2020-06-11 13:09:25 +01:00
rescue :: Exception = > e
elog ( " Broken encoder #{ encoder . refname } " , error : e )
2010-08-03 16:00:45 +00:00
next_encoder = true
break
2010-07-23 20:22:36 +00:00
end
2013-08-30 16:28:33 -05:00
2010-07-23 20:22:36 +00:00
# Check to see if we have enough room for the minimum requirements
if ( ( reqs [ 'Space' ] ) and ( reqs [ 'Space' ] < eout . length + min ) )
2014-02-02 22:28:23 -06:00
wlog ( " #{ err_start } : Encoded payload version is too large ( #{ eout . length } bytes) with encoder #{ encoder . refname } " ,
2010-07-23 20:22:36 +00:00
'core' , LEV_1 )
2010-08-03 16:00:45 +00:00
next_encoder = true
break
2010-07-23 20:22:36 +00:00
end
2013-08-30 16:28:33 -05:00
2010-08-03 16:00:45 +00:00
ilog ( " #{ err_start } : Successfully encoded with encoder #{ encoder . refname } (size is #{ eout . length } ) " ,
'core' , LEV_0 )
2010-07-23 20:22:36 +00:00
end
2013-08-30 16:28:33 -05:00
2010-08-03 16:00:45 +00:00
next if next_encoder
2013-08-30 16:28:33 -05:00
2010-07-23 20:22:36 +00:00
self . encoded = eout
2005-07-13 21:09:07 +00:00
break
2005-07-13 18:06:12 +00:00
}
2014-10-06 16:33:21 -05:00
2005-07-13 18:06:12 +00:00
# If the encoded payload is nil, raise an exception saying that we
# suck at life.
2005-07-13 21:09:07 +00:00
if ( self . encoded == nil )
2014-11-03 12:33:11 -06:00
self . encoder = nil
2010-08-03 16:00:45 +00:00
raise NoEncodersSucceededError ,
2005-07-13 18:06:12 +00:00
" #{ pinst . refname } : All encoders failed to encode. " ,
caller
end
2013-08-30 16:28:33 -05:00
2005-07-13 18:06:12 +00:00
# If there are no bad characters, then the raw is the same as the
# encoded
else
2020-08-14 19:57:09 -05:00
# NOTE: BadChars can contain whitespace, so don't use String#blank?
unless reqs [ 'BadChars' ] . nil? || reqs [ 'BadChars' ] . empty?
2020-05-07 10:58:03 -05:00
ilog ( " #{ pinst . refname } : payload contains no badchars, skipping automatic encoding " , 'core' , LEV_0 )
end
2022-05-13 19:14:00 -05:00
# Space = 0 is a special value used by msfvenom to generate the smallest
# payload possible. In that case do not raise an exception indicating
# that the payload is too large.
2022-05-13 16:18:08 -04:00
if reqs [ 'Space' ] && reqs [ 'Space' ] > 0 && reqs [ 'Space' ] < raw . length + min
2022-02-25 15:40:32 -05:00
wlog ( " #{ pinst . refname } : Raw (unencoded) payload is too large ( #{ raw . length } bytes) " , 'core' , LEV_1 )
raise PayloadSpaceViolation , 'The payload exceeds the specified space' , caller
end
2005-07-13 21:09:07 +00:00
self . encoded = raw
2005-07-13 18:06:12 +00:00
end
2013-08-30 16:28:33 -05:00
2005-07-13 18:06:12 +00:00
# Prefix the prepend encoder value
2005-07-13 21:09:07 +00:00
self . encoded = ( reqs [ 'PrependEncoder' ] || '' ) + self . encoded
2014-02-04 15:41:10 +00:00
self . encoded << ( reqs [ 'AppendEncoder' ] || '' )
2005-07-13 18:06:12 +00:00
end
2013-08-30 16:28:33 -05:00
2005-07-13 18:06:12 +00:00
#
# Construct a NOP sled if necessary
#
def generate_sled
min = reqs [ 'MinNops' ] || 0
space = reqs [ 'Space' ]
2019-02-11 03:00:45 -06:00
pad_nops = reqs [ 'PadNops' ]
2013-08-30 16:28:33 -05:00
2005-07-13 21:09:07 +00:00
self . nop_sled_size = min
2013-08-30 16:28:33 -05:00
2005-07-13 18:06:12 +00:00
# Calculate the number of NOPs to pad out the buffer with based on the
# requirements. If there was a space requirement, check to see if
# there's any room at all left for a sled.
2010-08-03 16:00:45 +00:00
if ( ( space ) and
2005-07-13 18:06:12 +00:00
( space > encoded . length ) )
2005-07-13 21:09:07 +00:00
self . nop_sled_size = reqs [ 'Space' ] - self . encoded . length
2005-07-13 18:06:12 +00:00
end
2013-08-30 16:28:33 -05:00
2005-07-13 18:06:12 +00:00
# If the maximum number of NOPs has been exceeded, wrap it back down.
if ( ( reqs [ 'MaxNops' ] ) and
2005-09-24 19:17:07 +00:00
( reqs [ 'MaxNops' ] < self . nop_sled_size ) )
2005-07-13 21:09:07 +00:00
self . nop_sled_size = reqs [ 'MaxNops' ]
2005-07-13 18:06:12 +00:00
end
2013-08-30 16:28:33 -05:00
2006-01-02 01:12:36 +00:00
# Check for the DisableNops setting
self . nop_sled_size = 0 if reqs [ 'DisableNops' ]
2013-08-30 16:28:33 -05:00
2019-02-11 03:00:45 -06:00
# Check for the PadNops setting
self . nop_sled_size = ( pad_nops - self . encoded . length ) if reqs [ 'PadNops' ]
2005-07-13 18:06:12 +00:00
# Now construct the actual sled
2005-07-13 21:09:07 +00:00
if ( self . nop_sled_size > 0 )
2006-01-17 01:11:26 +00:00
nops = pinst . compatible_nops
2013-08-30 16:28:33 -05:00
2006-01-17 01:11:26 +00:00
# If the caller had a preferred nop, try to find it and prefix it
if ( ( reqs [ 'Nop' ] ) and
2006-01-17 04:09:40 +00:00
( preferred = framework . nops [ reqs [ 'Nop' ] ] ) )
nops . unshift ( [ reqs [ 'Nop' ] , preferred ] )
2006-01-17 01:11:26 +00:00
elsif ( reqs [ 'Nop' ] )
wlog ( " #{ pinst . refname } : Failed to find preferred nop #{ reqs [ 'Nop' ] } " )
end
2013-08-30 16:28:33 -05:00
2024-02-13 11:15:27 +00:00
nops . each { | nopname , nopmod |
2005-07-13 18:06:12 +00:00
# Create an instance of the nop module
2005-07-13 21:09:07 +00:00
self . nop = nopmod . new
2013-08-30 16:28:33 -05:00
2012-03-12 23:28:47 -05:00
# Propagate options from the payload and possibly exploit
self . nop . share_datastore ( pinst . datastore )
2013-08-30 16:28:33 -05:00
2005-07-18 02:01:36 +00:00
# The list of save registers
save_regs = ( reqs [ 'SaveRegisters' ] || [ ] ) + ( pinst . save_registers || [ ] )
2013-08-30 16:28:33 -05:00
2005-07-18 02:01:36 +00:00
if ( save_regs . empty? == true )
save_regs = nil
end
2013-08-30 16:28:33 -05:00
2005-07-13 18:06:12 +00:00
begin
2005-12-30 02:38:18 +00:00
nop . copy_ui ( pinst )
2005-07-15 22:30:04 +00:00
self . nop_sled = nop . generate_sled ( self . nop_sled_size ,
2005-07-13 18:06:12 +00:00
'BadChars' = > reqs [ 'BadChars' ] ,
2005-07-18 02:01:36 +00:00
'SaveRegisters' = > save_regs )
2015-10-16 14:01:00 -05:00
if nop_sled && nop_sled . length == nop_sled_size
break
else
dlog ( " #{ pinst . refname } : Nop generator #{ nop . refname } failed to generate sled for payload " , 'core' , LEV_1 )
end
2005-07-13 18:06:12 +00:00
rescue
dlog ( " #{ pinst . refname } : Nop generator #{ nop . refname } failed to generate sled for payload: #{ $! } " ,
'core' , LEV_1 )
2013-08-30 16:28:33 -05:00
2005-11-11 01:22:03 +00:00
self . nop = nil
2005-07-13 18:06:12 +00:00
end
}
2013-08-30 16:28:33 -05:00
2005-07-13 21:09:07 +00:00
if ( self . nop_sled == nil )
2010-08-03 16:00:45 +00:00
raise NoNopsSucceededError ,
2005-07-13 18:06:12 +00:00
" #{ pinst . refname } : All NOP generators failed to construct sled for. " ,
caller
end
else
2005-07-13 21:09:07 +00:00
self . nop_sled = ''
2005-07-13 18:06:12 +00:00
end
2013-08-30 16:28:33 -05:00
2005-07-13 21:09:07 +00:00
return self . nop_sled
2005-07-13 18:06:12 +00:00
end
2013-08-30 16:28:33 -05:00
2010-11-11 23:01:35 +00:00
#
# Convert the payload to an executable appropriate for its arch and
# platform.
#
# +opts+ are passed directly to +Msf::Util::EXE.to_executable+
#
2010-11-22 17:48:35 +00:00
# see +Msf::Exploit::EXE+
#
2010-08-20 07:01:23 +00:00
def encoded_exe ( opts = { } )
2010-11-11 23:01:35 +00:00
# Ensure arch and platform are in the format that to_executable expects
2010-11-22 17:48:35 +00:00
if opts [ :arch ] and not opts [ :arch ] . kind_of? Array
2010-11-11 23:01:35 +00:00
opts [ :arch ] = [ opts [ :arch ] ]
end
if ( opts [ :platform ] . kind_of? Msf :: Module :: PlatformList )
opts [ :platform ] = opts [ :platform ] . platforms
end
2013-08-30 16:28:33 -05:00
2010-11-23 20:34:27 +00:00
emod = pinst . assoc_exploit if pinst . respond_to? :assoc_exploit
2013-08-30 16:28:33 -05:00
2010-11-11 23:01:35 +00:00
if emod
2012-04-13 18:41:08 -06:00
if ( emod . datastore [ " EXE::Custom " ] and emod . respond_to? :get_custom_exe )
return emod . get_custom_exe
end
2010-11-11 23:01:35 +00:00
# This is a little ghetto, grabbing datastore options from the
# associated exploit, but it doesn't really make sense for the
# payload to have exe options if the exploit doesn't need an exe.
# Msf::Util::EXE chooses reasonable defaults if these aren't given,
# so it's not that big of an issue.
opts . merge! ( {
:template_path = > emod . datastore [ 'EXE::Path' ] ,
:template = > emod . datastore [ 'EXE::Template' ] ,
:inject = > emod . datastore [ 'EXE::Inject' ] ,
:fallback = > emod . datastore [ 'EXE::FallBack' ] ,
:sub_method = > emod . datastore [ 'EXE::OldMethod' ]
} )
# Prefer the target's platform/architecture information, but use
# the exploit module's if no target specific information exists.
opts [ :platform ] || = emod . target_platform if emod . respond_to? :target_platform
opts [ :platform ] || = emod . platform if emod . respond_to? :platform
opts [ :arch ] || = emod . target_arch if emod . respond_to? :target_arch
opts [ :arch ] || = emod . arch if emod . respond_to? :arch
end
2010-11-23 20:37:32 +00:00
# Lastly, try the payload's. This always happens if we don't have an
# associated exploit module.
opts [ :platform ] || = pinst . platform if pinst . respond_to? :platform
opts [ :arch ] || = pinst . arch if pinst . respond_to? :arch
2013-08-30 16:28:33 -05:00
2010-11-11 23:01:35 +00:00
Msf :: Util :: EXE . to_executable ( framework , opts [ :arch ] , opts [ :platform ] , encoded , opts )
2010-10-22 20:40:25 +00:00
end
2013-08-30 16:28:33 -05:00
2010-11-11 23:01:35 +00:00
#
# Generate a jar file containing the encoded payload.
#
# Uses the payload's +generate_jar+ method if it is implemented (Java
# payloads should all have it). Otherwise, converts the payload to an
# executable and uses Msf::Util::EXE.to_jar to create a jar file that dumps
# the exe out to a random file name in the system's temporary directory and
# executes it.
#
2010-10-22 20:40:25 +00:00
def encoded_jar ( opts = { } )
2010-11-11 23:01:35 +00:00
return pinst . generate_jar ( opts ) if pinst . respond_to? :generate_jar
2013-08-30 16:28:33 -05:00
2011-07-19 02:54:38 +00:00
opts [ :spawn ] || = pinst . datastore [ " Spawn " ]
2013-08-30 16:28:33 -05:00
2010-11-11 23:01:35 +00:00
Msf :: Util :: EXE . to_jar ( encoded_exe ( opts ) , opts )
2010-08-20 07:01:23 +00:00
end
2013-08-30 16:28:33 -05:00
2010-11-11 23:01:35 +00:00
#
# Similar to +encoded_jar+ but builds a web archive for use in servlet
# containers such as Tomcat.
#
def encoded_war ( opts = { } )
return pinst . generate_war ( opts ) if pinst . respond_to? :generate_war
2013-08-30 16:28:33 -05:00
2010-11-11 23:01:35 +00:00
Msf :: Util :: EXE . to_jsp_war ( encoded_exe ( opts ) , opts )
end
2013-08-30 16:28:33 -05:00
2014-08-24 02:22:15 -05:00
#
# An array containing the architecture(s) that this payload was made to run on
#
def arch
if pinst
pinst . arch
end
end
2021-02-16 14:36:38 -05:00
#
# An array containing the platform(s) that this payload was made to run on
#
def platform
if pinst
pinst . platform
end
end
2005-07-13 18:06:12 +00:00
#
# The raw version of the payload
#
attr_reader :raw
#
# The encoded version of the raw payload plus the NOP sled
# if one was generated.
#
attr_reader :encoded
#
# The size of the NOP sled
#
attr_reader :nop_sled_size
#
# The NOP sled itself
#
attr_reader :nop_sled
2005-07-13 21:09:07 +00:00
#
# The encoder that was used
#
attr_reader :encoder
#
# The NOP generator that was used
#
attr_reader :nop
2010-07-23 20:22:36 +00:00
#
# The number of encoding iterations used
#
attr_reader :iterations
2015-03-04 19:25:04 -06:00
#
# The maximum number of bytes acceptable for the encoded payload
#
attr_reader :space
2005-07-13 18:06:12 +00:00
protected
2005-10-19 03:20:20 +00:00
attr_writer :raw # :nodoc:
attr_writer :encoded # :nodoc:
attr_writer :nop_sled_size # :nodoc:
attr_writer :nop_sled # :nodoc:
attr_writer :payload # :nodoc:
attr_writer :encoder # :nodoc:
attr_writer :nop # :nodoc:
2010-07-23 20:22:36 +00:00
attr_writer :iterations # :nodoc:
2015-03-04 19:25:04 -06:00
attr_writer :space # :nodoc
2013-08-30 16:28:33 -05:00
2005-07-13 18:06:12 +00:00
#
# The payload instance used to generate the payload
#
attr_accessor :pinst
#
# The requirements used for generation
#
attr_accessor :reqs
2020-09-23 10:26:13 -04:00
def needs_encoding
2022-02-25 15:40:32 -05:00
! reqs [ 'Encoder' ] . blank? || reqs [ 'ForceEncode' ] || has_chars? ( reqs [ 'BadChars' ] )
2020-09-23 10:26:13 -04:00
end
2020-05-07 10:58:03 -05:00
def has_chars? ( chars )
2020-08-14 19:57:09 -05:00
# NOTE: BadChars can contain whitespace, so don't use String#blank?
2020-09-23 10:26:13 -04:00
if chars . nil? || chars . empty?
2020-08-14 19:57:09 -05:00
return false
end
2020-05-07 10:58:03 -05:00
2020-09-23 10:26:13 -04:00
# payload hasn't been set yet but we have bad characters so assume they'll need to be encoded
return true if self . raw . nil?
return false if self . raw . empty?
2020-05-07 10:58:03 -05:00
chars . each_byte do | bad |
2020-09-22 02:56:51 +01:00
return true if self . raw . index ( bad . chr ( :: Encoding :: ASCII_8BIT ) )
2020-05-07 10:58:03 -05:00
end
false
end
2023-03-01 12:10:54 -05:00
def compatible_encoders
arch = reqs [ 'Arch' ] || pinst . arch
platform = reqs [ 'Platform' ] || pinst . platform
encoders = [ ]
framework . encoders . each_module_ranked (
'Arch' = > arch , 'Platform' = > platform ) { | name , mod |
encoders << [ name , mod ]
}
encoders
end
2005-07-13 18:06:12 +00:00
end
2008-11-09 22:23:29 +00:00
end