/
githubmirror
/
metasploit-framework
Обзор
Документация
Войти
/
githubmirror
/
metasploit-framework
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
modules/nops/x64/simple.rb
246 строк
8 KB
bcoles
modules/nops: Resolve RuboCop violations
13 апр 2025, 04:27
Не верифицирован
13 апр 2025, 04:27
5091539
Код
Авторство
О чём код?
## # 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 # 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... loop do # 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 && 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) && !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 !random if !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