def strings_jar(app_file, app_dir): """Extract the strings from an app.""" try: logger.info("Extracting Strings from APK") dat = [] apk_file = os.path.join(app_dir, app_file) and_a = apk.APK(apk_file) rsrc = and_a.get_android_resources() pkg = rsrc.get_packages_names()[0] rsrc.get_strings_resources() for i in rsrc.values[pkg].keys(): res_string = rsrc.values[pkg][i].get('string') if res_string: for duo in res_string: dat.append('"' + duo[0] + '" : "' + duo[1] + '"') data_string = "".join(dat) urls, urls_nf, emails_nf = url_n_email_extract( data_string, "Android String Resource") return { "strings": dat, "urls_list": urls, "url_nf": urls_nf, "emails_nf": emails_nf, } except: PrintException("Extracting Strings from APK") return {}
def code_analysis(app_dir, typ): """Perform the code analysis.""" try: logger.info('Static Android Code Analysis Started') root = Path(settings.BASE_DIR) / 'StaticAnalyzer' / 'views' code_rules = root / 'android' / 'rules' / 'android_rules.yaml' api_rules = root / 'android' / 'rules' / 'android_apis.yaml' code_findings = {} api_findings = {} email_n_file = [] url_n_file = [] url_list = [] app_dir = Path(app_dir) if typ == 'apk': src = app_dir / 'java_source' elif typ == 'studio': src = app_dir / 'app' / 'src' / 'main' / 'java' kt = app_dir / 'app' / 'src' / 'main' / 'kotlin' if not src.exists() and kt.exists(): src = kt elif typ == 'eclipse': src = app_dir / 'src' src = src.as_posix() + '/' logger.info('Code Analysis Started on - %s', filename_from_path(src)) # Code and API Analysis code_findings = scan(code_rules.as_posix(), {'.java', '.kt'}, [src], settings.SKIP_CLASS_PATH) api_findings = scan(api_rules.as_posix(), {'.java', '.kt'}, [src], settings.SKIP_CLASS_PATH) skp = settings.SKIP_CLASS_PATH # Extract URLs and Emails for pfile in Path(src).rglob('*'): if ((pfile.suffix in ('.java', '.kt') and any(skip_path in pfile.as_posix() for skip_path in skp) is False)): content = None try: content = pfile.read_text('utf-8', 'ignore') # Certain file path cannot be read in windows except Exception: continue relative_java_path = pfile.as_posix().replace(src, '') urls, urls_nf, emails_nf = url_n_email_extract( content, relative_java_path) url_list.extend(urls) url_n_file.extend(urls_nf) email_n_file.extend(emails_nf) logger.info('Finished Code Analysis, Email and URL Extraction') code_an_dic = { 'api': api_findings, 'findings': code_findings, 'urls_list': url_list, 'urls': url_n_file, 'emails': email_n_file, } return code_an_dic except Exception: logger.exception('Performing Code Analysis')
def strings_jar(app_file, app_dir): """Extract the strings from an app.""" try: logger.info('Extracting Strings from APK') dat = [] secrets = [] apk_file = os.path.join(app_dir, app_file) and_a = apk.APK(apk_file) rsrc = and_a.get_android_resources() pkg = rsrc.get_packages_names()[0] rsrc.get_strings_resources() for i in rsrc.values[pkg].keys(): res_string = rsrc.values[pkg][i].get('string') if res_string: for duo in res_string: cap_str = '"' + duo[0] + '" : "' + duo[1] + '"' if is_secret(duo[0] + '"'): secrets.append(cap_str) dat.append(cap_str) data_string = ''.join(dat) urls, urls_nf, emails_nf = url_n_email_extract( data_string, 'Android String Resource') return { 'strings': dat, 'urls_list': urls, 'url_nf': urls_nf, 'emails_nf': emails_nf, 'secrets': secrets, } except Exception: logger.exception('Extracting Strings from APK') return {}
def ios_source_analysis(src): """iOS Objective-C Code Analysis""" try: print("[INFO] Starting iOS Source Code and PLIST Analysis") api_rules = ios_apis.CODE_APIS code_rules = ios_rules.CODE_RULES code_findings = {} api_findings = {} email_n_file = [] url_n_file = [] url_list = [] domains = {} for dirname, _, files in os.walk(src): for jfile in files: if jfile.endswith(".m"): jfile_path = os.path.join(src, dirname, jfile) if "+" in jfile: new_path = os.path.join(src, dirname, jfile.replace("+", "x")) shutil.move(jfile_path, new_path) jfile_path = new_path dat = '' with io.open(jfile_path, mode='r', encoding="utf8", errors="ignore") as flip: dat = flip.read() # Code Analysis relative_src_path = jfile_path.replace(src, '') code_rule_matcher(code_findings, [], dat, relative_src_path, code_rules) # API Analysis api_rule_matcher(api_findings, [], dat, relative_src_path, api_rules) # Extract URLs and Emails urls, urls_nf, emails_nf = url_n_email_extract( dat, relative_src_path) url_list.extend(urls) url_n_file.extend(urls_nf) email_n_file.extend(emails_nf) # Domain Extraction and Malware Check print("[INFO] Performing Malware Check on extracted Domains") domains = malware_check(list(set(url_list))) print("[INFO] Finished Code Analysis, Email and URL Extraction") code_analysis_dict = { 'api': api_findings, 'code_anal': code_findings, 'urlnfile': url_n_file, 'domains': domains, 'emailnfile': email_n_file, } return code_analysis_dict except: PrintException("[ERROR] iOS Source Code Analysis")
def strings_from_apk(app_file, app_dir, elf_strings): """Extract the strings from an app.""" try: logger.info('Extracting Strings from APK') dat = [] secrets = [] apk_file = os.path.join(app_dir, app_file) and_a = apk.APK(apk_file) rsrc = and_a.get_android_resources() pkg = rsrc.get_packages_names()[0] rsrc.get_strings_resources() for i in rsrc.values[pkg].keys(): res_string = rsrc.values[pkg][i].get('string') if res_string: for duo in res_string: cap_str = '"' + duo[0] + '" : "' + duo[1] + '"' if is_secret(duo[0] + '"'): secrets.append(cap_str) dat.append(cap_str) data_string = ''.join(dat) urls, urls_nf, emails_nf = url_n_email_extract( data_string, 'Android String Resource') if elf_strings: for solib in elf_strings: for so, str_list in solib.items(): # add to strings from jar dat.extend(str_list) # extract url, email so_str = ' '.join(str_list) su, suf, sem = url_n_email_extract(so_str, so) urls.extend(su) urls_nf.extend(suf) emails_nf.extend(sem) strings_dat = list(set(dat)) return { 'strings': strings_dat, 'urls_list': urls, 'url_nf': urls_nf, 'emails_nf': emails_nf, 'secrets': secrets, } except Exception: logger.exception('Extracting Strings from APK') return {}
def ios_source_analysis(src): """iOS Objective-C Code Analysis""" try: logger.info("Starting iOS Source Code and PLIST Analysis") api_rules = ios_apis.CODE_APIS code_rules = ios_rules.CODE_RULES code_findings = {} api_findings = {} email_n_file = [] url_n_file = [] url_list = [] domains = {} for dirname, _, files in os.walk(src): for jfile in files: if jfile.endswith(".m"): jfile_path = os.path.join(src, dirname, jfile) if "+" in jfile: new_path = os.path.join( src, dirname, jfile.replace("+", "x")) shutil.move(jfile_path, new_path) jfile_path = new_path dat = '' with io.open(jfile_path, mode='r', encoding="utf8", errors="ignore") as flip: dat = flip.read() # Code Analysis relative_src_path = jfile_path.replace(src, '') code_rule_matcher(code_findings, [], dat, relative_src_path, code_rules) # API Analysis api_rule_matcher(api_findings, [], dat, relative_src_path, api_rules) # Extract URLs and Emails urls, urls_nf, emails_nf = url_n_email_extract(dat, relative_src_path) url_list.extend(urls) url_n_file.extend(urls_nf) email_n_file.extend(emails_nf) urls_list = list(set(url_list)) # Domain Extraction and Malware Check logger.info("Performing Malware Check on extracted Domains") domains = malware_check(urls_list) logger.info("Finished Code Analysis, Email and URL Extraction") code_analysis_dict = { 'api': api_findings, 'code_anal': code_findings, 'urls_list': urls_list, 'urlnfile': url_n_file, 'domains': domains, 'emailnfile': email_n_file, } return code_analysis_dict except: PrintException("iOS Source Code Analysis")
def extract_urls_n_email(src, all_files, strings): """IPA URL and Email Extraction.""" try: logger.info('Starting IPA URL and Email Extraction') email_n_file = [] url_n_file = [] url_list = [] domains = {} all_files.append({'data': strings, 'name': 'IPA Strings Dump'}) for file in all_files: if isinstance(file, dict): relative_src_path = file['name'] dat = '\n'.join(file['data']) # Skip CodeResources and contents under Frameworks elif 'CodeResources' in file or '/Frameworks/' in file: continue elif file.endswith(('.nib', '.ttf', '.svg', '.woff2', '.png', '.dylib', '.mobileprovision', 'Assets.car')): continue else: dat = '' relative_src_path = file.replace(src, '') with io.open(file, mode='r', encoding='utf8', errors='ignore') as flip: dat = flip.read() # Extract URLs and Emails from Plists urls, urls_nf, emails_nf = url_n_email_extract( dat, relative_src_path) url_list.extend(urls) url_n_file.extend(urls_nf) email_n_file.extend(emails_nf) # Unique URLs urls_list = list(set(url_list)) # Domain Extraction and Malware Check logger.info('Performing Malware Check on extracted Domains') domains = MalwareDomainCheck().scan(urls_list) logger.info('Finished URL and Email Extraction') binary_recon = { 'urls_list': urls_list, 'urlnfile': url_n_file, 'domains': domains, 'emailnfile': email_n_file, } return binary_recon except Exception: logger.exception('IPA URL and Email Extraction')
def code_analysis(app_dir, perms, typ): """Perform the code analysis.""" try: logger.info("Static Android Code Analysis Started") api_rules = android_apis.APIS code_rules = android_rules.RULES code_findings = {} api_findings = {} email_n_file = [] url_n_file = [] url_list = [] domains = {} if typ == "apk": java_src = os.path.join(app_dir, 'java_source/') elif typ == "studio": java_src = os.path.join(app_dir, 'app/src/main/java/') elif typ == "eclipse": java_src = os.path.join(app_dir, 'src/') logger.info("Code Analysis Started on - " + java_src) # pylint: disable=unused-variable # Needed by os.walk for dir_name, sub_dir, files in os.walk(java_src): for jfile in files: jfile_path = os.path.join(java_src, dir_name, jfile) if "+" in jfile: p_2 = os.path.join(java_src, dir_name, jfile.replace("+", "x")) shutil.move(jfile_path, p_2) jfile_path = p_2 repath = dir_name.replace(java_src, '') if (jfile.endswith('.java') and any( re.search(cls, repath) for cls in settings.SKIP_CLASSES) is False): dat = '' with io.open(jfile_path, mode='r', encoding="utf8", errors="ignore") as file_pointer: dat = file_pointer.read() # Code Analysis # print "[INFO] Doing Code Analysis on - " + jfile_path relative_java_path = jfile_path.replace(java_src, '') code_rule_matcher(code_findings, list(perms.keys()), dat, relative_java_path, code_rules) # API Check api_rule_matcher(api_findings, list(perms.keys()), dat, relative_java_path, api_rules) # Extract URLs and Emails urls, urls_nf, emails_nf = url_n_email_extract( dat, relative_java_path) url_list.extend(urls) url_n_file.extend(urls_nf) email_n_file.extend(emails_nf) # Domain Extraction and Malware Check logger.info("Performing Malware Check on extracted Domains") domains = malware_check(list(set(url_list))) logger.info("Finished Code Analysis, Email and URL Extraction") code_an_dic = { 'api': api_findings, 'findings': code_findings, 'urls': url_n_file, 'domains': domains, 'emails': email_n_file, } return code_an_dic except: PrintException("Performing Code Analysis")
def ios_source_analysis(src): """IOS Objective-C Code Analysis.""" try: logger.info('Starting iOS Source Code and PLIST Analysis') api_rules = ios_apis.CODE_APIS code_rules = ios_rules.CODE_RULES code_findings = {} api_findings = {} email_n_file = [] url_n_file = [] url_list = [] domains = {} for dirname, _, files in os.walk(src): for jfile in files: if jfile.endswith('.m'): jfile_path = os.path.join(src, dirname, jfile) if '+' in jfile: new_path = os.path.join(src, dirname, jfile.replace('+', 'x')) shutil.move(jfile_path, new_path) jfile_path = new_path dat = '' with io.open(jfile_path, mode='r', encoding='utf8', errors='ignore') as flip: dat = flip.read() # Code Analysis relative_src_path = jfile_path.replace(src, '') code_rule_matcher(code_findings, [], dat, relative_src_path, code_rules) # API Analysis api_rule_matcher(api_findings, [], dat, relative_src_path, api_rules) # Extract URLs and Emails urls, urls_nf, emails_nf = url_n_email_extract( dat, relative_src_path) url_list.extend(urls) url_n_file.extend(urls_nf) email_n_file.extend(emails_nf) urls_list = list(set(url_list)) # Domain Extraction and Malware Check logger.info('Performing Malware Check on extracted Domains') domains = malware_check(urls_list) logger.info('Finished Code Analysis, Email and URL Extraction') code_analysis_dict = { 'api': api_findings, 'code_anal': code_findings, 'urls_list': urls_list, 'urlnfile': url_n_file, 'domains': domains, 'emailnfile': email_n_file, } return code_analysis_dict except Exception: logger.exception('iOS Source Code Analysis')
def code_analysis(app_dir, perms, typ): """Perform the code analysis.""" try: logger.info('Static Android Code Analysis Started') api_rules = android_apis.APIS code_rules = android_rules.RULES code_findings = {} api_findings = {} email_n_file = [] url_n_file = [] url_list = [] logger.info("code_findings-%s" % code_findings) if typ == 'apk': java_src = os.path.join(app_dir, 'java_source/') elif typ == 'studio': java_src = os.path.join(app_dir, 'app/src/main/java/') elif typ == 'eclipse': java_src = os.path.join(app_dir, 'src/') logger.info('Code Analysis Started on - %s', filename_from_path(java_src)) # pylint: disable=unused-variable # Needed by os.walk for dir_name, _sub_dir, files in os.walk(java_src): for jfile in files: jfile_path = os.path.join(java_src, dir_name, jfile) if '+' in jfile: p_2 = os.path.join(java_src, dir_name, jfile.replace('+', 'x')) shutil.move(jfile_path, p_2) jfile_path = p_2 repath = dir_name.replace(java_src, '') + '/' if (jfile.endswith('.java') and any( re.search(cls, repath) for cls in settings.SKIP_CLASSES) is False): dat = '' with io.open( jfile_path, mode='r', encoding='utf8', errors='ignore', ) as file_pointer: dat = file_pointer.read() # Code Analysis relative_java_path = jfile_path.replace(java_src, '') code_rule_matcher(code_findings, list(perms.keys()), dat, relative_java_path, code_rules) # API Check api_rule_matcher(api_findings, list(perms.keys()), dat, relative_java_path, api_rules) # Extract URLs and Emails urls, urls_nf, emails_nf = url_n_email_extract( dat, relative_java_path) url_list.extend(urls) url_n_file.extend(urls_nf) email_n_file.extend(emails_nf) logger.info('Finished Code Analysis, Email and URL Extraction') code_an_dic = { 'api': api_findings, 'findings': code_findings, 'urls_list': url_list, 'urls': url_n_file, 'emails': email_n_file, } return code_an_dic except Exception: logger.exception('Performing Code Analysis')
def ios_source_analysis(src): """IOS Objective-C and Swift Code Analysis.""" try: logger.info('Starting iOS Source Code and PLIST Analysis') root = Path(settings.BASE_DIR) / 'StaticAnalyzer' / 'views' swift_rules = root / 'ios' / 'rules' / 'swift_rules.yaml' objective_c_rules = root / 'ios' / 'rules' / 'objective_c_rules.yaml' api_rules = root / 'ios' / 'rules' / 'ios_apis.yaml' code_findings = {} api_findings = {} email_n_file = [] url_n_file = [] url_list = [] domains = {} source_type = '' source_types = set() # Code and API Analysis code_findings = scan(objective_c_rules.as_posix(), {'.m'}, [src], settings.SKIP_CLASS_PATH) if code_findings: source_types.add(_SourceType.objc) code_findings.update( scan(swift_rules.as_posix(), {'.swift'}, [src], settings.SKIP_CLASS_PATH)) if code_findings: source_types.add(_SourceType.swift) api_findings = scan(api_rules.as_posix(), {'.m', '.swift'}, [src], settings.SKIP_CLASS_PATH) # Extract URLs and Emails skp = settings.SKIP_CLASS_PATH for pfile in Path(src).rglob('*'): if ((pfile.suffix in ('.m', '.swift') and any(skip_path in pfile.as_posix() for skip_path in skp) is False)): relative_java_path = pfile.as_posix().replace(src, '') urls, urls_nf, emails_nf = url_n_email_extract( pfile.read_text('utf-8', 'ignore'), relative_java_path) url_list.extend(urls) url_n_file.extend(urls_nf) email_n_file.extend(emails_nf) if not source_types: source_type = _SourceType.nocode.value elif len(source_types) > 1: source_type = _SourceType.swift_and_objc.value else: source_type = source_types.pop().value urls_list = list(set(url_list)) # Domain Extraction and Malware Check logger.info('Performing Malware Check on extracted Domains') domains = malware_check(urls_list) logger.info('Finished Code Analysis, Email and URL Extraction') code_analysis_dict = { 'api': api_findings, 'code_anal': code_findings, 'urls_list': urls_list, 'urlnfile': url_n_file, 'domains': domains, 'emailnfile': email_n_file, 'source_type': source_type, } return code_analysis_dict except Exception: logger.exception('iOS Source Code Analysis')
def code_analysis(app_dir, perms, typ): """Perform the code analysis.""" try: logger.info("Static Android Code Analysis Started") api_rules = android_apis.APIS code_rules = android_rules.RULES code_findings = {} api_findings = {} email_n_file = [] url_n_file = [] url_list = [] domains = {} if typ == "apk": java_src = os.path.join(app_dir, 'java_source/') elif typ == "studio": java_src = os.path.join(app_dir, 'app/src/main/java/') elif typ == "eclipse": java_src = os.path.join(app_dir, 'src/') logger.info("Code Analysis Started on - " + filename_from_path(java_src)) # pylint: disable=unused-variable # Needed by os.walk for dir_name, sub_dir, files in os.walk(java_src): for jfile in files: jfile_path = os.path.join(java_src, dir_name, jfile) if "+" in jfile: p_2 = os.path.join(java_src, dir_name, jfile.replace("+", "x")) shutil.move(jfile_path, p_2) jfile_path = p_2 repath = dir_name.replace(java_src, '') if ( jfile.endswith('.java') and any(re.search(cls, repath) for cls in settings.SKIP_CLASSES) is False ): dat = '' with io.open( jfile_path, mode='r', encoding="utf8", errors="ignore" ) as file_pointer: dat = file_pointer.read() # Code Analysis # print "[INFO] Doing Code Analysis on - " + jfile_path relative_java_path = jfile_path.replace(java_src, '') code_rule_matcher( code_findings, list(perms.keys()), dat, relative_java_path, code_rules) # API Check api_rule_matcher(api_findings, list(perms.keys()), dat, relative_java_path, api_rules) # Extract URLs and Emails urls, urls_nf, emails_nf = url_n_email_extract(dat, relative_java_path) url_list.extend(urls) url_n_file.extend(urls_nf) email_n_file.extend(emails_nf) logger.info("Finished Code Analysis, Email and URL Extraction") code_an_dic = { 'api': api_findings, 'findings': code_findings, 'urls_list': url_list, 'urls': url_n_file, 'emails': email_n_file, } return code_an_dic except: PrintException("Performing Code Analysis")
def ios_source_analysis(src): """IOS Objective-C and Swift Code Analysis.""" try: logger.info('Starting iOS Source Code and PLIST Analysis') code_findings = {} api_findings = {} email_n_file = [] url_n_file = [] url_list = [] domains = {} source_type = '' source_types = set() # Will inject the different pattern strategy # when it it will be requested match_command = MatchCommand() for dirname, _, files in os.walk(src): for jfile in files: if jfile.endswith('.m'): api_rules = ios_apis.CODE_APIS code_rules = objc_rules.OBJC_RULES source_types.add(_SourceType.objc) elif jfile.endswith('.swift'): api_rules = ios_apis.CODE_APIS code_rules = swift_rules.SWIFT_RULES source_types.add(_SourceType.swift) else: continue jfile_path = os.path.join(src, dirname, jfile) if '+' in jfile: new_path = os.path.join(src, dirname, jfile.replace('+', 'x')) shutil.move(jfile_path, new_path) jfile_path = new_path dat = '' with io.open(jfile_path, mode='r', encoding='utf8', errors='ignore') as flip: dat = flip.read() # Code Analysis relative_src_path = jfile_path.replace(src, '') code_rule_matcher(code_findings, [], dat, relative_src_path, code_rules, match_command) # API Analysis api_rule_matcher(api_findings, [], dat, relative_src_path, api_rules, match_command) # Extract URLs and Emails urls, urls_nf, emails_nf = url_n_email_extract( dat, relative_src_path) url_list.extend(urls) url_n_file.extend(urls_nf) email_n_file.extend(emails_nf) if not source_types: source_type = _SourceType.nocode.value elif len(source_types) > 1: source_type = _SourceType.swift_and_objc.value else: source_type = source_types.pop().value urls_list = list(set(url_list)) # Domain Extraction and Malware Check logger.info('Performing Malware Check on extracted Domains') domains = malware_check(urls_list) logger.info('Finished Code Analysis, Email and URL Extraction') code_analysis_dict = { 'api': api_findings, 'code_anal': code_findings, 'urls_list': urls_list, 'urlnfile': url_n_file, 'domains': domains, 'emailnfile': email_n_file, 'source_type': source_type, } return code_analysis_dict except Exception: logger.exception('iOS Source Code Analysis')