Пример #1
0
def tasklog(req, task_id):
    task = ScanTask.objects.filter(id=task_id).first()
    visit_token = ""

    if 'token' in req.GET:
        visit_token = req.GET['token']

    # check task是否存在
    if not task:
        return redirect("dashboard:tasks_list")

    # check task 的状态,只有完成才能继续
    if not task.is_finished:
        return HttpResponse(
            "Ooooops, Maybe this task still in progress or has error, you can't view the log..."
        )

    project_id = get_and_check_scantask_project_id(task_id)

    srts = get_and_check_scanresult(task_id).objects.filter(
        scan_project_id=project_id)
    nefs = NewEvilFunc.objects.filter(project_id=project_id)

    ResultFlow = get_resultflow_class(task_id)
    rfs = ResultFlow.objects.all()

    task.parameter_config = " ".join(ast.literal_eval(
        task.parameter_config)).replace('\\', '/')
    resultflowdict = {}

    for rf in rfs:
        if rf.vul_id not in resultflowdict:
            resultflowdict[rf.vul_id] = {
                'id': rf.vul_id,
                'flow': [],
            }

        rfdict = {
            'type': rf.node_type,
            'content': rf.node_content,
            'path': rf.node_path,
            'lineno': rf.node_lineno,
            'details': rf.node_source
        }

        resultflowdict[rf.vul_id]['flow'].append(rfdict)

    # 扫描结果
    data = {
        "task": task,
        "taskresults": srts,
        "newevilfuncs": nefs,
        "resultflowdict": resultflowdict,
        'visit_token': visit_token
    }
    return render(req, 'backend/tasklog.html', data)
Пример #2
0
def tasklog(req, task_id):
    task = ScanTask.objects.filter(id=task_id).first()

    # check task是否存在
    if not task:
        return redirect("dashboard:tasks_list")

    # check task 的状态,只有完成才能继续
    if not task.is_finished:
        return HttpResponse(
            "Ooooops, Maybe this task still in progress or has error, you can't view the log..."
        )

    srts = ScanResultTask.objects.filter(scan_task_id=task_id)
    nefs = NewEvilFunc.objects.filter(scan_task_id=task_id)

    ResultFlow = get_resultflow_class(task_id)
    rfs = ResultFlow.objects.all()

    resultflowdict = {}

    for rf in rfs:
        if rf.vul_id not in resultflowdict:
            resultflowdict[rf.vul_id] = {
                'id': rf.vul_id,
                'flow': [],
            }

        rfdict = {
            'type': rf.node_type,
            'content': rf.node_content,
            'path': rf.node_path,
            'lineno': rf.node_lineno,
            'details': show_context(rf.node_path, rf.node_lineno)
        }

        resultflowdict[rf.vul_id]['flow'].append(rfdict)

    # 扫描结果
    data = {
        "task": task,
        "taskresults": srts,
        "newevilfuncs": nefs,
        "resultflowdict": resultflowdict,
    }
    return render(req, 'backend/tasklog.html', data)
Пример #3
0
def check_and_save_result(task_id, language, vendor_name, vendor_version):
    """
    检查并保存结果。
    :param vendor_name:
    :param vendor_version:
    :return:
    """
    vvs = get_vendor_vul_by_name(vendor_name.strip())
    # vendor_version = abstract_version(vendor_version)
    result_list = []

    for vv in vvs:
        vv_affect_version = vv.affected_versions.split(',')

        if not vendor_version or vendor_version in vv_affect_version:

            if task_id:
                sr = check_update_or_new_scanresult(
                    scan_task_id=task_id,
                    cvi_id=VENDOR_CVIID,
                    language=language,
                    vulfile_path="VendorVul:{}".format(vv.id),
                    source_code="{}".format(vv.reference[:180]),
                    result_type=vendor_source_match,
                    is_unconfirm=False,
                    is_active=True
                )
                #  save into get_resultflow_class
                ResultFlow = get_resultflow_class(int(task_id))

                if sr:
                    node_source = vv.description
                    rf = ResultFlow(vul_id=sr.id, node_type='sca_scan',
                                    node_content=vv.title, node_path=vv.reference[:280],
                                    node_source=node_source, node_lineno=0)
                    rf.save()

            else:
                result_list.append(vv)

    return result_list
Пример #4
0
    def get(request, task_id):
        scantask = ScanTask.objects.filter(id=task_id).first()

        if not scantask.is_finished:
            return JsonResponse({
                "code":
                403,
                "status":
                False,
                "message":
                "Task {} not finished.".format(task_id)
            })

        ResultFlow = get_resultflow_class(int(task_id))
        rfs = ResultFlow.objects.filter().order_by('vul_id')

        resultflow_list = list(rfs.values())
        return JsonResponse({
            "code": 200,
            "status": True,
            "message": resultflow_list
        })
