예제 #1
0
    def testAPKManifest(self):
        from androguard.core.bytecodes.apk import APK
        a = APK("examples/android/TestsAndroguard/bin/TestActivity.apk",
                testzip=True)

        self.assertEqual(a.get_app_name(), "TestsAndroguardApplication")
        self.assertEqual(a.get_app_icon(), "res/drawable-hdpi/icon.png")
        self.assertEqual(a.get_app_icon(max_dpi=120),
                         "res/drawable-ldpi/icon.png")
        self.assertEqual(a.get_app_icon(max_dpi=160),
                         "res/drawable-mdpi/icon.png")
        self.assertEqual(a.get_app_icon(max_dpi=240),
                         "res/drawable-hdpi/icon.png")
        self.assertIsNone(a.get_app_icon(max_dpi=1))
        self.assertEqual(a.get_main_activity(),
                         "tests.androguard.TestActivity")
        self.assertEqual(a.get_package(), "tests.androguard")
        self.assertEqual(a.get_androidversion_code(), '1')
        self.assertEqual(a.get_androidversion_name(), "1.0")
        self.assertEqual(a.get_min_sdk_version(), "9")
        self.assertEqual(a.get_target_sdk_version(), "16")
        self.assertIsNone(a.get_max_sdk_version())
        self.assertEqual(a.get_permissions(), [])
        self.assertEqual(a.get_declared_permissions(), [])
        self.assertTrue(a.is_valid_APK())
예제 #2
0
    def testAPKManifest(self):
        from androguard.core.bytecodes.apk import APK
        a = APK("examples/android/TestsAndroguard/bin/TestActivity.apk", testzip=True)

        self.assertEqual(a.get_app_name(), "TestsAndroguardApplication")
        self.assertEqual(a.get_app_icon(), "res/drawable-hdpi/icon.png")
        self.assertEqual(a.get_app_icon(max_dpi=120), "res/drawable-ldpi/icon.png")
        self.assertEqual(a.get_app_icon(max_dpi=160), "res/drawable-mdpi/icon.png")
        self.assertEqual(a.get_app_icon(max_dpi=240), "res/drawable-hdpi/icon.png")
        self.assertIsNone(a.get_app_icon(max_dpi=1))
        self.assertEqual(a.get_main_activity(), "tests.androguard.TestActivity")
        self.assertEqual(a.get_package(), "tests.androguard")
        self.assertEqual(a.get_androidversion_code(), '1')
        self.assertEqual(a.get_androidversion_name(), "1.0")
        self.assertEqual(a.get_min_sdk_version(), "9")
        self.assertEqual(a.get_target_sdk_version(), "16")
        self.assertIsNone(a.get_max_sdk_version())
        self.assertEqual(a.get_permissions(), [])
        self.assertEqual(a.get_declared_permissions(), [])
        self.assertTrue(a.is_valid_APK())
