Ejemplo n.º 1
0
    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']))
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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))
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
0
    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