Пример #5
0
def check_scantask(task_name, target_path, parameter_config, project_origin, project_des="", auto_yes=False):
    s = ScanTask.objects.filter(task_name=task_name, target_path=target_path, parameter_config=parameter_config, is_finished=1).order_by("-id").first()

    if s and not auto_yes:
        logger.warning("[INIT] ScanTask for {} has been executed.".format(task_name))
        logger.warning("[INIT] whether rescan Task {}?(Y/N) (Default N)".format(task_name))

        if input().lower() != 'y':
            logger.warning("[INIT] whether Show Last Scan Result?(Y/N) (Default Y)")

            if input().lower() != 'n':
                scan_id = s.id
                table = PrettyTable(
                    ['#', 'CVI', 'Rule(ID/Name)', 'Lang/CVE-id', 'Level', 'Target-File:Line-Number',
                     'Commit(Author)', 'Source Code Content', 'Analysis'])
                table.align = 'l'

                # check unconfirm
                logger.warning("[INIT] whether Show Unconfirm Result?(Y/N) (Default Y)")
                project_id = get_and_check_scantask_project_id(scan_id)
                logger.info("[INIT] Now Project ID is {}".format(project_id))

                if input().lower() != 'n':
                    srs = get_and_check_scanresult(scan_id).objects.filter(scan_project_id=project_id, is_active=True)
                else:
                    srs = get_and_check_scanresult(scan_id).objects.filter(scan_project_id=project_id, is_active=True, is_unconfirm=False)

                if srs:
                    logger.info("[MainThread] Last Scan id {} Result: ".format(scan_id))

                    for sr in srs:
                        rule = Rules.objects.filter(svid=sr.cvi_id).first()
                        rule_name = rule.rule_name
                        author = rule.author
                        level = VUL_LEVEL[rule.level]

                        row = [sr.result_id, sr.cvi_id, rule_name, sr.language, level, sr.vulfile_path,
                               author, sr.source_code, sr.result_type]

                        table.add_row(row)

                        # show Vuls Chain
                        ResultFlow = get_resultflow_class(scan_id)
                        rfs = ResultFlow.objects.filter(vul_id=sr.id)

                        logger.info("[Chain] Vul {}".format(sr.id))
                        for rf in rfs:
                            logger.info("[Chain] {}, {}, {}:{}".format(rf.node_type, rf.node_content, rf.node_path, rf.node_lineno))
                            show_context(rf.node_path, rf.node_lineno)

                        logger.info(
                            "[SCAN] ending\r\n -------------------------------------------------------------------------")

                    logger.info("[SCAN] Trigger Vulnerabilities ({vn})\r\n{table}".format(vn=len(srs), table=table))

                    # show New evil Function
                    nfs = NewEvilFunc.objects.filter(project_id=project_id, is_active=1)

                    if nfs:

                        table2 = PrettyTable(
                            ['#', 'NewFunction', 'OriginFunction', 'Related Rules id'])

                        table2.align = 'l'
                        idy = 1

                        for nf in nfs:
                            row = [idy, nf.func_name, nf.origin_func_name, nf.svid]

                            table2.add_row(row)
                            idy += 1

                        logger.info("[MainThread] New evil Function list by NewCore:\r\n{table}".format(table=table2))

                else:
                    logger.info("[MainThread] Last Scan id {} has no Result.".format(scan_id))

        else:
            s = ScanTask(task_name=task_name, target_path=target_path, parameter_config=parameter_config)
            s.save()

            # check and new project
            check_and_new_project_id(scantask_id=s.id, task_name=task_name, project_origin=project_origin, project_des=project_des)

    else:
        s = ScanTask(task_name=task_name, target_path=target_path, parameter_config=parameter_config)
        s.save()

        # check and new project
        check_and_new_project_id(s.id, task_name=task_name, project_origin=project_origin, project_des=project_des)

    return s
