コード例 #1
0
ファイル: quark.py プロジェクト: quark-engine/quark-engine
 def show_call_graph(self, output_format=None):
     print_info("Creating Call Graph...")
     for (
         call_graph_analysis
     ) in self.quark_analysis.call_graph_analysis_list:
         call_graph(call_graph_analysis, output_format)
     print_success("Call Graph Completed")
コード例 #2
0
def entry_point():
    """
    The command-line entry point for freshquark. It will download the latest quark-rules.

    :return: None
    """
    print_info(f"Download the latest rules from {config.SOURCE}")
    download()
コード例 #3
0
ファイル: quark.py プロジェクト: haeter525/quark-engine
    def show_rule_classification(self):
        print_info("Rules Classification")

        data_bundle = get_rule_classification_data(
            self.quark_analysis.call_graph_analysis_list, MAX_SEARCH_LAYER)

        output_parent_function_table(data_bundle)
        output_parent_function_json(data_bundle)
        output_parent_function_graph(data_bundle)
コード例 #4
0
def test_print_info(capsys, bold_style, cyan_color):
    message = "message"

    print_info(message)

    output = capsys.readouterr().out
    if not sys.platform.startswith("win32"):
        assert bold_style in output
        assert cyan_color in output

    assert message in output
コード例 #5
0
ファイル: cli.py プロジェクト: haeter525/quark-engine
def entry_point(
    summary,
    detail,
    rule_generation,
    apk,
    rule,
    output,
    webreport,
    graph,
    classification,
    threshold,
    list,
    permission,
    label,
    comparison,
    core_library,
    num_of_process,
):
    """Quark is an Obfuscation-Neglect Android Malware Scoring System"""
    # Load rules
    rule_buffer_list = []
    rule_filter = summary or detail

    # Determine the location of rules
    if rule_filter and rule_filter.endswith("json"):
        if not os.path.isfile(rule_filter):
            print_warning(
                f"Specified rule not found.\n"
                f"If you want to specify one of the rules of Quark-Rule, "
                f"use {yellow(f'{config.DIR_PATH}/{rule_filter}')} "
                f"as an argument.")
            return

        rule_path_list = [rule_filter]
    else:
        rule_path_list = [
            os.path.join(dir_path, file)
            for dir_path, _, file_list in os.walk(rule) for file in file_list
            if file.endswith("json")
        ]

    # Load rules into memory
    update_rule_buffer(rule_buffer_list, rule_path_list)

    # Determine if the user provide a rule label
    if (rule_filter and rule_filter != "all_rules"
            and not rule_filter.endswith("json")):
        rule_checker_list = [
            rule_checker for rule_checker in rule_buffer_list
            if rule_filter in rule_checker.label
        ]
    else:
        rule_checker_list = rule_buffer_list

    if comparison:

        # selection of labels on which it will be done the comparison on radar chart
        # first look for all label found in the rule list
        all_labels = set()  # array type, e.g. ['network', 'collection']

        for rule_checker in rule_checker_list:
            all_labels.update(rule_checker.label)

        # let user choose a list of label on which it will be performed the analysis
        selected_label = np.array(
            select_label_menu(all_labels, min_labels=5, max_labels=15))

        # perform label based analysis on the apk_
        malware_confidences = {}
        for apk_ in apk:
            data = (ParallelQuark(apk_, core_library, num_of_process)
                    if num_of_process > 1 else Quark(apk_, core_library))
            all_labels = {}
            # dictionary containing
            # key: label
            # value: list of confidence values
            # $ print(all_rules["accessibility service"])
            # > [60, 40, 60, 40, 60, 40]

            # analyse malware only on rules where appears label selected
            rule_checker_list = [
                rule_checker for rule_checker in rule_buffer_list
                if len(np.intersect1d(rule_checker.label, selected_label)) != 0
            ]

            if num_of_process > 1:
                data.apply_rules(rule_checker_list)

            for rule_checker in tqdm(rule_checker_list):
                # Run the checker
                data.run(rule_checker)
                confidence = rule_checker.check_item.count(True) * 20
                labels = (rule_checker.label
                          )  # array type, e.g. ['network', 'collection']
                for single_label in labels:
                    if single_label in all_labels:
                        all_labels[single_label].append(confidence)
                    else:
                        all_labels[single_label] = [confidence]

            # extrapolate data used to plot radar chart
            radar_data = {}
            for _label in selected_label:
                confidences = np.array(all_labels[_label])
                # on radar data use the maximum confidence for a certain label
                radar_data[_label] = np.max(confidences)

            radar_confidence = [
                value_ for _label, value_ in radar_data.items()
            ]
            malware_confidences[apk_.split("/")[-1]] = radar_confidence

        show_comparison_graph(
            title=f"Malicious Actions Comparison Between {len(apk)} Malwares",
            lables=selected_label,
            malware_confidences=malware_confidences,
            font_size=22,
        )

        return

    # Load APK
    data = (ParallelQuark(apk[0], core_library, num_of_process)
            if num_of_process > 1 else Quark(apk[0], core_library))

    if label:
        all_labels = {}
        # dictionary containing
        # key: label
        # value: list of confidence values
        # $ print(all_rules["accessibility service"])
        # > [60, 40, 60, 40, 60, 40]

        if num_of_process > 1:
            data.apply_rules(rule_buffer_list)

        for rule_checker in tqdm(rule_buffer_list):
            # Run the checker
            data.run(rule_checker)
            confidence = rule_checker.check_item.count(True) * 20
            labels = (rule_checker.label
                      )  # array type, e.g. ['network', 'collection']
            for single_label in labels:
                if single_label in all_labels:
                    all_labels[single_label].append(confidence)
                else:
                    all_labels[single_label] = [confidence]

        # get how many label with max confidence >= 80%
        counter_high_confidence = sum(
            max(value) >= 80 for single_label, value in all_labels.items())

        print_info(f"Total Label found: {yellow(len(all_labels))}")
        print_info(
            f"Rules with label which max confidence >= 80%: {yellow(counter_high_confidence)}"
        )

        data.show_label_report(rule, all_labels, label)
        print(data.quark_analysis.label_report_table)

    # Show summary report
    if summary:

        if isinstance(data, ParallelQuark):
            data.apply_rules(rule_checker_list)

        for rule_checker in tqdm(rule_checker_list):
            # Run the checker
            data.run(rule_checker)

            data.show_summary_report(rule_checker, threshold)

        w = Weight(data.quark_analysis.score_sum,
                   data.quark_analysis.weight_sum)
        print_warning(w.calculate())
        print_info(f"Total Score: {data.quark_analysis.score_sum}")
        print(data.quark_analysis.summary_report_table)

        if classification:
            data.show_rule_classification()
        if graph:
            data.show_call_graph(graph)

    # Show detail report
    if detail:
        threshold_number = int(threshold) if threshold else 0

        if isinstance(data, ParallelQuark):
            data.apply_rules(rule_checker_list)

        for rule_checker in tqdm(rule_checker_list):
            # Run the checker
            data.run(rule_checker)

            confidence = rule_checker.check_item.count(True) * 20

            if confidence >= threshold_number:
                print(f"Rulepath: "
                      f"{os.path.join(rule, rule_checker.rule_filename)}")
                print(f"Rule crime: {rule_checker.crime}")
                data.show_detail_report(rule_checker)
                print_success("OK")

        if classification:
            data.show_rule_classification()
        if graph:
            data.show_call_graph()

    if rule_generation:
        generator = RuleGeneration(apk[0], rule_generation)

        if webreport:
            if ".html" not in webreport:
                webreport = f"{webreport}.html"
            webreport_file = os.path.join(rule_generation, webreport)
            generator.generate_rule(web_editor=webreport_file)
        else:
            generator.generate_rule()

    # Show JSON report
    if output:
        if isinstance(data, ParallelQuark):
            data.apply_rules(rule_buffer_list)

        for rule_checker in tqdm(rule_buffer_list):
            # Run the checker
            data.run(rule_checker)

            data.generate_json_report(rule_checker)

        json_report = data.get_json_report()

        with open(output, "w") as file:
            json.dump(json_report, file, indent=4)
            file.close()

    # Generate web report
    if webreport:
        if summary or detail:
            for rule_checker in tqdm(rule_buffer_list):
                data.generate_json_report(rule_checker)

            json_report = data.get_json_report()
            report_html = ReportGenerator(
                json_report).get_analysis_report_html()

            if ".html" not in webreport:
                webreport = f"{webreport}.html"

            with open(webreport, "w") as file:
                file.write(report_html)
                file.close()

    if list:

        if list == "all":
            for all_method in data.apkinfo.all_methods:
                print(all_method.full_name)
        if list == "native":
            for api in data.apkinfo.android_apis:
                print(api.full_name)
        if list == "custom":
            for custom_method in data.apkinfo.custom_methods:
                print(custom_method.full_name)

    if permission:

        for p in data.apkinfo.permissions:
            print(p)

    if isinstance(data, ParallelQuark):
        data.close()