Example #1
0
 def _get_return_labels(patch):
     """
     Adds labels to the jump out targets
     """
     ret = []
     p1 = AddLabelPatch(patch["dst_active"], patch["dst_active_name"])
     ret.append(p1)
     if type(patch["dst_zero"]) != str:
         p2 = AddLabelPatch(patch["dst_zero"], patch["dst_zero_name"])
         ret.append(p2)
     return ret
    def test_add_label_patch(self):
        p1 = AddLabelPatch(0x080484f4, "added_label")
        p2 = InlinePatch(0x08048442, "LEA EDX, [{added_label}]")

        self.run_test("printf_nopie", [p1, p2],
                      expected_output=b"s",
                      expected_returnCode=0)
    def test_add_label_patch(self):
        p1 = AddLabelPatch(0x400935, "added_label")
        added_code = '''
            li $v0, 4004
            li $a0, 1
            la $a1, {added_label}
            li $a2, 1
            syscall
        '''
        p2 = InsertCodePatch(0x40076c, added_code)

        self.run_test("printf_nopie", [p1, p2], expected_output=b"sHi", expected_returnCode=0)
    def test_add_label_patch(self):
        p1 = AddLabelPatch(0x400649, "added_label")
        added_code = '''
            mov x8, 0x40
            mov x0, 0x1
            ldr x1, ={added_label}
            mov x2, 1
            svc 0
        '''
        p2 = InsertCodePatch(0x400580, added_code)

        self.run_test("printf_nopie", [p1, p2], expected_output=b"sHi", expected_returnCode=0)
Example #5
0
    def test_add_label_patch(self):
        p1 = AddLabelPatch(0x120000cf9, "added_label")
        added_code = '''
            dli $v0, 5001
            dli $a0, 1
            dla $a1, {added_label}
            dli $a2, 1
            syscall
        '''
        p2 = InsertCodePatch(0x120000b20, added_code)

        self.run_test("printf_nopie", [p1, p2],
                      expected_output=b"sHi",
                      expected_returnCode=0)
    def test_add_label_patch(self):
        p1 = AddLabelPatch(0x10451, "added_label")
        added_code = '''
            mov r7, 0x4
            mov r0, 0x1
            ldr r1, ={added_label}
            mov r2, 1
            svc 0
        '''
        p2 = InsertCodePatch(0x103ec, added_code)

        self.run_test("printf_nopie", [p1, p2],
                      expected_output=b"sHi",
                      expected_returnCode=0)
    def test_add_label_patch(self):
        p1 = AddLabelPatch(0x10000759, "added_label")
        added_code = '''
            li r0, 4
            li r3, 1
            lis r4, {added_label}@h
            ori r4, r4, {added_label}@l
            li r5, 1
            sc
        '''
        p2 = InsertCodePatch(0x100004f8, added_code)

        self.run_test("printf_nopie", [p1, p2],
                      expected_output=b"sHi",
                      expected_returnCode=0)
Example #8
0
    def get_patches(self):
        cfg = self.patcher.cfg
        patches = []

        pnum = 0
        used_spec_chars = []
        for func, (func_name, func_obj) in self.ident.matches.items():
            if func_name not in PRINTF_VARIANTS:
                continue
            if func_obj.format_spec_char is None:
                l.warning("func_obj.format_spec_char is None")
                continue

            fmt_arg_pos = PRINTF_VARIANTS[func_name]
            callers = set.union(
                set(),
                *(cfg.get_predecessors(node)
                  for node in cfg.get_all_nodes(func.addr)))

            handled_addrs = set()
            func_to_cfg = {}
            for caller in callers:
                if caller.addr in handled_addrs:
                    continue

                try:
                    args, _ = self.ident.get_call_args(func, caller.addr)
                except KeyError:
                    continue

                fmt_str = args[fmt_arg_pos]
                if not claripy.is_true(claripy.Or(*(claripy.And(seg.min_addr <= fmt_str, fmt_str <= seg.max_addr)\
                        for seg in self.ro_segments))):
                    # we bad
                    break

                handled_addrs.add(caller.addr)
            else:
                # patch not necessary for this function
                continue

            pnum += 1  # we need this to ensure always different labels
            used_spec_chars.append(func_obj.format_spec_char)
            check = """
                ; is the address not in RO memory?
                cmp dword [esp+{stack_offset}], {{max_ro_addr}}
                jbe _end_printfcheck_%d

                ; int 3
                ; is the address in the flag page?
                cmp dword [esp+{stack_offset}], {flag_page}
                jb _check_for_percent_%d
                cmp dword [esp+{stack_offset}], {flag_page_almost_end}
                ja _check_for_percent_%d

                ; they're trying to read from the flag page! f**k them.
                jmp 0x41414141

            _check_for_percent_%d:
                push esi ; = pointer to string
                mov esi, [esp+{stack_offset_2}]
                push eax
                xor eax, eax; hash

            _loop_printfcheck_%d:
                cmp byte [esi], 0
                je _final_check_printfcheck_%d
                xor al, byte[esi]
                cmp byte[esi], {format_spec_char}
                jne _continue_printfcheck_%d
                    mov ah, 0x1
                _continue_printfcheck_%d:
                    inc esi
                    jmp _loop_printfcheck_%d

            _final_check_printfcheck_%d:
                test ah, ah
                je _restore_printfcheck_%d
                test al, al ; avoid al==0 as we do in the hash algorithm
                jne _do_not_inc_%d
                    inc al
                _do_not_inc_%d: ; the dynamic hash will always be bigger than 0, the hash list is null terminated
                    mov esi, {{hash_list_{format_spec_char}}}
                _hash_check_loop_%d:
                    cmp byte[esi], 0 ; the end of the list has been reached
                    je 0x41414141
                    cmp byte[esi], al ; esi points to the hash list
                    je _restore_printfcheck_%d
                    inc esi
                    jmp _hash_check_loop_%d

            _restore_printfcheck_%d:
                pop eax
                pop esi

            _end_printfcheck_%d:
            """.format(
                stack_offset=(fmt_arg_pos + 1) * 4,
                stack_offset_2=(fmt_arg_pos + 2) * 4,
                flag_page=FLAG_PAGE,
                flag_page_almost_end=FLAG_PAGE + 0xffc,
                format_spec_char=ord(func_obj.format_spec_char),
            ) % tuple([pnum] * 18)

            patches.append(
                InsertCodePatch(func.addr,
                                check,
                                priority=250,
                                name="noflagprintf_%d" % pnum))
            l.info("function at %#08x protected" % func.addr)

        if patches:
            max_ro_addr = max(seg.max_addr for seg in self.ro_segments)
            patches.append(AddLabelPatch(max_ro_addr, name="max_ro_addr"))

        # print repr(self.hash_dict)
        for fspec in set(used_spec_chars):
            hash_list = b"".join(self.hash_dict[fspec]) + b"\x00"
            patches.append(
                AddRODataPatch(hash_list,
                               name="hash_list_{format_spec_char}".format(
                                   format_spec_char=ord(fspec))))
        # print "\n".join(map(str,patches))
        return patches