Пример #6
0
def scan(target_directory, a_sid=None, s_sid=None, special_rules=None, language=None, framework=None, file_count=0,
         extension_count=0, files=None, tamper_name=None, is_unconfirm=False):
    r = Rule(language)
    vulnerabilities = r.vulnerabilities
    rules = r.rules(special_rules)
    find_vulnerabilities = []
    newcore_function_list = {}

    def store(result):
        if result is not None and isinstance(result, list) is True:
            for res in result:
                res.file_path = res.file_path
                find_vulnerabilities.append(res)
        else:
            logger.debug('[SCAN] [STORE] Not found vulnerabilities on this rule!')

    async def start_scan(target_directory, rule, files, language, tamper_name):

        result = scan_single(target_directory, rule, files, language, tamper_name, is_unconfirm, newcore_function_list)
        store(result)

    if len(rules) == 0:
        logger.critical('no rules!')
        return False
    logger.info('[PUSH] {rc} Rules'.format(rc=len(rules)))
    push_rules = []
    scan_list = []

    for idx, single_rule in enumerate(sorted(rules.keys())):

        # init rule class
        r = getattr(rules[single_rule], single_rule)
        rule = r()

        if rule.status is False and len(rules) != 1:
            logger.info('[CVI_{cvi}] [STATUS] OFF, CONTINUE...'.format(cvi=rule.svid))
            continue
        # SR(Single Rule)
        logger.debug("""[PUSH] [CVI_{cvi}] {idx}.{vulnerability}({language})""".format(
            cvi=rule.svid,
            idx=idx,
            vulnerability=rule.vulnerability,
            language=rule.language
        ))
        # result = scan_single(target_directory, rule, files, language, tamper_name)
        scan_list.append(start_scan(target_directory, rule, files, language, tamper_name))
        # store(result)

    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.gather(*scan_list))

    loop.stop()

    # print
    data = []
    data2 = []
    table = PrettyTable(
        ['#', 'CVI', 'Rule(ID/Name)', 'Lang/CVE-id', 'Target-File:Line-Number',
         'Commit(Author)', 'Source Code Content', 'Analysis'])

    table.align = 'l'
    trigger_rules = []
    for idx, x in enumerate(find_vulnerabilities):
        trigger = '{fp}:{ln}'.format(fp=x.file_path, ln=x.line_number)
        commit = u'@{author}'.format(author=x.commit_author)
        try:
            code_content = x.code_content[:50].strip()
        except AttributeError as e:
            code_content = x.code_content.decode('utf-8')[:100].strip()
        row = [idx + 1, x.id, x.rule_name, x.language, trigger, commit,
               code_content.replace('\r\n', ' ').replace('\n', ' '), x.analysis]
        row2 = [idx + 1, x.chain]

        is_unconfirm_result = False
        if "unconfirmed" in x.analysis.lower():
            is_unconfirm_result = True

        # save to database
        sr = ScanResultTask(scan_task_id=a_sid, result_id=idx + 1, cvi_id=x.id, language=x.language,
                            vulfile_path=trigger, source_code=code_content.replace('\r\n', ' ').replace('\n', ' '),
                            result_type=x.analysis, is_unconfirm=is_unconfirm_result)

        sr.save()

        for chain in x.chain:
            if type(chain) == tuple:
                ResultFlow = get_resultflow_class(int(a_sid))
                rf = ResultFlow(vul_id=idx + 1, node_type=chain[0], node_content=chain[1],
                                node_path=chain[2], node_lineno=chain[3])
                rf.save()

        data.append(row)
        data2.append(row2)

        table.add_row(row)

        if x.id not in trigger_rules:
            logger.debug(' > trigger rule (CVI-{cvi})'.format(cvi=x.id))
            trigger_rules.append(x.id)

        # clear
        x.chain = ""

    diff_rules = list(set(push_rules) - set(trigger_rules))
    vn = len(find_vulnerabilities)
    if vn == 0:
        logger.info('[SCAN] Not found vulnerability!')
    else:
        logger.info("[SCAN] Trigger Rules: {tr} Vulnerabilities ({vn})\r\n{table}".format(tr=len(trigger_rules),
                                                                                          vn=len(find_vulnerabilities),
                                                                                          table=table))

        # 输出chain for all
        logger.info("[SCAN] Vulnerabilities Chain list: ")
        for d in data2:
            logger.info("[SCAN] Vul {}".format(d[0]))
            for c in d[1]:
                logger.info("[Chain] {}".format(c))
                if type(c) is not tuple:
                    continue
                show_context(c[2], c[3])

            logger.info("[SCAN] ending\r\n" + '-' * (shutil.get_terminal_size().columns - 16))

        if len(diff_rules) > 0:
            logger.info(
                '[SCAN] Not Trigger Rules ({l}): {r}'.format(l=len(diff_rules), r=','.join(diff_rules)))

    # show detail about newcore function list
    table2 = PrettyTable(
        ['#', 'NewFunction', 'OriginFunction', 'Related Rules id'])

    table2.align = 'l'
    idy = 0
    for new_function_name in newcore_function_list:
        # add new evil func in database
        for svid in newcore_function_list[new_function_name]["svid"]:
            if new_function_name:

                nf = NewEvilFunc(svid=svid, scan_task_id=get_scan_id(), func_name=new_function_name,
                                 origin_func_name=newcore_function_list[new_function_name]["origin_func_name"])
                nf.save()

        table2.add_row([idy + 1, new_function_name, newcore_function_list[new_function_name]["origin_func_name"], newcore_function_list[new_function_name]["svid"]])
        idy += 1

    if len(newcore_function_list) > 0:
        logger.info("[SCAN] New evil Function list by NewCore:\r\n{}".format(table2))

    # completed running data
    if s_sid is not None:
        Running(s_sid).data({
            'code': 1001,
            'msg': 'scan finished',
            'result': {
                'vulnerabilities': [x.__dict__ for x in find_vulnerabilities],
                'language': ",".join(language),
                'framework': framework,
                'extension': extension_count,
                'file': file_count,
                'push_rules': len(rules),
                'trigger_rules': len(trigger_rules),
                'target_directory': target_directory
            }
        })
    return True
