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