Exemple #1
0
    def btn_get_one_sink_func_xref(self, code=0):
        """
        查看某个危险函数调用地址
        """

        tgt_t = ida_kernwin.ask_str('', 0, '请输入要查看的危险函数名')
        if tgt_t in SINK_FUNC:
            cols = [['', 0 | ida_kernwin.Choose.CHCOL_DEC],
                    ['函数名', 10 | ida_kernwin.Choose.CHCOL_PLAIN],
                    ['函数地址', 10 | ida_kernwin.Choose.CHCOL_HEX]]
            items = []

            mgr_t = FESinkFuncMgr()
            xref_list = mgr_t.get_one_func_xref(tgt_t)

            if not xref_list:
                FELogger.warn("未找到函数%s" % tgt_t)
                return

            tmp_list = []
            for xref_addr in xref_list:
                data = AnalysisChooseData(vuln=0, name=tgt_t, ea=xref_addr)
                items.append(data)
                tmp_list.append(xref_addr)
            self.sink_func_xref_dict[tgt_t] = tmp_list

            chooser = AnalysisChooser(title='危险函数调用地址', cols=cols, item=items)
            chooser.Show()
        else:
            FELogger.warn("未支持函数")
    def btn_func_xref_count(self, code=0):
        """
        函数调用次数统计
        """
        xref_count_dict = OrderedDict()
        for func_addr_t in idautils.Functions():
            count = len(list(idautils.CodeRefsTo(func_addr_t, 0)))
            xref_count_dict[ida_funcs.get_func_name(func_addr_t)] = [
                func_addr_t, count
            ]
        ordered_list = sorted(list(xref_count_dict.items()),
                              key=lambda x: x[1][1],
                              reverse=True)

        cols = [['', 0 | ida_kernwin.Choose.CHCOL_DEC],
                ['函数名', 15 | ida_kernwin.Choose.CHCOL_PLAIN],
                ['地址', 10 | ida_kernwin.Choose.CHCOL_HEX],
                ['次数', 10 | ida_kernwin.Choose.CHCOL_PLAIN]]
        items = []

        for x in ordered_list:
            data = AnalysisChooseData(vuln=0,
                                      name=x[0],
                                      ea=x[1][0],
                                      other1=str(x[1][1]))
            items.append(data)

        chooser = AnalysisChooser(title='函数调用次数统计', cols=cols, item=items)
        chooser.Show()
Exemple #3
0
def system_func_analysis(func_name, xref_list):
    """
    system系列函数漏洞分析    
    """

    vuln_flag = 0
    addr1 = 0
    str1 = ''

    func_name_t = func_name
    xref_list_t = xref_list
    items = []
    vuln_rule = SINK_FUNC[func_name_t]['vuln_rule']
    vuln_reg = vuln_rule[0]['vuln_regs'][0]

    FELogger.info('检测%s漏洞' % vuln_rule[0]['vuln_type'])
    for xref_addr_t in xref_list_t:
        FELogger.info("从%s回溯来源地址%s" % (hexstr(xref_addr_t), vuln_reg))
        tracer = FEArgsTracer(xref_addr_t, vuln_reg)
        source_addr = tracer.run()
        print('source_addr: ', source_addr)
        # 判断是否找到目标地址
        if source_addr == []:
            FELogger.info("目标地址未找到%s" % hexstr(xref_addr_t))
            vuln_flag = 1
        else:
            for cmd_addr in source_addr:
                addr1 = cmd_addr
                # 判断字符串是否来自内存
                if idc.get_operand_type(cmd_addr, 1) == ida_ua.o_mem:
                    cmd_str = FEStrMgr.get_mem_string(cmd_addr)
                    # 判断是否找到字符串
                    if cmd_str == []:
                        FELogger.info("硬编码命令未找到%s" % hexstr(xref_addr_t))
                        vuln_flag = 1
                    else:
                        vuln_flag = 0
                        str1 = cmd_str[0]
                else:
                    FELogger.info("命令来自外部%s" % hexstr(xref_addr_t))
                    vuln_flag = 1

        data = AnalysisChooseData(vuln=vuln_flag,
                                  name=func_name_t,
                                  ea=xref_addr_t,
                                  addr1=addr1,
                                  str1=str1)
        items.append(data)
    return items
