diff --git a/mobsf/DynamicAnalyzer/views/android/analysis.py b/mobsf/DynamicAnalyzer/views/android/analysis.py index 406f01b6b6..b46616d5c0 100644 --- a/mobsf/DynamicAnalyzer/views/android/analysis.py +++ b/mobsf/DynamicAnalyzer/views/android/analysis.py @@ -180,20 +180,19 @@ def safe_paths(tar_meta): yield fh -def get_app_files(apk_dir, package): - """Get files from device.""" - logger.info('Getting app files') - all_files = {'xml': [], 'sqlite': [], 'others': []} +def untar_files(tar_loc, untar_dir): + """Untar files.""" + logger.info('Extracting Tar files') # Extract Device Data - tar_loc = os.path.join(apk_dir, package + '.tar') - untar_dir = os.path.join(apk_dir, 'DYNAMIC_DeviceData/') - if not is_file_exists(tar_loc): - return all_files - if os.path.exists(untar_dir): + if not tar_loc.exists(): + return False + if untar_dir.exists(): # fix for permission errors shutil.rmtree(untar_dir) + else: + os.makedirs(untar_dir) try: - with tarfile.open(tar_loc, errorlevel=1) as tar: + with tarfile.open(tar_loc.as_posix(), errorlevel=1) as tar: def is_within_directory(directory, target): abs_directory = os.path.abspath(directory) @@ -216,14 +215,26 @@ def safe_extract(tar, path='.', pass except Exception: logger.exception('Tar extraction failed') + return True + + +def get_app_files(apk_dir, package): + """Get files from device.""" + logger.info('Getting app files') + all_files = {'xml': [], 'sqlite': [], 'others': [], 'plist': []} + app_dir = Path(apk_dir) + tar_loc = app_dir / f'{package}.tar' + untar_dir = app_dir / 'DYNAMIC_DeviceData' + success = untar_files(tar_loc, untar_dir) + if not success: + return all_files # Do Static Analysis on Data from Device try: - if not os.path.exists(untar_dir): - os.makedirs(untar_dir) + untar_dir = untar_dir.as_posix() for dir_name, _, files in os.walk(untar_dir): for jfile in files: file_path = os.path.join(untar_dir, dir_name, jfile) - fileparam = file_path.replace(untar_dir, '') + fileparam = file_path.replace(f'{untar_dir}/', '') if is_pipe_or_link(file_path): continue if jfile == 'lib': @@ -232,6 +243,9 @@ def safe_extract(tar, path='.', if jfile.endswith('.xml'): all_files['xml'].append( {'type': 'xml', 'file': fileparam}) + elif jfile.endswith('.plist'): + all_files['plist'].append( + {'type': 'plist', 'file': fileparam}) else: with open(file_path, # lgtm [py/path-injection] 'r', diff --git a/mobsf/DynamicAnalyzer/views/android/report.py b/mobsf/DynamicAnalyzer/views/android/report.py index 9b663c5a6f..f5e52a0b83 100644 --- a/mobsf/DynamicAnalyzer/views/android/report.py +++ b/mobsf/DynamicAnalyzer/views/android/report.py @@ -4,6 +4,7 @@ import ntpath import os import io +from pathlib import Path from django.conf import settings from django.shortcuts import render @@ -36,6 +37,10 @@ read_sqlite, ) +from biplist import ( + writePlistToString, +) + logger = logging.getLogger(__name__) register.filter('key', key) @@ -130,11 +135,10 @@ def view_file(request, api=False): return print_n_send_error_response(request, 'Invalid Parameters', api) - src = os.path.join( - settings.UPLD_DIR, - md5_hash, - 'DYNAMIC_DeviceData/') - sfile = os.path.join(src, fil) + src = Path(settings.UPLD_DIR) / md5_hash / 'DYNAMIC_DeviceData' + sfile = src / fil + src = src.as_posix() + sfile = sfile.as_posix() if not is_safe_path(src, sfile) or is_path_traversal(fil): err = 'Path Traversal Attack Detected' return print_n_send_error_response(request, err, api) @@ -143,7 +147,9 @@ def view_file(request, api=False): mode='r', encoding='ISO-8859-1') as flip: dat = flip.read() - if fil.endswith('.xml') and typ == 'xml': + if fil.endswith('.plist') and 'bplist00' in dat: + dat = writePlistToString(dat).decode('utf-8', 'ignore') + if fil.endswith(('.xml', '.plist')) and typ in ['xml', 'plist']: rtyp = 'xml' elif typ == 'db': dat = None diff --git a/mobsf/DynamicAnalyzer/views/ios/analysis.py b/mobsf/DynamicAnalyzer/views/ios/analysis.py index e7745bc17c..a1732de0c3 100644 --- a/mobsf/DynamicAnalyzer/views/ios/analysis.py +++ b/mobsf/DynamicAnalyzer/views/ios/analysis.py @@ -63,9 +63,12 @@ def run_analysis(app_dir, checksum): for email in EMAIL_REGEX.findall(data.lower()): if (email not in emails) and (not email.startswith('//')): emails.append(email) - analysis_result['appdata'] = get_app_files( + pfiles = get_app_files( app_dir, f'{checksum}-app-container') + analysis_result['sqlite'] = pfiles['sqlite'] + analysis_result['plist'] = pfiles['plist'] + analysis_result['others'] = pfiles['others'] analysis_result['urls'] = urls analysis_result['domains'] = domains analysis_result['emails'] = emails @@ -86,7 +89,7 @@ def ios_api_analysis(app_dir): 'pasteboard': [], 'textinputs': [], 'datadir': [], - 'sqlite': [], + 'sql': [], } try: dump_file = app_dir / 'mobsf_dump_file.txt' @@ -121,7 +124,7 @@ def ios_api_analysis(app_dir): elif parsed.get('datadir'): dump['datadir'] = parsed['datadir'] elif parsed.get('sql'): - dump['sqlite'].append(parsed['sql']) + dump['sql'].append(parsed['sql']) if len(dump['network']) > 0: dump['network'] = list( {v['url']: v for v in dump['network']}.values()) diff --git a/mobsf/templates/dynamic_analysis/ios/dynamic_report.html b/mobsf/templates/dynamic_analysis/ios/dynamic_report.html index b560afe7f3..7bad9c2136 100644 --- a/mobsf/templates/dynamic_analysis/ios/dynamic_report.html +++ b/mobsf/templates/dynamic_analysis/ios/dynamic_report.html @@ -413,7 +413,6 @@
-{{ appdata }}QUERIES | ||||||
---|---|---|---|---|---|---|
{{item}}
@@ -1137,6 +1136,104 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ + SQLITE DATABASE + +
+
+
+
+
+
+
+
+
+
+
+
+
+ + PLIST FILES + +
+
+
+
+
+
+
+
+
+
+
+
+
+ + OTHER FILES + +
+
+
|