def androguard_certinfo(app_dir, app_file): """Return certificate information.""" certlist = [] apk_file = os.path.join(app_dir, app_file) hashfunctions = dict( md5=hashlib.md5, sha1=hashlib.sha1, sha256=hashlib.sha256, sha512=hashlib.sha512, ) a = APK(apk_file) certlist.append("v1: {}".format(a.is_signed_v1())) certlist.append("v2: {}".format(a.is_signed_v2())) certlist.append("v3: {}".format(a.is_signed_v3())) certs = set(a.get_certificates_der_v3() + a.get_certificates_der_v2() + [a.get_certificate_der(x) for x in a.get_signature_names()]) pkeys = set(a.get_public_keys_der_v3() + a.get_public_keys_der_v2()) for cert in certs: x509_cert = x509.Certificate.load(cert) certlist.append("Subject: {}".format( get_certificate_name_string(x509_cert.subject, short=True))) certlist.append("Signature Algorithm: {}".format( x509_cert.signature_algo)) certlist.append("Valid From: {}".format( x509_cert['tbs_certificate']['validity']['not_before'].native)) certlist.append("Valid To: {}".format( x509_cert['tbs_certificate']['validity']['not_after'].native)) certlist.append("Issuer: {}".format( get_certificate_name_string(x509_cert.issuer, short=True))) certlist.append("Serial Number: {}".format(hex( x509_cert.serial_number))) certlist.append("Hash Algorithm: {}".format(x509_cert.hash_algo)) for k, v in hashfunctions.items(): certlist.append("{} {}".format(k, v(cert).hexdigest())) for public_key in pkeys: x509_public_key = keys.PublicKeyInfo.load(public_key) certlist.append("PublicKey Algorithm: {}".format( x509_public_key.algorithm)) certlist.append("Bit Size: {}".format(x509_public_key.bit_size)) certlist.append("Fingerprint: {}".format( binascii.hexlify(x509_public_key.fingerprint).decode("utf-8"))) try: certlist.append("Hash Algorithm: {}".format( x509_public_key.hash_algo)) except ValueError as ve: # RSA pkey does not have an hash algorithm pass return '\n'.join(certlist)
def cert_info(app_dir, app_file): """Return certificate information.""" try: logger.info('Reading Code Signing Certificate') manifestfile = None manidat = '' cert_info = '' certlist = [] cert_path = os.path.join(app_dir, 'META-INF/') apk_file = os.path.join(app_dir, app_file) hashfunctions = { 'md5': hashlib.md5, 'sha1': hashlib.sha1, 'sha256': hashlib.sha256, 'sha512': hashlib.sha512, } files = [ f for f in os.listdir(cert_path) if os.path.isfile(os.path.join(cert_path, f)) ] a = APK(apk_file) if a.is_signed(): certlist.append('APK is signed') else: certlist.append('Missing certificate') certlist.append('v1 signature: {}'.format(a.is_signed_v1())) certlist.append('v2 signature: {}'.format(a.is_signed_v2())) certlist.append('v3 signature: {}'.format(a.is_signed_v3())) certs = set( a.get_certificates_der_v3() + a.get_certificates_der_v2() + [a.get_certificate_der(x) for x in a.get_signature_names()]) pkeys = set(a.get_public_keys_der_v3() + a.get_public_keys_der_v2()) if len(certs) > 0: certlist.append('Found {} unique certificates'.format(len(certs))) for cert in certs: x509_cert = x509.Certificate.load(cert) certlist.append('Subject: {}'.format( get_certificate_name_string(x509_cert.subject, short=True))) certlist.append('Signature Algorithm: {}'.format( x509_cert.signature_algo)) certlist.append('Valid From: {}'.format( x509_cert['tbs_certificate']['validity']['not_before'].native)) certlist.append('Valid To: {}'.format( x509_cert['tbs_certificate']['validity']['not_after'].native)) certlist.append('Issuer: {}'.format( get_certificate_name_string(x509_cert.issuer, short=True))) certlist.append('Serial Number: {}'.format( hex(x509_cert.serial_number))) certlist.append('Hash Algorithm: {}'.format(x509_cert.hash_algo)) for k, v in hashfunctions.items(): certlist.append('{}: {}'.format(k, v(cert).hexdigest())) for public_key in pkeys: x509_public_key = asymmetric.load_public_key(public_key) certlist.append('PublicKey Algorithm: {}'.format( x509_public_key.algorithm)) certlist.append('Bit Size: {}'.format(x509_public_key.bit_size)) certlist.append('Fingerprint: {}'.format( binascii.hexlify(x509_public_key.fingerprint).decode('utf-8'))) cert_info = '\n'.join(certlist) if 'MANIFEST.MF' in files: manifestfile = os.path.join(cert_path, 'MANIFEST.MF') if manifestfile: with open(manifestfile, 'r', encoding='utf-8') as manifile: manidat = manifile.read() sha256_digest = bool(re.findall(r'SHA-256-Digest', manidat)) findings = [] if a.is_signed(): findings.append(('good', 'Application is signed with a code ' 'signing certificate')) else: findings.append(('bad', 'Code signing certificate not found')) if a.is_signed_v1(): status = 'bad' if a.is_signed_v2() or a.is_signed_v3(): status = 'warning' findings.append( (status, 'Application is signed with v1 signature scheme, ' 'making it vulnerable to Janus vulnerability on ' 'Android <7.0')) if re.findall(r'CN=Android Debug', cert_info): findings.append( ('bad', 'Application signed with a debug certificate. ' 'Production application must not be shipped ' 'with a debug certificate.')) if re.findall(r'Hash Algorithm: sha1', cert_info): status = 'bad' desc = ('Application is signed with SHA1withRSA. ' 'SHA1 hash algorithm is known to have ' 'collision issues.') if sha256_digest: status = 'warning' desc += (' The manifest file indicates SHA256withRSA' ' is in use.') findings.append((status, desc)) cert_dic = { 'certificate_info': cert_info, 'certificate_findings': findings, } return cert_dic except Exception: logger.exception('Reading Code Signing Certificate') return {}
def androsign_main(args_apk, args_hash, args_all, show): from androguard.core.bytecodes.apk import APK from androguard.util import get_certificate_name_string import hashlib import binascii import traceback from colorama import Fore, Style from asn1crypto import x509, keys from oscrypto import asymmetric # Keep the list of hash functions in sync with cli/entry_points.py:sign hashfunctions = dict(md5=hashlib.md5, sha1=hashlib.sha1, sha256=hashlib.sha256, sha512=hashlib.sha512, ) if args_hash.lower() not in hashfunctions: print("Hash function {} not supported!" .format(args_hash.lower()), file=sys.stderr) print("Use one of {}" .format(", ".join(hashfunctions.keys())), file=sys.stderr) sys.exit(1) for path in args_apk: try: a = APK(path) print("{}, package: '{}'".format(os.path.basename(path), a.get_package())) print("Is signed v1: {}".format(a.is_signed_v1())) print("Is signed v2: {}".format(a.is_signed_v2())) print("Is signed v3: {}".format(a.is_signed_v3())) certs = set(a.get_certificates_der_v3() + a.get_certificates_der_v2() + [a.get_certificate_der(x) for x in a.get_signature_names()]) pkeys = set(a.get_public_keys_der_v3() + a.get_public_keys_der_v2()) if len(certs) > 0: print("Found {} unique certificates".format(len(certs))) for cert in certs: if show: x509_cert = x509.Certificate.load(cert) print("Issuer:", get_certificate_name_string(x509_cert.issuer, short=True)) print("Subject:", get_certificate_name_string(x509_cert.subject, short=True)) print("Serial Number:", hex(x509_cert.serial_number)) print("Hash Algorithm:", x509_cert.hash_algo) print("Signature Algorithm:", x509_cert.signature_algo) print("Valid not before:", x509_cert['tbs_certificate']['validity']['not_before'].native) print("Valid not after:", x509_cert['tbs_certificate']['validity']['not_after'].native) if not args_all: print("{} {}".format(args_hash.lower(), hashfunctions[args_hash.lower()](cert).hexdigest())) else: for k, v in hashfunctions.items(): print("{} {}".format(k, v(cert).hexdigest())) print() if len(certs) > 0: print("Found {} unique public keys associated with the certs".format(len(pkeys))) for public_key in pkeys: if show: x509_public_key = asymmetric.load_public_key(public_key) print("PublicKey Algorithm:", x509_public_key.algorithm) print("Bit Size:", x509_public_key.bit_size) print("Fingerprint:", binascii.hexlify(x509_public_key.fingerprint)) try: print("Hash Algorithm:", hash_algo(x509_public_key)) except ValueError as ve: # RSA pkey does not have an hash algorithm pass print() except: print(Fore.RED + "Error in {}".format(os.path.basename(path)) + Style.RESET_ALL, file=sys.stderr) traceback.print_exc(file=sys.stderr) if len(args_apk) > 1: print()
def androsign_main(args_apk, args_hash, args_all, show): from androguard.core.bytecodes.apk import APK from androguard.util import get_certificate_name_string import hashlib import binascii import traceback from colorama import Fore, Style from asn1crypto import x509, keys # Keep the list of hash functions in sync with cli/entry_points.py:sign hashfunctions = dict(md5=hashlib.md5, sha1=hashlib.sha1, sha256=hashlib.sha256, sha512=hashlib.sha512, ) if args_hash.lower() not in hashfunctions: print("Hash function {} not supported!" .format(args_hash.lower()), file=sys.stderr) print("Use one of {}" .format(", ".join(hashfunctions.keys())), file=sys.stderr) sys.exit(1) for path in args_apk: try: a = APK(path) print("{}, package: '{}'".format(os.path.basename(path), a.get_package())) print("Is signed v1: {}".format(a.is_signed_v1())) print("Is signed v2: {}".format(a.is_signed_v2())) print("Is signed v3: {}".format(a.is_signed_v3())) certs = set(a.get_certificates_der_v3() + a.get_certificates_der_v2() + [a.get_certificate_der(x) for x in a.get_signature_names()]) pkeys = set(a.get_public_keys_der_v3() + a.get_public_keys_der_v2()) if len(certs) > 0: print("Found {} unique certificates".format(len(certs))) for cert in certs: if show: x509_cert = x509.Certificate.load(cert) print("Issuer:", get_certificate_name_string(x509_cert.issuer, short=True)) print("Subject:", get_certificate_name_string(x509_cert.subject, short=True)) print("Serial Number:", hex(x509_cert.serial_number)) print("Hash Algorithm:", x509_cert.hash_algo) print("Signature Algorithm:", x509_cert.signature_algo) print("Valid not before:", x509_cert['tbs_certificate']['validity']['not_before'].native) print("Valid not after:", x509_cert['tbs_certificate']['validity']['not_after'].native) if not args_all: print("{} {}".format(args_hash.lower(), hashfunctions[args_hash.lower()](cert).hexdigest())) else: for k, v in hashfunctions.items(): print("{} {}".format(k, v(cert).hexdigest())) print() if len(certs) > 0: print("Found {} unique public keys associated with the certs".format(len(pkeys))) for public_key in pkeys: if show: x509_public_key = keys.PublicKeyInfo.load(public_key) print("PublicKey Algorithm:", x509_public_key.algorithm) print("Bit Size:", x509_public_key.bit_size) print("Fingerprint:", binascii.hexlify(x509_public_key.fingerprint)) try: print("Hash Algorithm:", x509_public_key.hash_algo) except ValueError as ve: # RSA pkey does not have an hash algorithm pass print() except: print(Fore.RED + "Error in {}".format(os.path.basename(path)) + Style.RESET_ALL, file=sys.stderr) traceback.print_exc(file=sys.stderr) if len(args_apk) > 1: print()
def cert_info(app_dir, app_file): """Return certificate information.""" try: logger.info('Reading Code Signing Certificate') issued = '' manidat = '' certlist = [] cert_path = os.path.join(app_dir, 'META-INF/') apk_file = os.path.join(app_dir, app_file) hashfunctions = { 'md5': hashlib.md5, 'sha1': hashlib.sha1, 'sha256': hashlib.sha256, 'sha512': hashlib.sha512, } files = [ f for f in os.listdir(cert_path) if os.path.isfile(os.path.join(cert_path, f)) ] a = APK(apk_file) if a.is_signed(): certlist.append('APK is signed') else: certlist.append('Missing certificate') certlist.append('v1 signature: {}'.format(a.is_signed_v1())) certlist.append('v2 signature: {}'.format(a.is_signed_v2())) certlist.append('v3 signature: {}'.format(a.is_signed_v3())) certs = set( a.get_certificates_der_v3() + a.get_certificates_der_v2() + [a.get_certificate_der(x) for x in a.get_signature_names()]) pkeys = set(a.get_public_keys_der_v3() + a.get_public_keys_der_v2()) if len(certs) > 0: certlist.append('Found {} unique certificates'.format(len(certs))) for cert in certs: x509_cert = x509.Certificate.load(cert) certlist.append('Subject: {}'.format( get_certificate_name_string(x509_cert.subject, short=True))) certlist.append('Signature Algorithm: {}'.format( x509_cert.signature_algo)) certlist.append('Valid From: {}'.format( x509_cert['tbs_certificate']['validity']['not_before'].native)) certlist.append('Valid To: {}'.format( x509_cert['tbs_certificate']['validity']['not_after'].native)) certlist.append('Issuer: {}'.format( get_certificate_name_string(x509_cert.issuer, short=True))) certlist.append('Serial Number: {}'.format( hex(x509_cert.serial_number))) certlist.append('Hash Algorithm: {}'.format(x509_cert.hash_algo)) for k, v in hashfunctions.items(): certlist.append('{}: {}'.format(k, v(cert).hexdigest())) for public_key in pkeys: x509_public_key = keys.PublicKeyInfo.load(public_key) certlist.append('PublicKey Algorithm: {}'.format( x509_public_key.algorithm)) certlist.append('Bit Size: {}'.format(x509_public_key.bit_size)) certlist.append('Fingerprint: {}'.format( binascii.hexlify(x509_public_key.fingerprint).decode('utf-8'))) try: certlist.append('Hash Algorithm: {}'.format( x509_public_key.hash_algo)) except ValueError: pass certlist = '\n'.join(certlist) if a.is_signed(): issued = 'good' else: issued = 'missing' if re.findall(r'CN=Android Debug', certlist): issued = 'bad' if re.findall(r'Hash Algorithm: sha1', certlist): issued = 'bad hash' if 'MANIFEST.MF' in files: manifestfile = os.path.join(cert_path, 'MANIFEST.MF') if manifestfile: with open(manifestfile, 'r', encoding='utf-8') as manifile: manidat = manifile.read() sha256_digest = bool(re.findall(r'SHA-256-Digest', manidat)) cert_dic = { 'cert_info': certlist, 'issued': issued, 'sha256Digest': sha256_digest, } return cert_dic except Exception: logger.exception('Reading Code Signing Certificate')