Exemple #4
0
    def btn_get_sink_func_addr(self, code=0):
        """
        查看危险函数地址列表
        """
        cols = [['', 0 | ida_kernwin.Choose.CHCOL_DEC],
                ['函数名', 10 | ida_kernwin.Choose.CHCOL_PLAIN],
                ['函数地址', 10 | ida_kernwin.Choose.CHCOL_HEX]]
        items = []

        mgr_t = FESinkFuncMgr()
        for func_name, func_addr in mgr_t.gen_sink_func_addr():
            data = AnalysisChooseData(vuln=0, name=func_name, ea=func_addr)
            items.append(data)

        chooser = AnalysisChooser(title='危险函数地址', cols=cols, item=items)
        chooser.Show()
Exemple #5
0
    def check_src_reg(xref_addr_t, src_reg, siz_addr_t=0):
        vuln_flag = 0
        addr1 = 0
        str1 = ''

        if siz_addr_t == 0:
            str_siz_addr = ''
        else:
            str_siz_addr = hexstr(siz_addr_t)

        FELogger.info("从%s回溯来源地址%s" % (hexstr(xref_addr_t), src_reg))
        src_tracer = FEArgsTracer(xref_addr_t, src_reg)
        src_source_addr = src_tracer.run()
        print('src_source_addr: ', src_source_addr)
        # 判断是否找到字符串来源地址
        if src_source_addr == []:
            FELogger.info("未找到目标地址%s" % hexstr(xref_addr_t))
            vuln_flag = 1
        else:
            for src_addr in src_source_addr:
                addr1 = src_addr
                src_str = FEStrMgr.get_mem_string(src_addr)
                # 判断是否找到字符串
                if src_str == []:
                    FELogger.info('来源字符串未找到%s' % hexstr(xref_addr_t))
                    vuln_flag = 1
                else:
                    # 判断来源地址是否为内存
                    str1 = src_str[0]
                    if idc.get_operand_type(src_addr, 1) != ida_ua.o_mem:
                        vuln_flag = 1
                    else:
                        vuln_flag = 0

        data = AnalysisChooseData(vuln=vuln_flag,
                                  name=func_name_t,
                                  ea=xref_addr_t,
                                  addr1=addr1,
                                  str1=str1,
                                  other1=str_siz_addr)
        items.append(data)
Exemple #6
0
    def btn_get_all_sink_func_xref(self, code=0):
        """
        查看所有危险函数调用地址
        """

        cols = [['', 0 | ida_kernwin.Choose.CHCOL_DEC],
                ['函数名', 10 | ida_kernwin.Choose.CHCOL_PLAIN],
                ['函数地址', 10 | ida_kernwin.Choose.CHCOL_HEX]]
        items = []

        mgr_t = FESinkFuncMgr()
        for func_name, xref_list in mgr_t.gen_sink_func_xref():
            tmp_list = []
            for xref_addr in xref_list:
                data = AnalysisChooseData(vuln=0, name=func_name, ea=xref_addr)
                items.append(data)
                tmp_list.append(xref_addr)
            self.sink_func_xref_dict[func_name] = tmp_list

        chooser = AnalysisChooser(title='危险函数调用地址', cols=cols, item=items)
        chooser.Show()
Exemple #7
0
    def check_fmt_reg(xref_addr_t,
                      fmt_reg,
                      vuln_regs,
                      siz_addr_t=0,
                      parse=False):
        vuln_flag = 0
        addr1 = 0
        str1 = ''

        if siz_addr_t == 0:
            str_siz_addr = ''
        else:
            str_siz_addr = hexstr(siz_addr_t)

        FELogger.info("从%s回溯格式字符串%s" % (hexstr(xref_addr_t), fmt_reg))
        tracer = FEArgsTracer(xref_addr_t, fmt_reg)
        source_addr = tracer.run()
        print('source_addr: ', source_addr)
        # 判断是否找到字符串来源地址
        if source_addr == []:
            FELogger.info("未找到目标地址%s" % hexstr(xref_addr_t))
            vuln_flag = 1
        else:
            for fmt_addr in source_addr:
                addr1 = fmt_addr
                fmt_str = FEStrMgr.get_mem_string(fmt_addr)
                # 判断是否找到字符串
                if fmt_str == []:
                    FELogger.info('格式字符串未找到%s' % hexstr(xref_addr_t))
                    vuln_flag = 1
                    str1 = ''
                else:
                    FELogger.info('找到格式字符串%s' % hexstr(xref_addr_t))
                    str1 = fmt_str[0]
                    if parse == False:
                        vuln_flag = 0
                    else:
                        fmt_list = FEStrMgr.parse_format_string(str1)
                        # 判断字符串中的格式字符
                        if fmt_list != [] and 's' in ''.join(fmt_list):
                            if vuln_regs[-1] == '...':
                                args_num = len(fmt_list) + len(vuln_regs) - 1
                                if args_num > 4:
                                    fmt_list = fmt_list[:(
                                        4 - (len(vuln_regs) - 1))]

                                for idx in range(len(fmt_list)):
                                    if 's' in fmt_list[idx]:
                                        str_reg = 'R%s' % (len(vuln_regs) - 1 +
                                                           idx)
                                        FELogger.info(
                                            "从%s回溯字符串%s" %
                                            (hexstr(xref_addr_t), str_reg))
                                        str_tracer = FEArgsTracer(xref_addr_t,
                                                                  str_reg,
                                                                  max_node=256)
                                        str_source_addr = str_tracer.run()
                                        print('str_source_addr: ',
                                              str_source_addr)
                                        if str_source_addr == []:
                                            FELogger.info("未找到%s字符串地址" %
                                                          str_reg)
                                            vuln_flag = 1
                                            break
                                        else:
                                            for str_addr in str_source_addr:
                                                if idc.get_operand_type(
                                                        str_addr,
                                                        1) == ida_ua.o_mem:
                                                    vuln_flag = 0
                                                else:
                                                    vuln_flag = 1
                                                    break
                                    else:
                                        continue
                            else:
                                vuln_flag = 1
                        else:
                            FELogger.info("格式字符串不包含s转换符号")
                            vuln_flag = 0

        data = AnalysisChooseData(vuln=vuln_flag,
                                  name=func_name_t,
                                  ea=xref_addr_t,
                                  addr1=addr1,
                                  str1=str1,
                                  other1=str_siz_addr)
        items.append(data)
