示例#1
0
    def calculate(self):

        # Level 1 threshold
        level_one_threshold = self.score_sum / 2**4
        # Level 2 threshold
        level_two_threshold = self.score_sum / 2**3
        # Level 3 threshold
        level_three_threshold = self.score_sum / 2**2
        # Level 4 threshold
        level_four_threshold = self.score_sum / 2**1
        # Level 5 threshold
        level_five_threshold = self.score_sum / 2**0

        total_weight = self.weight_sum

        if 0 <= total_weight <= level_one_threshold:
            return green(LEVEL_INFO.LOW.value)

        elif level_one_threshold < total_weight <= level_two_threshold:
            return green(LEVEL_INFO.LOW.value)

        elif level_two_threshold < total_weight <= level_three_threshold:
            return yellow(LEVEL_INFO.Moderate.value)

        elif level_three_threshold < total_weight <= level_four_threshold:
            return yellow(LEVEL_INFO.Moderate.value)

        elif level_four_threshold < total_weight <= level_five_threshold:
            return red(LEVEL_INFO.High.value)

        else:
            raise ValueError("Weight calculate failed")
示例#2
0
    def show_label_report(self, rule_path, all_labels, table_version):
        """
        Show the report based on label, last column represents max confidence for that label
        :param rule_path: the path where may be present the file label_desc.csv.
        :param all_labels: dictionary containing label:<array of confidence values associated to that label>
        :return: None
        """
        label_desc = {}
        # clear table to manage max/detail version
        self.quark_analysis.label_report_table.clear()
        if os.path.isfile(os.path.join(rule_path, "label_desc.csv")):
            # associate to each label a description
            col_list = ["label", "description"]
            # csv file on form <label,description>
            # put this file in the folder of rules (it must not be a json file since it could create conflict with management of rules)
            df = pd.read_csv(
                os.path.join(rule_path, "label_desc.csv"), usecols=col_list
            )
            label_desc = dict(zip(df["label"], df["description"]))

        for label_name in all_labels:
            confidences = np.array(all_labels[label_name])

            if table_version == "max":
                self.quark_analysis.label_report_table.field_names = [
                    "Label",
                    "Description",
                    "Number of rules",
                    "MAX Confidence %",
                ]
                self.quark_analysis.label_report_table.add_row(
                    [
                        green(label_name),
                        yellow(label_desc.get(label_name, "-")),
                        (len(confidences)),
                        red(np.max(confidences)),
                    ]
                )
            else:
                self.quark_analysis.label_report_table.field_names = [
                    "Label",
                    "Description",
                    "Number of rules",
                    "MAX Confidence %",
                    "AVG Confidence",
                    "Std Deviation",
                    "# of Rules with Confidence >= 80%",
                ]
                self.quark_analysis.label_report_table.add_row(
                    [
                        green(label_name),
                        yellow(label_desc.get(label_name, "-")),
                        (len(confidences)),
                        red(np.max(confidences)),
                        magenta(round(np.mean(confidences), 2)),
                        lightblue(round(np.std(confidences), 2)),
                        lightyellow(np.count_nonzero(confidences >= 80)),
                    ]
                )
