##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Nop
def initialize
super(
'Name' => 'Simple',
'Alias' => 'x64_simple',
'Description' => 'An x64 single/multi byte NOP instruction generator.',
'Author' => [ 'sf' ],
'License' => MSF_LICENSE,
'Arch' => ARCH_X64 )
register_advanced_options( [ OptBool.new( 'RandomNops', [ false, "Generate a random NOP sled", true ] ) ])
register_advanced_options( [ OptBool.new( 'MultiByte', [ false, "Generate a multi byte instruction NOP sled", false ] ) ])
end
# This instruction list is far from complete (Only single byte instructions and some multi byte ADD/MOV instructions are used).
# A more complete list might warrant an pseudo assembler (Rex::Arch::X64) instead of hardcoding these.
INSTRUCTIONS = [ [ "\x90", 0, "nop" ],
[ "\x91", 0, "xchg eax, ecx" ],
[ "\x92", 0, "xchg eax, edx" ],
[ "\x93", 0, "xchg eax, ebx" ],
[ "\x94", 0, "xchg eax, esp" ],
[ "\x95", 0, "xchg eax, ebp" ],
[ "\x96", 0, "xchg eax, esi" ],
[ "\x97", 0, "xchg eax, edi" ],
[ "\x98", 0, "cwde" ],
[ "\x99", 0, "cdq" ],
[ "\x9B", 0, "wait" ],
[ "\x9C", 0, "pushfq" ],
[ "\x9D", 0, "popfq" ],
[ "\x9E", 0, "sahf" ],
[ "\x9F", 0, "lahf" ],
[ "\xFC", 0, "cld" ],
[ "\xFD", 0, "std" ],
[ "\xF8", 0, "clc" ],
[ "\xF9", 0, "cmc" ],
[ "\x50", 0, "push rax" ],
[ "\x51", 0, "push rcx" ],
[ "\x52", 0, "push rdx" ],
[ "\x53", 0, "push rbx" ],
[ "\x54", 0, "push rsp" ],
[ "\x55", 0, "push rbp" ],
[ "\x56", 0, "push rsi" ],
[ "\x57", 0, "push rdi" ],
[ "\x58", 0, "pop rax" ],
[ "\x59", 0, "pop rcx" ],
[ "\x5A", 0, "pop rdx" ],
[ "\x5B", 0, "pop rbx" ],
[ "\x5C", 0, "pop rsp" ],
[ "\x5D", 0, "pop rbp" ],
[ "\x5E", 0, "pop rsi" ],
[ "\x5F", 0, "pop rdi" ],
[ "\x04", 1, "add al, 0x??" ],
[ "\x80\xC3", 1, "add bl, 0x??" ],
[ "\x80\xC1", 1, "add cl, 0x??" ],
[ "\x80\xC2", 1, "add dl, 0x??" ],
[ "\x80\xC4", 1, "add ah, 0x??" ],
[ "\x80\xC7", 1, "add bh, 0x??" ],
[ "\x80\xC5", 1, "add ch, 0x??" ],
[ "\x80\xC6", 1, "add dh, 0x??" ],
[ "\x66\x05", 2, "add ax, 0x????" ],
[ "\x66\x81\xC3", 2, "add bx, 0x????" ],
[ "\x66\x81\xC1", 2, "add cx, 0x????" ],
[ "\x66\x81\xC2", 2, "add dx, 0x????" ],
[ "\x66\x81\xC6", 2, "add si, 0x????" ],
[ "\x66\x81\xC7", 2, "add di, 0x????" ],
[ "\x66\x41\x81\xC0", 2, "add r8w, 0x????" ],
[ "\x66\x41\x81\xC1", 2, "add r9w, 0x????" ],
[ "\x66\x41\x81\xC2", 2, "add r10w, 0x????" ],
[ "\x66\x41\x81\xC3", 2, "add r11w, 0x????" ],
[ "\x66\x41\x81\xC4", 2, "add r12w, 0x????" ],
[ "\x66\x41\x81\xC5", 2, "add r13w, 0x????" ],
[ "\x66\x41\x81\xC6", 2, "add r14w, 0x????" ],
[ "\x66\x41\x81\xC7", 2, "add r15w, 0x????" ],
[ "\x05", 4, "add eax, 0x????????" ],
[ "\x81\xC3", 4, "add ebx, 0x????????" ],
[ "\x81\xC1", 4, "add ecx, 0x????????" ],
[ "\x81\xC2", 4, "add edx, 0x????????" ],
[ "\x81\xC6", 4, "add esi, 0x????????" ],
[ "\x81\xC7", 4, "add edi, 0x????????" ],
[ "\x41\x81\xC0", 4, "add r8d, 0x????????" ],
[ "\x41\x81\xC1", 4, "add r9d, 0x????????" ],
[ "\x41\x81\xC2", 4, "add r10d, 0x????????" ],
[ "\x41\x81\xC3", 4, "add r11d, 0x????????" ],
[ "\x41\x81\xC4", 4, "add r12d, 0x????????" ],
[ "\x41\x81\xC5", 4, "add r13d, 0x????????" ],
[ "\x41\x81\xC6", 4, "add r14d, 0x????????" ],
[ "\x41\x81\xC7", 4, "add r15d, 0x????????" ],
[ "\x48\xB8", 8, "mov rax, 0x????????????????" ],
[ "\x48\xBB", 8, "mov rbx, 0x????????????????" ],
[ "\x48\xB9", 8, "mov rcx, 0x????????????????" ],
[ "\x48\xBA", 8, "mov rdx, 0x????????????????" ],
[ "\x48\xBE", 8, "mov rsi, 0x????????????????" ],
[ "\x48\xBF", 8, "mov rdi, 0x????????????????" ],
[ "\x49\xB8", 8, "mov r8, 0x????????????????" ],
[ "\x49\xB9", 8, "mov r8, 0x????????????????" ],
[ "\x49\xBA", 8, "mov r10, 0x????????????????" ],
[ "\x49\xBB", 8, "mov r11, 0x????????????????" ],
[ "\x49\xBC", 8, "mov r12, 0x????????????????" ],
[ "\x49\xBD", 8, "mov r13, 0x????????????????" ],
[ "\x49\xBE", 8, "mov r14, 0x????????????????" ],
[ "\x49\xBF", 8, "mov r15, 0x????????????????" ],
]
I_OP = 0
I_SIZE = 1
I_TEXT = 2
REGISTERS = [ [ "rsp", "esp", "sp" ],
[ "rbp", "ebp", "bp" ],
[ "rax", "eax", "ax", "al", "ah" ],
[ "rbx", "ebx", "bx", "bl", "bh" ],
[ "rcx", "ecx", "cx", "cl", "ch" ],
[ "rdx", "edx", "dx", "dl", "dh" ],
[ "rsi", "esi", "si" ],
[ "rdi", "edi", "di" ],
[ "r8", "r8d", "r8w", "r8b" ],
[ "r9", "r9d", "r9w", "r9b" ],
[ "r10", "r10d", "r10w", "r10b" ],
[ "r11", "r11d", "r11w", "r11b" ],
[ "r12", "r12d", "r12w", "r12b" ],
[ "r13", "r13d", "r13w", "r13b" ],
[ "r14", "r14d", "r14w", "r14b" ],
[ "r15", "r15d", "r15w", "r15b" ],
]
def generate_random_sled( length, instructions, badchars, badregs )
opcodes_stack = []
total_size = 0
sled = ''
try_count = 0
good_bytes = []
# Fixup SaveRegisters so for example, if we wish to preserve RSP we also should also preserve ESP and SP
REGISTERS.each { | reg | reg.each { |x| badregs += reg if badregs.include?( x ) } }
badregs = badregs.uniq()
# If we are preserving RSP we should avoid all PUSH/POP instructions...
if badregs.include?( "rsp" )
badregs.push( 'push' )
badregs.push( 'pop' )
end
# Loop while we still have bytes to fill in the sled...
while true
# Pick a random instruction and see if we can use it...
instruction = instructions[ rand(instructions.length) ]
# Avoid using any bad mnemonics/registers...
try_another = false
badregs.each do | bad |
try_another = true if instruction[I_TEXT].include?( bad.downcase() )
break if try_another
end
next if try_another
# Get the first bytes of the chosen instructions opcodes...
opcodes = instruction[I_OP]
# If their are additional bytes to append, do it now...
1.upto( instruction[I_SIZE] ) do | i |
opcodes += Rex::Text.rand_char( badchars )
end
# If we have gone over the requested sled length, try again.
if total_size + opcodes.length > length
try_count -= 1
# If we have tried unsuccessfully 32 times we start unwinding the chosen opcode_stack to speed things up
if try_count == 0
pop_count = 4
while opcodes_stack.length and pop_count
total_size -= opcodes_stack.pop().length
pop_count -= 1
end
end
next
end
# Reset the try_count for the next iteration.
try_count = 32
# save the opcodes we just generated.
opcodes_stack.push( opcodes )
# Increment the total size appropriately.
total_size += opcodes.length
# Once we have generated the requested amount of bytes we can finish.
break if total_size == length
end
# Now that we have chosen all the instructions to use we must generate the actual sled.
opcodes_stack.each do | opcodes_ |
sled += opcodes_
end
return sled
end
def generate_sled( length, opts )
badchars = opts['BadChars'] || ''
random = opts['Random'] || datastore['RandomNops']
badregs = opts['SaveRegisters'] || []
good_instructions = []
sled = ''
# Weed out any instructions which will contain a bad char/instruction...
INSTRUCTIONS.each do | instruction |
good = true;
# If the instruction contains some bad chars we wont use it...
badchars.each_char do | bc |
if instruction[I_OP].include?( bc )
good = false
break
end
end
# if we are only to generate single byte instructions, weed out the multi byte ones...
good = false if instruction[I_SIZE] > 0 and not datastore['MultiByte']
good_instructions.push( instruction ) if good
end
# After we have pruned the instruction list we can proceed to generate a sled...
if good_instructions.empty?
# If we are left with no valid instructions to use we simple can't generate a sled.
sled = nil
elsif not random
if not badchars.include?( "\x90" )
sled += "\x90" * length
else
sled = nil
end
else
sled += generate_random_sled( length, good_instructions, badchars, badregs )
end
return sled
end
end
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation