def test_scan_with_nested_zips(scanner: Scanner): third_layer = {'3.dex': b'dex\n'} second_layer = { '3.zip': make_zip(third_layer).read(), '2.dex': b'dex\n', } first_layer = { '2.zip': make_zip(second_layer).read(), '1.dex': b'dex\n', } zero_layer = { '1.zip': make_zip(first_layer).read(), '0.dex': b'dex\n', } print('zero layer', zero_layer) scanner.options.scan_depth = 2 with make_temp_zip(zero_layer) as tz: filename: str = os.path.basename(tz.name) results = scanner.scan_file(tz.name) print('all results', results) for key in (filename, f'{filename}!0.dex', f'{filename}!1.zip', f'{filename}!1.zip!1.dex', f'{filename}!1.zip!2.zip', f'{filename}!1.zip!2.zip!2.dex', f'{filename}!1.zip!2.zip!3.zip'): assert key in results assert len(results[key]) > 0
def test_scan_with_nested_zips(scanner: Scanner): third_layer = {'3.dex': b'dex\n'} second_layer = { '3.zip': make_zip(third_layer).read(), '2.dex': b'dex\n', } first_layer = { '2.zip': make_zip(second_layer).read(), '1.dex': b'dex\n', } zero_layer = { '1.zip': make_zip(first_layer).read(), '0.dex': b'dex\n', } scanner.options.scan_depth = 2 with make_temp_zip(zero_layer) as tz: results = scanner.scan_file(tz.name) for key in (tz.name, f'{tz.name}!0.dex', f'{tz.name}!1.zip', f'{tz.name}!1.zip!1.dex', f'{tz.name}!1.zip!2.zip', f'{tz.name}!1.zip!2.zip!2.dex', f'{tz.name}!1.zip!2.zip!3.zip'): assert key in results assert len(results[key]) > 0
def apkid_analysis(sha256): es.update(index=settings.ELASTICSEARCH_TASKS_INDEX, id=sha256, body={'doc': { 'apkid_analysis': 1 }}, retry_on_conflict=5) options = Options( timeout=30, verbose=False, entry_max_scan_size=settings.DATA_UPLOAD_MAX_MEMORY_SIZE, recursive=True, ) output = OutputFormatter( json_output=True, output_dir=None, rules_manager=RulesManager(), include_types=False, ) rules = options.rules_manager.load() scanner = Scanner(rules, options) with NamedTemporaryFile() as f: f.write(default_storage.open(sha256).read()) f.seek(0) res = scanner.scan_file(f.name) try: findings = output.build_json_output(res)['files'] es.update(index=settings.ELASTICSEARCH_APK_INDEX, id=sha256, body={'doc': { 'apkid': findings }}, retry_on_conflict=5) es.update(index=settings.ELASTICSEARCH_TASKS_INDEX, id=sha256, body={'doc': { 'apkid_analysis': 2 }}, retry_on_conflict=5) except AttributeError: findings = {} es.update(index=settings.ELASTICSEARCH_APK_INDEX, id=sha256, body={'doc': { 'apkid': findings }}, retry_on_conflict=5) es.update(index=settings.ELASTICSEARCH_TASKS_INDEX, id=sha256, body={'doc': { 'apkid_analysis': -1 }}, retry_on_conflict=5) del findings, rules, scanner, output, options, res gc.collect() return {'status': 'success', 'info': ''}
def apkid_analysis(app_dir, apk_file, apk_name): """APKiD Analysis of DEX files""" if not settings.APKID_ENABLED: return {} if not os.path.exists(apk_file): logger.error("APKiD - APK not found") return {} from apkid import __version__ as apkid_ver from apkid.apkid import Scanner, Options from apkid.output import OutputFormatter from apkid.rules import RulesManager logger.info("Running APKiD %s", apkid_ver) options = Options(timeout=30, verbose=False, entry_max_scan_size=100 * 1024 * 1024, recursive=True) output = OutputFormatter(json_output=True, output_dir=None, rules_manager=RulesManager()) rules = options.rules_manager.load() scanner = Scanner(rules, options) res = scanner.scan_file(apk_file) findings = output._build_json_output(res)['files'] sanitized = {} for item in findings: filename = item['filename'] sanitized[filename] = item['matches'] return sanitized
def test_scan_with_zip_with_dex(scanner: Scanner): zip_entries = {'classes.dex': b'dex\nnot a real dex!'} with make_temp_zip(zip_entries) as tz: results = scanner.scan_file(tz.name) for key in (tz.name, f'{tz.name}!classes.dex'): assert key in results assert len(results[key]) > 0
def test_scan_with_dummy_zip(scanner: Scanner): zip_entries = {'dummy': b'hello'} with make_temp_zip(zip_entries) as tz: results = scanner.scan_file(tz.name) assert tz.name in results assert len(results) == 1 assert len(results[tz.name]) > 0
def test_scan_with_dummy_zip(scanner: Scanner): zip_entries = {'dummy': b'hello'} with make_temp_zip(zip_entries) as tz: filename: str = os.path.basename(tz.name) results = scanner.scan_file(tz.name) assert filename in results assert len(results[filename]) > 0
def apkid_analysis(app_dir, apk_file, apk_name): """APKID Analysis of DEX files.""" if not settings.APKID_ENABLED: return {} try: import apkid except ImportError: logger.error('APKiD - Could not import APKiD') return {} if not os.path.exists(apk_file): logger.error('APKiD - APK not found') return {} apkid_ver = apkid.__version__ from apkid.apkid import Scanner, Options from apkid.output import OutputFormatter from apkid.rules import RulesManager logger.info('Running APKiD %s', apkid_ver) options = Options( timeout=30, verbose=False, entry_max_scan_size=settings.DATA_UPLOAD_MAX_MEMORY_SIZE, recursive=True, ) output = OutputFormatter( json_output=True, output_dir=None, rules_manager=RulesManager(), include_types=False, ) rules = options.rules_manager.load() scanner = Scanner(rules, options) res = scanner.scan_file(apk_file) try: findings = output._build_json_output(res)['files'] except AttributeError: # apkid >= 2.0.3 try: findings = output.build_json_output(res)['files'] except AttributeError: logger.error('yara-python dependency required by ' 'APKiD is not installed properly. ' 'Skipping APKiD analysis!') findings = {} sanitized = {} for item in findings: filename = item['filename'] if '!' in filename: filename = filename.split('!', 1)[1] sanitized[filename] = item['matches'] return sanitized
def apkid_analysis(app_dir, apk_file, apk_name): """APKID Analysis of DEX files.""" if not settings.APKID_ENABLED: return {} try: import apkid except ImportError: logger.error('APKiD - Could not import APKiD') return {} if not os.path.exists(apk_file): logger.error('APKiD - APK not found') return {} apkid_ver = apkid.__version__ from apkid.apkid import Scanner, Options from apkid.output import OutputFormatter from apkid.rules import RulesManager logger.info('Running APKiD %s', apkid_ver) options = Options( timeout=30, verbose=False, entry_max_scan_size=100 * 1024 * 1024, recursive=True, ) output = OutputFormatter( json_output=True, output_dir=None, rules_manager=RulesManager(), include_types=False, ) rules = options.rules_manager.load() scanner = Scanner(rules, options) res = scanner.scan_file(apk_file) try: findings = output._build_json_output(res)['files'] except AttributeError: # apkid >= 2.0.3 findings = output.build_json_output(res)['files'] sanitized = {} for item in findings: filename = item['filename'] sanitized[filename] = item['matches'] return sanitized
def test_scan_with_unscannable_file(scanner: Scanner): with make_temp_file(b'hello') as tz: results = scanner.scan_file(tz.name) assert len(results) == 0
def test_scan_with_unscannable_file(scanner: Scanner): with make_temp_file(b'hello') as tz: filename: str = os.path.basename(tz.name) results = scanner.scan_file(tz.name) assert results == {}