示例#3
0
    def analyze_multi_file(self, path):

        if not os.path.isdir(path):
            tqdm.write(red(f"[*] Error: Given path is not a directory: {path}"))
            return

        file_count = sum(len(files) for _, _, files in os.walk(path))

        progress_bar = tqdm(total=file_count)
        for root, dirs, files in os.walk(path):  # Walk the directory
            for name in files:

                file_path = os.path.join(root, name)

                try:
                    result = self.analyze_single_file(file_path)
                    progress_bar.update(1)  # Increment the progress bar

                    # All API keys are unavailable
                    if result == -1:
                        return

                    if not result:
                        continue

                    # Found positives file
                    if result > 0:
                        tqdm.write(green(f"[*] Found positives file: {file_path}"))

                except Exception as e:
                    tqdm.write(yellow(f"[WARN] Exception found: {e.message}"))
                    continue

        progress_bar.close()

        # Retrieve the file report from waiting queue
        tqdm.write(f"[*] Start to retrieve file report from waiting queue")
        for file_md5 in tqdm(self.waiting_queue):

            try:
                report = self.retreive_report(file_md5)

                if not report:
                    tqdm.write(red(f"[*] ERROR: All API keys are unavailable"))
                    return -1

                if report["response_code"] == 1:
                    self.reports[file_md5] = report["positives"]

            except Exception as e:
                tqdm.write(yellow(f"[WARN] Exception found: {e.message}"))
                continue
    def check_progress(self):

        apk_status = self.db.get_progress_status(self.apk.id)

        if not apk_status:
            print(colors.yellow("wait for a second then check"))
            return False
        if apk_status == 1:
            print("{} as known as {} has done analysis!".format(
                colors.yellow(self.apk.name), self.apk.id))
            return False
        elif apk_status == 4:
            print("{} as known as {} is failed parsing!".format(
                colors.yellow(self.apk.name), self.apk.id))
            return False

        return True
示例#5
0
    def add_table_row(self, rule_obj, confidence, score, weight):

        self.quark_analysis.summary_report_table.add_row([
            green(rule_obj.crime),
            yellow(confidence),
            score,
            red(weight),
        ])
示例#6
0
    def show_summary_report(self, rule_obj):
        """
        Show the summary report.

        :param rule_obj: the instance of the RuleObject.
        :return: None
        """
        # Count the confidence
        confidence = str(rule_obj.check_item.count(True) * 20) + "%"
        conf = rule_obj.check_item.count(True)
        weight = rule_obj.get_score(conf)
        score = rule_obj.yscore

        self.tb.add_row([green(rule_obj.crime), yellow(
            confidence), score, red(weight)])

        # add the weight
        self.weight_sum += weight
        # add the score
        self.score_sum += score
示例#7
0
def print_warning(message):
    print(bold(yellow("[!]")) + f" WARNING: {message}")
示例#8
0
def print_warning(message):
    print(bold(yellow("[!]")) + " WARNING: {0}".format(message))
示例#9
0
def entry_point(
    summary,
    detail,
    apk,
    rule,
    output,
    graph,
    classification,
    threshold,
    list,
    permission,
    label,
):
    """Quark is an Obfuscation-Neglect Android Malware Scoring System"""

    # Load APK
    data = Quark(apk)

    # Load rules
    rules_list = [x for x in os.listdir(rule) if x.endswith("json")]

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

        for single_rule in tqdm(rules_list):
            rulepath = os.path.join(rule, single_rule)
            rule_checker = QuarkRule(rulepath)
            # 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 = 0
        for single_label in all_labels:
            if max(all_labels[single_label]) >= 80:
                counter_high_confidence += 1

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

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

    # Show summary report
    if summary:

        if summary == "all_rules":
            label_flag = False
        elif summary.endswith("json"):
            rules_list = [summary]
            label_flag = False
        else:
            label_flag = True

        for single_rule in tqdm(rules_list):
            rulepath = os.path.join(rule, single_rule)
            rule_checker = QuarkRule(rulepath)

            labels = rule_checker._label
            if label_flag:
                if summary not in labels:
                    continue

            # 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("Total Score: " + str(data.quark_analysis.score_sum))
        print(data.quark_analysis.summary_report_table)

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

    # Show detail report
    if detail:

        if detail == "all_rules":
            label_flag = False
        elif detail.endswith("json"):
            rules_list = [detail]
            label_flag = False
        else:
            label_flag = True

        for single_rule in tqdm(rules_list):
            rulepath = os.path.join(rule, single_rule)
            rule_checker = QuarkRule(rulepath)

            labels = rule_checker._label
            if label_flag:
                if detail not in labels:
                    continue

            # Run the checker
            data.run(rule_checker)

            print("Rulepath: " + rulepath)
            print("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()

    # Show JSON report
    if output:

        for single_rule in tqdm(rules_list):
            rulepath = os.path.join(rule, single_rule)
            rule_checker = QuarkRule(rulepath)

            # 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()

    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)