Skip to content

Commit

Permalink
allow \'sqlite connect\' to download temp files (write-ahead-log and …
Browse files Browse the repository at this point in the history
…shared memory) (#392)
  • Loading branch information
mame82 committed Feb 17, 2021
1 parent 0dee9d6 commit 772154f
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 1 deletion.
15 changes: 15 additions & 0 deletions objection/commands/filemanager.py
Expand Up @@ -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.
Expand Down
33 changes: 32 additions & 1 deletion objection/commands/sqlite.py
Expand Up @@ -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):
Expand Down Expand Up @@ -66,13 +66,29 @@ 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 \
if os.path.isabs(db_location) else os.path.join(pwd(), db_location)

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:
Expand All @@ -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')

108 changes: 108 additions & 0 deletions 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 >
```


0 comments on commit 772154f

Please sign in to comment.