def clean_analysis(self): if self.UTILS.check_dependencies(['connection'], silent=True): self.UTILS.delete(self.IOS_WORKING_FOLDER) if settings.clean: Utils.run('rm -rf {working}'.format(working=self.LOCAL_WORKING_FOLDER)) if settings.ipa and settings.uninstall: self.UTILS.run_on_ios('{ipainstaller} -u {appid}'.format(ipainstaller=settings.ipainstaller, appid=self.APP_INFO['CFBundleIdentifier']))
def run_analysis(self, analysis_type='full'): if not self.PREPARED: Log.e('Error: Analysis not prepared') return [] Log.w("Starting iOS Analysis") ### checks start here if self.UTILS.check_dependencies(['static'], silent=True, install=False): issues = self.run_static_analysis() if analysis_type != 'static' and self.UTILS.check_dependencies(['dynamic'], silent=True, install=False): issues += self.run_dynamic_analysis() ### get data from device Log.d('Getting data from device') self.UTILS.pull(self.IOS_DATA_PATH, self.LOCAL_DATA_CONTENT) issues += self.run_cordova_checks() # calculate and save md5 md5 = Utils.run('{md5sum} {ipa}'.format(md5sum=settings.md5sum, ipa=self.LOCAL_IPA))[0] with open('{working}/{ipa}.md5'.format(working=self.LOCAL_BIN_FOLDER, ipa=self.IPA.rsplit('/', 1)[-1]), 'w') as f: f.write(md5.split(' ', 1)[0].strip()) # print app information Log.w('******************** Application Info ********************') Log.w('Application: {app}'.format(app=self.APP_INFO['CFBundleName'])) Log.w('Version : {version}'.format(version=self.APP_INFO['CFBundleShortVersionString'])) Log.w('Binary : {binary}'.format(binary= self.APP_INFO['CFBundleExecutable'])) Log.w('MD5 : {md5}'.format(md5=md5.strip().split('\n')[0])) Log.w('******************** End Info ********************') self.clean_analysis() return issues
def __init__(self, root=None, data=None, atype=None, config=None, cordova=None): self.ASSESSMENT_TYPE = atype self.ROOT = root self.CONFIG_FILE = config self.CORDOVA_FILE = cordova if self.ROOT and not self.CONFIG_FILE: for location in CordovaAnalysis.LOCATIONS['config']: if path.exists('{root}/{loc}'.format(root=self.ROOT, loc=location)): self.CONFIG_FILE = '{root}/{loc}'.format(root=self.ROOT, loc=location) break if self.ROOT and not self.CORDOVA_FILE: for location in CordovaAnalysis.LOCATIONS['cordova']: if path.exists('{root}/{loc}'.format(root=self.ROOT, loc=location)): self.CORDOVA_FILE = '{root}/{loc}'.format(root=self.ROOT, loc=location) break if not self.CORDOVA_FILE and data: self.CORDOVA_FILE = Utils.run( 'find {data} -name cordova.js'.format( data=data))[0].split('\n')[0].strip() if not self.CONFIG_FILE and self.ROOT: self.CONFIG_FILE = Utils.run('find {root} -name config.xml'.format( root=self.ROOT))[0].split('\n')[0].strip() Log.d('Root: {fpath}'.format(fpath=self.ROOT)) Log.d('cordova.js: {fpath}'.format(fpath=self.CORDOVA_FILE)) Log.d('config.xml: {fpath}'.format(fpath=self.CONFIG_FILE))
def run_analysis(self, analysis_type='full'): if not self.PREPARED: Log.e('Error: Analysis not prepared') return [] issues = [] Log.w('Starting Android Analysis') if self.UTILS.check_dependencies(['static'], silent=True, install=False): issues = self.run_static_analysis() issues += self.run_cordova_analysis() if analysis_type != 'static' and self.UTILS.check_dependencies( ['dynamic'], silent=True, install=False): Log.w('Starting Dynamic Analysis') issues += self.run_dynamic_analysis() # calculate and save md5 md5 = Utils.run('{md5sum} {working}'.format( md5sum=settings.md5sum, working=self.WORKING_APK_FILE))[0] with open('{working}.md5'.format(working=self.WORKING_APK_FILE), 'w') as f: f.write(md5.split(' ', 1)[0].strip()) # print app information Log.w('******************** Application Info ********************') Log.w('Package: {app}'.format(app=self.PACKAGE)) Log.w('Version: {version}'.format(version=self.MANIFEST.version)) Log.w('APK : {binary}'.format(binary=self.WORKING_APK_FILE)) Log.w('MD5 : {md5}'.format(md5=md5.strip().split('\n')[0])) Log.w('******************** End Info ********************') self.clean_analysis() return issues
def prepare_analysis(self): Log.w('Preparing iOS Analysis') if not self.UTILS.check_dependencies(['full'], install=True, silent=True): Log.e('Error: Required dependencies not met') # create local output folder Log.d('Creating local output folders') self.LOCAL_WORKING_FOLDER = '{output}/{work}-{uuid}'.format(output=settings.output, work=self.LOCAL_WORKING_FOLDER, uuid=(self.APP or self.IPA.rsplit('/',1)[-1].rsplit('.',1)[0])) self.LOCAL_DATA_CONTENT = '{main}/{data}'.format(main=self.LOCAL_WORKING_FOLDER, data=self.LOCAL_DATA_CONTENT) self.LOCAL_BIN_FOLDER = '{main}/{data}'.format(main=self.LOCAL_WORKING_FOLDER, data=self.LOCAL_BIN_FOLDER) self.LOCAL_CLASS_DUMP = '{main}/{data}'.format(main=self.LOCAL_WORKING_FOLDER, data=self.LOCAL_CLASS_DUMP) self.LOCAL_UNZIPED = '{main}/{data}'.format(main=self.LOCAL_WORKING_FOLDER, data=self.LOCAL_UNZIPED) local_paths = ['LOCAL_WORKING_FOLDER', 'LOCAL_DATA_CONTENT', 'LOCAL_BIN_FOLDER', 'LOCAL_CLASS_DUMP'] for local_path in local_paths: if not path.exists(getattr(self, local_path)): makedirs(getattr(self, local_path)) if self.UTILS.check_dependencies(['connection'], silent=True): # create a temp folder to work with Log.d('Creating iOS Working folders') self.UTILS.run_on_ios('mkdir {working}'.format(working=self.IOS_WORKING_FOLDER)) self.UTILS.run_on_ios('chmod 777 {working}'.format(working=self.IOS_WORKING_FOLDER)) # push tools to the temp folder self.UTILS.push(settings.dump_log, self.IOS_WORKING_FOLDER) self.UTILS.push(settings.dump_fileprot, self.IOS_WORKING_FOLDER) self.UTILS.push(settings.dump_decrypt, self.IOS_WORKING_FOLDER) self.UTILS.push(settings.keychain_dump, self.IOS_WORKING_FOLDER) self.UTILS.push(settings.backup_excluded, self.IOS_WORKING_FOLDER) # update binary paths self.UTILS.DUMP_DECRYPT = '{working}/{binary}'.format(working=self.IOS_WORKING_FOLDER, binary=settings.dump_decrypt.rsplit('/', 1)[1]) self.UTILS.KEYCHAIN_DUMP = '{working}/{binary}'.format(working=self.IOS_WORKING_FOLDER, binary=settings.keychain_dump.rsplit('/', 1)[1]) self.UTILS.DUMP_FILE_PROTECT = '{working}/{binary}'.format(working=self.IOS_WORKING_FOLDER, binary=settings.dump_fileprot.rsplit('/', 1)[1]) self.UTILS.DUMP_LOG = '{working}/{binary}'.format(working=self.IOS_WORKING_FOLDER, binary=settings.dump_log.rsplit('/', 1)[1]) self.UTILS.BACKUP_EXCLUDED = '{working}/{binary}'.format(working=self.IOS_WORKING_FOLDER, binary=settings.backup_excluded.rsplit('/', 1)[1]) if self.APP: # no need to check if there's connection - it will return None if there's no connection apps = self.UTILS.list_apps(silent=True) self.APP = apps[self.APP] if self.APP in apps else None if not self.APP: Log.e("Error: The ID specified was not found in the applications list.") return False if self.IPA: self.LOCAL_IPA = '{binaries}/{ipa}'.format(binaries=self.LOCAL_BIN_FOLDER, ipa=self.IPA.rsplit('/', 1)[-1]) Utils.run('cp {original} {dest}'.format(original=self.IPA, dest=self.LOCAL_IPA)) if self.UTILS.check_dependencies(['connection'], silent=True): self.APP = self.UTILS.install(self.LOCAL_IPA) if not self.APP: Log.e('Error: Couldn\'t install the app or retreive its details') return False if not self.IPA: self.APP_INFO = self.UTILS.get_info(self.APP_INFO['Path'], ios=True) self.LOCAL_WORKING_BIN, self.LOCAL_IPA = self.UTILS.pull_ipa(self.APP, self.APP_INFO, self.LOCAL_BIN_FOLDER) if self.LOCAL_IPA: UNZIPED_APP, self.APP_INFO = self.UTILS.unzip_to(self.LOCAL_IPA, self.LOCAL_UNZIPED) if not hasattr(self, 'LOCAL_WORKING_BIN'): self.LOCAL_WORKING_BIN = '{app}/{binary}'.format(app=UNZIPED_APP, binary=self.APP_INFO['CFBundleExecutable']) # copy working bin to the device: if not hasattr(self, 'LOCAL_WORKING_BIN') and self.UTILS.check_dependencies(['connection'], silent=True): self.IOS_WORKING_BIN = '{working}/{binary}'.format(working=self.IOS_WORKING_FOLDER, binary=self.APP_INFO['CFBundleExecutable']) self.UTILS.push(self.LOCAL_WORKING_BIN, self.IOS_WORKING_FOLDER) if self.APP and 'Container' in self.APP: self.IOS_DATA_PATH = self.APP['Container'].replace(' ', '\ ') if self.APP and self.APP_INFO: self.IOS_BIN_PATH = self.UTILS.app_executable(self.APP, self.APP_INFO) self.LOCAL_CLASS_DUMP = '{base}/{app}'.format(base=self.LOCAL_CLASS_DUMP, app=self.APP_INFO['CFBundleExecutable']) # get classes ########################## TESTING ##################################### if not path.exists(self.LOCAL_CLASS_DUMP): makedirs(self.LOCAL_CLASS_DUMP) self.UTILS.dump_classes_to_file(self.UTILS.dump_classes(self.LOCAL_WORKING_BIN), self.LOCAL_CLASS_DUMP) ########################## END ##################################### return True #and self.UTILS.check_dependencies(['full'], install=False, silent=True)
def prepare_analysis(self, decompile=True): Log.w('Preparing Android Analysis') if not self.UTILS.check_dependencies( ['static', 'dynamic'], install=True, silent=True): Log.e('Error: Not all ependencies met, run `-r` for more details') # Creates local folders to store the analysis data self.LOCAL_WORKING_FOLDER = '{output}/{work}-{uuid}'.format( output=settings.output, work=AndroidAnalysis.LOCAL_WORKING_FOLDER, uuid=(self.PACKAGE or self.WORKING_APK_FILE.rsplit( '/', 1)[-1].rsplit('.', 1)[0])) self.LOCAL_DATA_CONTENT = '{main}/{data}'.format( main=self.LOCAL_WORKING_FOLDER, data=AndroidAnalysis.LOCAL_DATA_CONTENT) self.LOCAL_DECOMPILED_APP = '{main}/{data}'.format( main=self.LOCAL_WORKING_FOLDER, data=AndroidAnalysis.LOCAL_DECOMPILED_APP) self.LOCAL_SOURCE = '{main}/{data}'.format( main=self.LOCAL_WORKING_FOLDER, data=AndroidAnalysis.LOCAL_SOURCE) local_paths = [ 'LOCAL_WORKING_FOLDER', 'LOCAL_DATA_CONTENT', 'LOCAL_DECOMPILED_APP', 'LOCAL_SOURCE' ] for local_path in local_paths: if not path.exists(getattr(self, local_path)): makedirs(getattr(self, local_path)) if self.WORKING_APK_FILE: original = self.WORKING_APK_FILE self.WORKING_APK_FILE = '{working}/{apk}'.format( working=self.LOCAL_WORKING_FOLDER, apk=self.WORKING_APK_FILE.rsplit('/', 1)[-1]) Utils.run('cp {oapk} {apk}'.format(oapk=original, apk=self.WORKING_APK_FILE)) if self.UTILS.device(): Log.w('Installing application') self.UTILS.install(self.WORKING_APK_FILE) elif self.PACKAGE: device_apk = self.UTILS.get_apk(self.PACKAGE) if not device_apk: Log.e('Error: Package not found on the device') return False self.WORKING_APK_FILE = '{working}/{package}.apk'.format( working=self.LOCAL_WORKING_FOLDER, package=self.PACKAGE) self.UTILS.pull(device_apk, self.WORKING_APK_FILE) if not self.WORKING_APK_FILE or not path.exists(self.WORKING_APK_FILE): Log.e('Error: Local APK file not found.') return False # decompile apk if decompile: Log.w('Decompiling {apk} to {dir}'.format( apk=self.WORKING_APK_FILE, dir=self.LOCAL_DECOMPILED_APP)) Utils.run('{apktool} -q d -f {apk} -o {out}'.format( apktool=settings.apktool, apk=self.WORKING_APK_FILE, out=self.LOCAL_DECOMPILED_APP)) self.MANIFEST = Manifest(self.LOCAL_DECOMPILED_APP, settings.apkfilename) self.PACKAGE = self.MANIFEST.package self.JAR_FILE = '{working}/{package}.jar'.format( working=self.LOCAL_WORKING_FOLDER, package=self.PACKAGE) self.LOCAL_SMALI = '{decompiled}/smali'.format( decompiled=self.LOCAL_DECOMPILED_APP) if decompile: Log.w('Converting {apk} classes to {jar}'.format( apk=self.WORKING_APK_FILE, jar=self.JAR_FILE)) Utils.run('{dex2jar} --force -o {jar} {apk}'.format( dex2jar=settings.dex2jar, apk=self.WORKING_APK_FILE, jar=self.JAR_FILE)) Log.d('Extrating java classes from {jar} to {src}'.format( src=self.LOCAL_SOURCE, jar=self.JAR_FILE)) Utils.run('{jdcli} {jar} -od {src}'.format(jdcli=settings.jdcli, src=self.LOCAL_SOURCE, jar=self.JAR_FILE)) return True