Exemplo n.º 1
0
def output_parent_function_table(call_graph_analysis_list):
    dd = defaultdict(list)

    for item in call_graph_analysis_list:
        # print(item["parent"].class_name, item["parent"].name, item["crime"])
        key = f"{item['parent'].class_name}{item['parent'].name}"
        dd[key].append(item["crime"])

    # Pretty Table Output

    for parent, crimes in dd.items():
        tb = PrettyTable()
        tb.field_names = ["Parent Function", f"{green(parent)}"]
        tb.align = "l"

        count = 1

        for crime in crimes:
            if count == 1:
                tb.add_row(["Crime Description", red(f"{count}. {crime}")])
            else:
                tb.add_row(["", red(f"{count}. {crime}")])
            count += 1

        print(tb)
Exemplo n.º 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)),
                    ]
                )
Exemplo n.º 3
0
    def analyze_single_file(self, path):

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

        # Retreive file report
        tqdm.write(f"[*] Retrieved file scan report: {path}")
        file_md5 = self.get_file_md5(path)

        if file_md5 in self.reports:
            tqdm.write(green(f"[*] {file_md5} already retrieved report"))
            return self.reports[file_md5]

        report = self.retreive_report(file_md5)
        time.sleep(self.WAITING_TIME)

        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"]
            return report["positives"]

        # Upload file to VT
        tqdm.write(f"[*] Upload file: {path}")
        with open(path, "rb") as f:
            scan_result = self.scan_file(os.path.basename(path), f)
        time.sleep(self.WAITING_TIME)

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

        if scan_result["response_code"] == 0:
            tqdm.write(red(f"[*] ERROR: Failed to upload file: {path}"))
            return

        tqdm.write(f"[*] Retrieve file scan reports again")

        re_report = self.retreive_report(file_md5)
        time.sleep(self.WAITING_TIME)

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

        if re_report["response_code"] == 1:
            self.reports[file_md5] = report["positives"]
            return report["positives"]
        else:
            tqdm.write(f"[*] Unable to retrieve {file_md5}, add to waiting queue")
            self.waiting_queue.add(file_md5)
            return
Exemplo n.º 4
0
    def show_detail_report(self, rule_obj):
        """
        Show the detail report.

        :param rule_obj: the instance of the RuleObject.
        :return: None
        """

        # Count the confidence
        print("")
        print(f"Confidence: {rule_obj.check_item.count(True) * 20}%")
        print("")

        if rule_obj.check_item[0]:

            print(red(CHECK_LIST), end="")
            print(green(bold("1.Permission Request")), end="")
            print("")

            for permission in rule_obj.x1_permission:
                print(f"\t\t {permission}")
        if rule_obj.check_item[1]:
            print(red(CHECK_LIST), end="")
            print(green(bold("2.Native API Usage")), end="")
            print("")

            for api in self.quark_analysis.level_2_result:
                print(f"\t\t ({api.class_name}, {api.name})")
        if rule_obj.check_item[2]:
            print(red(CHECK_LIST), end="")
            print(green(bold("3.Native API Combination")), end="")

            print("")
            print(
                f"\t\t ({rule_obj.x2n3n4_comb[0]['class']}, {rule_obj.x2n3n4_comb[0]['method']})",
            )
            print(
                f"\t\t ({rule_obj.x2n3n4_comb[1]['class']}, {rule_obj.x2n3n4_comb[1]['method']})",
            )
        if rule_obj.check_item[3]:

            print(red(CHECK_LIST), end="")
            print(green(bold("4.Native API Sequence")), end="")

            print("")
            print(f"\t\t Sequence show up in:")
            for seq_method in self.quark_analysis.level_4_result:
                print(f"\t\t {seq_method.full_name}")
        if rule_obj.check_item[4]:

            print(red(CHECK_LIST), end="")
            print(green(bold("5.Native API Use Same Parameter")), end="")
            print("")
            for seq_operation in self.quark_analysis.level_5_result:
                print(f"\t\t {seq_operation.full_name}")
