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/encoders/x64/zutto_dekiru.rb
Views: 11779
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45require 'metasm'6require 'rex/nop/opty2'78class MetasploitModule < Msf::Encoder::Xor9Rank = ManualRanking1011def initialize12super(13'Name' => 'Zutto Dekiru',14'Version' => '$Revision: 14774 $',15'Description' => 'Inspired by shikata_ga_nai using fxsave64 to work under x64 systems.',16'Author' => 'agix',17'Arch' => ARCH_X64,18'License' => MSF_LICENSE,19'EncoderType' => Msf::Encoder::Type::Raw,20'Decoder' =>21{22'KeySize' => 8,23'KeyPack' => 'Q<'24}25)26end2728@@cpu64 = Metasm::X86_64.new29def assemble(src, cpu=@@cpu64)30Metasm::Shellcode.assemble(cpu, src).encode_string31end323334def fxsave64(reg)35case reg36when "rax"37return "\x48\x0f\xae\x00"38when "rbx"39return "\x48\x0f\xae\x03"40when "rcx"41return "\x48\x0f\xae\x01"42when "rdx"43return "\x48\x0f\xae\x02"44when "rsi"45return "\x48\x0f\xae\x06"46when "rdi"47return "\x48\x0f\xae\x07"48when "rbp"49return "\x48\x0f\xae\x45\x00"50when "r8"51return "\x49\x0f\xae\x00"52when "r9"53return "\x49\x0f\xae\x01"54when "r10"55return "\x49\x0f\xae\x02"56when "r11"57return "\x49\x0f\xae\x03"58when "r12"59return "\x49\x0f\xae\x04\x24"60when "r13"61return "\x49\x0f\xae\x45\x00"62when "r14"63return "\x49\x0f\xae\x06"64when "r15"65return "\x49\x0f\xae\x07"66end67end6869def nop(length,save_registers=[])70test = Rex::Nop::Opty2.new('',save_registers)71return test.generate_sled(length)72end7374# Indicate that this module can preserve some registers75def can_preserve_registers?76true77end78#79# Returns the set of FPU instructions that can be used for the FPU block of80# the decoder stub.81#82def fpu_instructions83fpus = []84850xe8.upto(0xee) { |x| fpus << "\xd9" + x.chr }860xc0.upto(0xcf) { |x| fpus << "\xd9" + x.chr }870xc0.upto(0xdf) { |x| fpus << "\xda" + x.chr }880xc0.upto(0xdf) { |x| fpus << "\xdb" + x.chr }890xc0.upto(0xc7) { |x| fpus << "\xdd" + x.chr }9091fpus << "\xd9\xd0"92fpus << "\xd9\xe1"93fpus << "\xd9\xf6"94fpus << "\xd9\xf7"95fpus << "\xd9\xe5"9697# This FPU instruction seems to fail consistently on Linux98#fpus << "\xdb\xe1"99100fpus101end102103def rand_string(length)104o = [('0'..'9'),('a'..'z'),('A'..'Z')].map{|i| i.to_a}.flatten;105string = (0..(length-1)).map{ o[rand(o.length)] }.join;106107return string108end109110def xor_string(text,key)111text.length.times {|n| text[n] = (text[n].ord^key[n.modulo(key.length)].ord).chr }112return text113end114115116def ordered_random_merge(a,b)117a, b = a.dup, b.dup118a.map{rand(b.size+1)}.sort.reverse.each do |index|119b.insert(index, a.pop)120end121b122end123124def encode_block(state, block)125allowed_reg = [126["rax", "eax", "ax", "al" ],127["rbx", "ebx", "bx", "bl" ],128["rcx", "ecx", "cx", "cl" ],129["rdx", "edx", "dx", "dl" ],130["rsi", "esi", "si", "sil" ],131["rdi", "edi", "di", "dil" ],132["rbp", "ebp", "bp", "bpl" ],133["r8", "r8d", "r8w", "r8b" ],134["r9", "r9d", "r9w", "r9b" ],135["r10", "r10d", "r10w", "r10b"],136["r11", "r11d", "r11w", "r11b"],137["r12", "r12d", "r12w", "r12b"],138["r13", "r13d", "r13w", "r13b"],139["r14", "r14d", "r14w", "r14b"],140["r15", "r15d", "r15w", "r15b"],141]142allowed_reg.delete_if { |reg| datastore['SaveRegisters'] && datastore['SaveRegisters'].include?(reg.first) }143allowed_reg.shuffle!144145if block.length%8 != 0146block += nop(8-(block.length%8))147end148149reg_type = 3150151if (block.length/8) > 0xff152reg_type = 2153end154155if (block.length/8) > 0xffff156reg_type = 1157end158159if (block.length/8) > 0xffffffff160reg_type = 0161end162163reg_key = allowed_reg[0][0]164reg_size = allowed_reg[3]165reg_rip = allowed_reg[1][0]166reg_env = allowed_reg[2]167168flip_coin = rand(2)169170fpu_opcode = Rex::Poly::LogicalBlock.new('fpu',171*fpu_instructions)172173fpu = []174fpu << ["fpu",fpu_opcode.generate([], nil, state.badchars)]175176sub = (rand(0xd00)&0xfff0)+0xf000177lea = []178if flip_coin==0179lea << ["lea", assemble("mov %s, rsp"%reg_env[0])]180lea << ["lea1", assemble("and "+reg_env[2]+", 0x%x"%sub)]181else182lea << ["lea", assemble("push rsp")]183lea << ["lea1", assemble("pop "+reg_env[0])]184lea << ["lea2", assemble("and "+reg_env[2]+", 0x%x"%sub)]185end186187fpu_lea = ordered_random_merge(fpu, lea)188fpu_lea << ["fpu1", fxsave64(reg_env[0])] # fxsave64 doesn't seem to exist in metasm189190key_ins = [["key", assemble("mov "+reg_key+", 0x%x"%state.key)]]191192size = []193size << ["size", assemble("xor "+reg_size[0]+", "+reg_size[0])]194size << ["size", assemble("mov "+reg_size[reg_type]+", 0x%x"% (block.length/8))]195196getrip=0197198a = ordered_random_merge(size, key_ins)199decode_head_tab = ordered_random_merge(a, fpu_lea)200201decode_head_tab.length.times { |i| getrip = i if decode_head_tab[i][0] == "fpu"}202203decode_head = decode_head_tab.map { |j,i| i.to_s }.join204205flip_coin = rand(2)206207if flip_coin==0208decode_head += assemble("mov "+reg_rip+", ["+reg_env[0]+" + 0x8]")209else210decode_head += assemble("add "+reg_env[0]+", 0x8")211decode_head += assemble("mov "+reg_rip+", ["+reg_env[0]+"]")212end213214215decode_head_size = decode_head.length216getrip.times { |i| decode_head_size -= decode_head_tab[i][1].length }217218loop_code = assemble("dec "+reg_size[0])219loop_code += assemble("xor ["+reg_rip+"+("+reg_size[0]+"*8) + 0x7f], "+reg_key)220loop_code += assemble("test "+reg_size[0]+", "+reg_size[0])221222payload_offset = decode_head_size+loop_code.length+2223224loop_code = assemble("dec "+reg_size[0])225loop_code += assemble("xor ["+reg_rip+"+("+reg_size[0]+"*8) + 0x"+payload_offset.to_s(16)+"], "+reg_key)226loop_code += assemble("test "+reg_size[0]+", "+reg_size[0])227228jnz = "\x75"+(0x100-(loop_code.length+2)).chr229230decode = decode_head+loop_code+jnz231encode = xor_string(block, [state.key].pack('Q'))232233return decode + encode234end235236237end238239240