144 lines
4.7 KiB
Ruby
144 lines
4.7 KiB
Ruby
##
|
|
# This module requires Metasploit: https://metasploit.com/download
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
##
|
|
|
|
###
|
|
#
|
|
# This class implements single-byte NOP generation for X86. It takes from
|
|
# ADMmutate and from spoonfu.
|
|
#
|
|
###
|
|
class MetasploitModule < Msf::Nop
|
|
|
|
SINGLE_BYTE_SLED =
|
|
{
|
|
# opcode affected registers
|
|
# ------ ------------------
|
|
"\x90" => nil , # nop
|
|
"\x97" => [ 'eax', 'edi' ], # xchg eax,edi
|
|
"\x96" => [ 'eax', 'esi' ], # xchg eax,esi
|
|
"\x95" => [ 'eax', 'ebp' ], # xchg eax,ebp
|
|
"\x93" => [ 'eax', 'ebx' ], # xchg eax,ebx
|
|
"\x92" => [ 'eax', 'edx' ], # xchg eax,edx
|
|
"\x91" => [ 'eax', 'ecx' ], # xchg eax,ecx
|
|
"\x99" => [ 'edx' ], # cdq
|
|
"\x4d" => [ 'ebp' ], # dec ebp
|
|
"\x48" => [ 'eax' ], # dec eax
|
|
"\x47" => [ 'edi' ], # inc edi
|
|
"\x4f" => [ 'edi' ], # dec edi
|
|
"\x40" => [ 'eax' ], # inc eax
|
|
"\x41" => [ 'ecx' ], # inc ecx
|
|
"\x37" => [ 'eax' ], # aaa
|
|
"\x3f" => [ 'eax' ], # aas
|
|
"\x27" => [ 'eax' ], # daa
|
|
"\x2f" => [ 'eax' ], # das
|
|
"\x46" => [ 'esi' ], # inc esi
|
|
"\x4e" => [ 'esi' ], # dec esi
|
|
"\xfc" => nil , # cld
|
|
"\xfd" => nil , # std
|
|
"\xf8" => nil , # clc
|
|
"\xf9" => nil , # stc
|
|
"\xf5" => nil , # cmc
|
|
"\x98" => [ 'eax' ], # cwde
|
|
"\x9f" => [ 'eax' ], # lahf
|
|
"\x4a" => [ 'edx' ], # dec edx
|
|
"\x44" => [ 'esp', 'align' ], # inc esp
|
|
"\x42" => [ 'edx' ], # inc edx
|
|
"\x43" => [ 'ebx' ], # inc ebx
|
|
"\x49" => [ 'ecx' ], # dec ecx
|
|
"\x4b" => [ 'ebx' ], # dec ebx
|
|
"\x45" => [ 'ebp' ], # inc ebp
|
|
"\x4c" => [ 'esp', 'align' ], # dec esp
|
|
"\x9b" => nil , # wait
|
|
"\x60" => [ 'esp' ], # pusha
|
|
"\x0e" => [ 'esp', 'align' ], # push cs
|
|
"\x1e" => [ 'esp', 'align' ], # push ds
|
|
"\x50" => [ 'esp' ], # push eax
|
|
"\x55" => [ 'esp' ], # push ebp
|
|
"\x53" => [ 'esp' ], # push ebx
|
|
"\x51" => [ 'esp' ], # push ecx
|
|
"\x57" => [ 'esp' ], # push edi
|
|
"\x52" => [ 'esp' ], # push edx
|
|
"\x06" => [ 'esp', 'align' ], # push es
|
|
"\x56" => [ 'esp' ], # push esi
|
|
"\x54" => [ 'esp' ], # push esp
|
|
"\x16" => [ 'esp', 'align' ], # push ss
|
|
"\x58" => [ 'esp', 'eax' ], # pop eax
|
|
"\x5d" => [ 'esp', 'ebp' ], # pop ebp
|
|
"\x5b" => [ 'esp', 'ebx' ], # pop ebx
|
|
"\x59" => [ 'esp', 'ecx' ], # pop ecx
|
|
"\x5f" => [ 'esp', 'edi' ], # pop edi
|
|
"\x5a" => [ 'esp', 'edx' ], # pop edx
|
|
"\x5e" => [ 'esp', 'esi' ], # pop esi
|
|
"\xd6" => [ 'eax' ], # salc
|
|
}
|
|
|
|
def initialize
|
|
super(
|
|
'Name' => 'Single Byte',
|
|
'Alias' => 'ia32_singlebyte',
|
|
'Description' => 'Single-byte NOP generator',
|
|
'Author' => 'spoonm',
|
|
'License' => MSF_LICENSE,
|
|
'Arch' => ARCH_X86)
|
|
|
|
register_advanced_options(
|
|
[
|
|
OptBool.new('RandomNops', [ false, "Generate a random NOP sled", true ])
|
|
])
|
|
end
|
|
|
|
# Generate a single-byte NOP sled for X86
|
|
def generate_sled(length, opts = {})
|
|
sled_hash = SINGLE_BYTE_SLED
|
|
sled_max_idx = sled_hash.length
|
|
sled_cur_idx = 0
|
|
out_sled = ''
|
|
|
|
random = opts['Random']
|
|
badchars = opts['BadChars'] || ''
|
|
badregs = opts['SaveRegisters'] || []
|
|
|
|
# Did someone specify random NOPs in the environment?
|
|
if (!random and datastore['RandomNops'])
|
|
random = datastore['RandomNops']
|
|
end
|
|
|
|
# Generate the whole sled...
|
|
1.upto(length) { |current|
|
|
|
|
cur_char = nil
|
|
threshold = 0
|
|
|
|
# Keep snagging characters until we find one that satisfies both the
|
|
# bad character and bad register requirements
|
|
begin
|
|
sled_cur_idx = rand(sled_max_idx) if (random == true)
|
|
cur_char = sled_hash.keys[sled_cur_idx]
|
|
sled_cur_idx += 1 if (random == false)
|
|
sled_cur_idx = 0 if (sled_cur_idx >= sled_max_idx)
|
|
|
|
# Make sure that we haven't gone over the sled repeat threshold
|
|
if ((threshold += 1) > self.nop_repeat_threshold)
|
|
return nil
|
|
end
|
|
|
|
end while ((badchars.include?(cur_char)) or
|
|
((sled_hash[cur_char]) and
|
|
((sled_hash[cur_char] & badregs).length > 0)))
|
|
|
|
# Add the character to the sled now that it's passed our checks
|
|
out_sled += cur_char
|
|
}
|
|
|
|
# If the sled fails to entirely generate itself, then that's bogus,
|
|
# man...
|
|
if (out_sled.length != length)
|
|
return nil
|
|
end
|
|
|
|
return out_sled
|
|
end
|
|
end
|