Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/nops/x64/simple.rb
Views: 11778
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Nop67def initialize8super(9'Name' => 'Simple',10'Alias' => 'x64_simple',11'Description' => 'An x64 single/multi byte NOP instruction generator.',12'Author' => [ 'sf' ],13'License' => MSF_LICENSE,14'Arch' => ARCH_X64 )1516register_advanced_options( [ OptBool.new( 'RandomNops', [ false, "Generate a random NOP sled", true ] ) ])17register_advanced_options( [ OptBool.new( 'MultiByte', [ false, "Generate a multi byte instruction NOP sled", false ] ) ])18end1920# This instruction list is far from complete (Only single byte instructions and some multi byte ADD/MOV instructions are used).21# A more complete list might warrant an pseudo assembler (Rex::Arch::X64) instead of hardcoding these.22INSTRUCTIONS = [ [ "\x90", 0, "nop" ],23[ "\x91", 0, "xchg eax, ecx" ],24[ "\x92", 0, "xchg eax, edx" ],25[ "\x93", 0, "xchg eax, ebx" ],26[ "\x94", 0, "xchg eax, esp" ],27[ "\x95", 0, "xchg eax, ebp" ],28[ "\x96", 0, "xchg eax, esi" ],29[ "\x97", 0, "xchg eax, edi" ],30[ "\x98", 0, "cwde" ],31[ "\x99", 0, "cdq" ],32[ "\x9B", 0, "wait" ],33[ "\x9C", 0, "pushfq" ],34[ "\x9D", 0, "popfq" ],35[ "\x9E", 0, "sahf" ],36[ "\x9F", 0, "lahf" ],37[ "\xFC", 0, "cld" ],38[ "\xFD", 0, "std" ],39[ "\xF8", 0, "clc" ],40[ "\xF9", 0, "cmc" ],41[ "\x50", 0, "push rax" ],42[ "\x51", 0, "push rcx" ],43[ "\x52", 0, "push rdx" ],44[ "\x53", 0, "push rbx" ],45[ "\x54", 0, "push rsp" ],46[ "\x55", 0, "push rbp" ],47[ "\x56", 0, "push rsi" ],48[ "\x57", 0, "push rdi" ],49[ "\x58", 0, "pop rax" ],50[ "\x59", 0, "pop rcx" ],51[ "\x5A", 0, "pop rdx" ],52[ "\x5B", 0, "pop rbx" ],53[ "\x5C", 0, "pop rsp" ],54[ "\x5D", 0, "pop rbp" ],55[ "\x5E", 0, "pop rsi" ],56[ "\x5F", 0, "pop rdi" ],57[ "\x04", 1, "add al, 0x??" ],58[ "\x80\xC3", 1, "add bl, 0x??" ],59[ "\x80\xC1", 1, "add cl, 0x??" ],60[ "\x80\xC2", 1, "add dl, 0x??" ],61[ "\x80\xC4", 1, "add ah, 0x??" ],62[ "\x80\xC7", 1, "add bh, 0x??" ],63[ "\x80\xC5", 1, "add ch, 0x??" ],64[ "\x80\xC6", 1, "add dh, 0x??" ],65[ "\x66\x05", 2, "add ax, 0x????" ],66[ "\x66\x81\xC3", 2, "add bx, 0x????" ],67[ "\x66\x81\xC1", 2, "add cx, 0x????" ],68[ "\x66\x81\xC2", 2, "add dx, 0x????" ],69[ "\x66\x81\xC6", 2, "add si, 0x????" ],70[ "\x66\x81\xC7", 2, "add di, 0x????" ],71[ "\x66\x41\x81\xC0", 2, "add r8w, 0x????" ],72[ "\x66\x41\x81\xC1", 2, "add r9w, 0x????" ],73[ "\x66\x41\x81\xC2", 2, "add r10w, 0x????" ],74[ "\x66\x41\x81\xC3", 2, "add r11w, 0x????" ],75[ "\x66\x41\x81\xC4", 2, "add r12w, 0x????" ],76[ "\x66\x41\x81\xC5", 2, "add r13w, 0x????" ],77[ "\x66\x41\x81\xC6", 2, "add r14w, 0x????" ],78[ "\x66\x41\x81\xC7", 2, "add r15w, 0x????" ],79[ "\x05", 4, "add eax, 0x????????" ],80[ "\x81\xC3", 4, "add ebx, 0x????????" ],81[ "\x81\xC1", 4, "add ecx, 0x????????" ],82[ "\x81\xC2", 4, "add edx, 0x????????" ],83[ "\x81\xC6", 4, "add esi, 0x????????" ],84[ "\x81\xC7", 4, "add edi, 0x????????" ],85[ "\x41\x81\xC0", 4, "add r8d, 0x????????" ],86[ "\x41\x81\xC1", 4, "add r9d, 0x????????" ],87[ "\x41\x81\xC2", 4, "add r10d, 0x????????" ],88[ "\x41\x81\xC3", 4, "add r11d, 0x????????" ],89[ "\x41\x81\xC4", 4, "add r12d, 0x????????" ],90[ "\x41\x81\xC5", 4, "add r13d, 0x????????" ],91[ "\x41\x81\xC6", 4, "add r14d, 0x????????" ],92[ "\x41\x81\xC7", 4, "add r15d, 0x????????" ],93[ "\x48\xB8", 8, "mov rax, 0x????????????????" ],94[ "\x48\xBB", 8, "mov rbx, 0x????????????????" ],95[ "\x48\xB9", 8, "mov rcx, 0x????????????????" ],96[ "\x48\xBA", 8, "mov rdx, 0x????????????????" ],97[ "\x48\xBE", 8, "mov rsi, 0x????????????????" ],98[ "\x48\xBF", 8, "mov rdi, 0x????????????????" ],99[ "\x49\xB8", 8, "mov r8, 0x????????????????" ],100[ "\x49\xB9", 8, "mov r8, 0x????????????????" ],101[ "\x49\xBA", 8, "mov r10, 0x????????????????" ],102[ "\x49\xBB", 8, "mov r11, 0x????????????????" ],103[ "\x49\xBC", 8, "mov r12, 0x????????????????" ],104[ "\x49\xBD", 8, "mov r13, 0x????????????????" ],105[ "\x49\xBE", 8, "mov r14, 0x????????????????" ],106[ "\x49\xBF", 8, "mov r15, 0x????????????????" ],107]108109I_OP = 0110I_SIZE = 1111I_TEXT = 2112113REGISTERS = [ [ "rsp", "esp", "sp" ],114[ "rbp", "ebp", "bp" ],115[ "rax", "eax", "ax", "al", "ah" ],116[ "rbx", "ebx", "bx", "bl", "bh" ],117[ "rcx", "ecx", "cx", "cl", "ch" ],118[ "rdx", "edx", "dx", "dl", "dh" ],119[ "rsi", "esi", "si" ],120[ "rdi", "edi", "di" ],121[ "r8", "r8d", "r8w", "r8b" ],122[ "r9", "r9d", "r9w", "r9b" ],123[ "r10", "r10d", "r10w", "r10b" ],124[ "r11", "r11d", "r11w", "r11b" ],125[ "r12", "r12d", "r12w", "r12b" ],126[ "r13", "r13d", "r13w", "r13b" ],127[ "r14", "r14d", "r14w", "r14b" ],128[ "r15", "r15d", "r15w", "r15b" ],129]130131def generate_random_sled( length, instructions, badchars, badregs )132opcodes_stack = []133total_size = 0134sled = ''135try_count = 0136good_bytes = []137138# Fixup SaveRegisters so for example, if we wish to preserve RSP we also should also preserve ESP and SP139REGISTERS.each { | reg | reg.each { |x| badregs += reg if badregs.include?( x ) } }140badregs = badregs.uniq()141142# If we are preserving RSP we should avoid all PUSH/POP instructions...143if badregs.include?( "rsp" )144badregs.push( 'push' )145badregs.push( 'pop' )146end147148# Loop while we still have bytes to fill in the sled...149while true150# Pick a random instruction and see if we can use it...151instruction = instructions[ rand(instructions.length) ]152153# Avoid using any bad mnemonics/registers...154try_another = false155badregs.each do | bad |156try_another = true if instruction[I_TEXT].include?( bad.downcase() )157break if try_another158end159next if try_another160161# Get the first bytes of the chosen instructions opcodes...162opcodes = instruction[I_OP]163164# If their are additional bytes to append, do it now...1651.upto( instruction[I_SIZE] ) do | i |166opcodes += Rex::Text.rand_char( badchars )167end168169# If we have gone over the requested sled length, try again.170if total_size + opcodes.length > length171try_count -= 1172173# If we have tried unsuccessfully 32 times we start unwinding the chosen opcode_stack to speed things up174if try_count == 0175pop_count = 4176while opcodes_stack.length and pop_count177total_size -= opcodes_stack.pop().length178pop_count -= 1179end180end181next182end183184# Reset the try_count for the next iteration.185try_count = 32186187# save the opcodes we just generated.188opcodes_stack.push( opcodes )189190# Increment the total size appropriately.191total_size += opcodes.length192193# Once we have generated the requested amount of bytes we can finish.194break if total_size == length195end196197# Now that we have chosen all the instructions to use we must generate the actual sled.198opcodes_stack.each do | opcodes_ |199sled += opcodes_200end201202return sled203end204205def generate_sled( length, opts )206badchars = opts['BadChars'] || ''207random = opts['Random'] || datastore['RandomNops']208badregs = opts['SaveRegisters'] || []209good_instructions = []210sled = ''211212# Weed out any instructions which will contain a bad char/instruction...213INSTRUCTIONS.each do | instruction |214good = true;215# If the instruction contains some bad chars we wont use it...216badchars.each_char do | bc |217if instruction[I_OP].include?( bc )218good = false219break220end221end222# if we are only to generate single byte instructions, weed out the multi byte ones...223good = false if instruction[I_SIZE] > 0 and not datastore['MultiByte']224225good_instructions.push( instruction ) if good226end227228# After we have pruned the instruction list we can proceed to generate a sled...229if good_instructions.empty?230# If we are left with no valid instructions to use we simple can't generate a sled.231sled = nil232elsif not random233if not badchars.include?( "\x90" )234sled += "\x90" * length235else236sled = nil237end238else239sled += generate_random_sled( length, good_instructions, badchars, badregs )240end241242return sled243end244end245246247