예제 #3
0
class XAPK:
    def __init__(self, folder):
        self.folder = Path(folder)
        for x in self.folder.glob('*.apk'):
            self.apk_src = Path(x)
            break
        for x in self.folder.glob('*.obb'):
            self.obb_src = Path(x)
            break
        self.apk = APK(self.apk_src)
        self.manifest = self.make_manifest()
        self.icon = self.apk.get_file(self.apk.get_app_icon())

    def make_manifest(self):
        apk_size = self.apk_src.stat().st_size
        if self.obb_src:
            obb_size = self.obb_src.stat().st_size
        else:
            obb_size = 0
        total_size = apk_size + obb_size
        filename = self.apk.get_filename()

        manifest = {}
        manifest['xapk_version'] = 1
        manifest['package_name'] = self.apk.get_package()
        manifest['name'] = self.apk.get_app_name()
        # manifest['locales_name'] = {} # TODO
        manifest['version_code'] = self.apk.get_androidversion_code()
        manifest['version_name'] = self.apk.get_androidversion_name()
        manifest['min_sdk_version'] = self.apk.get_min_sdk_version()
        manifest['target_sdk_version'] = self.apk.get_target_sdk_version()
        manifest['permissions'] = self.apk.get_declared_permissions()
        manifest['total_size'] = total_size
        manifest['expansions'] = []

        if obb_size:
            main_obb = {}
            main_obb[
                'file'] = 'Android/obb/{package_name}/main.{version_code}.{package_name}.obb'.format(
                    **manifest)
            main_obb['install_location'] = 'EXTERNAL_STORAGE'
            main_obb[
                'install_path'] = 'Android/obb/{package_name}/main.{version_code}.{package_name}.obb'.format(
                    **manifest)
            manifest['expansions'].push(main_obb)

        return manifest

    def save(self):
        self.name = '{package_name}_v{version_name}.xapk'.format(
            **self.manifest)
        zip_path = self.folder.joinpath(self.name)

        zip_dir = tempfile.mkdtemp()
        try:
            print('copying apk to temp directory...')
            apk_name = '{package_name}.apk'.format(**self.manifest)
            apk_src = self.apk_src.resolve()
            apk_dest = PurePath(zip_dir).joinpath(apk_name)
            shutil.copy2(apk_src, apk_dest)
            print('apk: OK')

            if self.manifest.get('expansions'):
                print('copying obb to temp directory...')
                obb_name = self.manifest['expansions'][0]['install_path']
                obb_src = self.obb_src.resolve()
                obb_dest = PurePath(zip_dir).joinpath(obb_name)
                os.makedirs(Path(obb_dest).parent, exist_ok=True)
                shutil.copy2(obb_src, obb_dest)
                print('obb: OK')
            else:
                print('no obb found')

            print('creating icon in temp directory...')
            icon = self.icon
            icon_dest = PurePath(zip_dir).joinpath('icon.png')
            with open(icon_dest, 'wb') as iconfile:
                iconfile.write(icon)
            print('icon: OK')

            print('creating manifest in temp directory...')
            manifest_dest = PurePath(zip_dir).joinpath('manifest.json')
            with open(manifest_dest, 'w') as manifestfile:
                s = json.dumps(self.manifest, separators=(':', ','))
                manifestfile.write(s)
            print('manifest: OK')

            print('creating xapk archive...')
            with zipfile.ZipFile(zip_path,
                                 'w',
                                 compression=zipfile.ZIP_DEFLATED) as zfd:
                for root, dirs, files in os.walk(zip_dir):
                    for f in files:
                        filename = os.path.join(root, f)
                        zfd.write(filename, os.path.relpath(filename, zip_dir))
            print('xapk: OK')
        finally:
            print('cleaning up temp directory...')
            shutil.rmtree(zip_dir)
            print('cleanup: OK')