Exemplo n.º 5
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
Exemplo n.º 6
0
    def show_detail_report(self, rule_obj):
        """
        Show the detail report.

        :param rule_obj: the instance of the RuleObject.
        :return: None
        """

        # Count the confidence
        print("")
        print(f"Confidence: {rule_obj.check_item.count(True) * 20}%")
        print("")

        if rule_obj.check_item[0]:

            print(red(CHECK_LIST), end="")
            print(green(bold("1.Permission Request")), end="")
            print("")

            for permission in rule_obj.x1_permission:
                print("\t\t" + permission)
        if rule_obj.check_item[1]:
            print(red(CHECK_LIST), end="")
            print(green(bold("2.Native API Usage")), end="")
            print("")
            print("\t\t" + rule_obj.x2n3n4_comb[0]["method"])
        if rule_obj.check_item[2]:
            print(red(CHECK_LIST), end="")
            print(green(bold("3.Native API Combination")), end="")

            print("")
            print("\t\t" + rule_obj.x2n3n4_comb[0]["method"])
            print("\t\t" + rule_obj.x2n3n4_comb[1]["method"])
        if rule_obj.check_item[3]:

            print(red(CHECK_LIST), end="")
            print(green(bold("4.Native API Sequence")), end="")

            print("")
            print("\t\t" + "Sequence show up in:")
            for seq_methon in self.same_sequence_show_up:
                print("\t\t" + repr(seq_methon))
        if rule_obj.check_item[4]:

            print(red(CHECK_LIST), end="")
            print(green(bold("5.Native API Use Same Parameter")), end="")
            print("")
            for seq_operation in self.same_operation:
                print("\t\t" + repr(seq_operation))
Exemplo n.º 7
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 yel(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")
Exemplo n.º 8
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),
        ])
Exemplo n.º 9
0
def output_parent_function_table(rule_classification_data_bundle):
    dd = _convert_to_printable_dict(*rule_classification_data_bundle)

    # Pretty Table Output

    for parent, crimes in dd.items():
        tb = PrettyTable()
        tb.field_names = [
            "Parent Function",
            f"{green(parent)}",
        ]
        tb.align = "l"

        for count, crime in enumerate(set(crimes), start=1):
            if count == 1:
                tb.add_row(["Crime Description", red(f"* {crime}")])
            else:
                tb.add_row(["", red(f"* {crime}")])
        print(tb)
Exemplo n.º 10
0
    def change_api_key(self):
        tqdm.write(f"[*] {self.api_key} is unavailable, change another API key")
        self.api_keys_list[self.api_key] = False
        for api_key in self.api_keys_list:
            if self.api_keys_list[api_key]:
                self.api_key = api_key
                return True

        tqdm.write(red(f"[ERROR] There is no available api key"))
        return False
Exemplo n.º 11
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
Exemplo n.º 12
0
    def check_api_key_available(self):
        tqdm.write("[*] Check API keys available")

        for api_key in self.api_keys_list:
            try:
                params = {
                    "apikey": api_key,
                    "resource": "34efc3ebf51a6511c0d12cce7592db73",
                }
                res = requests.get(self.REPORT_URL, params)

                tqdm.write(f"API {api_key}: {res.status_code}")
                if res.status_code == 200:
                    self.api_keys_list[api_key] = True
                elif res.status_code == 403:
                    self.api_keys_list[api_key] = False
                elif res.status_code == 204:
                    self.api_keys_list[api_key] = False
                elif res.status_code == 400:
                    tqdm.write("Failed to check api key: Bad Request.")
            except Exception as e:
                tqdm.write(red(f"[ERROR] Failed to check api: {api_key}"))
                continue
Exemplo n.º 13
0
def print_error(message):
    print(bold(red("[!]")) + f" ERROR: {message}")
Exemplo n.º 14
0
def print_error(message):
    print(bold(red("[!]")) + " ERROR: {0}".format(message))