def secret_scanner(hash_of_apk): api_keys = [] dbname = 'adhrit.db' dbconstatus = dbconnection(dbname) create_secrets_table(dbconstatus) path = hash_of_apk os.chdir(path) with concurrent.futures.ProcessPoolExecutor() as executor: p1 = executor.submit(url_scanner) p2 = executor.submit(api_scanner) p3 = executor.submit(lib_pwn) urls = p1.result() strings_from_lib = p3.result() key = p2.result() api_keys.extend(key) print(strings_from_lib) path = os.getcwd() + '/..' os.chdir(path) allsecrets = (str(hash_of_apk), str(list(urls)), str(strings_from_lib), str(list(api_keys))) addtotable = insert_secretstable(dbconstatus, allsecrets) #-------------------------------- dbname = "adhrit.db" dbconstatus = dbconnection(dbname) query = f"UPDATE StatusDB SET Secrets='complete' WHERE Hash='{hash_of_apk}';" addedornot = insert_statustable(dbconstatus, query)
def add_to_db(hash_of_apk): dbname = "adhrit.db" hash_of_apk = hash_of_apk dbconstatus = dbconnection(dbname) create_bytecode_table(dbconstatus) datadetails = (str(hash_of_apk), str(sortify(set_of_unsafe_intent_list)), str(sortify(set_of_url_allowed_list)), str(sortify(set_of_content_allowed_list)), str(sortify(set_of_list_of_unenc_soc)), str(sortify(set_of_insecure_socket_list)), str(sortify(set_of_tls_validity_list)), str(sortify(set_of_sys_broadcast_list)), str(sortify(set_of_empty_pend_list)), str(sortify(set_of_search_dynamic)), str(sortify(set_of_ecb)), str(sortify(set_of_js)), str(sortify(set_of_list_of_cookie_overwrite)), str(sortify(set_of_weak_checks_list)), str(sortify(set_of_execsql_used)), str(sortify(set_of_sharedprefs_used)), str(sortify(set_of_sqli_used)), str(sortify(set_of_int_storage_used)), str(sortify(set_of_keystore_used))) addedornot = insert_bytecodetable(dbconstatus, datadetails)
def main(hash_of_apk): adhrit = Adhrit() apk_name = 'app.apk' adhrit.manifestanalyzer(apk_name, hash_of_apk) #-------------------------------- dbname = "adhrit.db" dbconstatus = dbconnection(dbname) query = f"UPDATE StatusDB SET Manifest='complete' WHERE Hash='{hash_of_apk}';" addedornot = insert_statustable(dbconstatus, query)
def del_row(hash_of_apk): dbname = "adhrit.db" conn = dbconnection(dbname) query1 = f"DELETE FROM DataDB WHERE Hash = '{hash_of_apk}'" query2 = f"DELETE FROM BytecodeDB WHERE Hash = '{hash_of_apk}'" query3 = f"DELETE FROM SecretsDB WHERE Hash = '{hash_of_apk}'" try: Cursor = conn.cursor() Cursor.execute(query1) Cursor.execute(query2) Cursor.execute(query3) conn.commit() except Error as e: print(e)
def add_to_db(): dbname = "adhrit.db" dbconstatus = dbconnection(dbname) create_bytecode_table(dbconstatus) thesid = get_config_data('scan_id') datadetails = (str(thesid), str(list(set_of_unsafe_intent_list)), str(list(set_of_url_allowed_list)), str(list(set_of_content_allowed_list)), str(list(set_of_list_of_unenc_soc)), str(list(set_of_insecure_socket_list)), str(list(set_of_tls_validity_list)), str(list(set_of_sys_broadcast_list)), str(list(set_of_empty_pend_list)), str(list(set_of_search_dynamic)), str(list(set_of_ecb)), str(list(set_of_js)), str(list(set_of_list_of_cookie_overwrite)), str(list(set_of_weak_checks_list))) addedornot = insert_bytecodetable(dbconstatus, datadetails)
def secret_scanner(): api_keys = [] dbname = 'adhrit.db' dbconstatus = dbconnection(dbname) create_secrets_table(dbconstatus) thesid = get_config_data('scan_id') urls = url_scanner() strings_from_lib = lib_pwn() print(str(strings_from_lib)) api_keys.append(api_scanner()) print(str(api_keys)) allsecrets = (str(thesid), str(list(urls)), str(list(strings_from_lib)), str(list(api_keys))) addtotable = insert_secretstable(dbconstatus, allsecrets)
def query_on_StatusDB(hash_of_apk): dbname = "adhrit.db" conn = dbconnection(dbname) create_status_table(conn) Cursor = conn.cursor() query = "SELECT Hash, Manifest, Bytecode, Secrets from `StatusDB` WHERE `Hash` = '%s'" % str(hash_of_apk) Cursor.execute(query) data=Cursor.fetchone() if data is None: query = f"INSERT INTO StatusDB(Hash, Manifest, Bytecode, Secrets) values('{hash_of_apk}', 'incomplete', 'incomplete', 'incomplete')" Cursor.execute(query) conn.commit() query = "SELECT Hash, Manifest, Bytecode, Secrets from `StatusDB` WHERE `Hash` = '%s'" % str(hash_of_apk) Cursor.execute(query) data=Cursor.fetchone() result ={'hash_of_apk': data[0], 'manifest':data[1], 'bytecode':data[2], 'secrets' : data[3]} return result else: result ={'hash_of_apk': data[0], 'manifest':data[1], 'bytecode':data[2], 'secrets' : data[3]} return result
def reset_db(): print("\n") dbname = 'adhrit.db' dbstat = dbconnection(dbname) truncate_table(dbstat) print("DATABASE HAS BEEN RESET")
def man_scanner(): global pkg_name scanned_acts = [] scanned_perms = [] scanned_custom_perms = [] scanned_critical_perms = [] scanned_exported_acts = [] scanned_receivers = [] scanned_exported_receivers = [] scanned_taskaffinity = [] scanned_deeplinks = [] scanned_exported_services = [] scanned_services = [] scanned_provider = [] scanned_implicit_intent = [] json_acts = [] json_export_acts = [] json_critical_perms = [] json_custom_perms = [] json_perms = [] json_receivers = [] json_export_receivers = [] json_taskaffinity = [] json_deeplinks = [] json_export_services = [] json_services = [] json_provider = [] json_implicit_intent = [] all_app_tags = [] name = "{http://schemas.android.com/apk/res/android}name" allow_backup = "{http://schemas.android.com/apk/res/android}allowBackup" debuggable = "{http://schemas.android.com/apk/res/android}debuggable" taskAffinity = "{http://schemas.android.com/apk/res/android}taskAffinity" permission = "{http://schemas.android.com/apk/res/android}permission" exported = 'http://schemas.android.com/apk/res/android}exported' host = '{http://schemas.android.com/apk/res/android}host' path = '{http://schemas.android.com/apk/res/android}path' pathPattern = '{http://schemas.android.com/apk/res/android}pathPattern' scheme = '{http://schemas.android.com/apk/res/android}scheme' category_BROWSABLE = "android.intent.category.BROWSABLE" action_VIEW = "android.intent.action.VIEW" exp_status = 0 act_count = 0 ta_count = 0 deeplinks_count = 0 check_deps = configparser.ConfigParser() check_deps.read('adhrit/config') thescanid = check_deps.get('config-data', 'scan_id') tstamp = strftime("%Y-%m-%d %H:%M:%S", gmtime()) dbname = "adhrit.db" scandetails = (str(thescanid), str(tstamp)) dbconstatus = dbconnection(dbname) print("MANIFEST ANALYSIS") perm_severe = { "android.permission.ACCESS_SUPERUSER", "android.permission.USE_FINGERPRINT", "android.permission.MANAGE_DOCUMENTS", "android.permission.READ_FRAME_BUFFER", "android.permission.READ_SMS", "android.permission.RECEIVE_SMS", "android.permission.RECEIVE_WAP_PUSH", "android.permission.RECORD_AUDIO", "android.permission.READ_PHONE_STATE", "android.permission.READ_PHONE_NUMBERS", "android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION", "android.permission.ADD_VOICEMAIL", "android.permission.ANSWER_PHONE_CALLS", "android.permission.BODY_SENSORS", "android.permission.CALL_PHONE", "android.permission.CAMERA", "android.permission.GET_ACCOUNTS", "android.permission.PROCESS_OUTGOING_CALLS", "android.permission.READ_CALENDAR", "android.permission.READ_CALL_LOG", "android.permission.READ_CONTACTS", "android.permission.READ_EXTERNAL_STORAGE", "android.permission.WRITE_EXTERNAL_STORAGE", "android.permission.USE_SIP", "android.permission.WRITE_CALENDAR", "android.permission.WRITE_CALL_LOG", "android.permission.WRITE_CONTACTS" } xmlfile = 'Manifest.xml' if os.path.exists(xmlfile): print("Manifest found. Starting analysis\n") tree = Et.parse(xmlfile) root = tree.getroot() for pkg_attribs in root.attrib: if pkg_attribs == "package": pkg_name = root.attrib[pkg_attribs] # Checking for backup status backup_status = root.findall("application") for acts in backup_status: for bckp in acts.attrib: if bckp == allow_backup: if acts.attrib[bckp] == "true": print('Backup Status: ' + str(' True')) else: print('Backup Status: ' + str(' False')) # Checking for debug flag for debugattrib in backup_status: for dbgstatus in debugattrib.attrib: if dbgstatus == debuggable: if debugattrib.attrib[dbgstatus] == "true": print('Debug Status: ' + str(' True')) else: print('Debug Status: ' + str(' False')) # List of critical permissions permissions = root.iter('uses-permission') for perms in permissions: if perms.attrib[name] in perm_severe: # c3 += 1 #JSON DATA scanned_critical_perms.append(perms.attrib[name]) json_critical_perms = json.dumps(scanned_critical_perms) # List of all permissions print("Listing all permissions.") permissions = root.iter('uses-permission') for perms in permissions: # c2 += 1 if not perms.attrib[name].startswith( "android.permission"): # Custom permissions # print(perms.attrib[name]) # JSON DATA var = perms.tag + ' : ' + str(perms.attrib[name]) scanned_custom_perms.append(var) json_custom_perms = json.dumps(scanned_custom_perms) else: #normal permissions # JSON DATA scanned_perms.append(perms.attrib[name]) json_perms = json.dumps(scanned_perms) # List of activities print("List of Activities") act_lists = root.iter('activity') for activity in act_lists: act_count += 1 # JSON DATA scanned_acts.append(str(activity.attrib[name])) json_acts = json.dumps(scanned_acts) act_alias_lists = root.iter( 'activity-alias') # appending Activity alias to activity list for activityalias in act_alias_lists: act_count += 1 # JSON DATA scanned_acts.append(str(activityalias.attrib[name])) json_acts = json.dumps(scanned_acts) # List of exported activities exp_act_list = root.iter('activity') for activity in exp_act_list: for act_key, act_val in activity.attrib.items(): if exported in act_key and act_val == 'true': #JSON DATA scanned_exported_acts.append(activity.attrib[name]) json_export_acts = json.dumps(scanned_exported_acts) if not scanned_exported_acts: print("No exported activities found.") # Checking for receivers print("Checking for BroadcastReceivers") rec_count = 0 sts_code = 0 receiver_list = root.iter('receiver') for receiver in receiver_list: sts_code = 0 rec_count += 1 for recv_key, recv_val in receiver.attrib.items(): if exported in recv_key and recv_val == 'true': #exported broadcast receiver # print(f'{rec_count} {receiver.attrib[name]}') sts_code = 1 # JSON DATA scanned_exported_receivers.append( str(receiver.attrib[name])) json_export_receivers = json.dumps( scanned_exported_receivers) if permission in recv_key: #custom permissions for broadcast receiver # print(receiver.attrib[permission]) # JSON DATA var = receiver.tag + ' : ' + str( receiver.attrib[permission]) scanned_custom_perms.append(var) json_custom_perms = json.dumps(scanned_custom_perms) if (sts_code != 1): # print(f'{rec_count} {receiver.attrib[name]}') # JSON DATA scanned_receivers.append(str(receiver.attrib[name])) json_receivers = json.dumps(scanned_receivers) pass # DeepLinks intentFilter = root.findall("./application/activity/") for eachIntentFilter in intentFilter: newparent = eachIntentFilter for action in newparent.iter('action'): if action_VIEW in action.attrib[name]: # print(action.attrib[name]) for category in newparent.iter('category'): if category_BROWSABLE in category.attrib[name]: for data in newparent.iter('data'): deeplink = '' deeplink = str( data.attrib[scheme]) + '://' + str( data.attrib[host]) # print(data.attrib[host]+data.attrib[scheme]+data.attrib[path]) if pathPattern in data.attrib: tmp = str(data.attrib[pathPattern]) elif path in data.attrib: tmp = str(data.attrib[path]) else: # print('no path or path prefix predifined') tmp = '' deeplinks_count += 1 deeplink += tmp scanned_deeplinks.append(deeplink) json_deeplinks = json.dumps(scanned_deeplinks) # print(deeplink) # TaskAffinity # Check in application tag for affinity_status in backup_status: for affkey, affval in affinity_status.attrib.items(): all_app_tags.append(str(affkey)) if affkey == taskAffinity: if affval == "": info = "Null predifined in application tag." # JSON DATA scanned_taskaffinity.append(info) json_taskaffinity = json.dumps(scanned_taskaffinity) pass # if taskAffinity not in all_app_tags: # info = "The application tag has no taskAffinity set to NULL. Activities Hijackable!" # # JSON DATA # scanned_taskaffinity.append(info) # json_taskaffinity = json.dumps(scanned_taskaffinity) # Check in all activity tag for activity in root.iter('activity'): for affkey, affval in activity.attrib.items(): if taskAffinity in affkey: ta_count += 1 info = str(activity.attrib[name]) # JSON DATA scanned_taskaffinity.append(info) json_taskaffinity = json.dumps(scanned_taskaffinity) if ta_count == 0: info = 'None of the activity tag has TaskAffinity predifined in it.' # JSON DATA # scanned_taskaffinity.append(info) # json_taskaffinity = json.dumps(scanned_taskaffinity) # Services and Exp Services print('Checking for Services') ser_cnt = 0 sts_code = 0 service_list = root.iter('service') for service in service_list: sts_code = 0 ser_cnt += 1 for ser_key, ser_val in service.attrib.items(): if exported in ser_key and ser_val == 'true': # print(f'{ser_cnt} ** {service.attrib[name]}') sts_code = 1 # JSON DATA scanned_exported_services.append(str(service.attrib[name])) json_export_services = json.dumps( scanned_exported_services) if permission in ser_key: #Custom Perm for services var = service.tag + ' : ' + str(service.attrib[permission]) if var not in scanned_custom_perms: scanned_custom_perms.append(var) json_custom_perms = json.dumps(scanned_custom_perms) if (sts_code != 1): # print(f'{ser_cnt} * {service.attrib[name]}') # JSON DATA scanned_services.append(str(service.attrib[name])) json_services = json.dumps(scanned_services) # Provider print('Checking for Content Providers') pr_cnt = 0 sts_code = 0 pr_parent_dic = {} pr_child_dic = {} provider_list = root.iter('provider') for provider in provider_list: pr_child_dic = {} pr_cnt += 1 for pr_key, pr_val in provider.attrib.items(): pr_key = pr_key.partition( '{http://schemas.android.com/apk/res/android}')[2] pr_child_dic.__setitem__(pr_key, pr_val) # print(pr_child_dic) pr_parent_dic.__setitem__(pr_cnt, pr_child_dic) # print(pr_parent_dic) json_provider = json.dumps(pr_parent_dic) name_loc = 0 iter_no = 0 for i in range(1, pr_cnt + 1): name_loc = iter_no for key, val in pr_parent_dic[i].items(): iter_no += 1 var = key + ' : ' + val if key == 'name': scanned_provider.insert(name_loc, var) else: scanned_provider.append(var) scanned_provider.append(' ') iter_no += 1 # print(scanned_provider) #Implicit Intent print('Checking for Implicit Intent') intent_fiter_dict = {} sts_code = 0 intent_filter_parents = [ "activity", "activity-alias", "service", "provider", "receiver" ] for each_intent_filter_parent in intent_filter_parents: single_intent_filter_obj = [] parent_elems = root.getiterator(each_intent_filter_parent) for parent_elem in parent_elems: for each_intent_filter in list(parent_elem): var_key = parent_elem.tag + ' : ' + parent_elem.attrib[name] if var_key in intent_fiter_dict.keys(): single_intent_filter_obj.pop() sts_code = 1 pass else: if 'data : ' not in str( single_intent_filter_obj ) and len(single_intent_filter_obj) > 1: scanned_implicit_intent.extend( single_intent_filter_obj) single_intent_filter_obj = [] single_intent_filter_obj.append(var_key) for i in list(each_intent_filter): var = str(i.tag) + ' : ' + str(i.get(name)) # print(var) single_intent_filter_obj.append(var) if 'data : ' not in str(single_intent_filter_obj) and len( single_intent_filter_obj) > 1: if sts_code == 1: intent_fiter_dict[ var_key] = single_intent_filter_obj single_intent_filter_obj.append(' ') else: intent_fiter_dict.__setitem__( var_key, single_intent_filter_obj) single_intent_filter_obj.append(' ') if 'data : ' not in str(single_intent_filter_obj ) and len(single_intent_filter_obj) > 1: scanned_implicit_intent.extend(single_intent_filter_obj) json_implicit_intent = json.dumps(intent_fiter_dict) return dbconstatus, str(thescanid), str(json_perms), str( json_critical_perms), str(json_custom_perms), str(json_acts), str( json_export_acts), str(json_receivers), str( json_export_receivers), str(json_deeplinks), str( json_taskaffinity), str(json_services), str( json_export_services), str(json_provider), str( json_implicit_intent)
def parser(hash_of_apk): receiver_set = set() printflag = 0 print(Fore.YELLOW + "\n\n--------------------------------------------------") print(Fore.GREEN + "[INFO] " + Fore.BLUE + "SCANNING FOR VULNERABILITIES\n") path = hash_of_apk os.chdir(path) filename = None app = SmaliscaApp() app.setup() location = './Bytecode' suffix = 'smali' parser = SmaliParser(location, suffix) parser.run() results = parser.get_results() for i in results: for key, values in i.items(): if key == "path": filename = values if key == "const-strings": search_ecb(filename, values) elif key == "methods": for j in values: for mkey, mvalue in j.items(): if mkey == "calls": receiver_set = pattern_receiver(filename, mvalue) for i in receiver_set: for x in i: if 'JAVASCRIPT' in x: set_of_js.update(i) if 'ECB' in x: set_of_ecb.update(i) if 'DYNAMIC_RECEIVER' in x: set_of_search_dynamic.update(i) if 'EMPTY_PENDING_INTENT' in x: set_of_empty_pend_list.update(i) if 'SYSTEM_BROADCAST_RECEIVER' in x: set_of_sys_broadcast_list.update(i) if 'TLS_VALIDTY' in x: set_of_tls_validity_list.update(i) if 'INSECURE_SOCKET' in x: set_of_insecure_socket_list.update(i) if 'UNENCRYPTED_COMMUNICATION' in x: set_of_list_of_unenc_soc.update(i) if 'UNSAFE_INTENT' in x: set_of_unsafe_intent_list.update(i) if 'COOKIE_OVERWRITE' in x: set_of_list_of_cookie_overwrite.update(i) if 'FILE_FROM_URL' in x: set_of_url_allowed_list.update(i) if 'CONTENT_FROM_URL' in x: set_of_content_allowed_list.update(i) if 'DYNAMIC_WEAK_CHECKS' in x: set_of_weak_checks_list.update(i) if 'EXECSQL_USAGE' in x: set_of_execsql_used.update(i) if 'SHAREDPREFS_USAGE' in x: set_of_sharedprefs_used.update(i) if 'SQLITE_USAGE' in x: set_of_sqli_used.update(i) if 'INT_STORAGE_USAGE' in x: set_of_int_storage_used.update(i) if 'KEYSTORE_USAGE' in x: set_of_keystore_used.update(i) else: pass set_updater(set_of_js, 'JAVASCRIPT') set_updater(set_of_ecb, 'ECB') set_updater(set_of_search_dynamic, 'DYNAMIC_RECEIVER') set_updater(set_of_empty_pend_list, 'EMPTY_PENDING_INTENT') set_updater(set_of_sys_broadcast_list, 'SYSTEM_BROADCAST_RECEIVER') set_updater(set_of_tls_validity_list, 'TLS_VALIDTY') set_updater(set_of_insecure_socket_list, 'INSECURE_SOCKET') set_updater(set_of_list_of_unenc_soc, 'UNENCRYPTED_COMMUNICATION') set_updater(set_of_unsafe_intent_list, 'UNSAFE_INTENT') set_updater(set_of_list_of_cookie_overwrite, 'COOKIE_OVERWRITE') set_updater(set_of_url_allowed_list, 'FILE_FROM_URL') set_updater(set_of_content_allowed_list, 'CONTENT_FROM_URL') set_updater(set_of_weak_checks_list, 'DYNAMIC_WEAK_CHECKS') set_updater(set_of_execsql_used, 'EXECSQL_USAGE') set_updater(set_of_sharedprefs_used, 'SHAREDPREFS_USAGE') set_updater(set_of_sqli_used, 'SQLITE_USAGE') set_updater(set_of_int_storage_used, 'INT_STORAGE_USAGE') set_updater(set_of_keystore_used, 'KEYSTORE_USAGE') print(Fore.RED + "\n\t\t[!] " + Fore.RED + "Javascript is enabled \n") printer(set_of_js) print(Fore.RED + "\n\t\t[!] " + Fore.RED + "ECB cipher usage instance found \n") printer(set_of_ecb) print(Fore.RED + "\n\t\t[!] " + Fore.RED + "Broadcast Receiver Exported \n") printer(set_of_search_dynamic) print(Fore.RED + "\n\t\t[!] " + Fore.RED + "Empty Pending Intent Found \n") printer(set_of_empty_pend_list) print(Fore.RED + "\n\t\t[!] " + Fore.RED + "Sticky Broadcast Found \n") printer(set_of_sys_broadcast_list) print(Fore.RED + "\n\t\t[!] " + Fore.RED + "Certificate Validity Checks Not Found\n") printer(set_of_tls_validity_list) print(Fore.RED + "\n\t\t[!] " + Fore.RED + "Insecure Hostname Verification Routine Found\n") printer(set_of_insecure_socket_list) # print(Fore.RED + "\n\t\t[!] " + Fore.RED + "HTTP URLs Found\n") print(Fore.RED + "\n\t\t[!] " + Fore.RED + "SetCookie is Enabled. Cookie overwrite possible \n") printer(set_of_list_of_cookie_overwrite) print(Fore.RED + "\n\t\t[!] " + Fore.RED + "File Access from URLs Allowed \n") printer(set_of_url_allowed_list) print(Fore.RED + "\n\t\t[!] " + Fore.RED + "Content Access from URLs Allowed \n") printer(set_of_content_allowed_list) print(Fore.RED + "\n\t\t[!] " + Fore.RED + "Usage of 'Call' for ContentProvider! \n") printer(set_of_weak_checks_list) print(Fore.RED + "\n\t\t[!] " + Fore.RED + "Usage of 'execSQL'! \n") printer(set_of_execsql_used) print(Fore.YELLOW + "\n\t\t[!] " + Fore.RED + "SharedPreference has been used \n") printer(set_of_sharedprefs_used) print(Fore.RED + "\n\t\t[!] " + Fore.RED + "SQLite DB used\n") printer(set_of_sqli_used) print(Fore.RED + "\n\t\t[!] " + Fore.RED + "Internal storage used\n") printer(set_of_int_storage_used) print(Fore.RED + "\n\t\t[!] " + Fore.RED + "Keystore used\n") printer(set_of_keystore_used) path = os.getcwd() + '/..' os.chdir(path) add_to_db(hash_of_apk) print(Fore.BLUE + "\n\t\t[INFO] Vulnerability References written to 'Vulnerabilities.txt'") #-------------------------------- dbname = "adhrit.db" dbconstatus = dbconnection(dbname) query = f"UPDATE StatusDB SET Bytecode = 'complete' WHERE Hash='{hash_of_apk}';" addedornot = insert_statustable(dbconstatus, query)