예제 #4
0
def analyze(path):
    try:
        start = process_time()
        hashfunctions = dict(md5=hashlib.md5,
                             sha1=hashlib.sha1,
                             sha256=hashlib.sha256,
                             sha512=hashlib.sha512)
        a = APK(path)

        certs = set(
            a.get_certificates_der_v3() + a.get_certificates_der_v2() +
            [a.get_certificate_der(x) for x in a.get_signature_names()])

        for cert in certs:
            x509_cert = x509.Certificate.load(cert)

            issuer = {
                'commonName': None,
                'organizationName': None,
                'organizationalUnitName': None,
                'countryName': None,
                'stateOrProvinceName': None,
                'localityName': None
            }
            subject = {
                'commonName': None,
                'organizationName': None,
                'organizationalUnitName': None,
                'countryName': None,
                'stateOrProvinceName': None,
                'localityName': None
            }

            strIssuer = get_certificate_name_string(x509_cert.issuer,
                                                    short=False)
            strSubject = get_certificate_name_string(x509_cert.subject,
                                                     short=False)

            arrIssuer = strIssuer.split(',')
            for i in arrIssuer:
                if i.lstrip().split('=')[0] == 'commonName':
                    issuer['commonName'] = i.lstrip().split('=')[1]
                elif i.lstrip().split('=')[0] == 'organizationName':
                    issuer['organizationName'] = i.lstrip().split('=')[1]
                elif i.lstrip().split('=')[0] == 'organizationalUnitName':
                    issuer['organizationalUnitName'] = i.lstrip().split('=')[1]
                elif i.lstrip().split('=')[0] == 'countryName':
                    issuer['countryName'] = i.lstrip().split('=')[1]
                elif i.lstrip().split('=')[0] == 'stateOrProvinceName':
                    issuer['stateOrProvinceName'] = i.lstrip().split('=')[1]
                elif i.lstrip().split('=')[0] == 'localityName':
                    issuer['localityName'] = i.lstrip().split('=')[1]

            arrSubject = strSubject.split(',')
            for i in arrSubject:
                if i.lstrip().split('=')[0] == 'commonName':
                    subject['commonName'] = i.lstrip().split('=')[1]
                elif i.lstrip().split('=')[0] == 'organizationName':
                    subject['organizationName'] = i.lstrip().split('=')[1]
                elif i.lstrip().split('=')[0] == 'organizationalUnitName':
                    subject['organizationalUnitName'] = i.lstrip().split(
                        '=')[1]
                elif i.lstrip().split('=')[0] == 'countryName':
                    subject['countryName'] = i.lstrip().split('=')[1]
                elif i.lstrip().split('=')[0] == 'stateOrProvinceName':
                    subject['stateOrProvinceName'] = i.lstrip().split('=')[1]
                elif i.lstrip().split('=')[0] == 'localityName':
                    subject['localityName'] = i.lstrip().split('=')[1]

            for k, v in hashfunctions.items():
                if k == 'md5':
                    md5 = v(cert).hexdigest()
                elif k == 'sha1':
                    sha1 = v(cert).hexdigest()
                elif k == 'sha256':
                    sha256 = v(cert).hexdigest()
                elif k == 'sha512':
                    sha512 = v(cert).hexdigest()

        md5 = md5

        appName = a.get_app_name()
        fileSize = os.stat(a.get_filename()).st_size
        sha1 = sha1
        sha256 = sha256
        sha512 = sha512
        timestamp = time.time()
        dateTime = datetime.fromtimestamp(timestamp)
        timeOfSubmit = dateTime.strftime("%Y-%m-%d %H:%M:%S")
        package = a.get_package()
        androidversionCode = a.get_androidversion_code()
        androidversionName = a.get_androidversion_name()
        minSDKVersion = a.get_min_sdk_version()
        maxSDKVersion = a.get_max_sdk_version()
        targetSDKVersion = a.get_target_sdk_version()
        mainActivity = a.get_main_activity()

        attributes = {
            'validFrom':
            x509_cert['tbs_certificate']['validity']
            ['not_before'].native.strftime("%Y-%m-%d %H:%M:%S"),
            'validTo':
            x509_cert['tbs_certificate']['validity']
            ['not_after'].native.strftime("%Y-%m-%d %H:%M:%S"),
            'serialNumber':
            hex(x509_cert.serial_number),
            'hashAlgorithm':
            x509_cert.hash_algo,
            'signatureAlgorithm':
            x509_cert.signature_algo
        }

        certificateAttributes = json.dumps(attributes)
        certificateIssuer = json.dumps(issuer)
        certificateSubject = json.dumps(subject)

        declaredPermissions = json.dumps(a.get_declared_permissions())

        requestedPermissions = json.dumps(a.get_permissions())

        activities = json.dumps(a.get_activities())

        services = json.dumps(a.get_services())

        receivers = json.dumps(a.get_receivers())

        providers = json.dumps(a.get_providers())

        stop = process_time()
        analysisTime = stop - start

        connect = mysql.connect()
        cursor = connect.cursor()

        sql = "INSERT INTO tbl_apkinfo (md5, appName, fileSize, analysisTime, sha1, sha256, sha512, firstSubmission, lastSubmission, package, androidversionCode, androidversionName, minSDKVersion, maxSDKVersion, targetSDKVersion, mainActivity, certificateAttributes, certificateIssuer, certificateSubject,	declaredPermissions, requestedPermissions, activities, services, providers, receivers) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"
        param = (md5, appName, fileSize, analysisTime, sha1, sha256, sha512,
                 timeOfSubmit, timeOfSubmit, package, androidversionCode,
                 androidversionName, minSDKVersion, maxSDKVersion,
                 targetSDKVersion, mainActivity, certificateAttributes,
                 certificateIssuer, certificateSubject, declaredPermissions,
                 requestedPermissions, activities, services, providers,
                 receivers)
        cursor.execute(sql, param)

        connect.commit()
        connect.close()

        androaxml_main(path,
                       os.path.join(app.config['OUTPUT_PATH'], md5 + '.xml'))
        return True
    except:
        return False