def each(self, target): self.results = dict() try: apk, vm, vm_analysis = AnalyzeAPK(target) # First, get basic information about the APK self.results['name'] = apk.get_app_name() self.results['package'] = apk.get_package() self.results['permissions'] = apk.get_permissions() self.results['main_activity'] = apk.get_main_activity() self.results['receivers'] = apk.get_receivers() self.results['services'] = apk.get_services() self.results['main_activity_content'] = vm.get_class("L{};".format( self.results['main_activity']).replace('.', '/')).get_source() except: apk = None vm, vm_analysis = AnalyzeDex(target) self.results['dex'] = True # Then, run all the APK Plugins in order to see if this is a known malware for plugin in APKPlugin.__subclasses__(): plugin = plugin(target, apk, vm, vm_analysis) plugin.apply(self) return True
def each(self, target): self.results = dict(name=None, files=[], package=None, permissions=[], declared_permissions=[], main_activity=None, activities=[], receivers=[], services=[], manifest=None, libraries=[], main_activity_content=None, internal_classes=[]) try: apk, vm, vm_analysis = AnalyzeAPK(target) # First, get basic information about the APK self.results['name'] = apk.get_app_name() self.results['files'] = apk.get_files_types() self.results['package'] = apk.get_package() self.results['permissions'] = apk.get_details_permissions() self.results[ 'declared_permissions'] = apk.get_declared_permissions_details( ) self.results['main_activity'] = apk.get_main_activity() self.results['activities'] = apk.get_activities() self.results['receivers'] = apk.get_receivers() self.results['services'] = apk.get_services() self.results['manifest'] = apk.get_android_manifest_axml().get_xml( ) self.results['libraries'] = list(apk.get_libraries()) self.results['main_activity_content'] = None self.results['internal_classes'] = [] try: self.results['main_activity_content'] = self.results[ 'main_activity_content'] = vm[0].get_class( "L{};".format(self.results['main_activity']).replace( '.', '/')).get_source() except: self.log('error', traceback.print_exc()) try: self.results['internal_classes'] = self._get_internal_classes( vm_analysis) self._store_internal_classes() except: self.log('error', traceback.print_exc()) # Then, run all the APK Plugins in order to see if this is a known malware for plugin in APKPlugin.__subclasses__(): plugin = plugin(target, apk, vm, vm_analysis) plugin.apply(self) except: self.log('error', traceback.print_exc()) return True
def androcg_main(verbose, APK, classname, methodname, descriptor, accessflag, no_isolated, show, output): from androguard.core.androconf import show_logging from androguard.core.bytecode import FormatClassToJava from androguard.misc import AnalyzeAPK import networkx as nx import logging log = logging.getLogger("androcfg") if verbose: show_logging(logging.INFO) a, d, dx = AnalyzeAPK(APK) entry_points = map(FormatClassToJava, a.get_activities() + a.get_providers() + a.get_services() + a.get_receivers()) entry_points = list(entry_points) log.info("Found The following entry points by search AndroidManifest.xml: " "{}".format(entry_points)) CG = dx.get_call_graph(classname, methodname, descriptor, accessflag, no_isolated, entry_points, ) write_methods = dict(gml=_write_gml, gexf=nx.write_gexf, gpickle=nx.write_gpickle, graphml=nx.write_graphml, yaml=nx.write_yaml, net=nx.write_pajek, ) if show: plot(CG) else: writer = output.rsplit(".", 1)[1] if writer in ["bz2", "gz"]: writer = output.rsplit(".", 2)[1] if writer not in write_methods: print("Could not find a method to export files to {}!" .format(writer)) sys.exit(1) write_methods[writer](CG, output)
def androcg_main(verbose, APK, classname, methodname, descriptor, accessflag, no_isolated, show, output): from androguard.core.androconf import show_logging from androguard.core.bytecode import FormatClassToJava from androguard.misc import AnalyzeAPK import networkx as nx import logging log = logging.getLogger("androcfg") if verbose: show_logging(logging.INFO) a, d, dx = AnalyzeAPK(APK) entry_points = map(FormatClassToJava, a.get_activities() + a.get_providers() + a.get_services() + a.get_receivers()) entry_points = list(entry_points) log.info("Found The following entry points by search AndroidManifest.xml: " "{}".format(entry_points)) CG = dx.get_call_graph(classname, methodname, descriptor, accessflag, no_isolated, entry_points, ) write_methods = dict(gml=_write_gml, gexf=nx.write_gexf, gpickle=nx.write_gpickle, graphml=nx.write_graphml, yaml=nx.write_yaml, net=nx.write_pajek, ) if show: plot(CG) else: writer = output.rsplit(".", 1)[1] if writer in ["bz2", "gz"]: writer = output.rsplit(".", 2)[1] if writer not in write_methods: print("Could not find a method to export files to {}!" .format(writer)) sys.exit(1) write_methods[writer](CG, output)
def get_call_graph(self, apk): a, d, dx = AnalyzeAPK(apk) entry_points = map( FormatClassToJava, a.get_activities() + a.get_providers() + a.get_services() + a.get_receivers()) entry_points = list(entry_points) #TODO make these Configurable # args.classname, # args.methodname, # args.descriptor, # args.accessflag, # args.no_isolated, CG = dx.get_call_graph(entry_points=entry_points) # write_methods = dict(gml=_write_gml, # gexf=nx.write_gexf, # gpickle=nx.write_gpickle, # graphml=nx.write_graphml, # yaml=nx.write_yaml, # net=nx.write_pajek, return CG
def main(): parser = ArgumentParser(description="Create a call graph based on the data" "of Analysis and export it into a graph format.") parser.add_argument("APK", nargs=1, help="The APK to analyze") parser.add_argument( "--output", "-o", default="callgraph.gml", help= "Filename of the output file, the extension is used to decide which format to use (default callgraph.gml)" ) parser.add_argument( "--show", "-s", action="store_true", default=False, help= "instead of saving the graph, print it with mathplotlib (you might not see anything!" ) parser.add_argument("--verbose", "-v", action="store_true", default=False, help="Print more output") parser.add_argument("--classname", default=".*", help="Regex to filter by classname") parser.add_argument("--methodname", default=".*", help="Regex to filter by methodname") parser.add_argument("--descriptor", default=".*", help="Regex to filter by descriptor") parser.add_argument("--accessflag", default=".*", help="Regex to filter by accessflags") parser.add_argument("--no-isolated", default=False, action="store_true", help="Do not store methods which has no xrefs") args = parser.parse_args() if args.verbose: show_logging(logging.INFO) a, d, dx = AnalyzeAPK(args.APK[0]) entry_points = map( FormatClassToJava, a.get_activities() + a.get_providers() + a.get_services() + a.get_receivers()) entry_points = list(entry_points) log.info( "Found The following entry points by search AndroidManifest.xml: {}". format(entry_points)) CG = dx.get_call_graph( args.classname, args.methodname, args.descriptor, args.accessflag, args.no_isolated, entry_points, ) write_methods = dict( gml=_write_gml, gexf=nx.write_gexf, gpickle=nx.write_gpickle, graphml=nx.write_graphml, yaml=nx.write_yaml, net=nx.write_pajek, ) if args.show: plot(CG) else: writer = args.output.rsplit(".", 1)[1] if writer in ["bz2", "gz"]: writer = args.output.rsplit(".", 2)[1] if writer not in write_methods: print("Could not find a method to export files to {}!".format( writer)) sys.exit(1) write_methods[writer](CG, args.output)
def main(file_name): #apk_file="com.coloros.gallery3d.apk" if (len(file_name) < 2): apk_file = "BackupAndRestore.apk" else: apk_file = file_name #apk_file="BackupAndRestore.apk" a, d, dalvik_ctx = AnalyzeAPK(apk_file) #print("[+] %s init Done" %(apk_file)) signed_flag = True for cert in a.get_certificates(): # cert.sha1 # the sha1 fingerprint # cert.sha256 # the sha256 fingerprint # cert.issuer.human_friendly # issuer # cert.subject.human_friendly # subject, usually the same # cert.hash_algo # hash algorithm # cert.signature_algo # Signature algorithm # cert.serial_number # Serial number # cert.contents # The DER coded bytes of the certificate itself finger_print = "9C A5 17 0F 38 19 19 DF E0 44 6F CD AB 18 B1 9A 14 3B 31 63" if (str(finger_print) == str(cert.sha1_fingerprint)): signed_flag = True print("----------------------------------------------------") print("[+] %s init Done" % (apk_file)) print("[+] is priv-app [True] ") break else: signed_flag = False #print("[-] is priv-app [False]") break if (signed_flag == False): sys.exit(1) if (not a.is_signed_v2() or not a.is_signed_v3()): print("[!] APK [%s] is not signed from v2, v3" % (apk_file)) service_lists = a.get_services() manifestData = str(a.get_android_manifest_axml().get_xml()) soup = BeautifulSoup(manifestData, 'html.parser') for service_name in service_lists: tmpData = "" intent_filter = [] permission = "" exported = False has_ifilter = False service_name = service_name.split(".")[-1] services = soup.find_all("service") for service in services: if (service.has_attr('android:name')): if (service_name in service['android:name']): pass else: continue if (service.has_attr('android:permission')): permission = service['android:permission'] else: permission = "" if (service.has_attr('android:exported')): if (service['android:exported'] == "true"): exported = True else: exported = False # intent filter if (len(service.find_all('intent-filter')) > 0): has_ifilter = True intents = service.find_all('intent-filter') for intent in intents: actions = intent.find_all('action') #print(actions) for action in actions: #print(action) intent_filter.append(action['android:name']) if (exported == True or has_ifilter == True): print("[!] (exported=[%s]) ->" % (exported), end=' ') print(service_name, end='') print(" (perm:[%s])" % permission, end="->") import subprocess if (permission != ""): command_string = 'adb shell "pm list permissions -f |grep %s -A 10 |grep protection | head -n 1"' % ( permission) output = subprocess.check_output(command_string, shell=True) output = output.decode("utf-8").strip() if (len(str(output)) < 2): print("[can not find permission]") else: print("[%s]" % (output)) else: print("[no permission]") for intent in intent_filter: print("\t[->]intent-filter action: [%s] " % intent) receivers = a.get_receivers() for receive_name in receivers: print("[+] Receiver : " + receive_name)
def main(): parser = ArgumentParser(description="Create a call graph based on the data" "of Analysis and export it into a graph format.") parser.add_argument("APK", nargs=1, help="The APK to analyze") parser.add_argument("--output", "-o", default="callgraph.gml", help="Filename of the output file, the extension is used to decide which format to use (default callgraph.gml)") parser.add_argument("--show", "-s", action="store_true", default=False, help="instead of saving the graph, print it with mathplotlib (you might not see anything!") parser.add_argument("--verbose", "-v", action="store_true", default=False, help="Print more output") parser.add_argument("--classname", default=".*", help="Regex to filter by classname") parser.add_argument("--methodname", default=".*", help="Regex to filter by methodname") parser.add_argument("--descriptor", default=".*", help="Regex to filter by descriptor") parser.add_argument("--accessflag", default=".*", help="Regex to filter by accessflags") parser.add_argument("--no-isolated", default=False, action="store_true", help="Do not store methods which has no xrefs") args = parser.parse_args() if args.verbose: show_logging(logging.INFO) a, d, dx = AnalyzeAPK(args.APK[0]) entry_points = map(FormatClassToJava, a.get_activities() + a.get_providers() + a.get_services() + a.get_receivers()) entry_points = list(entry_points) log.info("Found The following entry points by search AndroidManifest.xml: {}".format(entry_points)) CG = dx.get_call_graph(args.classname, args.methodname, args.descriptor, args.accessflag, args.no_isolated, entry_points, ) write_methods = dict(gml=_write_gml, gexf=nx.write_gexf, gpickle=nx.write_gpickle, graphml=nx.write_graphml, yaml=nx.write_yaml, net=nx.write_pajek, ) if args.show: plot(CG) else: writer = args.output.rsplit(".", 1)[1] if writer in ["bz2", "gz"]: writer = args.output.rsplit(".", 2)[1] if writer not in write_methods: print("Could not find a method to export files to {}!".format(writer)) sys.exit(1) write_methods[writer](CG, args.output)
return alista i = 0 while i < 1200: file = (data.iloc[i][0]) numero = (data.iloc[i][1]) try: a, d, dx = AnalyzeAPK(file) print ("===> "+ file + " <===") perms = (a.get_permissions()) prov = (a.get_providers()) serv = (a.get_services()) sint = helper(serv,'service') receivers = a.get_receivers() r = [] for x in receivers: r.append(x) rint = helper(receivers,'receiver') writer.writerow((numero,file,perms,prov,serv,sint,r,rint)) csv_base.flush() except zipfile.BadZipFile: # WiNDOWS FILE print ('THEY TRY 2 GET ME' + str(numero) ) except KeyError: # DIC ERROR print('F**K ====>' + str(numero)) except TypeError: print ('Really ====>' + str(numero)) print ("===> "+ str(numero) + " <===") i = i + 1
print('\nMain activity:') print(apk.get_main_activity()) print('\nSuper dangerous permissions:') for perm, details in apk.get_details_permissions().items(): if details[0] == 'dangerous': # Protection levels: https://developer.android.com/guide/topics/permissions/overview#normal-dangerous print(perm) print('\nServices:') for service in apk.get_services(): print(service) print('\nBroadcasts:') for receiver in apk.get_receivers(): print(receiver) print('\nIntent Filters:') for service in apk.get_services(): print('\nFilters for {}'.format(service)) filters = apk.get_intent_filters('service', service) if filters: print(filters) for receiver in apk.get_receivers(): print('\nFilters for {}'.format(receiver)) filters = apk.get_intent_filters('receiver', receiver) if filters: print(filters)
'version_code': apk.xml['AndroidManifest.xml'].get( '{http://schemas.android.com/apk/res/android}versionCode'), 'libraries': list(apk.get_libraries()), 'androidtv': apk.is_androidtv(), 'target_sdk_version': apk.get_target_sdk_version(), 'api_keys': {}, # TODO 'activities': apk.get_activities(), 'main_activity': apk.get_main_activity(), 'receivers': apk.get_receivers(), 'signature_name': apk.get_signature_name(), 'dexes': {}, 'displayed_version': apk.xml['AndroidManifest.xml'].get( '{http://schemas.android.com/apk/res/android}versionName'), 'services': apk.get_services(), 'permissions': apk.get_permissions(), 'cordova': None, #What is this ? 'functionalities': {}, 'urls': get_urls(apk),
def run(self): app.logger.info('new analysis') s = Session() self.status = 'Analyzing APK' a, d, dx = AnalyzeAPK(self.target_file, session=s) #APK,list[DalvikVMFormat],Analysis print(type(a), type(d[0]), type(dx)) #cache activities, receivers, services, and providers, because for some reason, saving the Session causes a bug, breaking getters """i.e. bytecodes/apk.py", line 582, in get_elements for item in self.xml[i].findall('.//' + tag_name): TypeError: string indices must be integers """ activities = a.get_activities() receivers = a.get_receivers() services = a.get_services() providers = a.get_providers() self.main_activity = a.get_main_activity() if self.session_save_file: sys.setrecursionlimit(100000000) self.status = 'Saving session file' Save(s, self.session_save_file) cached_analyses.append({'md5': self.md5, 'analysis': (a, d, dx)}) #gather all classes from dexs 'd' #classes = get_all_classes_from_dexs(d) classes = dx.classes total_num = len(classes) done = 0 #num of done classes #result_classes contains the completed analysis info for each class run through the ClassAnalysis object result_classes = [] analysis_start_time = time.time() self.status = 'Getting all classes' for c_name, c_analysis in classes.items(): ca = ClassAnalysis(c_name, c_analysis, activities, receivers, services, providers) ca_result = ca.run() result_classes.append(ca_result) done += 1 if done % ceil(total_num / 100) == 0: self.progress += 1 #app.logger.info(self.progress) # with app.test_request_context('/'): # socketio.emit('newstatus', {'data':self.progress}, namespace='/status') analysis_end_time = time.time() analysis_total_time = analysis_end_time - analysis_start_time #debugging: self.status = 'Writing beforenetworkx debugging JSON' with open(self.graph_out_path + '.beforenetworkx', 'w') as f: json.dump(result_classes, f, indent=4, separators=(',', ': '), sort_keys=True) #create a networkx graph given the completed analyses in result_classess create_graph_start_time = time.time() self.status = 'Creating graph out of {} classes analyzed'.format( len(result_classes)) graph = create_graph(classes=result_classes) create_graph_end_time = time.time() create_graph_total_time = create_graph_end_time - create_graph_start_time #write graph to file: graph_out_path write_graph_start_time = time.time() self.status = 'Writing graph to disk' write_graph(graph, self.graph_out_path) write_graph_end_time = time.time() write_graph_total_time = write_graph_end_time - write_graph_start_time #build and write another graph that contains only providers,receivers,activities, and services if self.component_subgraph_out_path: component_names = [] self.status = 'Getting component nodes from graph' for node in graph: node_tmp = graph.node[node] if node_tmp[ 'component_type'] != NonComponentType.EXTERNAL and node_tmp[ 'component_type'] != NonComponentType.INTERNAL: component_names.append(node_tmp['name']) self.status = 'Creating subgraph containing only components' subgraph = get_class_subgraph(graph, class_names=component_names) self.status = 'Writing subgraph to disk' write_graph(subgraph, self.component_subgraph_out_path) #app metadata for misc/debugging apk_size = os.path.getsize(self.target_file) self.status = 'Writing metadata' self.write_app_metadata(result_classes, a, analysis_total_time, apk_size, create_graph_total_time, write_graph_total_time) #debugging # with open(self.graph_out_path+'.runmetrics', 'w') as f: # json.dump() self.progress = 100 self.status = 'Done' self.paused.wait( ) #wait for caller to collect last status and reset event before finishing app.logger.info('done')