def getObf(self): self.ObfDic['REFLECTION'] = int(analysis.is_reflection_code(self.dx)) self.ObfDic['NATIVE'] = int(analysis.is_native_code(self.dx)) self.ObfDic['DYNAMIC'] = int(analysis.is_dyn_code(self.dx)) self.ObfDic['CRYPTO'] = int(analysis.is_crypto_code(self.dx)) return self.ObfDic
def load_app_info_table(self): self.info = {} self.info["Application Name"] = self.apk.get_app_name() self.info["Application Size"] = util.sizeof_fmt( os.path.getsize(self.apk_path)) self.info["Android Version Name"] = self.apk.get_androidversion_name() self.info["Android Version Code"] = self.apk.get_androidversion_code() self.info["Android Package Name"] = self.apk.get_package() self.info["Signature Name"] = self.apk.get_signature_name() self.info["Uses Dynamic Code Loading"] = str( analysis.is_dyn_code(self.x)) self.info["Uses Reflection"] = str(analysis.is_reflection_code(self.x)) self.info["Uses Crypto"] = str(analysis.is_crypto_code(self.x)) self.info["Privacy Leaks"] = str(len(self.get_privacy_leaks())) self.info["Number of Providers"] = str(len(self.apk.get_providers())) self.info["Number of Activities"] = str(len(self.apk.get_activities())) self.info["Number of Services"] = str(len(self.apk.get_services())) self.info["Number of Libraries"] = str(len(self.apk.get_libraries())) self.info["Number of Permissions"] = str( len(self.get_uses_permissions())) self.info_actions = {} self.info_actions["Application Name"] = None self.info_actions["Application Size"] = None self.info_actions["Android Version Name"] = None self.info_actions["Android Version Code"] = None self.info_actions["Android Package Name"] = None self.info_actions["Signature Name"] = self.show_signature self.info_actions["Uses Dynamic Code Loading"] = self.show_dyncode self.info_actions["Uses Reflection"] = self.show_reflection self.info_actions["Uses Crypto"] = self.show_cryptocode self.info_actions["Privacy Leaks"] = self.show_privacy_leaks self.info_actions["Number of Providers"] = self.show_providers self.info_actions["Number of Activities"] = self.show_activities self.info_actions["Number of Services"] = self.show_services self.info_actions["Number of Libraries"] = self.show_libraries self.info_actions["Number of Permissions"] = self.show_permissions info_table = self.ui.appInfoTable info_table.setRowCount(len(self.info)) info_table.setColumnWidth(1, 200) info_table.horizontalHeader().setResizeMode(0, QtGui.QHeaderView.Stretch) row = 0 for key in sorted(self.info): action = self.info_actions[key] action_button = None if action is not None: action_button = QtGui.QPushButton() action_button.setText("Show") action_button.clicked.connect(action) key_item = QtGui.QTableWidgetItem(key) value_item = QtGui.QTableWidgetItem(self.info[key]) info_table.setItem(row, 0, key_item) info_table.setItem(row, 1, value_item) if action_button is not None: info_table.setCellWidget(row, 2, action_button) row += 1
def print_crypto(dx, cm): OutStream.write("***crypto code loading***\n") if analysis.is_crypto_code(dx) == True: paths1 = dx.get_tainted_packages().search_methods("Ljavax/crypto/.",".",".") write_Paths(paths1, cm, OutStream) paths = dx.get_tainted_packages().search_methods("Ljava/security/spec/.",".",".") write_Paths(paths, cm, OutStream) OutStream.write("True\n") else: OutStream.write("False\n")
def load_app_info_table(self): self.info = {} self.info["Application Name"] = self.apk.get_app_name() self.info["Application Size"] = util.sizeof_fmt(os.path.getsize(self.apk_path)) self.info["Android Version Name"] = self.apk.get_androidversion_name() self.info["Android Version Code"] = self.apk.get_androidversion_code() self.info["Android Package Name"] = self.apk.get_package() self.info["Signature Name"] = self.apk.get_signature_name() self.info["Uses Dynamic Code Loading"] = str(analysis.is_dyn_code(self.x)) self.info["Uses Reflection"] = str(analysis.is_reflection_code(self.x)) self.info["Uses Crypto"] = str(analysis.is_crypto_code(self.x)) self.info["Privacy Leaks"] = str(len(self.get_privacy_leaks())) self.info["Number of Providers"] = str(len(self.apk.get_providers())) self.info["Number of Activities"] = str(len(self.apk.get_activities())) self.info["Number of Services"] = str(len(self.apk.get_services())) self.info["Number of Libraries"] = str(len(self.apk.get_libraries())) self.info["Number of Permissions"] = str(len(self.get_uses_permissions())) self.info_actions = {} self.info_actions["Application Name"] = None self.info_actions["Application Size"] = None self.info_actions["Android Version Name"] = None self.info_actions["Android Version Code"] = None self.info_actions["Android Package Name"] = None self.info_actions["Signature Name"] = self.show_signature self.info_actions["Uses Dynamic Code Loading"] = self.show_dyncode self.info_actions["Uses Reflection"] = self.show_reflection self.info_actions["Uses Crypto"] = self.show_cryptocode self.info_actions["Privacy Leaks"] = self.show_privacy_leaks self.info_actions["Number of Providers"] = self.show_providers self.info_actions["Number of Activities"] = self.show_activities self.info_actions["Number of Services"] = self.show_services self.info_actions["Number of Libraries"] = self.show_libraries self.info_actions["Number of Permissions"] = self.show_permissions info_table = self.ui.appInfoTable info_table.setRowCount(len(self.info)) info_table.setColumnWidth(1, 200) info_table.horizontalHeader().setResizeMode(0, QtGui.QHeaderView.Stretch) row = 0 for key in sorted(self.info): action = self.info_actions[key] action_button = None if action is not None: action_button = QtGui.QPushButton() action_button.setText("Show") action_button.clicked.connect(action) key_item = QtGui.QTableWidgetItem(key) value_item = QtGui.QTableWidgetItem(self.info[key]) info_table.setItem(row,0,key_item) info_table.setItem(row,1,value_item) if action_button is not None: info_table.setCellWidget(row,2,action_button) row += 1
def main(options, args) : print options.input print options.output if options.input == None or options.output == None : print "static_analysis.py -i <inputfile> -o <outputfolder>" sys.exit(2) else : ret_type = androconf.is_android( options.input ) if ret_type == "APK" : try : a = apk.APK(options.input, zipmodule=2) if a.is_valid_APK() : vm = dvm.DalvikVMFormat(a.get_dex()) vmx = analysis.uVMAnalysis(vm) data = { 'mainActivity' : a.get_main_activity(), 'activities' : a.get_activities(), 'providers' : a.get_providers(), 'receivers' : a.get_receivers(), 'services' : a.get_services(), 'androidVersion' : a.get_androidversion_code(), 'maxSdkVersion' : a.get_max_sdk_version(), 'minSdkVersion' : a.get_min_sdk_version(), 'targetSdkVersion' : a.get_target_sdk_version(), 'package' : a.get_package(), 'libraries' : a.get_libraries(), 'isCryptoCode' : analysis.is_crypto_code(vmx), 'isDynamicCode' : analysis.is_dyn_code(vmx), 'isNativeCode' : analysis.is_native_code(vmx), 'nativeMethodCount' : native_method_count(vm), 'isReflectionCode' : analysis.is_reflection_code(vmx), 'reflectionCount' : len(vmx.get_tainted_packages().search_methods("Ljava/lang/reflect/Method;", ".", ".")), 'isAsciiObfuscation' : analysis.is_ascii_obfuscation(vm), 'permissions' : a.get_permissions(), 'actualPermissions' : actual_permissions(vm, vmx), #'internalMethodCalls' : get_methods(vm.get_class_manager(), vmx.get_tainted_packages().get_internal_packages(), {}), 'externalMethodCalls' : get_methods(vm.get_class_manager(), vmx.get_tainted_packages().get_external_packages(), {}) } with io.open(options.output + "/" + hashfile(options.input) + ".json", 'w', encoding='utf-8') as f: f.write(unicode(json.dumps(data, sort_keys=False, indent=2, separators=(',', ': '), ensure_ascii=False))) else : print "INVALID APK" except Exception, e : print "ERROR", e import traceback traceback.print_exc()
def show_cryptocode(self): if analysis.is_crypto_code(self.x) is False: self.__logger.log(Logger.WARNING,"No crypto code was found! Maybe it uses adapted or obfuscated encryption code.") return paths = [] paths.extend(self.x.get_tainted_packages().search_methods("Ljavax/crypto/.", ".", ".")) paths.extend(self.x.get_tainted_packages().search_methods("Ljava/security/spec/.", ".", ".")) str_info_dyn="\t" for path in paths: str_info_dyn += (self.show_Path(self.x.get_vm(), path )+"\n\n\t") self.__logger.log_with_title("Usage of Crypto Code",str_info_dyn)
def show_cryptocode(self): if analysis.is_crypto_code(self.x) is False: self.__logger.log( Logger.WARNING, "No crypto code was found! Maybe it uses adapted or obfuscated encryption code." ) return paths = [] paths.extend(self.x.get_tainted_packages().search_methods( "Ljavax/crypto/.", ".", ".")) paths.extend(self.x.get_tainted_packages().search_methods( "Ljava/security/spec/.", ".", ".")) str_info_dyn = "\t" for path in paths: str_info_dyn += (self.show_Path(self.x.get_vm(), path) + "\n\n\t") self.__logger.log_with_title("Usage of Crypto Code", str_info_dyn)
def analyze_dex(self, d, dx, flags): flags["REFLECTION"] = int(analysis.is_reflection_code(dx)) flags["NATIVE"] = int(analysis.is_native_code(dx)) flags["DYNAMIC"] = int(analysis.is_dyn_code(dx)) flags["CRYPTO"] = int(analysis.is_crypto_code(dx))
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()] 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'] = {} # 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) 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 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 has_crypto(self): if analysis.is_crypto_code(self.dx): self.risk += 1 return True else: return False
def main(options, args) : print options.input if options.input == None or options.output == None : print "static_analysis.py -i <inputfile> -o <outputfolder>" sys.exit(2) elif db.static_features.find({"_id": hashfile(options.input)}, limit=1).count() == 1 : print "static analysis found.. skipping.." sys.exit(0) elif db.virustotal_features.find({"sha1": hashfile(options.input)}).count() == 0 : print "virus total metadata not found.. skipping.." sys.exit(0) elif db.virustotal_features.find({ "$or": [ { "positives": 0 }, { "positives": { "$gte": 35 } } ], "sha1": hashfile(options.input) }).count() == 0 : print "not clear enough benign or malicious.. skipping.." sys.exit(0) t_beginning = time.time() ret_type = androconf.is_android( options.input ) if ret_type == "APK" : try : a = apk.APK(options.input, zipmodule=2) if a.is_valid_APK() : vm = dvm.DalvikVMFormat(a.get_dex()) vmx = analysis.uVMAnalysis(vm) data = { '_id' : hashfile(options.input), 'validApk' : True, 'mainActivity' : a.get_main_activity(), 'activities' : a.get_activities(), 'providers' : a.get_providers(), 'receivers' : a.get_receivers(), 'services' : a.get_services(), 'androidVersion' : a.get_androidversion_code(), 'maxSdkVersion' : a.get_max_sdk_version(), 'minSdkVersion' : a.get_min_sdk_version(), 'targetSdkVersion' : a.get_target_sdk_version(), 'package' : a.get_package(), 'libraries' : a.get_libraries(), 'isCryptoCode' : analysis.is_crypto_code(vmx), 'isDynamicCode' : analysis.is_dyn_code(vmx), 'isNativeCode' : analysis.is_native_code(vmx), 'nativeMethodCount' : native_method_count(vm), 'isReflectionCode' : analysis.is_reflection_code(vmx), 'reflectionCount' : len(vmx.get_tainted_packages().search_methods("Ljava/lang/reflect/Method;", ".", ".")), 'isAsciiObfuscation' : analysis.is_ascii_obfuscation(vm), 'permissions' : a.get_permissions(), 'actualPermissions' : actual_permissions(vm, vmx), 'internalMethodCalls' : get_methods(vm.get_class_manager(), vmx.get_tainted_packages().get_internal_packages(), {}), 'externalMethodCalls' : get_methods(vm.get_class_manager(), vmx.get_tainted_packages().get_external_packages(), {}) } data['duration'] = time.time() - t_beginning db.static_features.insert(data) else : print "INVALID APK" data = { '_id' : hashfile(options.input), 'validApk' : False } db.static_features.insert(data) except Exception, e : print "ERROR", e import traceback traceback.print_exc()