Exemple #8
0
def printf_func_analysis(func_name, xref_list):
    """
    printf系列函数漏洞分析
    """
    def check_fmt_reg(xref_addr_t,
                      fmt_reg,
                      vuln_regs,
                      siz_addr_t=0,
                      parse=False):
        vuln_flag = 0
        addr1 = 0
        str1 = ''

        if siz_addr_t == 0:
            str_siz_addr = ''
        else:
            str_siz_addr = hexstr(siz_addr_t)

        FELogger.info("从%s回溯格式字符串%s" % (hexstr(xref_addr_t), fmt_reg))
        tracer = FEArgsTracer(xref_addr_t, fmt_reg)
        source_addr = tracer.run()
        print('source_addr: ', source_addr)
        # 判断是否找到字符串来源地址
        if source_addr == []:
            FELogger.info("未找到目标地址%s" % hexstr(xref_addr_t))
            vuln_flag = 1
        else:
            for fmt_addr in source_addr:
                addr1 = fmt_addr
                fmt_str = FEStrMgr.get_mem_string(fmt_addr)
                # 判断是否找到字符串
                if fmt_str == []:
                    FELogger.info('格式字符串未找到%s' % hexstr(xref_addr_t))
                    vuln_flag = 1
                    str1 = ''
                else:
                    FELogger.info('找到格式字符串%s' % hexstr(xref_addr_t))
                    str1 = fmt_str[0]
                    if parse == False:
                        vuln_flag = 0
                    else:
                        fmt_list = FEStrMgr.parse_format_string(str1)
                        # 判断字符串中的格式字符
                        if fmt_list != [] and 's' in ''.join(fmt_list):
                            if vuln_regs[-1] == '...':
                                args_num = len(fmt_list) + len(vuln_regs) - 1
                                if args_num > 4:
                                    fmt_list = fmt_list[:(
                                        4 - (len(vuln_regs) - 1))]

                                for idx in range(len(fmt_list)):
                                    if 's' in fmt_list[idx]:
                                        str_reg = 'R%s' % (len(vuln_regs) - 1 +
                                                           idx)
                                        FELogger.info(
                                            "从%s回溯字符串%s" %
                                            (hexstr(xref_addr_t), str_reg))
                                        str_tracer = FEArgsTracer(xref_addr_t,
                                                                  str_reg,
                                                                  max_node=256)
                                        str_source_addr = str_tracer.run()
                                        print('str_source_addr: ',
                                              str_source_addr)
                                        if str_source_addr == []:
                                            FELogger.info("未找到%s字符串地址" %
                                                          str_reg)
                                            vuln_flag = 1
                                            break
                                        else:
                                            for str_addr in str_source_addr:
                                                if idc.get_operand_type(
                                                        str_addr,
                                                        1) == ida_ua.o_mem:
                                                    vuln_flag = 0
                                                else:
                                                    vuln_flag = 1
                                                    break
                                    else:
                                        continue
                            else:
                                vuln_flag = 1
                        else:
                            FELogger.info("格式字符串不包含s转换符号")
                            vuln_flag = 0

        data = AnalysisChooseData(vuln=vuln_flag,
                                  name=func_name_t,
                                  ea=xref_addr_t,
                                  addr1=addr1,
                                  str1=str1,
                                  other1=str_siz_addr)
        items.append(data)

    func_name_t = func_name
    xref_list_t = xref_list
    items = []
    vuln_rule = SINK_FUNC[func_name_t]['vuln_rule']
    args_rule = SINK_FUNC[func_name_t]['args_rule']
    for xref_addr_t in xref_list_t:
        for rule in vuln_rule:
            FELogger.info('检测%s漏洞' % rule['vuln_type'])

            if rule['vuln_type'] == 'format_string':
                fmt_reg = rule['vuln_regs'][0]
                check_fmt_reg(xref_addr_t, fmt_reg, args_rule, parse=False)
            else:
                vuln_regs = rule['vuln_regs']
                if vuln_regs[-1] == '...':
                    fmt_reg = vuln_regs[-2]
                    if len(vuln_regs) == 3:
                        siz_reg = vuln_regs[0]
                    else:
                        siz_reg = None
                else:
                    fmt_reg = vuln_regs[-1]
                    if len(vuln_regs) == 2:
                        siz_reg = vuln_regs[0]
                    else:
                        siz_reg = None

                # 判断是否有size参数
                if siz_reg != None:
                    FELogger.info("从%s回溯字符串长度%s" %
                                  (hexstr(xref_addr_t), siz_reg))
                    siz_tracer = FEArgsTracer(xref_addr_t,
                                              siz_reg,
                                              max_node=256)
                    siz_source_addr = siz_tracer.run()
                    print('siz_source_addr: ', siz_source_addr)
                    # 判断是否找到size的地址
                    if siz_source_addr == []:
                        FELogger.info("未找到size地址%s" % hexstr(xref_addr_t))
                        check_fmt_reg(xref_addr_t,
                                      fmt_reg,
                                      args_rule,
                                      parse=True)
                    else:
                        for siz_addr_t in siz_source_addr:
                            # 判断size是否为立即数
                            if idc.get_operand_type(siz_addr_t,
                                                    1) != ida_ua.o_imm:
                                check_fmt_reg(xref_addr_t,
                                              fmt_reg,
                                              args_rule,
                                              siz_addr_t,
                                              parse=True)
                            else:
                                num = idc.print_operand(siz_addr_t, 1)
                                data = AnalysisChooseData(vuln=0,
                                                          name=func_name_t,
                                                          ea=xref_addr_t,
                                                          addr1=siz_addr_t,
                                                          str1='',
                                                          other1=num)
                                items.append(data)
                else:
                    check_fmt_reg(xref_addr_t, fmt_reg, args_rule, parse=True)
    return items