Пример #7
0
def display_result(scan_id, is_ask=False):

    table = PrettyTable([
        '#', 'CVI', 'Rule(ID/Name)', 'Lang/CVE-id', 'Level',
        'Target-File:Line-Number', 'Commit(Author)', 'Source Code Content',
        'Analysis'
    ])
    table.align = 'l'

    # check unconfirm
    if is_ask:
        logger.warning(
            "[INIT] whether Show Unconfirm Result?(Y/N) (Default Y)")

    project_id = get_and_check_scantask_project_id(scan_id)

    if is_ask:
        if input().lower() != 'n':
            srs = get_and_check_scanresult(scan_id).objects.filter(
                scan_project_id=project_id, is_active=True)
        else:
            srs = get_and_check_scanresult(scan_id).objects.filter(
                scan_project_id=project_id, is_active=True, is_unconfirm=False)
    else:
        srs = get_and_check_scanresult(scan_id).objects.filter(
            scan_project_id=project_id, is_active=True, is_unconfirm=False)
    logger.info("[INIT] Project ID is {}".format(project_id))

    if srs:
        logger.info("[MainThread] Scan id {} Result: ".format(scan_id))

        for sr in srs:

            # for vendor scan
            if sr.cvi_id == '9999':
                vendor_vuls_id = int(sr.vulfile_path.split(':')[-1])
                vv = VendorVulns.objects.filter(id=vendor_vuls_id).first()

                if vv:
                    rule_name = vv.title
                    author = 'SCA'
                    level = VENDOR_VUL_LEVEL[int(vv.severity)]
                    # sr.source_code = vv.description
                else:
                    rule_name = 'SCA Scan'
                    author = 'SCA'
                    level = VENDOR_VUL_LEVEL[1]

            else:
                rule = Rules.objects.filter(svid=sr.cvi_id).first()
                rule_name = rule.rule_name
                author = rule.author
                level = VUL_LEVEL[rule.level]

            row = [
                sr.id, sr.cvi_id, rule_name, sr.language, level,
                sr.vulfile_path, author, sr.source_code, sr.result_type
            ]

            table.add_row(row)

            # show Vuls Chain
            ResultFlow = get_resultflow_class(scan_id)
            rfs = ResultFlow.objects.filter(vul_id=sr.id)

            logger.info("[Chain] Vul {}".format(sr.id))
            for rf in rfs:
                logger.info("[Chain] {}, {}, {}:{}".format(
                    rf.node_type, rf.node_content, rf.node_path,
                    rf.node_lineno))

                try:
                    if author == 'SCA':
                        continue

                    if not show_context(rf.node_path, rf.node_lineno):
                        logger_console.info(rf.node_source)
                except:
                    logger.error("[SCAN] Error: {}".format(
                        traceback.print_exc()))
                    continue

            logger.info(
                "[SCAN] ending\r\n -------------------------------------------------------------------------"
            )

        logger.info("[SCAN] Trigger Vulnerabilities ({vn})\r\n{table}".format(
            vn=len(srs), table=table))

        # show New evil Function
        nfs = NewEvilFunc.objects.filter(project_id=project_id, is_active=1)

        if nfs:

            table2 = PrettyTable(
                ['#', 'NewFunction', 'OriginFunction', 'Related Rules id'])

            table2.align = 'l'
            idy = 1

            for nf in nfs:
                row = [idy, nf.func_name, nf.origin_func_name, nf.svid]

                table2.add_row(row)
                idy += 1

            logger.info(
                "[MainThread] New evil Function list by NewCore:\r\n{table}".
                format(table=table2))

    else:
        logger.info("[MainThread] Scan id {} has no Result.".format(scan_id))