From 772154f12e146fa6f79f41d0d54e4a5994b3227f Mon Sep 17 00:00:00 2001 From: mame82 Date: Wed, 17 Feb 2021 13:18:03 +0100 Subject: [PATCH] allow \'sqlite connect\' to download temp files (write-ahead-log and shared memory) (#392) --- objection/commands/filemanager.py | 15 +++++ objection/commands/sqlite.py | 33 ++++++++- sqlite_patch.md | 108 ++++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 sqlite_patch.md diff --git a/objection/commands/filemanager.py b/objection/commands/filemanager.py index 03e4fb09..51b17b76 100644 --- a/objection/commands/filemanager.py +++ b/objection/commands/filemanager.py @@ -114,6 +114,21 @@ def cd(args: list) -> None: click.secho('Invalid path: `{0}`'.format(proposed_path), fg='red') +def path_exists(path: str) -> bool: + """ + Checks if a path exists on remote device. + + :param path: + :return: + """ + + if device_state.device_type == Ios: + return _path_exists_ios(path) + + if device_state.device_type == Android: + return _path_exists_android(path) + + def _path_exists_ios(path: str) -> bool: """ Checks an iOS device if a path exists. diff --git a/objection/commands/sqlite.py b/objection/commands/sqlite.py index 7e4c1193..6443ec3b 100644 --- a/objection/commands/sqlite.py +++ b/objection/commands/sqlite.py @@ -6,7 +6,7 @@ import litecli from litecli.main import LiteCli -from ..commands.filemanager import download, upload, pwd +from ..commands.filemanager import download, upload, pwd, path_exists def modify_config(rc): @@ -66,6 +66,10 @@ def connect(args: list) -> None: db_location = args[0] _, local_path = tempfile.mkstemp('.sqlite') + use_shm = False # does Shared Memory temp file exist ? + use_wal = False # does Write-Ahead-Log temp file exist ? + use_jnl = False # does Journal temp file exist ? + write_back_tmp_sqlite = False # if enabled temporary DB files are re-uploaded, this has not been testes # update the full remote path for future syncs full_remote_file = db_location \ @@ -73,6 +77,18 @@ def connect(args: list) -> None: click.secho('Caching local copy of database file...', fg='green') download([db_location, local_path]) + if path_exists(full_remote_file + '-shm'): + click.secho('... caching local copy of database "shm" file...', fg='green') + download([db_location + '-shm', local_path + '-shm']) + use_shm = True + if path_exists(full_remote_file + '-wal'): + click.secho('... caching local copy of database "wal" file...', fg='green') + download([db_location + '-wal', local_path + '-wal']) + use_wal = True + if path_exists(full_remote_file + '-journal'): + click.secho('... caching local copy of database "journal" file...', fg='green') + download([db_location + '-journal', local_path + '-journal']) + use_jnl = True click.secho('Validating SQLite database format', dim=True) with open(local_path, 'rb') as f: @@ -95,8 +111,23 @@ def connect(args: list) -> None: if _should_sync_once_done(args): click.secho('Synchronizing changes back...', dim=True) upload([local_path, full_remote_file]) + # re-uploading temp sqlite files has not been tested and thus is disabled by default + if write_back_tmp_sqlite: + if use_shm: + upload([local_path + '-shm', full_remote_file + '-shm']) + if use_wal: + upload([local_path + '-wal', full_remote_file + '-wal']) + if use_jnl: + upload([local_path + '-journal', full_remote_file + '-journal']) else: click.secho('NOT synchronizing changes back to device. Use --sync if you want that.', fg='green') # maak skoon cleanup(local_path) + if use_shm: + cleanup(local_path + '-shm') + if use_wal: + cleanup(local_path + '-wal') + if use_jnl: + cleanup(local_path + '-journal') + diff --git a/sqlite_patch.md b/sqlite_patch.md new file mode 100644 index 00000000..ba2ef2a0 --- /dev/null +++ b/sqlite_patch.md @@ -0,0 +1,108 @@ +# Attempt to download additional temporary SQLite files for DB inspection + +Android apps have been found to use 'Write-Ahead-Log' and 'Shared-Memory' +SQLite functionality. If the respective files aren't downloaded for local +inspection, database entries would be missing. + +## Test app TikTok for Android without patch + +Tables/DB entries missing: + +``` +root@who-knows:~/research/android/frida# objection --gadget com.zhiliaoapp.musically explore +Using USB device `GT-I9300` +Agent injected and responds ok! + + _ _ _ _ + ___| |_|_|___ ___| |_|_|___ ___ +| . | . | | -_| _| _| | . | | +|___|___| |___|___|_| |_|___|_|_| + |___|(object)inject(ion) v1.9.5 + + Runtime Mobile Exploration + by: @leonjza from @sensepost + +[tab] for command suggestions +com.zhiliaoapp.musically on (samsung: 7.1.2) [usb] # cd .. +/data/user/0/com.zhiliaoapp.musically +com.zhiliaoapp.musically on (samsung: 7.1.2) [usb] # cd databases +/data/user/0/com.zhiliaoapp.musically/databases +com.zhiliaoapp.musically on (samsung: 7.1.2) [usb] # sqlite connect androidx.work.workdb +Caching local copy of database file... +Downloading /data/user/0/com.zhiliaoapp.musically/databases/androidx.work.workdb to /tmp/tmpk7_eoerg.sqlite +Streaming file from device... +Writing bytes to destination... +Successfully downloaded /data/user/0/com.zhiliaoapp.musically/databases/androidx.work.workdb to /tmp/tmpk7_eoerg.sqlite +Validating SQLite database format +Connected to SQLite database at: androidx.work.workdb +SQLite @ androidx.work.workdb > .tables +Time: 0.001s +SQLite @ androidx.work.workdb > + +``` + +## Test app TikTok for Android with patch + +No tables/DB entries missing: + + +``` +root@who-knows:~/research/android/frida# objection --gadget com.zhiliaoapp.musically explore +Using USB device `GT-I9300` +Agent injected and responds ok! + + _ _ _ _ + ___| |_|_|___ ___| |_|_|___ ___ +| . | . | | -_| _| _| | . | | +|___|___| |___|___|_| |_|___|_|_| + |___|(object)inject(ion) v1.9.5 + + Runtime Mobile Exploration + by: @leonjza from @sensepost + +[tab] for command suggestions +com.zhiliaoapp.musically on (samsung: 7.1.2) [usb] # sqlite connect androidx.work.workdb +Caching local copy of database file... +Downloading /data/user/0/com.zhiliaoapp.musically/files/androidx.work.workdb to /tmp/tmpgc5zr1bj.sqlite +Unable to download file. Target path is not readable. +Validating SQLite database format +File does not appear to be a SQLite3 db. Try downloading and manually inspecting this one. +com.zhiliaoapp.musically on (samsung: 7.1.2) [usb] # cd .. +/data/user/0/com.zhiliaoapp.musically +com.zhiliaoapp.musically on (samsung: 7.1.2) [usb] # cd databases +/data/user/0/com.zhiliaoapp.musically/databases +com.zhiliaoapp.musically on (samsung: 7.1.2) [usb] # sqlite connect androidx.work.workdb +Caching local copy of database file... +Downloading /data/user/0/com.zhiliaoapp.musically/databases/androidx.work.workdb to /tmp/tmpuee0o3pf.sqlite +Streaming file from device... +Writing bytes to destination... +Successfully downloaded /data/user/0/com.zhiliaoapp.musically/databases/androidx.work.workdb to /tmp/tmpuee0o3pf.sqlite +... caching local copy of database "shm" file... +Downloading /data/user/0/com.zhiliaoapp.musically/databases/androidx.work.workdb-shm to /tmp/tmpuee0o3pf.sqlite-shm +Streaming file from device... +Writing bytes to destination... +Successfully downloaded /data/user/0/com.zhiliaoapp.musically/databases/androidx.work.workdb-shm to /tmp/tmpuee0o3pf.sqlite-shm +... caching local copy of database "wal" file... +Downloading /data/user/0/com.zhiliaoapp.musically/databases/androidx.work.workdb-wal to /tmp/tmpuee0o3pf.sqlite-wal +Streaming file from device... +Writing bytes to destination... +Successfully downloaded /data/user/0/com.zhiliaoapp.musically/databases/androidx.work.workdb-wal to /tmp/tmpuee0o3pf.sqlite-wal +Validating SQLite database format +Connected to SQLite database at: androidx.work.workdb +SQLite @ androidx.work.workdb > .tables ++-------------------+ +| name | ++-------------------+ +| Dependency | +| SystemIdInfo | +| WorkName | +| WorkSpec | +| WorkTag | +| android_metadata | +| room_master_table | ++-------------------+ +Time: 0.030s +SQLite @ androidx.work.workdb > +``` + +