Exemple #9
0
def str_func_analysis(func_name, xref_list):
    """
    str操作类函数漏洞分析
    """
    def check_src_reg(xref_addr_t, src_reg, siz_addr_t=0):
        vuln_flag = 0
        addr1 = 0
        str1 = ''

        if siz_addr_t == 0:
            str_siz_addr = ''
        else:
            str_siz_addr = hexstr(siz_addr_t)

        FELogger.info("从%s回溯来源地址%s" % (hexstr(xref_addr_t), src_reg))
        src_tracer = FEArgsTracer(xref_addr_t, src_reg)
        src_source_addr = src_tracer.run()
        print('src_source_addr: ', src_source_addr)
        # 判断是否找到字符串来源地址
        if src_source_addr == []:
            FELogger.info("未找到目标地址%s" % hexstr(xref_addr_t))
            vuln_flag = 1
        else:
            for src_addr in src_source_addr:
                addr1 = src_addr
                src_str = FEStrMgr.get_mem_string(src_addr)
                # 判断是否找到字符串
                if src_str == []:
                    FELogger.info('来源字符串未找到%s' % hexstr(xref_addr_t))
                    vuln_flag = 1
                else:
                    # 判断来源地址是否为内存
                    str1 = src_str[0]
                    if idc.get_operand_type(src_addr, 1) != ida_ua.o_mem:
                        vuln_flag = 1
                    else:
                        vuln_flag = 0

        data = AnalysisChooseData(vuln=vuln_flag,
                                  name=func_name_t,
                                  ea=xref_addr_t,
                                  addr1=addr1,
                                  str1=str1,
                                  other1=str_siz_addr)
        items.append(data)

    func_name_t = func_name
    xref_list_t = xref_list
    items = []
    vuln_rule = SINK_FUNC[func_name_t]['vuln_rule']
    vuln_regs = vuln_rule[0]['vuln_regs']
    src_reg = vuln_regs[0]
    siz_reg = None
    if len(vuln_regs) == 2:
        siz_reg = vuln_regs[1]

    FELogger.info('检测%s漏洞' % vuln_rule[0]['vuln_type'])
    for xref_addr_t in xref_list_t:
        # 判断是否有size参数
        if siz_reg != None:
            FELogger.info("从%s回溯字符串长度%s" % (hexstr(xref_addr_t), siz_reg))
            siz_tracer = FEArgsTracer(xref_addr_t, siz_reg, max_node=256)
            siz_source_addr = siz_tracer.run()
            print('siz_source_addr: ', siz_source_addr)
            # 判断是否找到size的地址
            if siz_source_addr == []:
                FELogger.info("未找到size地址%s" % hexstr(xref_addr_t))
                data = AnalysisChooseData(vuln=1,
                                          name=func_name_t,
                                          ea=xref_addr_t)
                items.append(data)
            else:
                for siz_addr_t in siz_source_addr:
                    # 判断size是否为立即数
                    if idc.get_operand_type(siz_addr_t, 1) != ida_ua.o_imm:
                        check_src_reg(xref_addr_t, src_reg, siz_addr_t)
                    else:
                        num = idc.print_operand(siz_addr_t, 1)
                        data = AnalysisChooseData(vuln=0,
                                                  name=func_name_t,
                                                  ea=xref_addr_t,
                                                  addr1=siz_addr_t,
                                                  str1='',
                                                  other1=num)
                        items.append(data)
        else:
            check_src_reg(xref_addr_t, src_reg)
    return items