def testAPKIntentFilters(self): from androguard.core.bytecodes.apk import APK a = APK("examples/tests/a2dp.Vol_137.apk", testzip=True) activities = a.get_activities() receivers = a.get_receivers() services = a.get_services() filter_list = [] for i in activities: filters = a.get_intent_filters("activity", i) if len(filters) > 0: filter_list.append(filters) for i in receivers: filters = a.get_intent_filters("receiver", i) if len(filters) > 0: filter_list.append(filters) for i in services: filters = a.get_intent_filters("service", i) if len(filters) > 0: filter_list.append(filters) pairs = zip(filter_list, [{'action': ['android.intent.action.MAIN'], 'category': ['android.intent.category.LAUNCHER']}, {'action': ['android.service.notification.NotificationListenerService']}, {'action': ['android.intent.action.BOOT_COMPLETED', 'android.intent.action.MY_PACKAGE_REPLACED'], 'category': ['android.intent.category.HOME']}, {'action': ['android.appwidget.action.APPWIDGET_UPDATE']}]) self.assertTrue(any(x != y for x, y in pairs))
def test(app_path): if not app_path: return False if not os.path.exists(app_path): return False app_apk = APK(app_path) dvm = DalvikVMFormat(app_apk.get_dex()) receivers = app_apk.get_receivers() activities = app_apk.get_activities() services = app_apk.get_services() for activity in activities: if not check_class_in_dex(dvm, activity): return True for receiver in receivers: if not check_class_in_dex(dvm, receiver): return True for service in services: if not check_class_in_dex(dvm, service): return True return False
def testAPKIntentFilters(self): from androguard.core.bytecodes.apk import APK a = APK("examples/tests/a2dp.Vol_137.apk", testzip=True) activities = a.get_activities() receivers = a.get_receivers() services = a.get_services() filter_list = [] for i in activities: filters = a.get_intent_filters("activity", i) if len(filters) > 0: filter_list.append(filters) for i in receivers: filters = a.get_intent_filters("receiver", i) if len(filters) > 0: filter_list.append(filters) for i in services: filters = a.get_intent_filters("service", i) if len(filters) > 0: filter_list.append(filters) pairs = zip(filter_list, [{ 'action': ['android.intent.action.MAIN'], 'category': ['android.intent.category.LAUNCHER'] }, { 'action': ['android.service.notification.NotificationListenerService'] }, { 'action': [ 'android.intent.action.BOOT_COMPLETED', 'android.intent.action.MY_PACKAGE_REPLACED' ], 'category': ['android.intent.category.HOME'] }, { 'action': ['android.appwidget.action.APPWIDGET_UPDATE'] }]) self.assertTrue(any(x != y for x, y in pairs))
def run(self): """Run androguard to extract static android information @return: list of static features """ self.key = "apkinfo" apkinfo = {} if "file" not in self.task["category"]: return from androguard.core.bytecodes.apk import APK from androguard.core.bytecodes.dvm import DalvikVMFormat from androguard.core.analysis.analysis import uVMAnalysis from androguard.core.analysis import analysis f = File(self.task["target"]) if f.get_name().endswith((".zip", ".apk")) or "zip" in f.get_type(): if not os.path.exists(self.file_path): raise CuckooProcessingError("Sample file doesn't exist: \"%s\"" % self.file_path) try: a = APK(self.file_path) if a.is_valid_APK(): manifest = {} apkinfo["files"] = self._apk_files(a) manifest["package"] = a.get_package() # manifest["permissions"]=a.get_details_permissions_new() manifest["main_activity"] = a.get_main_activity() manifest["activities"] = a.get_activities() manifest["services"] = a.get_services() manifest["receivers"] = a.get_receivers() # manifest["receivers_actions"]=a.get__extended_receivers() manifest["providers"] = a.get_providers() manifest["libraries"] = a.get_libraries() apkinfo["manifest"] = manifest # apkinfo["certificate"] = a.get_certificate() static_calls = {} if self.check_size(apkinfo["files"]): vm = DalvikVMFormat(a.get_dex()) vmx = uVMAnalysis(vm) static_calls["all_methods"] = self.get_methods(vmx) static_calls["is_native_code"] = analysis.is_native_code(vmx) static_calls["is_dynamic_code"] = analysis.is_dyn_code(vmx) static_calls["is_reflection_code"] = analysis.is_reflection_code(vmx) # static_calls["dynamic_method_calls"]= analysis.get_show_DynCode(vmx) # static_calls["reflection_method_calls"]= analysis.get_show_ReflectionCode(vmx) # static_calls["permissions_method_calls"]= analysis.get_show_Permissions(vmx) # static_calls["crypto_method_calls"]= analysis.get_show_CryptoCode(vmx) # static_calls["native_method_calls"]= analysis.get_show_NativeMethods(vmx) else: log.warning("Dex size bigger than: %s", self.options.decompilation_threshold) apkinfo["static_method_calls"] = static_calls except (IOError, OSError, zipfile.BadZipfile) as e: raise CuckooProcessingError("Error opening file %s" % e) return apkinfo
def run(self): """Run androguard to extract static android information @return: list of static features """ self.key = "apkinfo" apkinfo = {} if "file" not in self.task["category"] or not HAVE_ANDROGUARD: return f = File(self.task["target"]) if f.get_name().endswith((".zip", ".apk")) or "zip" in f.get_type(): if not os.path.exists(self.file_path): raise CuckooProcessingError( "Sample file doesn't exist: \"%s\"" % self.file_path) try: a = APK(self.file_path) if a.is_valid_APK(): manifest = {} apkinfo["files"] = self._apk_files(a) manifest["package"] = a.get_package() # manifest["permissions"]=a.get_details_permissions_new() manifest["main_activity"] = a.get_main_activity() manifest["activities"] = a.get_activities() manifest["services"] = a.get_services() manifest["receivers"] = a.get_receivers() # manifest["receivers_actions"]=a.get__extended_receivers() manifest["providers"] = a.get_providers() manifest["libraries"] = a.get_libraries() apkinfo["manifest"] = manifest # apkinfo["certificate"] = a.get_certificate() static_calls = {} if self.check_size(apkinfo["files"]): vm = DalvikVMFormat(a.get_dex()) vmx = uVMAnalysis(vm) static_calls["all_methods"] = self.get_methods(vmx) static_calls[ "is_native_code"] = analysis.is_native_code(vmx) static_calls["is_dynamic_code"] = analysis.is_dyn_code( vmx) static_calls[ "is_reflection_code"] = analysis.is_reflection_code( vmx) # static_calls["dynamic_method_calls"]= analysis.get_show_DynCode(vmx) # static_calls["reflection_method_calls"]= analysis.get_show_ReflectionCode(vmx) # static_calls["permissions_method_calls"]= analysis.get_show_Permissions(vmx) # static_calls["crypto_method_calls"]= analysis.get_show_CryptoCode(vmx) # static_calls["native_method_calls"]= analysis.get_show_NativeMethods(vmx) else: log.warning("Dex size bigger than: %s", self.options.decompilation_threshold) apkinfo["static_method_calls"] = static_calls except (IOError, OSError, BadZipfile) as e: raise CuckooProcessingError("Error opening file %s" % e) return apkinfo
def extract_attributes(sha256): with NamedTemporaryFile() as f: f.write(default_storage.open(sha256).read()) f.seek(0) sign = ApplicationSignature.compute_from_apk(f.name) package = sign.handle sign = sign.to_dict() a = APK(f.name) sign['uploaded_at'] = datetime.now() sign['sha256'] = sha256 sign['activities'] = a.get_activities() sign['features'] = a.get_features() sign['libraries'] = a.get_libraries() sign['main_activity'] = a.get_activities() sign['min_sdk_version'] = a.get_min_sdk_version() sign['max_sdk_version'] = a.get_max_sdk_version() sign['target_sdk_version'] = a.get_target_sdk_version() sign['permissions'] = a.get_permissions() sign['aosp_permissions'] = a.get_requested_aosp_permissions() sign[ 'third_party_permissions'] = a.get_requested_third_party_permissions( ) sign['providers'] = a.get_providers() sign['receivers'] = a.get_receivers() sign['services'] = a.get_services() sign['is_valid'] = a.is_valid_APK() sign['is_signed'] = a.is_signed() sign['is_signed_v1'] = a.is_signed_v1() sign['is_signed_v2'] = a.is_signed_v2() sign['is_signed_v3'] = a.is_signed_v3() if not es.exists(settings.ELASTICSEARCH_APK_INDEX, id=sha256): es.index(index=settings.ELASTICSEARCH_APK_INDEX, id=sha256, body=sign) else: es.update(index=settings.ELASTICSEARCH_APK_INDEX, id=sha256, body={'doc': sign}, retry_on_conflict=5) del a, sign, f gc.collect() return package
def extract_features_using_androguard(androguard: APK): resulat_dict = dict() count_dict = dict() _permissions = androguard.get_permissions() _hardwares = list(androguard.get_features()) np = len(_permissions) if np > 0: resulat_dict = { 'defined_perm': dict(Counter(_permissions)), } count_dict = {'num_permission': np} nh = len(_hardwares) if nh > 0: resulat_dict.update({'hardware': dict(Counter(_hardwares))}) count_dict.update({'num_hardware': len(_hardwares)}) # List of all intents in apk _filters = list() # Apk components components_dict = { 'activity': androguard.get_activities(), 'service': androguard.get_services(), 'receiver': androguard.get_receivers(), 'provider': androguard.get_providers() } # Extract intents for categorie, names in components_dict.items(): # Components and Count the number of each components in apk nm = len(names) if nm > 0: count_dict.update({'num_' + categorie: nm}) resulat_dict.update( {categorie: dict(Counter(components_dict[categorie]))}) # Extract intent filter for each component intents = extract_intent(androguard, categorie, names) ni = len(intents) if ni > 0: _filters.extend(intents) count_dict.update({'num_intent_' + categorie: ni}) nf = len(_filters) if nf > 0: resulat_dict.update({'intent': dict(Counter(_filters))}) count_dict.update({'num_intent': nf}) resulat_dict.update({'component_count': count_dict}) return resulat_dict
def get_data(apkPath, apkName): a = APK(apkPath) jsonFile = apkName + ".json" pro = a.get_providers() rec = a.get_receivers() ser = a.get_services() act = a.get_activities() per = a.get_permissions() hwc = get_hardware(a) data = {'permissions': [], 'hardwareComponent': [], 'components': {}} data['permissions'] = per data['hardwareComponent'] = hwc data['components']['providers'] = pro data['components']['receivers'] = rec data['components']['services'] = rec data['components']['activities'] = act with open(jsonFile, 'w') as f: json.dump(data, f)
def lim_features_categories(apk_filepath): try: apk = APK(apk_filepath) info = { 'declared permissions': sorted(apk.get_permissions()), 'activities': apk.get_activities(), 'services': apk.get_services(), 'intent filters': apk.get_intent_filters('receiver', ''), 'content providers': apk.get_providers(), 'broadcast receivers': apk.get_receivers(), 'hardware components': apk.get_features() } for category in info: info[category] = [ feature.replace(".", "_").lower() for feature in info[category] ] return info except: # We just do not process the APK pass
def main(options, args): if options.emulator is None or options.file is None or options.policy is None: sys.exit('please confirm the parameters are correct') emulator = options.emulator apk_path = options.file policy = options.policy device = Device(emulator) if options.install: stevedore.install_apk(apk_path, device) if not os.path.isdir(LOGS): os.mkdir(LOGS) sha256 = hashlib.sha256() sha256.update(open(apk_path).read()) sha256sum = sha256.hexdigest() log_file = os.path.join(LOGS, sha256sum + '.log') if not os.path.isfile(log_file): #print 'writing log file into %s' % log_file try: apk = APK(apk_path) except Exception as ex: return False, ex if not apk.is_valid_APK(): return False, 'It is not a valid apk' activities = [] for act in apk.get_activities(): if not filtered(act, FILTERED_ACTIVITY): activities.append(act) services = apk.get_services() receivers = [] for rec in apk.get_receivers(): if not filtered(rec, FILTERED_BROADCAST): receivers.append(rec) package_name = apk.get_package() #write to log file with open(log_file, 'w') as fout: fout.write('package_name=' + package_name + '\n') fout.write('activity=' + ' '.join(activities) + '\n') fout.write('service=' + ' '.join(services) + '\n') fout.write('receiver=' + ' '.join(receivers) + '\n') else: #print 'reading log file from %s' % log_file with open(log_file, 'r') as fin: for line in fin.readlines(): if line.startswith('package_name='): package_name = line.replace('package_name=', '') elif line.startswith('activity='): activities = line.replace('activity=', '').split() elif line.startswith('service='): services = line.replace('service=', '').split() elif line.startswith('receiver='): receivers = line.replace('receiver=', '').split() if policy == 'random': policy = ['broadcast', 'listener', 'launcher', 'service', 'receiver'][random.randint(0, 4)] if policy == 'broadcast': actions = IntentEvent.get_intent_actions() if len(actions) > 0: selected = actions[random.randint(0, len(actions) - 1)] intent = IntentEvent(action=selected, package_name=package_name) intent.execute(device) elif policy == 'listener': if emulator.startswith('emulator'): listener_type = ['sms', 'gsm', 'rotate', 'volume'][random.randint(0, 3)] listener = ListenerEvent(listener_type) listener.execute(device) else: listener_type = ['sms', 'rotate', 'volume'][random.randint(0, 2)] if listener_type == 'sms': intent = IntentEvent( action='android.provider.Telephony.SMS_RECEIVED' ) #, package_name=package_name) intent.execute(device) else: listener = ListenerEvent(listener_type) listener.execute(device) elif policy == 'launcher': if len(activities) > 0: selected = activities[random.randint(0, len(activities) - 1)] launcher = LauncherEvent(package_name, selected) launcher.execute(device) elif policy == 'service': if len(services) > 0: selected = services[random.randint(0, len(services) - 1)] service = ServiceEvent(package_name, selected) service.execute(device) if random.randint(0, 1) == 1: import time time.sleep(3) service = ServiceEvent(package_name=package_name, service_name=selected, stop=True) service.execute(device) elif policy == 'receiver': if len(receivers) > 0: selected = receivers[random.randint(0, len(receivers) - 1)] receiver = ReceiverEvent(package_name, selected) receiver.execute(device)
def extract_features(file_path): result = {} try: a = APK(file_path) d = DalvikVMFormat(a.get_dex()) dx = Analysis(d) vm = dvm.DalvikVMFormat(a.get_dex()) vmx = analysis.Analysis(vm) d.set_vmanalysis(dx) d.set_decompiler(DecompilerDAD(d, dx)) except Exception as e: print e return None result['android_version_code'] = a.get_androidversion_code() result['android_version_name'] = a.get_androidversion_name() result['max_sdk'] = a.get_max_sdk_version() result['min_sdk'] = a.get_min_sdk_version() result['libraries'] = a.get_libraries() result['filename'] = a.get_filename() result['target_sdk'] = a.get_target_sdk_version() result['md5'] = hashlib.md5(a.get_raw()).hexdigest() result['sha256'] = hashlib.sha256(a.get_raw()).hexdigest() result['permissions'] = a.get_permissions() result['activities'] = a.get_activities() result['providers'] = a.get_providers() result['services'] = a.get_services() result['strings'] = d.get_strings() result['class_names'] = [c.get_name() for c in d.get_classes()] result['method_names'] = [m.get_name() for m in d.get_methods()] result['field_names'] = [f.get_name() for f in d.get_fields()] # result['is_native_code'] = 1 if analysis.is_native_code(dx) else 0 result['is_obfuscation'] = 1 if analysis.is_ascii_obfuscation(d) else 0 # result['is_crypto_code'] = 1 if analysis.is_crypto_code(dx) else 0 # result['is_dyn_code'] = 1 if analysis.is_dyn_code(dx) else 0 # result['is_reflection_code'] = 1 if analysis.is_reflection_code(vmx) else 0 result['is_database'] = 1 if d.get_regex_strings(DB_REGEX) else 0 s_list = [] s_list.extend(result['class_names']) s_list.extend(result['method_names']) s_list.extend(result['field_names']) result['entropy_rate'] = entropy_rate(s_list) result['feature_vectors'] = {} result['feature_vectors']['api_calls'] = [] for call in API_CALLS: status = 1 if dx.get_method_by_name(".", call, ".") else 0 result['feature_vectors']['api_calls'].append(status) result['feature_vectors']['permissions'] = [] for permission in PERMISSIONS: status = 1 if permission in result['permissions'] else 0 result['feature_vectors']['permissions'].append(status) result['feature_vectors']['special_strings'] = [] for word in SPECIAL_STRINGS: status = 1 if d.get_regex_strings(word) else 0 result['feature_vectors']['special_strings'].append(status) result['feature_vectors']['others'] = [ # result['is_reflection_code'], # result['is_crypto_code'], # result['is_native_code'], result['is_obfuscation'], result['is_database'], # result['is_dyn_code'] ] return result
def run(self): """Run androguard to extract static android information @return: list of static features """ self.key = "apkinfo" apkinfo = {} if "file" not in self.task["category"] or not HAVE_ANDROGUARD: return f = File(self.task["target"]) #if f.get_name().endswith((".zip", ".apk")) or "zip" in f.get_type(): if not os.path.exists(self.file_path): raise CuckooProcessingError("Sample file doesn't exist: \"%s\"" % self.file_path) try: a = APK(self.file_path) if a.is_valid_APK(): manifest = {} apkinfo["files"] = self._apk_files(a) manifest["package"] = a.get_package() apkinfo["hidden_payload"] = [] for file in apkinfo["files"]: if self.file_type_check(file): apkinfo["hidden_payload"].append(file) apkinfo["files_flaged"] = self.files_name_map manifest["permissions"] = get_permissions(a) manifest["main_activity"] = a.get_main_activity() manifest["activities"] = a.get_activities() manifest["services"] = a.get_services() manifest["receivers"] = a.get_receivers() manifest["receivers_actions"] = get_extended_receivers(a) manifest["providers"] = a.get_providers() manifest["libraries"] = list(a.get_libraries()) apkinfo["manifest"] = manifest apkinfo["icon"] = get_apk_icon(self.file_path) certificate = get_certificate(self.file_path) if certificate: apkinfo["certificate"] = certificate #vm = DalvikVMFormat(a.get_dex()) #strings = vm.get_strings() strings = self._get_strings(self.file_path) apkinfo["interesting_strings"] = find_strings(strings) apkinfo["dex_strings"] = strings static_calls = {} if self.options.decompilation: if self.check_size(apkinfo["files"]): vm = DalvikVMFormat(a.get_dex()) vmx = Analysis(vm) vmx.create_xref() static_calls["all_methods"] = get_methods(vmx) static_calls[ "permissions_method_calls"] = get_show_Permissions( vmx) static_calls[ "native_method_calls"] = get_show_NativeMethods( vmx) static_calls["is_native_code"] = bool( static_calls["native_method_calls"] ) # True if not empty, False if empty static_calls[ "dynamic_method_calls"] = get_show_DynCode(vmx) static_calls["is_dynamic_code"] = bool( static_calls["dynamic_method_calls"]) static_calls[ "reflection_method_calls"] = get_show_ReflectionCode( vmx) static_calls["is_reflection_code"] = bool( static_calls["reflection_method_calls"]) static_calls[ "crypto_method_calls"] = get_show_CryptoCode(vmx) static_calls["is_crypto_code"] = bool( static_calls["crypto_method_calls"]) classes = list() for cls in vm.get_classes(): classes.append(cls.name) static_calls["classes"] = classes else: log.warning( "Aborted decompilation, static extraction of calls not perforemd", ) apkinfo["static_method_calls"] = static_calls except (IOError, OSError, BadZipfile) as e: raise CuckooProcessingError("Error opening file %s" % e) return apkinfo
def reverse(nameApk): # doc file config with open(config_file, "r+") as f: dataConfig = json.load(f) maxLabelsNum = dataConfig['maxLabelsNum'] # Label tong hop # with open(LabelsNum_file, "r+") as file_LabeslNum: # LABELSNUMANDTEXT = json.load(file_LabeslNum) # Load Android API packages and classes global API_PACKAGES_LIST, API_CLASSES_LIST, API_SYSTEM_COMMANDS ############################################################ # READING PACKAGES, CLASSES AND SYSTEM COMMANDS ############################################################ package_file = load_file(str(package_index_file)) API_PACKAGES_LIST = [x.strip() for x in package_file] class_file = load_file(str(classes_index_file)) API_CLASSES_LIST = [x.strip() for x in class_file] commands_file = load_file(str(system_commands_file)) API_SYSTEM_COMMANDS = [x.strip() for x in commands_file] static_analysis_dict = collections.OrderedDict() try: analyze_apk = os.path.join(TEMP,nameApk) # Getting the name of the folder that contains all apks and folders with apks base_folder = TEMP.split("/")[-1] apk_filename = join_dir(base_folder, analyze_apk.replace(TEMP, '')) apk_filename = apk_filename.replace("//", "/") apk_name_no_extensions = "".join(apk_filename.split("/")[-1].split(".")[:-1]) # export to monggoDB # if os.path.isfile(join_dir(output_folder, apk_filename.split("/")[-1].replace('.apk', '-analysis.json'))): # database[apk_filename.replace('.apk', '')] = json.load( # open(join_dir(output_folder, apk_filename.split("/")[-1]. # replace('.apk', '-analysis.json')))) # continue pre_static_dict = collections.OrderedDict() pre_static_dict['Filename'] = apk_filename hasher_md5 = hashlib.md5() hasher_sha256 = hashlib.sha256() hasher_sha1 = hashlib.sha1() with open(analyze_apk, 'rb') as afile: buf = afile.read() hasher_md5.update(buf) hasher_sha256.update(buf) hasher_sha1.update(buf) md5 = hasher_md5.hexdigest() sha256 = hasher_sha256.hexdigest() sha1 = hasher_sha1.hexdigest() pre_static_dict["md5"] = md5 pre_static_dict["sha256"] = sha256 pre_static_dict["sha1"] = sha1 """ if label is not None: pre_static_dict["Label"] = label else: pre_static_dict["Label"] = "/".join(apk_filename.split("/")[:-1]) """ pre_static_dict["VT_positives"] = None apk_Oject = APK(analyze_apk) # get package name static_analysis_dict['Package_name'] = apk_Oject.get_package() # get Permission static_analysis_dict['Permissions'] = apk_Oject.get_permissions() # Activities try: list_activities = apk_Oject.get_activities() except UnicodeEncodeError: list_activities = [] # get Main ACtivity static_analysis_dict['Main_activity'] = apk_Oject.get_main_activity() # Receivers try: list_receivers = apk_Oject.get_receivers() except UnicodeEncodeError: list_receivers = [] # Services try: list_services = apk_Oject.get_services() except UnicodeEncodeError: list_services = [] # API calls and Strings list_smali_api_calls, list_smali_strings = read_strings_and_apicalls(analyze_apk, API_PACKAGES_LIST, API_CLASSES_LIST) for api_call in list_smali_api_calls.keys(): new_api_call = '.'.join(api_call.split(".")[:-1]) if new_api_call in list_smali_api_calls.keys(): list_smali_api_calls[new_api_call] = list_smali_api_calls[new_api_call] + list_smali_api_calls[ api_call] else: list_smali_api_calls[new_api_call] = list_smali_api_calls[api_call] del list_smali_api_calls[api_call] static_analysis_dict['API_calls'] = list_smali_api_calls static_analysis_dict['Strings'] = Counter(filter(None, list_smali_strings)) # API packages API_packages_dict = collections.OrderedDict() android_list_packages_lenghts = [len(x.split(".")) for x in API_PACKAGES_LIST] list_api_calls_keys = list_smali_api_calls.keys() for api_call in list_api_calls_keys: score = 0 package_chosen = None for i, package in enumerate(API_PACKAGES_LIST): len_package = android_list_packages_lenghts[i] if api_call.startswith(package) and len_package > score: score = len_package package_chosen = package if package_chosen is not None: if not package_chosen in API_packages_dict.keys(): API_packages_dict[package_chosen] = list_smali_api_calls[api_call] else: API_packages_dict[package_chosen] += list_smali_api_calls[api_call] static_analysis_dict['API_packages'] = API_packages_dict # Intents try: static_analysis_dict['Intents'] = intents_analysis(join_dir(analyze_apk.replace('.apk', ''), 'AndroidManifest.xml')) except: static_analysis_dict['Intents'] = {'Failed to extract intents': 0} # Intents of activities intents_activities = collections.OrderedDict() for activity in list_activities: intents_activities[activity] = check_for_intents(join_dir(analyze_apk.replace('.apk', ''), 'AndroidManifest.xml'), activity, 'activity') static_analysis_dict['Activities'] = intents_activities # Intents of services intents_services = collections.OrderedDict() for service in list_services: intents_services[service] = check_for_intents(join_dir(analyze_apk.replace('.apk', ''), 'AndroidManifest.xml'), service, 'service') static_analysis_dict['Services'] = intents_services # Intents of receivers intents_receivers = collections.OrderedDict() for intent in list_receivers: intents_receivers[intent] = check_for_intents(join_dir(analyze_apk.replace('.apk', '/'), 'AndroidManifest.xml'), intent, 'receiver') static_analysis_dict['Receivers'] = intents_receivers static_analysis_dict['Receivers'] = intents_receivers apk_total_analysis = collections.OrderedDict([("Pre_static_analysis", pre_static_dict), ("Static_analysis", static_analysis_dict)]) # # save_as_json(apk_total_analysis, output_name=join_dir(output_folder, apk_name_no_extensions + # "-analysis.json")) row = standardData(pre_static_dict, static_analysis_dict) csvFileClient = open(DataCSVClient + md5 + '.csv', 'w+', newline='') writer = csv.writer(csvFileClient, delimiter=',') writer.writerow(row) csvFileClient.close() delAPk(analyze_apk) if checkMerge(DataCSVClient, dataConfig['mergeCSV']): mergeCSV() return md5, apk_total_analysis except Exception as e: print('Exception: ', e) return 'Error', 'No features'
def extract_features(file_path): result = {} try: a = APK(file_path) d = DalvikVMFormat(a.get_dex()) dx = VMAnalysis(d) vm = dvm.DalvikVMFormat(a.get_dex()) vmx = analysis.uVMAnalysis(vm) d.set_vmanalysis(dx) d.set_decompiler(DecompilerDAD(d, dx)) except: return None result['android_version_code'] = a.get_androidversion_code() result['android_version_name'] = a.get_androidversion_name() result['max_sdk'] = a.get_max_sdk_version() result['min_sdk'] = a.get_min_sdk_version() result['libraries'] = a.get_libraries() result['filename'] = a.get_filename() result['target_sdk'] = a.get_target_sdk_version() result['md5'] = hashlib.md5(a.get_raw()).hexdigest() result['sha256'] = hashlib.sha256(a.get_raw()).hexdigest() result['permissions'] = a.get_permissions() result['activities'] = a.get_activities() result['providers'] = a.get_providers() result['services'] = a.get_services() #result['strings'] = d.get_strings() #result['class_names'] = [c.get_name() for c in d.get_classes()] #result['method_names'] = [m.get_name() for m in d.get_methods()] #result['field_names'] = [f.get_name() for f in d.get_fields()] class_names = [c.get_name() for c in d.get_classes()] method_names = [m.get_name() for m in d.get_methods()] field_names = [ f.get_name() for f in d.get_fields()] result['is_native_code'] = 1 if analysis.is_native_code(dx) else 0 result['is_obfuscation'] = 1 if analysis.is_ascii_obfuscation(d) else 0 result['is_crypto_code'] = 1 if analysis.is_crypto_code(dx) else 0 result['is_dyn_code'] = 1 if analysis.is_dyn_code(dx) else 0 result['is_reflection_code'] = 1 if analysis.is_reflection_code(vmx) else 0 result['is_database'] = 1 if d.get_regex_strings(DB_REGEX) else 0 s_list = [] #s_list.extend(result['class_names']) #s_list.extend(result['method_names']) #s_list.extend(result['field_names']) s_list.extend(class_names) s_list.extend(method_names) s_list.extend(method_names) result['entropy_rate'] = entropy_rate(s_list) result['feature_vectors'] = {} # Search for the presence of api calls in a given apk result['feature_vectors']['api_calls'] = [] for call in API_CALLS: status = 1 if dx.tainted_packages.search_methods(".", call, ".") else 0 result['feature_vectors']['api_calls'].append(status) # Search for the presence of permissions in a given apk result['feature_vectors']['permissions'] = [] for permission in PERMISSIONS: status = 1 if permission in result['permissions'] else 0 result['feature_vectors']['permissions'].append(status) result['feature_vectors']['special_strings'] = [] for word in SPECIAL_STRINGS: status = 1 if d.get_regex_strings(word) else 0 result['feature_vectors']['special_strings'].append(status) opt_seq = [] for m in d.get_methods(): for i in m.get_instructions(): opt_seq.append(i.get_name()) optngramlist = [tuple(opt_seq[i:i+NGRAM]) for i in xrange(len(opt_seq) - NGRAM)] optngram = Counter(optngramlist) optcodes = dict() tmpCodes = dict(optngram) #for k,v in optngram.iteritems(): # if v>=NGRAM_THRE: #optcodes[str(k)] = v # optcodes[str(k)] = 1 tmpCodes = sorted(tmpCodes.items(),key =lambda d:d[1],reverse=True) for value in tmpCodes[:NGRAM_THRE]: optcodes[str(value[0])] = 1 result['feature_vectors']['opt_codes'] = optcodes return result
def analyze(path): try: start = process_time() hashfunctions = dict(md5=hashlib.md5, sha1=hashlib.sha1, sha256=hashlib.sha256, sha512=hashlib.sha512) a = APK(path) certs = set( a.get_certificates_der_v3() + a.get_certificates_der_v2() + [a.get_certificate_der(x) for x in a.get_signature_names()]) for cert in certs: x509_cert = x509.Certificate.load(cert) issuer = { 'commonName': None, 'organizationName': None, 'organizationalUnitName': None, 'countryName': None, 'stateOrProvinceName': None, 'localityName': None } subject = { 'commonName': None, 'organizationName': None, 'organizationalUnitName': None, 'countryName': None, 'stateOrProvinceName': None, 'localityName': None } strIssuer = get_certificate_name_string(x509_cert.issuer, short=False) strSubject = get_certificate_name_string(x509_cert.subject, short=False) arrIssuer = strIssuer.split(',') for i in arrIssuer: if i.lstrip().split('=')[0] == 'commonName': issuer['commonName'] = i.lstrip().split('=')[1] elif i.lstrip().split('=')[0] == 'organizationName': issuer['organizationName'] = i.lstrip().split('=')[1] elif i.lstrip().split('=')[0] == 'organizationalUnitName': issuer['organizationalUnitName'] = i.lstrip().split('=')[1] elif i.lstrip().split('=')[0] == 'countryName': issuer['countryName'] = i.lstrip().split('=')[1] elif i.lstrip().split('=')[0] == 'stateOrProvinceName': issuer['stateOrProvinceName'] = i.lstrip().split('=')[1] elif i.lstrip().split('=')[0] == 'localityName': issuer['localityName'] = i.lstrip().split('=')[1] arrSubject = strSubject.split(',') for i in arrSubject: if i.lstrip().split('=')[0] == 'commonName': subject['commonName'] = i.lstrip().split('=')[1] elif i.lstrip().split('=')[0] == 'organizationName': subject['organizationName'] = i.lstrip().split('=')[1] elif i.lstrip().split('=')[0] == 'organizationalUnitName': subject['organizationalUnitName'] = i.lstrip().split( '=')[1] elif i.lstrip().split('=')[0] == 'countryName': subject['countryName'] = i.lstrip().split('=')[1] elif i.lstrip().split('=')[0] == 'stateOrProvinceName': subject['stateOrProvinceName'] = i.lstrip().split('=')[1] elif i.lstrip().split('=')[0] == 'localityName': subject['localityName'] = i.lstrip().split('=')[1] for k, v in hashfunctions.items(): if k == 'md5': md5 = v(cert).hexdigest() elif k == 'sha1': sha1 = v(cert).hexdigest() elif k == 'sha256': sha256 = v(cert).hexdigest() elif k == 'sha512': sha512 = v(cert).hexdigest() md5 = md5 appName = a.get_app_name() fileSize = os.stat(a.get_filename()).st_size sha1 = sha1 sha256 = sha256 sha512 = sha512 timestamp = time.time() dateTime = datetime.fromtimestamp(timestamp) timeOfSubmit = dateTime.strftime("%Y-%m-%d %H:%M:%S") package = a.get_package() androidversionCode = a.get_androidversion_code() androidversionName = a.get_androidversion_name() minSDKVersion = a.get_min_sdk_version() maxSDKVersion = a.get_max_sdk_version() targetSDKVersion = a.get_target_sdk_version() mainActivity = a.get_main_activity() attributes = { 'validFrom': x509_cert['tbs_certificate']['validity'] ['not_before'].native.strftime("%Y-%m-%d %H:%M:%S"), 'validTo': x509_cert['tbs_certificate']['validity'] ['not_after'].native.strftime("%Y-%m-%d %H:%M:%S"), 'serialNumber': hex(x509_cert.serial_number), 'hashAlgorithm': x509_cert.hash_algo, 'signatureAlgorithm': x509_cert.signature_algo } certificateAttributes = json.dumps(attributes) certificateIssuer = json.dumps(issuer) certificateSubject = json.dumps(subject) declaredPermissions = json.dumps(a.get_declared_permissions()) requestedPermissions = json.dumps(a.get_permissions()) activities = json.dumps(a.get_activities()) services = json.dumps(a.get_services()) receivers = json.dumps(a.get_receivers()) providers = json.dumps(a.get_providers()) stop = process_time() analysisTime = stop - start connect = mysql.connect() cursor = connect.cursor() sql = "INSERT INTO tbl_apkinfo (md5, appName, fileSize, analysisTime, sha1, sha256, sha512, firstSubmission, lastSubmission, package, androidversionCode, androidversionName, minSDKVersion, maxSDKVersion, targetSDKVersion, mainActivity, certificateAttributes, certificateIssuer, certificateSubject, declaredPermissions, requestedPermissions, activities, services, providers, receivers) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)" param = (md5, appName, fileSize, analysisTime, sha1, sha256, sha512, timeOfSubmit, timeOfSubmit, package, androidversionCode, androidversionName, minSDKVersion, maxSDKVersion, targetSDKVersion, mainActivity, certificateAttributes, certificateIssuer, certificateSubject, declaredPermissions, requestedPermissions, activities, services, providers, receivers) cursor.execute(sql, param) connect.commit() connect.close() androaxml_main(path, os.path.join(app.config['OUTPUT_PATH'], md5 + '.xml')) return True except: return False
def extract_features(file_path): result = {} try: a = APK(file_path) d = DalvikVMFormat(a.get_dex()) dx = Analysis(d) vm = dvm.DalvikVMFormat(a.get_dex()) #vmx = analysis.uVMAnalysis(vm) d.set_vmanalysis(dx) d.set_decompiler(DecompilerDAD(d, dx)) except: return None result['android_version_code'] = a.get_androidversion_code() result['android_version_name'] = a.get_androidversion_name() result['max_sdk'] = a.get_max_sdk_version() result['min_sdk'] = a.get_min_sdk_version() #result['libraries'] = a.get_libraries() result['filename'] = a.get_filename() result['target_sdk'] = a.get_target_sdk_version() result['md5'] = hashlib.md5(a.get_raw()).hexdigest() result['sha256'] = hashlib.sha256(a.get_raw()).hexdigest() result['permissions'] = a.get_permissions() result['activities'] = a.get_activities() result['providers'] = a.get_providers() result['services'] = a.get_services() result['strings'] = d.get_strings() result['class_names'] = [c.get_name() for c in d.get_classes()] result['method_names'] = [m.get_name() for m in d.get_methods()] result['field_names'] = [f.get_name() for f in d.get_fields()] #result['is_native_code'] = 1 if analysis.is_native_code(dx) else 0 result['is_obfuscation'] = 1 if analysis.is_ascii_obfuscation(d) else 0 #result['is_crypto_code'] = 1 if analysis.is_crypto_code(dx) else 0 '''result['is_dyn_code'] = 1 if analysis.is_dyn_code(dx) else 0 result['is_reflection_code'] = 1 if analysis.is_reflection_code(vmx) else 0''' result['is_database'] = 1 if d.get_regex_strings(DB_REGEX) else 0 arr = [] s = a.get_elements("action", "name") for i in s: arr.append(i) result['intents'] = arr s_list = [] s_list.extend(result['class_names']) s_list.extend(result['method_names']) s_list.extend(result['field_names']) result['entropy_rate'] = entropy_rate(s_list) result['feature_vectors'] = {} # Search for the presence of api calls in a given apk result['feature_vectors']['api_calls'] = [] for call in API_CALLS: status = 1 if dx.get_method(call) else 0 result['feature_vectors']['api_calls'].append(status) # Search for the presence of permissions in a given apk result['feature_vectors']['permissions'] = [] for permission in PERMISSIONS: status = 1 if permission in result['permissions'] else 0 result['feature_vectors']['permissions'].append(status) #Search for the presence of intents in a given apk result['feature_vectors']['intents'] = [] n = len(INTENTS) m = len(result['intents']) for i in range(n): stri = INTENTS[i] flg = False for j in range(m): if stri in result['intents'][j]: flg = True break if flg: status = 1 else: status = 0 result['feature_vectors']['intents'].append(status) #Check for special strings in code result['feature_vectors']['special_strings'] = [] for word in SPECIAL_STRINGS: status = 1 if d.get_regex_strings(word) else 0 result['feature_vectors']['special_strings'].append(status) return result
def run(self): """Run androguard to extract static android information @return: list of static features """ self.key = "apkinfo" apkinfo = {} if "file" not in self.task["category"] or not HAVE_ANDROGUARD: return #f = File(self.task["target"]) #if f.get_name().endswith((".zip", ".apk")) or "zip" in f.get_type(): if not os.path.exists(self.file_path): raise CuckooProcessingError("Sample file doesn't exist: \"%s\"" % self.file_path) apkinfo["APKiD"] = self._scan_APKiD(self.file_path) try: a = APK(self.file_path) if a.is_valid_APK(): manifest = {} apkinfo["files"] = self._apk_files(a) apkinfo["encrypted_assets"] = self.find_encrypted_assets(a) manifest["package"] = a.get_package() apkinfo["hidden_payload"] = [] for file in apkinfo["files"]: if self.file_type_check(file): apkinfo["hidden_payload"].append(file) apkinfo["files_flaged"] = self.files_name_map manifest["permissions"]= get_permissions(a) manifest["main_activity"] = a.get_main_activity() manifest["activities"] = a.get_activities() manifest["services"] = a.get_services() manifest["receivers"] = a.get_receivers() manifest["receivers_actions"] = get_extended_receivers(a) manifest["receivers_info"] = get_receivers_info(a) manifest["providers"] = a.get_providers() manifest["libraries"] = a.get_libraries() apkinfo["manifest"] = manifest apkinfo["icon"] = get_apk_icon(self.file_path) certificate = get_certificate(self.file_path) if certificate: apkinfo["certificate"] = certificate #vm = DalvikVMFormat(a.get_dex()) #strings = vm.get_strings() strings = self._get_strings(self.file_path) for subdir, dirs, files in os.walk(self.dropped_path): for file in files: path = os.path.join(subdir, file) try: extra_strings = self._get_strings(path) strings = list(set(extra_strings + strings)) except: pass apkinfo["dex_strings"] = strings static_calls = {} if self.options.decompilation: if self.check_size(apkinfo["files"]): vm = DalvikVMFormat(a.get_dex()) vmx = uVMAnalysis(vm) # Be less verbose about androguard logging messages. logging.getLogger("andro.runtime").setLevel(logging.CRITICAL) static_calls["all_methods"] = get_methods(vmx) static_calls["is_native_code"] = analysis.is_native_code(vmx) static_calls["is_dynamic_code"] = analysis.is_dyn_code(vmx) static_calls["is_reflection_code"] = analysis.is_reflection_code(vmx) static_calls["is_crypto_code"] = is_crypto_code(vmx) static_calls["dynamic_method_calls"] = get_show_DynCode(vmx) static_calls["reflection_method_calls"] = get_show_ReflectionCode(vmx) static_calls["permissions_method_calls"] = get_show_Permissions(vmx) static_calls["crypto_method_calls"] = get_show_CryptoCode(vmx) static_calls["native_method_calls"] = get_show_NativeMethods(vmx) classes = list() for cls in vm.get_classes(): classes.append(cls.name) static_calls["classes"] = classes else: log.warning("Dex size bigger than: %s", self.options.decompilation_threshold) apkinfo["static_method_calls"] = static_calls except (IOError, OSError, BadZipfile) as e: raise CuckooProcessingError("Error opening file %s" % e) return apkinfo
def run(self): """Run androguard to extract static android information @return: list of static features """ self.key = "apkinfo" apkinfo = {} if "file" not in self.task["category"] or not HAVE_ANDROGUARD: return f = File(self.task["target"]) #if f.get_name().endswith((".zip", ".apk")) or "zip" in f.get_type(): if not os.path.exists(self.file_path): raise CuckooProcessingError("Sample file doesn't exist: \"%s\"" % self.file_path) try: a = APK(self.file_path) if a.is_valid_APK(): manifest = {} apkinfo["files"] = self._apk_files(a) manifest["package"] = a.get_package() apkinfo["hidden_payload"] = [] for file in apkinfo["files"]: if self.file_type_check(file): apkinfo["hidden_payload"].append(file) apkinfo["files_flaged"] = self.files_name_map manifest["permissions"]= get_permissions(a) manifest["main_activity"] = a.get_main_activity() manifest["activities"] = a.get_activities() manifest["services"] = a.get_services() manifest["receivers"] = a.get_receivers() manifest["receivers_actions"] = get_extended_receivers(a) manifest["providers"] = a.get_providers() manifest["libraries"] = a.get_libraries() apkinfo["manifest"] = manifest apkinfo["icon"] = get_apk_icon(self.file_path) certificate = get_certificate(self.file_path) if certificate: apkinfo["certificate"] = certificate #vm = DalvikVMFormat(a.get_dex()) #strings = vm.get_strings() strings = self._get_strings(self.file_path) apkinfo["interesting_strings"] = find_strings(strings) apkinfo["dex_strings"] = strings static_calls = {} if self.options.decompilation: if self.check_size(apkinfo["files"]): vm = DalvikVMFormat(a.get_dex()) vmx = uVMAnalysis(vm) static_calls["all_methods"] = get_methods(vmx) static_calls["is_native_code"] = analysis.is_native_code(vmx) static_calls["is_dynamic_code"] = analysis.is_dyn_code(vmx) static_calls["is_reflection_code"] = analysis.is_reflection_code(vmx) static_calls["is_crypto_code"] = is_crypto_code(vmx) static_calls["dynamic_method_calls"] = get_show_DynCode(vmx) static_calls["reflection_method_calls"] = get_show_ReflectionCode(vmx) static_calls["permissions_method_calls"] = get_show_Permissions(vmx) static_calls["crypto_method_calls"] = get_show_CryptoCode(vmx) static_calls["native_method_calls"] = get_show_NativeMethods(vmx) classes = list() for cls in vm.get_classes(): classes.append(cls.name) static_calls["classes"] = classes else: log.warning("Dex size bigger than: %s", self.options.decompilation_threshold) apkinfo["static_method_calls"] = static_calls except (IOError, OSError, BadZipfile) as e: raise CuckooProcessingError("Error opening file %s" % e) return apkinfo
def main(): parser = argparse.ArgumentParser() parser.add_argument("target", type=str, nargs="?", help="URL, path to the file or folder to analyze") parser.add_argument("-d", "--debug", action="store_true", help="Enable debug logging") parser.add_argument( "--remote", type=str, action="store", default=None, help="Specify IP:port to a Cuckoo API server to submit remotely", required=False) parser.add_argument("--url", action="store_true", default=False, help="Specify whether the target is an URL", required=False) parser.add_argument("--package", type=str, action="store", default="", help="Specify an analysis package", required=False) parser.add_argument("--custom", type=str, action="store", default="", help="Specify any custom value", required=False) parser.add_argument("--owner", type=str, action="store", default="", help="Specify the task owner", required=False) parser.add_argument("--timeout", type=int, action="store", default=0, help="Specify an analysis timeout", required=False) parser.add_argument( "-o", "--options", type=str, action="store", default="", help= "Specify options for the analysis package (e.g. \"name=value,name2=value2\")", required=False) parser.add_argument( "--priority", type=int, action="store", default=1, help="Specify a priority for the analysis represented by an integer", required=False) parser.add_argument( "--machine", type=str, action="store", default="", help="Specify the identifier of a machine you want to use", required=False) parser.add_argument( "--platform", type=str, action="store", default="", help= "Specify the operating system platform you want to use (windows/darwin/linux)", required=False) parser.add_argument( "--memory", action="store_true", default=False, help="Enable to take a memory dump of the analysis machine", required=False) parser.add_argument( "--enforce-timeout", action="store_true", default=False, help="Enable to force the analysis to run for the full timeout period", required=False) parser.add_argument("--clock", type=str, action="store", default=None, help="Set virtual machine clock", required=False) parser.add_argument( "--tags", type=str, action="store", default=None, help="Specify tags identifier of a machine you want to use", required=False) parser.add_argument("--baseline", action="store_true", default=None, help="Run a baseline analysis", required=False) parser.add_argument("--max", type=int, action="store", default=None, help="Maximum samples to add in a row", required=False) parser.add_argument("--pattern", type=str, action="store", default=None, help="Pattern of files to submit", required=False) parser.add_argument("--shuffle", action="store_true", default=False, help="Shuffle samples before submitting them", required=False) parser.add_argument("--unique", action="store_true", default=False, help="Only submit new samples, ignore duplicates", required=False) parser.add_argument("--quiet", action="store_true", default=False, help="Only print text on failure", required=False) parser.add_argument("--valid_apk", action="store_true", default=False, help="validates APK file", required=False) try: args = parser.parse_args() except IOError as e: parser.error(e) return False if not args.baseline and not args.target: print "No file or URL has been specified!" exit(1) # If the quiet flag has been set, then we also disable the "warning" # level of the logging module. (E.g., when pydeep has not been installed, # there will be a warning message, because Cuckoo can't resolve the # ssdeep hash of this particular sample.) if args.debug: logging.basicConfig(level=logging.DEBUG) else: logging.basicConfig() if args.quiet: logging.disable(logging.WARNING) db = Database() if args.url: target = to_unicode(args.target) if args.remote: if not HAVE_REQUESTS: print( bold(red("Error")) + ": you need to install python-requests (`pip install requests`)" ) return False url = "http://{0}/tasks/create/url".format(args.remote) data = dict(url=target, package=args.package, timeout=args.timeout, options=args.options, priority=args.priority, machine=args.machine, platform=args.platform, memory=args.memory, enforce_timeout=args.enforce_timeout, custom=args.custom, owner=args.owner, tags=args.tags) try: response = requests.post(url, data=data) except Exception as e: print( bold(red("Error")) + ": unable to send URL: {0}".format(e)) return False json = response.json() task_id = json["task_id"] else: task_id = db.add_url(target, package=args.package, timeout=args.timeout, options=args.options, priority=args.priority, machine=args.machine, platform=args.platform, custom=args.custom, owner=args.owner, memory=args.memory, enforce_timeout=args.enforce_timeout, clock=args.clock, tags=args.tags) if task_id: if not args.quiet: print( bold(green("Success")) + u": URL \"{0}\" added as task with ID {1}".format( target, task_id)) else: print(bold(red("Error")) + ": adding task to database") elif args.baseline: if args.remote: print "Remote baseline support has not yet been implemented." exit(1) task_id = db.add_baseline(args.timeout, args.owner, args.machine, args.memory) if task_id: if not args.quiet: print( bold(green("Success")) + u": Baseline analysis added as task with ID {0}".format( task_id)) else: print(bold(red("Error")) + ": adding task to database") else: target = to_unicode(args.target) # Get absolute path to deal with relative. path = to_unicode(os.path.abspath(target)) if not os.path.exists(path): print( bold(red("Error")) + u": the specified file/folder does not exist at path \"{0}\"". format(path)) return False files = [] if os.path.isdir(path): for dirname, dirnames, filenames in os.walk(path): for file_name in filenames: file_path = os.path.join(dirname, file_name) if os.path.isfile(file_path): if args.pattern: if fnmatch.fnmatch(file_name, args.pattern): files.append(to_unicode(file_path)) else: files.append(to_unicode(file_path)) else: files.append(path) if args.shuffle: random.shuffle(files) else: files = sorted(files) for file_path in files: if not File(file_path).get_size(): if not args.quiet: print( bold( yellow("Empty") + ": sample {0} (skipping file)".format(file_path))) continue if args.valid_apk: try: a = APK(file_path) if not a.is_valid_APK(): if not args.quiet: print( bold( yellow("Invalid APK") + ": sample {0} (skipping file)".format( file_path))) continue else: if len(a.get_activities()) == 0: if not args.quiet: print( bold( yellow("NO Activities APK") + ": sample {0} (skipping file)".format( file_path))) continue if len(a.get_services()) == 0: if not args.quiet: print( bold( yellow("Non-Executable APK") + ": sample {0} (skipping file)".format( file_path))) continue except: if not args.quiet: print( bold( yellow("Invalid APK") + ": sample {0} (skipping file)".format( file_path))) continue if args.max is not None: # Break if the maximum number of samples has been reached. if not args.max: break args.max -= 1 if args.remote: if not HAVE_REQUESTS: print( bold(red("Error")) + ": you need to install python-requests (`pip install requests`)" ) return False url = "http://{0}/tasks/create/file".format(args.remote) files = dict(file=open(file_path, "rb"), filename=os.path.basename(file_path)) data = dict(package=args.package, timeout=args.timeout, options=args.options, priority=args.priority, machine=args.machine, platform=args.platform, memory=args.memory, enforce_timeout=args.enforce_timeout, custom=args.custom, owner=args.owner, tags=args.tags) try: response = requests.post(url, files=files, data=data) except Exception as e: print( bold(red("Error")) + ": unable to send file: {0}".format(e)) return False json = response.json() task_id = json["task_id"] else: if args.unique: sha256 = File(file_path).get_sha256() if not db.find_sample(sha256=sha256) is None: msg = ": Sample {0} (skipping file)".format(file_path) if not args.quiet: print(bold(yellow("Duplicate")) + msg) continue task_id = db.add_path(file_path=file_path, package=args.package, timeout=args.timeout, options=args.options, priority=args.priority, machine=args.machine, platform=args.platform, custom=args.custom, owner=args.owner, memory=args.memory, enforce_timeout=args.enforce_timeout, clock=args.clock, tags=args.tags) if task_id: if not args.quiet: print( bold(green("Success")) + u": File \"{0}\" added as task with ID {1}".format( file_path, task_id)) else: print(bold(red("Error")) + ": adding task to database")
def getFeatures(source_directory): ############################################################ # Label tong hop with open(LabelsNum_file, "r+") as file_LabeslNum: LABELSNUMANDTEXT = json.load(file_LabeslNum) # doc file config with open(config_file, "r+") as f: dataConfig = json.load(f) maxLabelsNum = dataConfig['maxLabelsNum'] #lay part Data partData = dataConfig['partData'] time = datetime.datetime.now() partDataFile = str(partData) + '_' + str(time).strip() + '.csv' csvFile = open(r'DataCSV/' + partDataFile, 'w+', newline='') writer = csv.writer(csvFile, delimiter=',') source_directory = str(source_directory) #if not os.path.exists(output_folder): # os.makedirs(output_folder) # Load Android API packages and classes global API_PACKAGES_LIST, API_CLASSES_LIST, API_SYSTEM_COMMANDS ############################################################ # get name and labels ARRNAME, ARRLABELS = load_NameandLabels(labels) ############################################################ # READING PACKAGES, CLASSES AND SYSTEM COMMANDS ############################################################ package_file = load_file(str(package_index_file)) API_PACKAGES_LIST = [x.strip() for x in package_file] class_file = load_file(str(classes_index_file)) API_CLASSES_LIST = [x.strip() for x in class_file] commands_file = load_file(str(system_commands_file)) API_SYSTEM_COMMANDS = [x.strip() for x in commands_file] ############################################################ ############################################################ apk_list = list_files(source_directory, '*.apk') for analyze_apk in tqdm(apk_list): # Getting the name of the folder that contains all apks and folders with apks base_folder = source_directory.split("/")[-1] apk_filename = join_dir(base_folder, analyze_apk.replace(source_directory, '')) apk_filename = apk_filename.replace("//", "/") apk_name_no_extensions = "".join( apk_filename.split("/")[-1].split(".")[:-1]) # export to monggoDB #if os.path.isfile(join_dir(output_folder, apk_filename.split("/")[-1].replace('.apk', '-analysis.json'))): # database[apk_filename.replace('.apk', '')] = json.load( # open(join_dir(output_folder, apk_filename.split("/")[-1]. # replace('.apk', '-analysis.json')))) # continue pre_static_dict = collections.OrderedDict() pre_static_dict['Filename'] = apk_filename hasher_md5 = hashlib.md5() hasher_sha256 = hashlib.sha256() hasher_sha1 = hashlib.sha1() with open(analyze_apk, 'rb') as afile: buf = afile.read() hasher_md5.update(buf) hasher_sha256.update(buf) hasher_sha1.update(buf) md5 = hasher_md5.hexdigest() sha256 = hasher_sha256.hexdigest() sha1 = hasher_sha1.hexdigest() pre_static_dict["md5"] = md5 pre_static_dict["sha256"] = sha256 pre_static_dict["sha1"] = sha1 """ if label is not None: pre_static_dict["Label"] = label else: pre_static_dict["Label"] = "/".join(apk_filename.split("/")[:-1]) """ pre_static_dict["VT_positives"] = None try: androguard_apk_object = APK(analyze_apk) except Exception: print("ERROR in APK: " + apk_name_no_extensions) continue static_analysis_dict = collections.OrderedDict() # Package name static_analysis_dict[ 'Package name'] = androguard_apk_object.get_package() # Permissions static_analysis_dict[ 'Permissions'] = androguard_apk_object.get_permissions() # Activities try: list_activities = androguard_apk_object.get_activities() except UnicodeEncodeError: list_activities = [] # Main activity static_analysis_dict[ 'Main activity'] = androguard_apk_object.get_main_activity() # Receivers try: list_receivers = androguard_apk_object.get_receivers() except UnicodeEncodeError: list_receivers = [] # Services try: list_services = androguard_apk_object.get_services() except UnicodeEncodeError: list_services = [] # API calls and Strings list_smali_api_calls, list_smali_strings = read_strings_and_apicalls( analyze_apk, API_PACKAGES_LIST, API_CLASSES_LIST) for api_call in list_smali_api_calls.keys(): new_api_call = '.'.join(api_call.split(".")[:-1]) if new_api_call in list_smali_api_calls.keys(): list_smali_api_calls[new_api_call] = list_smali_api_calls[ new_api_call] + list_smali_api_calls[api_call] else: list_smali_api_calls[new_api_call] = list_smali_api_calls[ api_call] del list_smali_api_calls[api_call] static_analysis_dict['API calls'] = list_smali_api_calls static_analysis_dict['Strings'] = Counter( filter(None, list_smali_strings)) # API packages API_packages_dict = collections.OrderedDict() android_list_packages_lenghts = [ len(x.split(".")) for x in API_PACKAGES_LIST ] list_api_calls_keys = list_smali_api_calls.keys() for api_call in list_api_calls_keys: score = 0 package_chosen = None for i, package in enumerate(API_PACKAGES_LIST): len_package = android_list_packages_lenghts[i] if api_call.startswith(package) and len_package > score: score = len_package package_chosen = package if package_chosen is not None: if not package_chosen in API_packages_dict.keys(): API_packages_dict[package_chosen] = list_smali_api_calls[ api_call] else: API_packages_dict[package_chosen] += list_smali_api_calls[ api_call] static_analysis_dict['API packages'] = API_packages_dict # Intents try: static_analysis_dict['Intents'] = intents_analysis( join_dir(analyze_apk.replace('.apk', ''), 'AndroidManifest.xml')) except: static_analysis_dict['Intents'] = {'Failed to extract intents': 0} # Intents of activities intents_activities = collections.OrderedDict() for activity in list_activities: intents_activities[activity] = check_for_intents( join_dir(analyze_apk.replace('.apk', ''), 'AndroidManifest.xml'), activity, 'activity') static_analysis_dict['Activities'] = intents_activities # Intents of services intents_services = collections.OrderedDict() for service in list_services: intents_services[service] = check_for_intents( join_dir(analyze_apk.replace('.apk', ''), 'AndroidManifest.xml'), service, 'service') static_analysis_dict['Services'] = intents_services # Intents of receivers intents_receivers = collections.OrderedDict() for intent in list_receivers: intents_receivers[intent] = check_for_intents( join_dir(analyze_apk.replace('.apk', '/'), 'AndroidManifest.xml'), intent, 'receiver') static_analysis_dict['Receivers'] = intents_receivers row = standardData(pre_static_dict, static_analysis_dict) if md5 in ARRNAME: index = -1 if md5 in ARRNAME: index = ARRNAME.index(md5) if sha256 in ARRNAME: index = ARRNAME.index(sha256) if index != -1: label = ARRLABELS[index] try: if label not in LABELSNUMANDTEXT: if 'SINGLETON' in label: continue continue # maxLabelsNum += 1 # temp = collections.OrderedDict() # temp[label] = maxLabelsNum # LABELSNUMANDTEXT[label] = maxLabelsNum except: continue labelNum = [LABELSNUMANDTEXT[label]] labelNum.extend(row) writer.writerow(labelNum) # apk_total_analysis = collections.OrderedDict([("Pre_static_analysis", pre_static_dict), # ("Static_analysis", static_analysis_dict)]) # # save_as_json(apk_total_analysis, output_name=join_dir(output_folder, apk_name_no_extensions + # "-analysis.json")) #save labelsnum neu co them nhan moo with open(str(LabelsNum_file), 'w+') as fp: json.dump(LABELSNUMANDTEXT, fp, indent=4) fp.close() # Save data config partData += 1 dataConfig['partData'] = partData dataConfig['maxLabelsNum'] = maxLabelsNum with open(str(config_file), 'w+') as fp: json.dump(dataConfig, fp, indent=4) fp.close() csvFile.close()
def testAPKIntentFilters(self): from androguard.core.bytecodes.apk import APK a = APK("examples/tests/a2dp.Vol_137.apk", testzip=True) activities = a.get_activities() receivers = a.get_receivers() services = a.get_services() filter_list = [] for i in activities: filters = a.get_intent_filters("activity", i) if len(filters) > 0: filter_list.append(filters) for i in receivers: filters = a.get_intent_filters("receiver", i) if len(filters) > 0: filter_list.append(filters) for i in services: filters = a.get_intent_filters("service", i) if len(filters) > 0: filter_list.append(filters) pairs = zip(filter_list, [{ 'action': ['android.intent.action.MAIN'], 'category': ['android.intent.category.LAUNCHER'] }, { 'action': [ 'android.intent.action.BOOT_COMPLETED', 'android.intent.action.MY_PACKAGE_REPLACED' ], 'category': ['android.intent.category.HOME'] }, { 'action': ['android.appwidget.action.APPWIDGET_UPDATE'] }, { 'action': ['android.service.notification.NotificationListenerService'] }]) self.assertFalse(any(x != y for x, y in pairs)) a = APK("examples/tests/com.test.intent_filter.apk", testzip=True) activities = a.get_activities() activities = a.get_activities() receivers = a.get_receivers() services = a.get_services() filter_list = [] for i in activities: filters = a.get_intent_filters("activity", i) if len(filters) > 0: filter_list.append(filters) for i in receivers: filters = a.get_intent_filters("receiver", i) if len(filters) > 0: filter_list.append(filters) for i in services: filters = a.get_intent_filters("service", i) if len(filters) > 0: filter_list.append(filters) pairs = zip(filter_list, [{ 'action': ['android.intent.action.VIEW'], 'category': [ 'android.intent.category.APP_BROWSER', 'android.intent.category.DEFAULT', 'android.intent.category.BROWSABLE' ], 'data': [{ 'scheme': 'testscheme', 'host': 'testhost', 'port': '0301', 'path': '/testpath', 'pathPattern': 'testpattern', 'mimeType': 'text/html' }] }, { 'action': ['android.intent.action.MAIN'], 'category': ['android.intent.category.LAUNCHER'] }, { 'action': ['android.intent.action.VIEW'], 'category': ['android.intent.category.DEFAULT', 'android.intent.category.BROWSABLE'], 'data': [{ 'scheme': 'testhost', 'host': 'testscheme', 'port': '0301', 'path': '/testpath', 'pathPattern': 'testpattern', 'mimeType': 'text/html' }] }, { 'action': ['android.intent.action.RESPOND_VIA_MESSAGE'], 'data': [{ 'scheme': 'testhost', 'host': 'testscheme', 'port': '0301', 'path': '/testpath', 'pathPattern': 'testpattern', 'mimeType': 'text/html' }, { 'scheme': 'testscheme2', 'host': 'testhost2', 'port': '0301', 'path': '/testpath2', 'pathPattern': 'testpattern2', 'mimeType': 'image/png' }] }]) self.assertFalse(any(x != y for x, y in pairs))
def processCheck(apkPath,total,already): global rootdir unionFingerOutputPath = rootdir+'unionFingerOutput/' unionOutputPath = rootdir+'unionOutput/' fidoOutputPath = rootdir+'fidoOutput/' fidoPermissionOutputPath = rootdir+'fidoPermissionOutput/' failedPath=rootdir+'failed/' unionfs = r'cn.com.union.fido.ui.finger.FingerActivity' #unionfs = r'cn.com.union.fido.service.AuthenticatorService' unions = r'union.fido' fidos = r'fido' try: a = APK(apkPath) except: print('[{0}/{1}]Analysis Failed {2}'.format(already,total,apkPath)) return activities = a.get_activities() name = a.get_app_name() find = False findstr = [] for activity in activities: if activity==unionfs: find=True findstr.append('[ACTIVITY]'+activity) if find: print('[{0}/{1}]FIND unionFinger in {2}'.format(already,total,apkPath)) copyTo(apkPath,unionFingerOutputPath,findstr,name) return findstr.clear() find=False for activity in activities: if(re.search(unions,activity.lower())): find=True findstr.append('[ACTIVITY]'+activity) permissions = a.get_permissions() for permission in permissions: if re.search(unions,permission.lower()): find=True, findstr.append('[PERMISSION]'+permission) services = a.get_services() for service in services: if re.search(unions,service.lower()): find=True, findstr.append('[SERVICE]'+service) if find: print('[{0}/{1}]FIND union in {2}'.format(already,total,apkPath)) copyTo(apkPath,unionOutputPath,findstr,name) return findstr.clear() find=False for activity in activities: if(re.search(fidos,activity.lower())): find=True findstr.append('[ACTIVITY]'+activity) hasFidoPermission = False fidoPermission=[] for permission in permissions: if re.search(fidos,permission.lower()): find=True, hasFidoPermission=True findstr.append('[PERMISSION]'+permission) fidoPermission.append('[PERMISSION]'+permission) if hasFidoPermission: print('[{0}/{1}]FIND fido permission in {2}'.format(already,total,apkPath)) copyTo(apkPath,fidoPermissionOutputPath,fidoPermission,name) for service in services: if re.search(fidos,service.lower()): find=True, findstr.append('[SERVICE]'+service) if find: print('[{0}/{1}]FIND fido in {2}'.format(already,total,apkPath)) copyTo(apkPath,fidoOutputPath,findstr,name) return print('[{0}/{1}]Nothing FOUND in {2}'.format(already,total,apkPath))